我想使用图像序列预测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)],
…
]
为什么?
这个选择确实取决于您要实现的目标。了解您的数据是完全影响决定的。(不仅是数据的形状和类型,而且它的含义和您想要什么。它是视频吗?许多视频?我想要视频的小部分中的角色名称吗?还是知道沿视频持续的情节状态?)
选项A:
当您的所有图像形成一个长序列时,都会使用此选项,并且您想通过了解特定数量的先前图像来预测序列中的下一个元素。
该批次中的每组3张图像都是完全独立的。该图层不会在它们之间保留内存,而实际的内存为长度3。
发生长序列的模拟是因为您在每个批处理中重复图像,例如滑动窗口。但是没有连接或内存从一个组到另一组的转移。
如果序列具有从3个图像预测的任何逻辑可能性,则使用此方法。
想象一下您有一个很长的视频,但是您只观看了三秒钟的三秒钟,并尝试从这3秒钟中推断出一些东西。但是,在您观看另外3秒钟之前,您的记忆被完全冲走了。当您观看这3秒钟的新秒时,您将无法记住您之前观看的内容,也无法说自己观看了4秒钟。您所学的所有内容都将被限制在3秒内。
选项B:
在此选项中,每个3张图像的每组完全没有与其他图像的联系。您可以使用它,就好像3个图像的每组都是不同的序列(不属于长序列)。
图像您有很多视频,他们谈论了不同的事情。一个是泰坦尼克号,另一个是复仇者联盟,依此类推。
此批次可用于类似于A中建议的情况,但是您的滑动窗口将具有第3步。这将使学习更快,但也使其减少了学习。
其他选项:
您可以查看这个问题,其答案和评论以有更多想法。
关于拆分数据的一些提示:
首先,输入和输出数据必须分开:
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需要将输入成形为(numberOf sequences,sequenceCelength,功能)
>一个建议是使用重塑层:
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.