Keras 检查输入时出错:预期时间\u分布\u 136\u输入有5个维度,但得到了形状为(16、128、128、3)的数组
我正在用LSTM训练CNN,在那里我使用时间分布,但显然它需要额外的数据维度。我不知道如何添加它。 我的想法是,问题出在ImageGenerator中,但我不知道如何重塑由它生成的图像Keras 检查输入时出错:预期时间\u分布\u 136\u输入有5个维度,但得到了形状为(16、128、128、3)的数组,keras,deep-learning,Keras,Deep Learning,我正在用LSTM训练CNN,在那里我使用时间分布,但显然它需要额外的数据维度。我不知道如何添加它。 我的想法是,问题出在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_mo
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级
--视频1
--frame1.jpg
--frame2.jpg
--frame3.jpg
--第一类
--frame1.jpg
--frame2.jpg
--frame3.jpg
--第二类
--第三类
--试验
(与列车相同)
谢谢您的帮助。我想您的问题出在您的
型号上。在模型中,您将TimeDistributed
的输入形状定义为input\u-shape=(16,128,128,3)
,我想应该是input\u-shape=(128,128,3)
更改此行:
model.add(TimeDistributed(cnn_model, input_shape=(16, 128, 128,3)))
致:
我希望它能起作用。你正在模糊每个张量的第一维,也就是批量大小。除非绝对必要,否则不定义批次大小,因此输入形状不考虑它。p>
定义input\u shape=(16128128,3)
时,这意味着数据必须有五个维度:(示例16、128、128,3)
数据中缺少示例维度
如果你说它们是电影,你应该有像(电影、帧、高度、宽度、频道)
这样的数据。然后这将被input\u shape=(帧、高度、宽度、通道)
接受 经过几次试验后,我最终使用了相同的代码,但使用了Keras“ImageDataGenerator”类的一个经过调整的版本,为数据添加了一个额外的维度,使其成为5D。
(这也适用于Conv3D的使用)
对于面临相同问题的任何人,您都可以找到我的ImageDataGenerator类的调整版本
它与主Keras ImageDataGenerator相同,但我添加了一个选项,可以在每次迭代中获取多个图像/帧。这是通过更改参数frames\u per\u 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)
从调整的_ImageGenerator_v2导入ImageDataGenerator
datagen=ImageDataGenerator()
train_data=datagen.flow_from_directory('path/to/data',target_size=(x,y),batch_size=32,frames_per_step=4)为什么要将输入传递到TimeDistributed,而不是直接传递到LSTM?为什么定义两个顺序模型而一个就足够了?我想为视频分类制作一个堆叠的CNN层,而这两个顺序模型并不构成问题。为什么要将TimeDistributed
的输入形状确定为input\u shape=(16,128,128,3)
而不仅仅是TimeDiinput\u shape=(128,128,3)
?不,这是不对的。请查查原因?问题出在哪里?我的答案完全是根据文档给出的。下面是文档中的代码:model=Sequential()model.add(TimeDistributed(Conv2D(64,(3,3)),input_shape=(10299299,299,3)),是的,我试过了,它给出了一个错误:那么你能发布这个新错误吗。也许你的问题解决了,而现在你又面临新的问题。谢谢,我得到了你的答案,但我不知道如何解决这个问题,也不知道要改变什么。这是否意味着改变数据的组织方式?你的形状是什么?每个批次的帧数是多少?好的,那么一切都是正确的,你只需要多部电影。(你可以证明这一点)
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)