PyTorch版本:1.9.0
Conv1d的构造函数中必须传入的参数有下列三个:
- 输入通道数(in_channels)
- 输出通道数(out_channels)
- 卷积核大小(kernel_size)
比如,下面的代码创建了一个输入通道数为2,输出通道数为3,卷积核大小为5的Conv1d实例。
from torch import nn
conv1d = nn.Conv1d(2,3,5)
实例创建好后,就可以确认已经初始化好的权重(weight)和偏置(bias)。
>>> conv1d.weight.shape
torch.Size([3, 2, 5])
>>> conv1d.weight
Parameter containing:
tensor([[[ 0.2594, -0.2927, 0.3010, -0.3144, -0.0263],
[ 0.1818, 0.1792, -0.1513, 0.0448, 0.2669]],
[[-0.1189, 0.1470, -0.1873, -0.1977, 0.0357],
[ 0.1807, 0.0479, 0.2231, -0.2369, -0.1685]],
[[ 0.0283, 0.0707, 0.0137, -0.0436, -0.2092],
[ 0.1842, 0.2262, -0.1358, -0.1469, 0.0953]]], requires_grad=True)
>>> conv1d.bias
Parameter containing:
tensor([ 0.1507, -0.0665, 0.2158], requires_grad=True)
为了使用创建好的conv1d实例,还需要准备好输入用的数组(tensor)。输入数组必须是三维。
- 第一维的大小:样本数量(batch_size)
- 第二维的大小:输入通道数,必须和创建conv1d实例时设置的输入通道数保持一致
- 第三维的大小:每个样本的长度。比如在语音领域一般就是时间轴上的采样(帧)数
>>> import torch
>>> x = torch.rand(4,2,6)
>>> x
tensor([[[0.8598, 0.9945, 0.8397, 0.0875, 0.1347, 0.2212],
[0.9039, 0.9663, 0.2980, 0.4002, 0.8641, 0.1295]],
[[0.6044, 0.1435, 0.9415, 0.6749, 0.1406, 0.5504],
[0.5129, 0.1664, 0.3843, 0.5065, 0.4144, 0.2583]],
[[0.9566, 0.8054, 0.3213, 0.8039, 0.4228, 0.9182],
[0.8417, 0.0937, 0.0542, 0.2004, 0.9569, 0.3480]],
[[0.7783, 0.7377, 0.9412, 0.3135, 0.7974, 0.1117],
[0.5227, 0.1919, 0.0875, 0.8341, 0.0841, 0.1266]]])
接下来确认卷积的计算结果。
>>> y = conv1d(x)
>>> y.shape
torch.Size([4, 3, 2])
>>> y
tensor([[[ 0.8454, 0.3828],
[-0.1566, -0.0447],
[ 0.6581, 0.3289]],
[[ 0.5311, 0.1668],
[-0.4254, -0.0599],
[ 0.2421, 0.1869]],
[[ 0.4219, 0.4825],
[-0.3059, -0.5375],
[ 0.4113, -0.0433]],
[[ 0.4764, -0.1308],
[-0.3490, -0.0444],
[ 0.1357, 0.1910]]], grad_fn=<SqueezeBackward1>)
接下来说明上面结果的计算过程。
输入数组x
的样本数是4。也就是说,有四条数据。卷积运算分别在x[0]
、x[1]
、x[2]
和x[3]
上独立进行,然后得到y[0]
、y[1]
、y[2]
和y[3]
。
conv1d.weight[0]
和conv1d.bias[0]
对应y[:,0]
(输出通道0)。
>>> conv1d.weight[0]
tensor([[ 0.2594, -0.2927, 0.3010, -0.3144, -0.0263],
[ 0.1818, 0.1792, -0.1513, 0.0448, 0.2669]],
grad_fn=<SelectBackward>)
>>> conv1d.weight[0,0]
tensor([ 0.2594, -0.2927, 0.3010, -0.3144, -0.0263], grad_fn=<SelectBackward>)
>>> y[0,0] # 第0条数据在通道0上的输出
tensor([0.8454, 0.3828], grad_fn=<SelectBackward>)
>>> x[0,0,0:5].dot(conv1d.weight[0,0]) + x[0,1,0:5].dot(conv1d.weight[0,1]) + conv1d.bias[0]
tensor(0.8454, grad_fn=<AddBackward0>)
>>> x[0,0,1:6].dot(conv1d.weight[0,0]) + x[0,1,1:6].dot(conv1d.weight[0,1]) + conv1d.bias[0]
tensor(0.3828, grad_fn=<AddBackward0>)
>>> y[1,0] # 第1条数据在通道0上的输出
tensor([0.5311, 0.1668], grad_fn=<SelectBackward>)
>>> x[1,0,0:5].dot(conv1d.weight[0,0]) + x[1,1,0:5].dot(conv1d.weight[0,1]) + conv1d.bias[0]
tensor(0.5311, grad_fn=<AddBackward0>)
>>> x[1,0,1:6].dot(conv1d.weight[0,0]) + x[1,1,1:6].dot(conv1d.weight[0,1]) + conv1d.bias[0]
tensor(0.1668, grad_fn=<AddBackward0>)
conv1d.weight[1]
和conv1d.bias[1]
对应y[:,1]
(输出通道1)。
>>> y[0,1] # 第0条数据在通道1上的输出
tensor([-0.1566, -0.0447], grad_fn=<SelectBackward>)
>>> x[0,0,0:5].dot(conv1d.weight[1,0]) + x[0,1,0:5].dot(conv1d.weight[1,1]) + conv1d.bias[1]
tensor(-0.1566, grad_fn=<AddBackward0>)
>>> x[0,0,1:6].dot(conv1d.weight[1,0]) + x[0,1,1:6].dot(conv1d.weight[1,1]) + conv1d.bias[1]
tensor(-0.0447, grad_fn=<AddBackward0>)
>>> y[1,1] # 第1条数据在通道1上的输出
tensor([-0.4254, -0.0599], grad_fn=<SelectBackward>)
>>> x[1,0,0:5].dot(conv1d.weight[1,0]) + x[1,1,0:5].dot(conv1d.weight[1,1]) + conv1d.bias[1]
tensor(-0.4254, grad_fn=<AddBackward0>)
>>> x[1,0,1:6].dot(conv1d.weight[1,0]) + x[1,1,1:6].dot(conv1d.weight[1,1]) + conv1d.bias[1]
tensor(-0.0599, grad_fn=<AddBackward0>)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。