• pytorch深度学习实战lesson21


    第二十一课 卷积神经网络之池化层

    卷积神经网络的一个重要概念就是池化层,一般是在卷积层之后。池化层对输入做降采样,常用的池化做法是对每个滤波器的输出求最大值,平均值,中位数等。下面我们和沐神详细学习一下池化层的原理与实现方法吧!

    目录

    理论部分

    实践部分


    理论部分

    下面举一个老的例子。

    对于X矩阵,卷积层可以很容易得把1-0的边缘检测处来,也就是说,卷积对位置信息十分的敏感。但是仔细想想,这貌似也不是啥好东西,因为我的图片不能保证边缘就是一条竖直的直线,可能有倾斜或差别,那么有差别后,可能卷积对它的识别就从原本的“1”变成“0”了。。。这就需要一个手段让卷积能够“模棱两可”的识别同一个东西使其输出结果相同且正确。这个手段就是池化层

    池化层的工作原理如下图所示。

    它的原理形似卷积,但他不是卷积,区别就在于,输出的每一个元素都是一个特定区域里的最大元素。

    这里我考虑了一个问题,那就是卷积、池化和激活的顺序要如何设置,大家可以参考一下这篇博客会受益匪浅的:https://blog.csdn.net/Lyndon0_0/article/details/116118004

    从上面这幅图可以看出,最大池化层可以允许输入发送偏移,而且他作用在卷积输出上可以时输出结果有一定的模糊效果,这也就是我刚才所说的“模棱两可”的含义。

    和卷积一样,池化也有填充和步幅这两个超参数。但是它没有可供学习的参数,没有kernal参数,他就是一个最大的计算子。池化层给每个通道做一次池化层,也就是说,它不会和卷积层那样去融合通道,因此池化层的输出通道数=输入通道数。

    除了最大池化层,还有平均池化层这种常用的池化层。也就是取一个区域的平均值。

    实践部分

    代码:

    1. #汇聚层
    2. #实现汇聚层的正向传播
    3. import torch
    4. from torch import nn
    5. from d2l import torch as d2l
    6. def pool2d(X, pool_size, mode='max'):#正向传播函数,X是输入,pool_size池化窗口大小,mode表示最大池化
    7. p_h, p_w = pool_size
    8. Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))#输出的大小和卷积的计算一样
    9. for i in range(Y.shape[0]):#每行迭代
    10. for j in range(Y.shape[1]):#每列迭代
    11. if mode == 'max':#最大池化
    12. Y[i, j] = X[i:i + p_h, j:j + p_w].max()#对池化的区域取最大
    13. elif mode == 'avg':#平均池化
    14. Y[i, j] = X[i:i + p_h, j:j + p_w].mean()#对池化的区域取平均
    15. return Y
    16. #验证二维最大汇聚层的输出
    17. X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
    18. print(pool2d(X, (2, 2)))
    19. print('#######################################################################')
    20. #验证平均汇聚层
    21. print(pool2d(X, (2, 2), 'avg'))
    22. print('#######################################################################')
    23. #填充和步幅
    24. X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
    25. print(X)
    26. print('#######################################################################')
    27. #深度学习框架中的步幅与池化窗口的大小相同
    28. pool2d = nn.MaxPool2d(3)#直接调用,3*3的窗口,这里步幅和窗口大小是相同的,这样的话
    29. #池化一次后下一次池化窗口不会重叠。
    30. print(pool2d(X))
    31. print('#######################################################################')
    32. #填充和步幅可以手动设定
    33. pool2d = nn.MaxPool2d(3, padding=1, stride=2)#padding是填充,后者是步幅
    34. print(pool2d(X))
    35. print('#######################################################################')
    36. #设定一个任意大小的矩形池化窗口,并分别设定填充和步幅的高度和宽度
    37. pool2d = nn.MaxPool2d((2, 3), padding=(1, 1), stride=(2, 3))
    38. print(pool2d(X))
    39. print('#######################################################################')
    40. #汇聚层在每个输入通道上单独运算
    41. X = torch.cat((X, X + 1), 1)
    42. print(X)
    43. pool2d = nn.MaxPool2d(3, padding=1, stride=2)
    44. print(pool2d(X))

    tensor([[4., 5.],
            [7., 8.]])
    #######################################################################
    tensor([[2., 3.],
            [5., 6.]])
    #######################################################################
    tensor([[[[ 0.,  1.,  2.,  3.],
              [ 4.,  5.,  6.,  7.],
              [ 8.,  9., 10., 11.],
              [12., 13., 14., 15.]]]])
    #######################################################################
    tensor([[[[10.]]]])
    #######################################################################
    tensor([[[[ 5.,  7.],
              [13., 15.]]]])
    #######################################################################
    tensor([[[[ 1.,  3.],
              [ 9., 11.],
              [13., 15.]]]])
    #######################################################################
    tensor([[[[ 0.,  1.,  2.,  3.],
              [ 4.,  5.,  6.,  7.],
              [ 8.,  9., 10., 11.],
              [12., 13., 14., 15.]],

             [[ 1.,  2.,  3.,  4.],
              [ 5.,  6.,  7.,  8.],
              [ 9., 10., 11., 12.],
              [13., 14., 15., 16.]]]])
    tensor([[[[ 5.,  7.],
              [13., 15.]],

             [[ 6.,  8.],
              [14., 16.]]]])

    进程已结束,退出代码0
     

  • 相关阅读:
    Java基于SpringBoot的会员制医疗预约服务系统,可作为毕业设计
    TTL、RS232、485到底能传输多远距离?
    Unity_建造系统及保存加载
    有哪些编程后找错误的心得?
    双标引领:汽车软件安全的ASPICE与ISO21434之道
    easyExcel注解详情
    使用 llama.cpp 在本地部署 AI 大模型的一次尝试
    vue2踩坑之项目:Swiper轮播图使用
    层次分明井然有条,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang包管理机制(package)EP10
    HTTPS
  • 原文地址:https://blog.csdn.net/weixin_48304306/article/details/127933742