新手刚学习卷积,不知道理解的有没有问题,如果有问题劳烦大家指出。
官方文档链接
torch.nn.Conv1d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
bias=True,
padding_mode='zeros')
作用是Applies a 1D convolution over an input signal composed of several input planes.
首先要明确CONV1D和一维卷积(1D convolution)并不是一个概念。
参数:
在最简单的情况下,输入维度为 ( N , C i n , L i n ) (N, C_{in}, L_{in}) (N,Cin,Lin),输出维度为 ( N , C o u t , L o u t ) (N, C_{out}, L_{out}) (N,Cout,Lout)
这个公式看着非常的抽象,暂且放在一边。
先来观察输入输出,不考虑代表batch size的N
那么输入为一个 ( C i n , L i n ) (C_{in}, L_{in}) (Cin,Lin)大小的矩阵,输出为 ( C o u t , L o u t ) (C_{out}, L_{out}) (Cout,Lout)大小的矩阵
其中 L o u t L_{out} Lout的大小可以根据输入大小和卷积核的参数来确定。
通俗地说, L o u t L_{out} Lout代表一个filter能在输入中滑动多少次。
再看一下weight的维度
out_channels应该表示有out_channels个的卷积核,暂且设groups为1,即一个卷积核要处理输入的所有通道。那么卷积核的尺寸为 ( C i n , k e r n e l s i z e ) (C_{in}, kernel_size) (Cin,kernelsize)
再来看离散信号的互相关函数计算公式:
看了Weight的size和互相关函数的公式,再回头去看公式,就能大致了解了。
然后我将CONV1D的计算画成了一张图:
下面来对上图做一些说明,暂时不考虑batch size,先设batch size = 1
Weight中存放了 C o u t C_{out} Cout个卷积核,对应了 C o u t C_{out} Cout个输出的feature map
每一个卷积核的kernel_size是我们定义的,卷积核的另一个维度为输入通道数 C i n C_{in} Cin
我们先来看一个输出的feature map如何计算
Weight[j,:,:]
,让其在输入数据中“滑动”,它能“滑动”多少次,决定了输出的序列长度。代码示例
import torch
import torch.nn as nn
# 输入通道大小为16, 输出通道大小为33, kernel_size为3, 步长为2
m = nn.Conv1d(16, 33, 3, stride=2)
# 输入数据,假设batch_size为20, 输入通道数为16, 序列长度为50
input = torch.randn(20, 16, 50)
# 根据公式可计算出输出序列长度(50-1x(3-1)-1)/2 + 1 = 24
output = m(input) # 20, 33, 24
下面这个例子来自斯坦福cs224n 2019年的课件
CS224N Winter 2019
PyTorch实现
import torch
import torch.nn as nn
batch_size = 16
word_embed_size = 4 # embedding维度,对应输入通道数量
seq_len = 7 # 句子长度,对应输入序列长度
input = torch.randn(batch_size, word_embed_size, seq_len)
conv1 = torch.nn.Conv1d(in_channels=word_embed_size,
out_channels=3,
kernel_size=3,
padding = 1)
hidden1 = conv1(input) #torch.Size([16, 3, 7])
# max pooling
hidden2 = torch.max(hidden1, dim=2)