如何在张量流keras中将多图像输入正确地馈送到多输入cnn模型

时间:2019-05-20 13:23:09

标签: python tensorflow keras deep-learning

我正在尝试将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

这是我从csv文件中为每个存储桶中的4张图像加载值的方法:

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维,我仍然会收到该错误!我想念什么?

0 个答案:

没有答案