PyTorch中的nn.Conv1d与nn.Conv2d

作者: 81f83b4769e0 | 来源:发表于2019-04-29 20:30 被阅读0次

    本文主要介绍PyTorch中的nn.Conv1dnn.Conv2d方法,并给出相应代码示例,加深理解。

    一维卷积nn.Conv1d

    一般来说,一维卷积nn.Conv1d用于文本数据,只对宽度进行卷积,对高度不卷积。通常,输入大小为word_embedding_dim * max_length,其中,word_embedding_dim为词向量的维度,max_length为句子的最大长度。卷积核窗口在句子长度的方向上滑动,进行卷积操作。

    定义

    class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

    主要参数说明:

    • in_channels:在文本应用中,即为词向量的维度
    • out_channels:卷积产生的通道数,有多少个out_channels,就需要多少个一维卷积(也就是卷积核的数量)
    • kernel_size:卷积核的尺寸;卷积核的第二个维度由in_channels决定,所以实际上卷积核的大小为kernel_size * in_channels
    • padding:对输入的每一条边,补充0的层数

    代码示例

    输入:批大小为32,句子的最大长度为35,词向量维度为256
    目标:句子分类,共2类

    conv1 = nn.Conv1d(in_channels=256, out_channels=100, kernel_size=2)
    input = torch.randn(32, 35, 256)
    input = input.permute(0, 2, 1)
    output = conv1(input)
    

    假设window_size = [3, 4, 5, 6],即共有四个卷积核,基于上述代码,具体计算过程如下:

    1. 原始输入大小为(32, 35, 256),经过permute(0, 2, 1)操作后,输入的大小变为(32, 256, 35)
    2. 使用1个卷积核进行卷积,可得到1个大小为32 x 100 x 1的输出,共4个卷积核,故共有4个大小为32 x 100 x 1的输出;
    3. 将上一步得到的4个结果在dim = 1上进行拼接,输出大小为32 x 400 x 1
    4. view操作后,输出大小变为32 x 400
    5. 全连接,最终输出大小为32 x 2,即分别预测为2类的概率大小。

    一维卷积过程图解

    Yoon Kim在2014年发表的论文Convolutional Neural Networks for Sentence Classification中,给出了一个非常形象的图,诠释了文本卷积模型的框架,如下所示。

    nn.Conv1d详细图解(使用多个卷积核)

    二维卷积nn.Conv2d

    一般来说,二维卷积nn.Conv2d用于图像数据,对宽度和高度都进行卷积。

    定义

    class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

    代码示例

    假设现有大小为32 x 32的图片样本,输入样本的channels为1,该图片可能属于10个类中的某一类。CNN框架定义如下:

    class CNN(nn.Module):
        def __init__(self):
            nn.Model.__init__(self)
     
            self.conv1 = nn.Conv2d(1, 6, 5)  # 输入通道数为1,输出通道数为6
            self.conv2 = nn.Conv2d(6, 16, 5)  # 输入通道数为6,输出通道数为16
            self.fc1 = nn.Linear(5 * 5 * 16, 120)
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)
    
        def forward(self,x):
            # 输入x -> conv1 -> relu -> 2x2窗口的最大池化
            x = self.conv1(x)
            x = F.relu(x)
            x = F.max_pool2d(x, 2)
            # 输入x -> conv2 -> relu -> 2x2窗口的最大池化
            x = self.conv2(x)
            x = F.relu(x)
            x = F.max_pool2d(x, 2)
            # view函数将张量x变形成一维向量形式,总特征数不变,为全连接层做准备
            x = x.view(x.size()[0], -1)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    

    网络整体结构:[conv + relu + pooling] * 2 + FC * 3
    原始输入样本的大小:32 x 32 x 1

    1. 第一次卷积:使用6个大小为5 x 5的卷积核,故卷积核的规模为(5 x 5) x 6;卷积操作的stride参数默认值为1 x 1,32 - 5 + 1 = 28,并且使用ReLU对第一次卷积后的结果进行非线性处理,输出大小为28 x 28 x 6
    2. 第一次卷积后池化kernel_size2 x 2,输出大小变为14 x 14 x 6
    3. 第二次卷积:使用16个卷积核,故卷积核的规模为(5 x 5 x 6) x 16;使用ReLU对第二次卷积后的结果进行非线性处理,14 - 5 + 1 = 10,故输出大小为10 x 10 x 16
    4. 第二次卷积后池化kernel_size同样为2 x 2,输出大小变为5 x 5 x 16
    5. 第一次全连接:将上一步得到的结果铺平成一维向量形式,5 x 5 x 16 = 400,即输入大小为400 x 1,W大小为120 x 400,输出大小为120 x 1
    6. 第二次全连接,W大小为84 x 120,输入大小为120 x 1,输出大小为84 x 1
    7. 第三次全连接:W大小为10 x 84,输入大小为84 x 1,输出大小为10 x 1,即分别预测为10类的概率值。
    nn.Conv2d详细图解

    注意

    1. 在PyTorch中,池化操作默认的stride大小与卷积核的大小一致;
    2. 如果池化核的大小为一个方阵,则仅需要指明一个数,即kernel_size参数为常数n,表示池化核大小为n x n

    相关文章

      网友评论

        本文标题:PyTorch中的nn.Conv1d与nn.Conv2d

        本文链接:https://www.haomeiwen.com/subject/tiiunqtx.html