提示:记录自己在第一次写Conv1d代码过程中遇到的几个问题,如有不当之处,欢迎讨论。
用pytorch实现序列分类问题。
输入是序列向量(序列长度为1*256)
输出是该序列的类别
网络:Conv1d (详情参考:https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html)
两层模型代码如下:
import torch
import torch.nn as nn
class Classifier(nn.Module):
def __init__(self,input_channels=input_channels, output_dim=120):
super(Classifier, self).__init__()
# torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride, padding)
# input 維度 [2, 1, 256]
self.con1 = nn.Sequential(
nn.Conv1d(input_channels,64, 3, 1, 1), # [64, 1, 256]
nn.ReLU(),
)
self.con2 = nn.Sequential(
nn.Conv1d(64, 128, 3, 1, 1), # [128, 1, 256]
nn.ReLU(),
)
self.fc = nn.Sequential(
nn.Linear(128*1*256, 512),
nn.ReLU(),
nn.Linear(512, output_dim)
)
def forward(self, x):
out = self.con1(x)
out = self.con2(out)
out = out.view(out.size()[0], -1)
return self.fc(out)
问题1:nn.Conv1d的网络输入,网络输出以及网络参数设置
上图是pytorch官网对于输入输出的解释,我以序列分类问题为例做一些具体的解释。
input就是我的序列向量,输入数据的格式应该为 ( N , C i n , L ) (N, C_{in}, L) (N,Cin,L), 其中 N N N为batch size, C i n C_{in} Cin为输入通道数, L L L为序列长度。如果没有batch那就直接省略第一项。以我的序列向量为例,通道数为2(幅值和相位)或者上一层的网络输出通道数,长度为256。将输入数据整理成 2 ∗ 256 2*256 2∗256的矩阵。
output是变形后的数据矩阵, C o u t C_{out} Cout是自己定义的卷积核个数,也是接在该网络后的下一层网络的输入通道数。输入向量的长度根据网络参数中卷积核的大小,移动步长等参数计算,如上图计算 L o u t L_{out} Lout的公式。
网络参数:
in_channels上接网络输入的通道数,或者上层网络的out_channels,
out_channels下接下层网络的网络输入,
kernel_size为卷积核的大小,
stride为移动步长,
padding是指当卷积核移动到边缘部位的时候是否对向量进行填充。
问题2:全连接层的输入大小计算
全连接层输入=上层网络输出通道数*输出数据向量的长度
输出向量的长度由 L o u t L_{out} Lout的公式的计算公式得到。
此处有一个小技巧:在每层网络参数的设置中,都满足 p a d d i n g = ( k e r n e l s i z e − 1 ) / 2 padding=(kernel size -1)/2 padding=(kernelsize−1)/2, 就可以使向量的长度保持不变。此时全连接层的输入=长层网络输出通道式*网络输入向量的长度(256)。
今天先整理到这,后续有空再补充,欢迎大家讨论指正。