• PyTorch学习笔记-Convolution Layers与Pooling Layers


    1. Convolution Layers

    由于图像是二维的,因此基本上最常用到的就是二维的卷积类:torch.nn.Conv2d,官方文档:torch.nn.Conv2d

    Conv2d 的主要参数有以下几个:

    • in_channels:输入图像的通道数,彩色图像一般都是三通道。
    • out_channels:通过卷积后产生的输出图像的通道数。
    • kernel_size:可以是一个数或一个元组,表示卷积核的大小,卷积核的参数是从数据的分布中采样得到的,这些数是多少无所谓,因为在神经网络训练的过程中就是对这些参数进行不断地调整。
    • stride:步长。
    • padding:填充。
    • padding_mode:填充模式,有 zerosreflectreplicatecircular,默认为 zeros
    • dilation:可以是一个数或一个元组,表示卷积核各个元素间的距离。
    • group:一般设置为1,基本用不到。
    • bias:偏置,一般设置为 True。

    例如以下代码构建了一个只有一层卷积层的神经网络,该卷积层的输入和输出通道数都为三通道,卷积核大小为3*3,步长为1,无填充,然后用 CIFAR10 测试数据集进行测试:

    from torchvision import transforms, datasets
    from torch.utils.data import DataLoader
    from torch.utils.tensorboard import SummaryWriter
    import torch.nn as nn
    
    test_set = datasets.CIFAR10('dataset/CIFAR10', train=False, transform=transforms.ToTensor())
    
    data_loader = DataLoader(test_set, batch_size=64)
    
    class Network(nn.Module):
        def __init__(self):
            super(Network, self).__init__()
            self.conv1 = nn.Conv2d(in_channels=3, out_channels=3, kernel_size=3, stride=1, padding=0)
    
        def forward(self, input):
            output = self.conv1(input)
            return output
    
    network = Network()
    print(network)  # Network((conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1)))
    
    writer = SummaryWriter('logs')
    
    for step, data in enumerate(data_loader):
        imgs, targets = data
        output = network(imgs)
        writer.add_images('input', imgs, step)
        writer.add_images('output', output, step)
    
    writer.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    测试结果如下:

    在这里插入图片描述

    可以看到卷积运算能够提取输入图像的不同特征,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网络能从低级特征中迭代提取更复杂的特征。

    2. Pooling Layers

    Pooling Layers 相关函数介绍的官方文档:Pooling Layers

    其中的 MaxPool 表示最大池化,也称上采样;MaxUnpool 表示最小池化,也称下采样;AvgPool 表示平均池化。其中最常用的为 MaxPool2d,官方文档:torch.nn.MaxPool2d

    最大池化的步骤如下图所示:

    在这里插入图片描述

    MaxPool2d 的主要参数有以下几个:

    • kernel_size:用来取最大值的窗口(池化核)大小,和之前的卷积核类似。
    • stride:步长,注意默认值为 kernel_size
    • padding:填充,和 Conv2d 一样。
    • dilation:池化核中各个元素间的距离,和 Conv2d 一样。
    • return_indices:如果为 True,表示返回值中包含最大值位置的索引。注意这个最大值指的是在所有窗口中产生的最大值,如果窗口产生的最大值总共有5个,就会有5个返回值。
    • ceil_mode:如果为 True,表示在计算输出结果形状的时候,使用向上取整,否则默认向下取整。

    输出结果形状的计算公式如下:

    在这里插入图片描述

    接下来我们用代码实现这个池化层:

    from torchvision import transforms, datasets
    from torch.utils.data import DataLoader
    from torch.utils.tensorboard import SummaryWriter
    import torch.nn as nn
    import torch
    
    class Network(nn.Module):
        def __init__(self):
            super(Network, self).__init__()
            self.maxpool1 = nn.MaxPool2d(kernel_size=2)
    
        def forward(self, input):
            output = self.maxpool1(input)
            return output
    
    input = torch.tensor([
        [1, 2, 1, 0],
        [0, 1, 2, 3],
        [3, 0, 1, 2],
        [2, 4, 0, 1]
    ], dtype=torch.float32)  # 注意池化层读入的数据需要为浮点型
    
    input = torch.reshape(input, (1, 1, 4, 4))
    
    network = Network()
    print(network)  # Network((maxpool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))
    
    output = network(input)
    print(output)
    # tensor([[[[2., 3.],
    #           [4., 2.]]]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    我们用图像来试试效果:

    from torchvision import transforms, datasets
    from torch.utils.data import DataLoader
    from torch.utils.tensorboard import SummaryWriter
    import torch.nn as nn
    
    test_set = datasets.CIFAR10('dataset/CIFAR10', train=False, transform=transforms.ToTensor())
    
    data_loader = DataLoader(test_set, batch_size=64)
    
    class Network(nn.Module):
        def __init__(self):
            super(Network, self).__init__()
            self.maxpool1 = nn.MaxPool2d(kernel_size=2)
    
        def forward(self, input):
            output = self.maxpool1(input)
            return output
    
    network = Network()
    
    writer = SummaryWriter('logs')
    
    for step, data in enumerate(data_loader):
        imgs, targets = data
        output = network(imgs)
        writer.add_images('input', imgs, step)
        writer.add_images('output', output, step)
    
    writer.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    测试结果如下:

    在这里插入图片描述

    可以看到最大池化的目的是保留输入数据的特征,同时减小特征的数据量

  • 相关阅读:
    C++ 之 Visual Studio 搭建 EasyX Graphics Library 图形库环境,并使用EasyX(graphics.h)绘制第一个图形
    SpringCloud使用Ribbon和Feign组件
    股票战法课程之业绩跟股价的关系
    STM32F40X之时钟树
    【算法竞赛入门练习题】判断输入的数字是否为回文数字的俩种方法,数字逆置的方法
    HIVE及SparkSQL优化经验
    POJ3322 Bloxorz I 题解
    人脸活体检测技术的应用,有效避免人脸识别容易被攻击的缺陷
    深入探索(淘宝1688京东)API商品详情数据:从价格到销量,一应俱全
    MySQL数据备份与恢复
  • 原文地址:https://blog.csdn.net/m0_51755720/article/details/128075491