官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html?highlight=nn%20conv1d#torch.nn.Conv1d
作用:对由多个输入平面组成的输入信号应用一维卷积。
在最简单的情况下,输入大小为
(
N
,
C
in
,
L
)
(N, C_{\text{in}}, L)
(N,Cin,L) 和输出
(
N
,
C
out
,
L
out
)
(N, C_{\text{out}}, L_{\text{out}})
(N,Cout,Lout)可以精确地描述为:
out
(
N
i
,
C
out
j
)
=
bias
(
C
out
j
)
+
∑
k
=
0
C
i
n
−
1
weight
(
C
out
j
,
k
)
⋆
input
(
N
i
,
k
)
\text{out}(N_i, C_{\text{out}_j}) = \text{bias}(C_{\text{out}_j}) + \sum_{k = 0}^{C_{in} - 1} \text{weight}(C_{\text{out}_j}, k) \star \text{input}(N_i, k)
out(Ni,Coutj)=bias(Coutj)+k=0∑Cin−1weight(Coutj,k)⋆input(Ni,k)
其中
⋆
\star
⋆是互相关算子(计算卷积的方式),
N
N
N是batch_size,
C
C
C表示通道数,
L
L
L表示序列的长度。
参数:
-
in_channels (int) – Number of channels in the input image
-
out_channels (int) – Number of channels produced by the convolution
-
kernel_size (int or tuple) – Size of the convolving kernel
-
stride (int or tuple, optional) – Stride of the convolution. Default: 1,控制互相关、单个数字或单元素元组的步幅。
-
padding (int, tuple or str, optional) – Padding added to both sides of the input. Default: 0,控制应用于输入的填充量。它可以是一个字符串 {‘valid’, ‘same’} 或一个整数元组,给出在两边应用的隐式填充量。
-
padding_mode (string, optional) – ‘zeros’, ‘reflect’, ‘replicate’ or ‘circular’. Default: ‘zeros’
-
dilation (int or tuple, optional) – Spacing between kernel elements. Default: 1,控制内核点之间的间距;也称为 à trous 算法。很难描述,但是这个链接很好地可视化了膨胀的作用。
-
groups (int, optional) – Number of blocked connections from input channels to output channels. Default: 1,控制输入和输出之间的连接。 in_channels 和 out_channels 都必须能被组整除。通常我们用不到。
-
bias (bool, optional) – If True, adds a learnable bias to the output. Default: True
输入、输出形状:
input:
(
N
,
C
i
n
,
L
i
n
)
(N, C_{in}, L_{in})
(N,Cin,Lin)或者
(
C
i
n
,
L
i
n
)
(C_{in}, L_{in})
(Cin,Lin)
output:
(
N
,
C
o
u
t
,
L
o
u
t
)
(N, C_{out}, L_{out})
(N,Cout,Lout)或者
(
C
o
u
t
,
L
o
u
t
)
(C_{out}, L_{out})
(Cout,Lout)
L
o
u
t
=
⌊
L
i
n
+
2
×
padding
−
dilation
×
(
kernel_size
−
1
)
−
1
stride
+
1
⌋
L_{out} = \left\lfloor\frac{L_{in} + 2 \times \text{padding} - \text{dilation} \times (\text{kernel\_size} - 1) - 1}{\text{stride}} + 1\right\rfloor
Lout=⌊strideLin+2×padding−dilation×(kernel_size−1)−1+1⌋
变量:
- ~Conv1d.weight (Tensor) – the learnable weights of the module of shape ( out_channels , in_channels groups , kernel_size ) (\text{out\_channels}, \frac{\text{in\_channels}}{\text{groups}}, \text{kernel\_size}) (out_channels,groupsin_channels,kernel_size) The values of these weights are sampled from U ( − k , k ) \mathcal{U}(-\sqrt{k}, \sqrt{k}) U(−k,k) where k = g r o u p s C in ∗ kernel_size k = \frac{groups}{C_\text{in} * \text{kernel\_size}} k=Cin∗kernel_sizegroups.
- ~Conv1d.bias (Tensor) – the learnable bias of the module of shape (out_channels). If bias is True, then the values of these weights are sampled from U ( − k , k ) \mathcal{U}(-\sqrt{k}, \sqrt{k}) U(−k,k) where k = g r o u p s C in ∗ kernel_size k = \frac{groups}{C_\text{in} * \text{kernel\_size}} k=Cin∗kernel_sizegroups.
我使用比较多的实在textcnn模型中,使用cnn模型进行特征提取,以及在IDCNN模型中进行NER任务。以textcnn为例进行介绍,batch_size=N, 批次文本的长度为seq_len(批次数据如果长度不一致时,会使用pad的方式对数据进行对齐),设定的token(textcnn的文本处理单元,可以是字也可以是词)的Embedding维度为embedding_dim,embedding_dim也是conv1d的通道数。根据这个定义输入的数据可以如下形式:
以batch_size中的一条数据处理为例,进行卷积计算时需要有一个滑动的kernel,以及每次滑动的步幅stride,其他参数先保持默认。kernel的选择与N-gram相似,我们可以选择[2,3,4],stride通常也是设置为1的,也就是逐单元滑动,以kernel=2为例,输出通道output_channels=2,计算如下:
经过Conv1d之后,输出的就是
2
×
3
2\times3
2×3的结果,其中2就是output_channels决定的,与其相等,3是根据seq_len以及stride共同决定的,那么预期的结果size就是
N
×
2
×
3
N\times2\times3
N×2×3。假如in_channels=100,out_channels=2,kernel_size=2,batch_size=4,seq_len=10,stride=1那么输入该如何处理?输出又是什么样子呢?程序实现如下:
in_channels = 100
out_channels = 2
kernel_size = 2
batch_size = 4
seq_len = 10
conv1 = torch.nn.Conv1d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size)
# 文本处理形式
input_data = torch.randn(batch_size, seq_len, in_channels)
# conv1d输入形式, (batch_size, channels, seq_len)
input_data = input_data.permute(0, 2, 1) # torch.Size([4, 100, 10])
print(input_data.size())
conv_out = conv1(input_data)
print(conv_out.size()) # torch.Size([4, 2, 9])
输出结果的形状中4,2都比较好理解,9则是根据如下公式计算出的:
L
o
u
t
=
⌊
L
i
n
+
2
×
padding
−
dilation
×
(
kernel_size
−
1
)
−
1
stride
+
1
⌋
L_{out} = \left\lfloor\frac{L_{in} + 2 \times \text{padding} - \text{dilation} \times (\text{kernel\_size} - 1) - 1}{\text{stride}} + 1\right\rfloor
Lout=⌊strideLin+2×padding−dilation×(kernel_size−1)−1+1⌋
对应的参数带入即可计算出。在本例中padding=0,dilation=1,kernel_size=1,stride=1.