为啥 Keras Conv1D 层的输出张量没有输入维度?

Posted

技术标签:

【中文标题】为啥 Keras Conv1D 层的输出张量没有输入维度?【英文标题】:Why do Keras Conv1D layers' output tensors not have the input dimension?为什么 Keras Conv1D 层的输出张量没有输入维度? 【发布时间】:2017-12-18 14:31:31 【问题描述】:

根据 keras 文档 (https://keras.io/layers/convolutional/),Conv1D 输出张量的形状是 (batch_size, new_steps, filters),而输入张量形状是 (batch_size, steps, input_dim)。我不明白这是怎么回事,因为这意味着如果你传递一个长度为 8000 的一维输入,其中 batch_size = 1 和 steps = 1(我听说 steps 意味着你输入中的通道数)那么这个层会有形状为 (1,1,X) 的输出,其中 X 是 Conv 层中的过滤器数量。但是输入维度会发生什么?由于层中的 X 过滤器应用于整个输入维度,因此输出维度中的一个不应该是 8000(或更少,取决于填充),比如 (1,1,8000,X)?我检查了 Conv2D 层的行为方式更有意义,它们的 output_shape 是(样本、过滤器、new_rows、new_cols),其中 new_rows 和 new_cols 将是再次根据填充调整的输入图像的尺寸。如果 Conv2D 层保留其输入尺寸,为什么 Conv1D 层不保留?我这里有什么遗漏吗?

背景信息:

我正在尝试可视化我的 CNN 的 1d 卷积层激活,但我发现的大多数在线工具似乎只适用于 2d 卷积层,所以我决定为它编写自己的代码。我已经很好地理解了它的工作原理是我到目前为止的代码:

# all the model's activation layer output tensors
activation_output_tensors = [layer.output for layer in model.layers if type(layer) is keras.layers.Activation]

# make a function that computes activation layer outputs
activation_comp_function = K.function([model.input, K.learning_phase()], activation_output_tensors)

# 0 means learning phase = False (i.e. the model isn't learning right now)
activation_arrays = activation_comp_function([training_data[0,:-1], 0])

此代码基于 julienr 在thread 中的第一条评论,并对当前版本的 keras 进行了一些修改。果然当我使用它时,虽然所有的激活数组都是形状(1,1,X)......我昨天花了一整天试图弄清楚为什么会这样,但没有运气,非常感谢任何帮助。

更新:原来我把 input_dimension 的含义误认为是 steps 维度。这主要是因为我使用的架构来自另一组,他们在mathematica 中构建他们的模型,在mathematica 中,Conv1D 层的(X,Y) 输入形状意味着X“通道”(或X 的input_dimension)和Y 步。感谢 gionni 帮助我实现这一点并很好地解释了“input_dimension”如何成为“filter”维度。

【问题讨论】:

【参考方案1】:

我曾经在 2D 卷积上遇到过同样的问题。问题是,当您应用卷积层时,您应用的内核的大小不是(kernel_size, 1),而是实际上(kernel_size, input_dim)

如果不是这样,带有kernel_size = 1 的一维卷积层将不会对它接收到的输入做任何事情。

相反,它在每个时间步计算输入特征的加权平均值,对每个时间步使用相同的权重(尽管每个过滤器使用不同的权重集)。我认为这有助于将input_dim 可视化为图像的二维卷积中channels 的数量,其中适用相同的推理(在这种情况下,channels “迷路”并转换为过滤器的数量)。

为了让自己相信这一点,您可以使用kernel_size=(1D_kernel_size, input_dim) 和相同数量的过滤器来重现具有 2D 卷积层的 1D 卷积。举个例子:

from keras.layers import Conv1D, Conv2D
import keras.backend as K
import numpy as np

# create an input with 4 steps and 5 channels/input_dim
channels = 5
steps = 4
filters = 3
val = np.array([list(range(i * channels, (i + 1) * channels)) for i in range(1, steps + 1)])
val = np.expand_dims(val, axis=0)
x = K.variable(value=val)

# 1D convolution. Initialize the kernels to ones so that it's easier to compute the result by hand

conv1d = Conv1D(filters=filters, kernel_size=1, kernel_initializer='ones')(x)

# 2D convolution that replicates the 1D one

# need to add a dimension to your input since conv2d expects 4D inputs. I add it at axis 4 since my keras is setup with `channel_last`
val1 = np.expand_dims(val, axis=3)
x1 = K.variable(value=val1)

conv2d = Conv2D(filters=filters, kernel_size=(1, 5), kernel_initializer='ones')(x1)

# evaluate and print the outputs

print(K.eval(conv1d))
print(K.eval(conv2d))

正如我所说,我也花了一段时间才理解这一点,我想主要是因为没有教程解释清楚

【讨论】:

以上是关于为啥 Keras Conv1D 层的输出张量没有输入维度?的主要内容,如果未能解决你的问题,请参考以下文章

求助c语言大佬们,急! 为啥我多次调用函数,然而输出的时候只有第一层函数输出了,后几层的都没有输

Keras Conv1d 参数及输入输出详解

Conv1D 层 Keras 的 input_shape

访问在 TF 2.0 中未显式公开为层的 Keras 模型的中间张量

从 Conv1D 层到 MaxPool1D 层的额外维度

计算CNN模型中Conv层的输出大小