检查输入时出错:预期time_distributed_136_input具有5个维,但数组的形状为(16,128,128,3)

时间:2018-12-29 14:14:13

标签: keras deep-learning

我正在使用LSTM训练CNN,我在其中使用TimeDistributed,但显然它想要为数据提供额外的维度。我不知道如何添加。 我的想法是问题出在ImageGenerator中,但我不知道如何重塑由此生成的图像。

cnn_model = Sequential()

cnn_model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(128,128,3)))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))

cnn_model.add(Conv2D(32, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))

cnn_model.add(Conv2D(64, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))

cnn_model.add(Conv2D(128, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))
cnn_model.add(Flatten())

model = Sequential()
model.add(TimeDistributed(cnn_model, input_shape=(16, 128, 128,3)))
model.add(LSTM(128, return_sequences=True, dropout=0.5))
# model.add(Dropout(0.2)) #added
model.add(Dense(4, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
batch_size = 16


train_datagen = ImageDataGenerator(rescale=1. / 255)
test_datagen = ImageDataGenerator(rescale=1./255)


train_generator = train_datagen.flow_from_directory(
        'train/',  # this is the target directory
        target_size=(128,128),  
        batch_size=batch_size,
        class_mode='categorical',
        shuffle=True,
        classes=['class_0', 'class_1','class_2','class_3'])

validation_generator = test_datagen.flow_from_directory(
        'test/',
        target_size=(128,128),  
        batch_size=batch_size,
        class_mode='categorical',
        shuffle=True,
        classes=['class_0', 'class_1','class_2','class_3'])
model.fit_generator(
        train_generator,
        steps_per_epoch=47549 // batch_size,
        epochs=5,
        validation_data=validation_generator,
        validation_steps=5444 // batch_size)

但是我收到以下错误消息

ValueError: Error when checking input: expected time_distributed_136_input to have 5 dimensions, but got array with shape (16, 128, 128, 3)

数据文件夹如下:

 -- train
    -- class 0
       -- vid 1
          -- frame1.jpg
          -- frame2.jpg
          -- frame3.jpg
    -- class 1
          -- frame1.jpg
          -- frame2.jpg
          -- frame3.jpg
    -- class 2
    -- class 3
 -- test
   (same as train) 

感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

我认为您的问题出在您的model上。您在TimeDistributed中将model的输入形状定义为input_shape=(16, 128, 128,3),我想应该是input_shape=(128, 128,3)

更改此行:

model.add(TimeDistributed(cnn_model, input_shape=(16, 128, 128,3)))

收件人:

model.add(TimeDistributed(cnn_model, input_shape=(128, 128,3)))

我希望它会起作用。

答案 1 :(得分:0)

您正在模糊每个张量的第一维,即批量大小。除非绝对必要,否则不要定义批处理大小,因此输入形状不会考虑。

定义input_shape=(16,128,128,3)时,这意味着您的数据必须具有五个维度:(examples, 16, 128, 128, 3)

示例维度在您的数据中丢失。

如果您说它们是电影,则可能应该有(movies, frames, height, width, channels)之类的数据。然后input_shape=(frames, height, width, channels)会接受。

答案 2 :(得分:0)

经过几次试验,我最终使用了相同的代码,但使用了Keras“ ImageDataGenerator”类的经过调整的版本,为数据添加了额外的维度,从而使其成为5D。 (这对于使用Conv3D也有效)

对于遇到相同问题的任何人,您都可以找到我经过调整的ImageDataGenerator类here的版本。

它与主要的Keras ImageDataGenerator相同,但是我添加了一个选项,可以在每次迭代中获取多个图像/帧。这是通过更改参数 frames_per_step 来指定要在每次迭代中包含的帧/图像的数量。

所以这是使用方法:

from tweaked_ImageGenerator_v2 import ImageDataGenerator
datagen = ImageDataGenerator()
train_data=datagen.flow_from_directory('path/to/data', target_size=(x, y), batch_size=32, frames_per_step=4)