Я пытаюсь подать 4 разных изображения на мульти вход CNN.
Вот как я загружаю изображения:
data_root = pathlib.Path('dataset/')
all_image_paths = list(data_root.glob('*/*'))
all_image_paths = [str(path) for path in all_image_paths]
image_count = len(all_image_paths)
size = 300
def load_and_preprocess_image(path):
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image,3)
# image = tf.image.central_crop(image, 0.8)
image = tf.image.resize(image, [size, size])
image /= 255.0 # normalize to [0,1] range
return image
trainA = []
trainB = []
trainC = []
trainD = []
testA = []
testB = []
testC = []
testD = []
i = 0
while i < 140:
trainA.append(load_and_preprocess_image(all_image_paths[i]))
trainB.append(load_and_preprocess_image(all_image_paths[i + 1]))
trainC.append(load_and_preprocess_image(all_image_paths[i + 2]))
trainD.append(load_and_preprocess_image(all_image_paths[i + 3]))
i = i+4
while i < 160:
testA.append(load_and_preprocess_image(all_image_paths[i]))
testB.append(load_and_preprocess_image(all_image_paths[i + 1]))
testC.append(load_and_preprocess_image(all_image_paths[i + 2]))
testD.append(load_and_preprocess_image(all_image_paths[i + 3]))
i = i+4
И вот как я загружаю значения для каждого блока из 4 изображений из файла CSV:
import csv
values = []
with open('dataset/agrumeto.csv', newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in spamreader:
values.append(', '.join(row))
kilo_train = values[:35]
kilo_test = values[35:]
Я определил свою модель следующим образом:
def create_conv_layer(input):
# the first branch operates on the first input
x = tf.keras.layers.Conv2D(32, (7, 7), activation='relu')(input)
x = tf.keras.layers.MaxPooling2D((2, 2), (2,2))(x)
x = tf.keras.Model(inputs=input, outputs=x)
return x
# define two sets of inputs
inputA = tf.keras.Input(shape=(size,size,3))
inputB = tf.keras.Input(shape=(size,size,3))
inputC = tf.keras.Input(shape=(size,size,3))
inputD = tf.keras.Input(shape=(size,size,3))
x = create_conv_layer(inputA)
y = create_conv_layer(inputB)
w = create_conv_layer(inputC)
z = create_conv_layer(inputD)
# combine the output of the two branches
combined = tf.keras.layers.concatenate([x.output, y.output, w.output, z.output])
layer_1 = tf.keras.layers.Conv2D(16, (3,3), activation="relu")(combined)
layer_1 = tf.keras.layers.MaxPooling2D((2, 2))(layer_1)
layer_2 = tf.keras.layers.Conv2D(16, (3,3), activation="relu")(layer_1)
layer_2 = tf.keras.layers.MaxPooling2D((2, 2), (2,2))(layer_2)
layer_3 = tf.keras.layers.Conv2D(32, (3,3), activation="relu")(layer_2)
layer_3 = tf.keras.layers.MaxPooling2D((2, 2), (2,2))(layer_3)
layer_4 = tf.keras.layers.Conv2D(32, (3,3), activation="relu")(layer_3)
layer_4 = tf.keras.layers.MaxPooling2D((2, 2), (2,2))(layer_4)
flatten = tf.keras.layers.Flatten()(layer_4)
hidden1 = tf.keras.layers.Dense(10, activation='relu')(flatten)
output = tf.keras.layers.Dense(1, activation='relu')(hidden1)
model = tf.keras.Model(inputs=[x.input, y.input, w.input, z.input], outputs=output)
# print(model.summary())
Я пытаюсь запустить модель, используя следующий код:
model.compile(optimizer='adam', loss="mean_absolute_percentage_error")
print("[INFO] training model...")
dataset = tf.data.Dataset.from_tensor_slices(
(tf.stack(trainA), tf.stack(trainB),tf.stack(trainC), tf.stack(trainD)) )
output_set = tf.data.Dataset.from_tensor_slices(kilo_train)
dataset = tf.data.Dataset.zip((dataset, output_set))
model.fit(dataset, epochs=5, steps_per_epoch=10, verbose=1)
test_loss, test_acc = model.evaluate([testA, testB, testC, testD], kilo_test)
print(test_acc)
Но я получаю следующую ошибку:
> ValueError: Error when checking input: expected input_1 to have 4
> dimensions, but got array with shape (300, 300, 3)
Я использую tf.stack для получения одного тензора для каждой серии изображений:
<tf.Tensor: id=3439, shape=(35, 300, 300, 3)
without tf.stack, I get the following data structure:
<tf.Tensor: id=10, shape=(300, 300, 3) ( followed by more tensors )
В основном это список тензоров
Если я не использую tf.stack, я все равно получаю ту же ошибку. Если я изменю набор данных на:
> dataset = tf.data.Dataset.from_tensor_slices( [
> trainA, trainB,trainC, trainD])
Я получаю еще одну ошибку:
> Error when checking model input: the list of Numpy arrays that you are
> passing to your model is not the size the model expected. Expected to
> see 4 array(s), but instead got the following list of 1 arrays:
> [<tf.Tensor: id=3850, shape=(35, 300, 300, 3), dtype=float32, numpy=
Но даже если я пропущу кортеж из 4 массивов, я все равно получу эту ошибку, даже если использование tf.stack сделает тензоры 4-мерными! Чего мне не хватает?