如何将3D矩阵降维为2D矩阵使用Keras?

我已经构建了一个Keras的ConvLSTM神经网络,并且我想基于10个时间步的序列来预测下一帧:

from keras.models import Sequentialfrom keras.layers.convolutional import Conv3Dfrom keras.layers.convolutional_recurrent import ConvLSTM2Dfrom keras.layers.normalization import BatchNormalizationimport numpy as npimport pylab as pltfrom keras import layers# 我们创建一个层,该层接受形状为# (n_frames, width, height, channels) 的电影作为输入,并返回一个形状相同的电影。model = Sequential()model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),                   input_shape=(None, 64, 64, 1),                   padding='same', return_sequences=True))model.add(BatchNormalization())model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),                   padding='same', return_sequences=True))model.add(BatchNormalization())model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),                   padding='same', return_sequences=True))model.add(BatchNormalization())model.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),                   padding='same', return_sequences=True))model.add(BatchNormalization())model.add(Conv3D(filters=1, kernel_size=(3, 3, 3),               activation='sigmoid',               padding='same', data_format='channels_last'))model.compile(loss='binary_crossentropy', optimizer='adadelta')

训练:

data_train_x = data_4[0:20, 0:10, :, :, :]data_train_y = data_4[0:20, 10:11, :, :, :]model.fit(data_train_x, data_train_y, batch_size=10, epochs=1, validation_split=0.05)

然后我测试模型:

test_x = np.reshape(data_test_x[2,:,:,:,:], [1,10,64,64,1])next_frame = model.predict(test_x,batch_size=1, verbose=1, steps=None)

但问题是’next_frame’的形状是:(1, 10, 64, 64, 1),而我希望它的形状是(1, 1, 64, 64, 1)。

这是’model.summary()’的结果:

_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================conv_lst_m2d_1 (ConvLSTM2D)  (None, None, 64, 64, 40)  59200     _________________________________________________________________batch_normalization_1 (Batch (None, None, 64, 64, 40)  160       _________________________________________________________________conv_lst_m2d_2 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    _________________________________________________________________batch_normalization_2 (Batch (None, None, 64, 64, 40)  160       _________________________________________________________________conv_lst_m2d_3 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    _________________________________________________________________batch_normalization_3 (Batch (None, None, 64, 64, 40)  160       _________________________________________________________________conv_lst_m2d_4 (ConvLSTM2D)  (None, None, 64, 64, 40)  115360    _________________________________________________________________batch_normalization_4 (Batch (None, None, 64, 64, 40)  160       _________________________________________________________________conv3d_1 (Conv3D)            (None, None, 64, 64, 1)   1081      =================================================================Total params: 407,001Trainable params: 406,681Non-trainable params: 320

所以我不知道应该添加哪一层来将输出减少到1帧而不是10帧?


回答:

基于最终层的3D卷积,这是预期的结果。例如,如果你在3维张量上使用一个Conv2D层,并且设置padding=’same’,这意味着它将生成一个相同高度和宽度的2D输出(例如,过滤器隐式地也在深度轴上捕获)。

对于4维张量的3D卷积也是如此,它隐式地在通道维度的深度轴上捕获,生成一个与输入相同(序列索引、高度、宽度)的3-D张量。

听起来你想在Conv3D层之后添加某种池化步骤,使其在序列维度上展平,例如使用AveragePooling3D,其池化元组为(10, 1, 1),以在第一个非批次维度上进行平均(或根据你的具体网络需求进行修改)。

或者,假设你想通过仅取最后一个序列元素来专门“池化”序列维度(例如,不是通过序列进行平均或最大池化)。你可以将最后一个ConvLSTM2D层设置为return_sequences=False,然后在最后一步中进行2D卷积,但这意味着你的最终卷积将无法从预测帧序列的聚合中受益。是否这样做是一个好主意,可能取决于具体应用。

为了确认第一种方法,我添加了:

model.add(layers.AveragePooling3D(pool_size=(10, 1, 1), padding='same'))

就在Conv3D层之后,然后制作了玩具数据:

x = np.random.rand(1, 10, 64, 64, 1)

然后:

In [22]: z = model.predict(x)In [23]: z.shapeOut[23]: (1, 1, 64, 64, 1)

你需要确保在第一个非批次维度上的池化大小设置为最大可能的序列长度,以确保最终输出形状总是(1, 1, …)。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注