我正在使用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)
感谢您的帮助。
答案 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)