当前位置:   article > 正文

PyTorch基础教程(六)torch.nn 模块(2)_卷积运算输出特征映射的数量

卷积运算输出特征映射的数量

目录

一、卷积层

二、池化层

1.示意图

2.常用的池化操作

3.函数原型

4.实例展示 

(1)最大值池化

(2)平均值池化

(3)自适应平均值池化


一、卷积层

        卷积可以看作是输入和卷积核之间的内积运算,是两个实值函数之间的一种数学运算。在卷积运算中,通常使用卷积核将输入数据进行卷积运算得到输出作为特征映射,每个卷积核可获得一个特征映射。针对二维图像使用2x2的卷积核步长为1的运算过程如 图1-1 所示。

图 1-1 二维卷积运算过程示意图 

        图1-1 是一个二维卷积运算的示例,可以发现,卷积操作将周围几个像素的取值经过计算得到一个像素值。
        使用卷积运算在图像识别图像分割图像重建等应用中有三个好处,即卷积稀疏连接、参数共享、等变表示,正是这些好处让卷积神经网络在图像处理算法中脱颖而出。
        在卷积神经网络中,通过输入卷积核来进行卷积操作,使输入单元(图像或特征映射)和输出单元(特征映射)之间的连接是稀疏的,这样能够减少需要训练参数的数量从而加快网络的计算速度
        卷积操作的参数共享特点,主要体现在模型中同一组参数可以被多个函数或操作共同使用。在卷积神经网络中,针对不同的输入会利用同样的卷积核来获得相应的输出。这种参数共享的特点是只需要训练一个参数集,而不需对每个位置学习一个参数集合。由于卷积核尺寸可以远远小于输入尺寸,即减少需要学习的参数的数量,并且针对每个卷积层可以使用多个卷积核获取输入的特征映射,对数据(尤其是图像)具有很强的特征提取和表示能力,并且在卷积运算之后,使得卷积神经网络结构对输入的图像具有平移不变的性质。
        在 PyTorch 中针对卷积操作的对象和使用的场景不同,有一维卷积、二维卷积、三维卷积与转置卷积(可以简单理解为卷积操作的逆操作),但它们的使用方法比较相似,都可以从 torch . nn 模块中调用,需要用的类如 表1-2 所示。

表 1-2 常用的卷积操作对应的类
层对应的类功能作用
torch.nn.Conv1d ( )针对输入信号上应用1D卷积
torch.nn.Conv2d ( )针对输入信号上应用2D卷积
torch.nn.Conv3d ( )针对输入信号上应用3D卷积
torch.nn.ConvTranspose1d ( )在输入信号上应用1D转置卷积
torch.nn.ConvTranspose2d ( )在输入信号上应用2D转置卷积
torch.nn.ConvTranspose3d ( )在输入信号上应用3D转置卷积

        下面以 torch.nn.Conv2d ( ) 为例,介绍卷积在图像上的使用方法,调用方式为:

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

参数说明:

                ① in_channels:(整数)输入图像的通道数;

                ② out_channels:(整数)经过卷积运算后,输出特征映射的数量;

                ③ kernel_size:(整数或者数组)卷积核的大小;

                ④ stride:(整数或者数组,正数)卷积的步长,默认为1;

                ⑤ padding:(整数或者数组,正数)在输入两边进行0填充的数量,默认为0;

                ⑥ dilation:(整数或者数组,正数)卷积核元素之间的步幅,该参数可调整空洞卷积的空洞大小,默认为1;

                ⑦ groups:(整数,正数)从输入通道到输出通道的阻塞连接数;

                ⑧ bias:(布尔值,正数)如果 bias = True,则添加偏置,默认为True

torch.nn.Conv2d ( ) 输入的张量为(N,Cin,Hin,Win),输出的张量为(N,Cout,Hout,Wout)。

其中:

        

        下面通过一个实例,展示图像经过二维卷积后的效果。先导入相关的包和模块,并且使用PIL包读取图像数据,使用 matplotlib 包来可视化图像和卷积后的结果,示例程序如下:

  1. '''使用一张图片展示经过卷积后的图像效果'''
  2. import torch
  3. import numpy as np
  4. import torch.nn as nn
  5. import matplotlib.pyplot as plt
  6. from PIL import Image
  7. #读取图像→转化为灰度图片→转化为Numpy数组
  8. image = Image.open(r'C:\Users\lenovo\Pictures\image.png')
  9. gray = np.array(image.convert("L"),dtype = np.float32)
  10. #可视化图片
  11. plt.figure(figsize = (6,6))
  12. plt.imshow(gray, cmap = plt.cm.gray)
  13. plt.axis("off")
  14. plt.show()

     

                         图 1-3 原始图片                                                        图 1-4 灰度图片

        经过上述操作后,得到一个 512×512数组,在使用 PyTorch 进行卷积操作之前,需要将其转化为 1×1×512×512张量

  1. #将数组装换为张量
  2. imh,imw = gray.shape
  3. Gray = torch.from_numpy(gray.reshape((1,1,imh, imw)))
  4. print('Gray.shape: \n',Gray.shape)
  1. #运行结果
  2. Gray.shape:
  3. torch.Size([1, 1, 512, 512])

         卷积时需要将图像转化为四维来表示[ batch , channel , h , w ]。在对图像进行卷积操作后,获得两个特征映射。第一个特征映射使用图像轮廓提取卷积核获取,第二个特征映射使用的卷积核为随机数,卷积核大小为 5x5,对图像的边缘不使用0填充,所以卷积后输出特征映射的尺寸为508x508。使用下面的程序进行卷积运算,并对卷积后的两个特征映射进行可视化:

  1. #对灰度图像进行卷积提取图像轮廓
  2. kersize = 5 #定义边缘检测卷积核,并将维度处理为 1×1×5×5
  3. ker = torch.ones(kersize,kersize,dtype = torch.float32)*-1
  4. ker[2,2] = 24
  5. ker = ker.reshape((1,1,kersize,kersize))
  6. #进行卷积操作
  7. conv2d = nn.Conv2d(1, 2,(kersize,kersize),bias=True)
  8. #设置卷积时使用的核,第一个核使用边缘检测核
  9. conv2d.weight.data[0] = ker
  10. #对灰度图像进行卷积操作
  11. imconv2dout = conv2d(Gray)
  12. #对卷积后的输出进行维度压缩
  13. Imconv2dout = imconv2dout.data.squeeze()
  14. print('卷积后尺寸: \n',Imconv2dout.shape)
  15. #可视化卷积后的图像
  16. plt.figure(figsize = (12,6))
  17. plt.subplot(1,2,1)
  18. plt.imshow(Imconv2dout[0], cmap = plt.cm.gray)
  19. plt.axis('off')
  20. plt.subplot(1,2,2)
  21. plt.imshow(Imconv2dout[1],cmap = plt.cm.gray)
  22. plt.axis('off')
  23. plt.show()
  1. #输出结果
  2. 卷积后尺寸:
  3. torch.Size([2, 508, 508])

                               (a)                                                                           (b)

图 1-5 卷积后的两个特征映射可视化 

        从 图 1-5 (a)可以看到,使用的边缘特征提取卷积核很好地提取出了图像的边缘信息。而右边的图像使用的卷积核为随机数,得到的卷积结果与原始图像很相似


二、池化层

1.示意图

图 2-1 池化层示意图

2.常用的池化操作

        在 PyTorch 中,提供了多种池化的类,分别是最大值池化( MaxPool )、最大值池化的逆过程( MaxUnPool )、平均值池化( AvgPool )与自适应池化AdaptiveMaxPool 、 AdaptiveAvgPool )等。并且均提供了一维、二维和三维的池化操作。具体的池化类和功能如表2-2所示。

图 2-2 PyTorch 中常用的池化操作
层对应的类功能
torch.nn.MaxPool1d ( )针对输入信号上应用1D最大值池化
torch.nn.MaxPool2d ( )针对输入信号上应用2D最大值池化
torch.nn.MaxPool3d ( )针对输入信号上应用3D最大值池化
torch.nn.MaxUnPool1d ( )1D最大值池化的部分逆运算
torch.nn.MaxUnPool2d ( )2D最大值池化的部分逆运算
torch.nn.MaxUnPool3d ( )3D最大值池化的部分逆运算
torch.nn.AvgPool1d ( )针对输入信号上应用1D平均值池化
torch.nn.AvgPool2d ( )针对输入信号上应用2D平均值池化
torch.nn.AvgPool3d ( )针对输入信号上应用3D平均值池化
torch.nn.AdaptiveMaxPool1d ( )针对输入信号上应用1D自适应最大值池化
torch.nn.AdaptiveMaxPool2d ( )针对输入信号上应用2D自适应最大值池化
torch.nn.AdaptiveMaxPool3d ( )针对输入信号上应用3D自适应最大值池化
torch.nn.AdaptiveAvgPool1d ( )针对输入信号上应用1D自适应平均值池化
torch.nn.AdaptiveAvgPool2d ( )针对输入信号上应用2D自适应平均值池化
torch.nn.AdaptiveAvgPool3d ( )针对输入信号上应用3D自适应平均值池化

3.函数原型

        对于 torch.nn.MaxPool2d ( )  池化操作相关参数的应用,其使用方法如下:

torch.nn.MaxPool2d(kernel_size,stride=None,padding=0,dilation=1,return_indices=False,ceil_mode=False)

参数说明:

                ① kernel_size:(整数或数组)最大值池化的窗口大小;

                ② stride:(整数或数组,正数)最大值池化窗口移动的步长,默认值是 kernel_size;

                ③ padding:(整数或数组,正数)输入的每一条补充 0 的层数;

                ④ dilation:(整数或数组,正数)一个控制窗口中元素步幅的参数;

                ⑤ return_indices:如果为 True ,则会返回输出最大值的索引,这样会更加便于之后的torch.nn.MaxUnPool2d ( ) 操作。

                ⑥ ceil_mode:如果等于 True ,计算输出信号大小的时候,会使用向上取整,默认是向下取整。

torch.nn.MaxPool2d ( ) 输入的张量为(N,Cin,Hin,Win),输出的张量为(N,Cout,Hout,Wout)。

其中:

4.实例展示 

        下面以 图2-1 卷积后的结果为例,对其进行最大值池化平均值池化自适应平均值池化

(1)最大值池化

        首先使用 nn.MaxPool2d ( ) 函数,对卷积后的输出进行最大值池化,并对其进行可视化,程序如下:

  1. #对卷积后的结果进行最大值池化
  2. maxpool2 = nn.MaxPool2d(2,stride=2)
  3. pool2_out = maxpool2(imconv2dout)
  4. pool2_out_im = pool2_out.squeeze()
  5. print('pool2_out.shape: \n',pool2_out.shape)

         通过上面程序发现,原始 508x508 的特征映射在经过窗口为 2x2 ,步长为 2 的最大值池化后,尺寸变化为 254×254 的特征映射。将两个特征映射进行可视化,得到如 图2-2 所示的图像。

  1. #可视化最大值池化后的结果
  2. plt.figure(figsize=(12,6))
  3. plt.subplot(1,2,1)
  4. plt.imshow(pool2_out_im[0].data, cmap=plt.cm.gray)
  5. plt.axis('off')
  6. plt.subplot(1,2,2)
  7. plt.imshow(pool2_out_im[1].data, cmap=plt.cm.gray)
  8. plt.axis('off')

                             ( a )                                                                          ( b )

图 2-2 最大值池化后的结果图像 

(2)平均值池化

        接下来使用 nn.AvgPool2d ( ) 函数,对卷积后的输出进行平均值池化,并对其进行可视化,程序如下:

  1. #对卷积后的结果进行平均值池化
  2. avgpool2 = nn.AvgPool2d(2,stride=2)
  3. pool2_out = avgpool2(imconv2dout)
  4. pool2_out_im = pool2_out.squeeze()
  5. print('pool2_out.shape: \n',pool2_out.shape)
  6. #可视化平均值池化后的结果
  7. plt.figure(figsize=(12,6))
  8. plt.subplot(1,2,1)
  9. plt.imshow(pool2_out_im[0].data, cmap=plt.cm.gray)
  10. plt.axis('off')
  11. plt.subplot(1,2,2)
  12. plt.imshow(pool2_out_im[1].data, cmap=plt.cm.gray)
  13. plt.axis('off')
  14. plt.show()
  1. #运行结果
  2. pool2_out.shape:
  3. torch.Size([1, 2, 254, 254])

                               ( a )                                                                         ( b )

图 2-3 平均值池化后的结果图像 

(3)自适应平均值池化

         再使用 nn .AdaptiveAvgPool2d ( ) 函数,对卷积后的输出进行自适应平均值池化并可视化。在使用该函数时,可以使用 output _ size 参数指定输出特征映射的尺寸。程序如下:

  1. #对卷积后的结果进行自适应平均值池化
  2. AdaAvgpool2 = nn.AdaptiveAvgPool2d(output_size = (100,100))
  3. pool2_out = AdaAvgpool2(imconv2dout)
  4. pool2_out_im = pool2_out.squeeze ()
  5. print('pool2_out.shape: \n',pool2_out.shape)
  6. #可视化自适应平均值池化后的结果
  7. plt.figure ( figsize =(12,6))
  8. plt.subplot (1,2,1)
  9. plt.imshow (pool2_out_im[0].data , cmap = plt.cm.gray )
  10. plt.axis('off')
  11. plt.subplot (1,2,2)
  12. plt.imshow (pool2_out_im[1].data , cmap = plt.cm.gray )
  13. plt.axis('off')
  14. plt.show ()
  1. #运行结果
  2. pool2_out.shape:
  3. torch.Size([1, 2, 100, 100])

                                ( a )                                                                         ( b )

图 2-4 自适应平均值池化后的结果图像 

最新动态,请关注微信公众号回不去的明天 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号