Keras LSTM CNN处理图像序列的批次应该是什么

时间:2017-09-13 00:34:40

标签: keras lstm

我想使用图像序列来预测1输出。

培训数据:

[(x_img1, y1), (x_img2, y2), ..., (x_img10, y10)]

彩色图像尺寸:

(100, 120, 3) 

输出维度:(1)

在Keras实施的模型:

img_sequence_length = 3

 model = Sequential()
 model.add(TimeDistributed(Convolution2D(24, 5, 5, subsample=(2, 2), border_mode="same", activation=‘rely’, name='conv1'),
          input_shape=(img_sequence_length,
                       100,
                       120,
                       3)))

...

model.add(LSTM(64, return_sequences=True, name='lstm_1'))
model.add(LSTM(10, return_sequences=False, name='lstm_2'))
model.add(Dense(256))
model.add(Dense(1, name='output'))

批次应为:

A)

[ [(x_img1, y1), (x_img2, y2), (x_img3, y3)], 
  [(x_img2, y2), (x_img3, y3), (x_img4, y4)],

…
]

B)

[ [(x_img1, y1), (x_img2, y2), (x_img3, y3)], 
  [(x_img4, y4), (x_img5, y5), (x_img6, y6)],
…
]

为什么?

1 个答案:

答案 0 :(得分:0)

这个选择实际上取决于你想要达到的目标。了解您的数据完全会影响决策。 (不仅是数据的形状和类型,还有它的含义和你想要的东西。它是一个视频吗?很多视频?我想在视频的一小部分中找到角色的名字吗?或者知道情节的状态不断沿着视频?)

在选项A中:

当所有图像形成单个长序列并且您想要通过了解特定数量的先前图像来预测序列中的下一个元素时,将使用此选项。

该批次中的每组3幅图像完全独立。 该层不会在它们之间保留内存,实际内存长度为3.

长序列的模拟发生是因为您在每个批次中重复图像,如滑动窗口。但是没有从一个组到另一个组的连接或内存传输。

如果序列具有从3个图像预测的任何逻辑可能性,则使用此项。

  

想象一下,你有一个很长的视频,但是你只观看了3秒,然后尝试从这3秒钟中推断出一些东西。但是,在你再观看3秒之前,你的记忆会完全消失。当你观看这3个新的秒数时,你将无法记住你之前看过的内容,你将无法说你看了4秒钟。你所学到的只会被限制在3秒内。

在选项B中:

在此选项中,每组3张图像与其他图像完全没有任何关联。你可以使用它,好像每组3个图像都是不同的序列(不属于长序列)。

  

图片你有很多视频,他们谈论不同的事情。一个是泰坦尼克号,另一个是复仇者,等等。

此批次可用于类似于A中提出的情况,但您的滑动窗口将有第3步。这将使学习更快,但也减少学习。

其他选项:

您可以查看this question,其答案和评论,以获得更多想法。

有关拆分数据的一些提示:

首先,输入和输出数据必须是分开的:

X = [item[0] for item in training_data]
Y = [item[1] for item in training_data]

然后你必须正确地分开序列。 正如您在input_shape中定义的那样,X必须遵循相同的形状。

X.shape must be (numberOfSequences, img_sequence_length, 100, 120, 3)

因此,如果它是一个图像列表,你必须确保每个图像都是一个numpy数组(必要时转换它们),然后你将把X转换为numpy:

X = np.asarray(X_with_numpy_images)

如果每个序列只有一个Y,则可以将其整形为:

Y.shape must be (numberOfSequences,1)

你可能会按照3的步骤安装它:

Y = [Y[(i+1)*3 - 1] for i in range(numberOfSequences)]

现在重要的是要了解3个图像的每个序列是否独立于其他序列,或者只有一个巨大的序列分成小部分。

如果是一个,请使用LSTM(..., stateful=False),如果是两个,请使用LSTM(...,stateful=True)

并且您可能还需要在从卷积层到LSTM层的过渡中正确地重新形成张量,因为LSTM将需要形状为(NumberOfSequences,SequenceLength,Features)的输入

建议使用重塑图层:

model.add(Reshape((img_sequence_length,100*120*3)))
#of course the last dimension may be different if you don't use `padding='same'` in the convolutions of if you use pooling.