2

假设我有一个包含灰度视频的数据集。每个视频的长度和大小可能会有所不同,因此我通过以下形状表示三个维度的数据:

批量大小 时间 是的 X 渠道
没有任何 没有任何 没有任何 没有任何 1

我想从时间维度中提取特征(比如 16 个),同时保持相同的空间维度,这会给我以下输出形状:

批量大小 是的 X 过滤器
没有任何 没有任何 没有任何 16

值得注意的是,数据的形状已经减少了一维。在我看来,我应该能够使用 Conv3D 算子(特征生成)然后在时间维度上进行一些聚合操作(全局/平均池或一些线性算子)来完成此操作。生成的形状将是 (None, 1, None, None, 16) ,我相信我可以使用这个答案将其简化为 (None, None, None, 16) 。

我的问题是我无法弄清楚如何在一个维度上应用 Keras 的任何全局运算符。由于时间维度的大小是未知的,因此我无法为将跨越整个时间维度的MaxPooling卷积层指定窗口大小(未知、1、1)。另一方面,GlobalMaxPooling层不接受用于指定要对哪些维度进行操作的参数。

我是否必须为此实现一些复杂的自定义层,或者是否已经存在解决方案?我用 MaxPooling1D 看过 Reshape 层,但我遇到了同样的问题,即在池化操作后不知道 x 和 y 维度的大小来重新组装空间结构。

4

1 回答 1

1

如果您不想使用自定义图层,我相信您可以执行以下操作:

x = Input(shape=(Batch_size, time, y, x, 1))
# Process data wrt time and spaciall info, as many layer as you want
x = Conv3D(filters_num_0, kernel_size_0, strides=1, padding="same", activation=activation_0)(x) # (Batch_size, time, y, x, filters_num_0)
x = Conv3D(filters_num_1, kernel_size_1, strides=1, padding="same", activation=activation_1)(x) # (Batch_size, time, y, x, filters_num_1)
# # Aggregate channel info
x = Conv3D(1, kernel_size_2, strides=1, padding="same", activation=activation_2)(x) # (Batch_size, time, y, x, 1)
# Reshape for dimension reduce
x = Reshape(target_shape=(Batch_size, y, x, time))(x) 
# Aggregate time info
x = Conv2D(16, kernel_size_3, strides=1, padding="same", activation=activation_3 ) # (Batch_size, y, x, 16)

使用自定义层为跨时间的全局平均池做:

class GlobalAvgPoolAcrossTime(layers.Layer):
    def __init__(self, **kwargs):
        super(GlobalAvgPoolAcrossTime, self).__init__(**kwargs)

    # (Batch_size, time, y, x, channels) -> (Batch_size, 1, y, x, channels)
    def call(self, inputs):
        return keras.backend.mean(inputs, axis=1, keepdims=True)

x = Input(shape=(Batch_size, time, y, x, 1))
# Process data wrt time and spaciall info, as many layer as you want
x = Conv3D(filters_num_0, kernel_size_0, strides=1, padding="same", activation=activation_0)(x) # (Batch_size, time, y, x, filters_num_0)
x = Conv3D(filters_num_1, kernel_size_1, strides=1, padding="same", activation=activation_1)(x) # (Batch_size, time, y, x, filters_num_1)
x = GlobalAvgPoolAcrossTime()(x) # (Batch_size, 1, y, x, filters_num_1)
# Reshape for dimension reduce
x = Reshape(target_shape=(Batch_size, y, x, filters_num_1))(x)
x = Conv2D(16, kernel_size_2, strides=1, padding="same", activation=activation_3 ) # (Batch_size, y, x, 16)
于 2020-12-16T03:41:02.043 回答