Как правильно подать вход с несколькими изображениями на модель cnn с несколькими входами в тензорном режиме - PullRequest
0 голосов
/ 20 мая 2019

Я пытаюсь подать 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-мерными! Чего мне не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...