我目前正在尝试构建一个使用图像序列的模型,并使用TF后端对Keras中序列中的每个项目进行分类(不保留序列之间的状态);但是,我遇到了第一层输入形状的问题。
模型看起来像这样:
model.add(TimeDistributed(Conv2D(64, (3, 3), activation='relu'), input_shape=(10, 1, 224, 224, 3)))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(1, 1))))
model.add(TimeDistributed(Conv2D(128, (4,4), activation='relu')))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Conv2D(256, (4,4), activation='relu')))
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2))))
model.add(TimeDistributed(Flatten()))
model.add(Dropout(0.5))
model.add(LSTM(256, return_sequences=False, dropout=0.5))
model.add(Dense(num_classes, activation='sigmoid'))
我认为我的问题来自于对阵列形状缺乏了解,而且我很可能在这里犯了一个业余错误。每个单独的序列被加载到一个numpy形状的数组(10,1,224,224,3),其中第一个轴是序列中的项目数(它们被填充为相同的长度),第二个是批处理大小,其他只是一个RGB图像。根据我的理解,通过阅读有关文档(和我的错误)的可用信息,时间分布式包装器中的conv2D采用5D数组,基本上被格式化为(批量大小,行,列,通道)的正常conv2D输入加上添加时间维度(序列中的每个项目)。这是否接近准确?
继续讨论我面临的问题...... 如果我尝试输入形状的图像序列(10,1,224,224,3),我会得到错误 “ValueError:输入通道的数量与过滤器的相应尺寸不匹配,224!= 3”。任何人都可以对此有所了解吗?我很确定我没有正确地调整输入数组和input_shape。
我可以回答的另一个问题是: 一旦解决了这个问题并且我可以使用序列作为输入,我该如何为模型提供不仅仅是如上所示的单个图像序列,而是使用序列数组?我的数据集由数千个这些序列组成。我之前使用Caffe的所有经验都是使用Caffe,当然不是任何使用循环模型的东西,所以我不仅不熟悉实际的循环网络,我不熟悉Keras整体(虽然我开始学习,虽然慢慢地大声笑)。根据我的经验和观察,Caffe在您和数据输入之间提供了一个沉重的抽象层,所以我以前从未处理过这个问题。
我希望这个问题和我的问题清晰简洁,所提供的任何信息都非常感谢!
答案 0 :(得分:1)
根据Keras文档,您必须将input_dim更新为
model.add(TimeDistributed(Conv2D(64, (3, 3), activation='relu'), input_shape=(10, 224, 224, 3)))
,然后使用适合新数据形状的图像生成器。 您可以在此gist中使用经过调整的版本。
它与主要的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)