为什么Keras Conv1D层的输出张量没有输入维?

2024-03-29 04:47:50 发布

您现在位置:Python中文网/ 问答频道 /正文

根据keras文档(https://keras.io/layers/convolutional/),Conv1D输出张量的形状是(批处理大小、新步骤、过滤器),而输入张量形状是(批处理大小、步数、输入维数)。我不明白这是怎么回事,因为这意味着如果你传递一个长度为8000的1d输入,其中batch_size=1,steps=1(我听说steps是指输入中的通道数),那么这个层的输出将是shape(1,1,X),其中X是Conv层中过滤器的数量。但是输入维度会发生什么呢?由于层中的X过滤器应用于整个输入维度,那么输出维度中不应该有一个是8000(或者更少,取决于填充),比如(1,18000,X)?我检查了Conv2D层的行为方式,使它们的输出形状更合理(示例、过滤器、新行、新列),其中新行和新列将是输入图像的尺寸,再次根据填充进行调整。如果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_维度和steps维度的含义弄错了。这主要是因为我使用的体系结构来自于另一个在mathematica和mathematica中构建模型的小组,Conv1D层的输入形状(X,Y)意味着X“通道”(或X的输入维数)和Y步进。感谢gionni帮助我认识到这一点,并很好地解释了“input_dimension”是如何变成“filter”维的。在


Tags: 代码layer过滤器inputoutputmodellayersfunction
1条回答
网友
1楼 · 发布于 2024-03-29 04:47:50

我以前对二维卷积也有同样的问题。问题是,当你应用一个卷积层时,你所应用的内核大小不是(kernel_size, 1),而是(kernel_size, input_dim)。在

如果你想一想,如果不是这样的话,一个1D的卷积层kernel_size = 1对它接收到的输入没有任何作用。在

相反,它是在每个时间步计算输入特征的加权平均值,对每个时间步使用相同的权重(尽管每个过滤器使用不同的权重集)。我认为将input_dim形象化为一幅图像的二维卷积中的channels的数目,在这种情况下,同样的重新划分适用于(在这种情况下,channels会“丢失”并转换成过滤器的数量)。在

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

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))

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

相关问题 更多 >