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 包来可视化图像和卷积后的结果,示例程序如下:

'''使用一张图片展示经过卷积后的图像效果'''
import torch
import numpy as np
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image

#读取图像→转化为灰度图片→转化为Numpy数组
image = Image.open(r'C:\Users\lenovo\Pictures\image.png')
gray = np.array(image.convert("L"),dtype = np.float32)

#可视化图片
plt.figure(figsize = (6,6))
plt.imshow(gray, cmap = plt.cm.gray)
plt.axis("off")
plt.show()

     

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

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

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

Gray.shape:  
 torch.Size([1, 1, 512, 512])

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

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

卷积后尺寸:  
 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 ( ) 函数,对卷积后的输出进行最大值池化,并对其进行可视化,程序如下:

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

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

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

                             ( a )                                                                          ( b )

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

(2)平均值池化

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

#对卷积后的结果进行平均值池化
avgpool2 = nn.AvgPool2d(2,stride=2)
pool2_out = avgpool2(imconv2dout)
pool2_out_im = pool2_out.squeeze()
print('pool2_out.shape: \n',pool2_out.shape)

#可视化平均值池化后的结果
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(pool2_out_im[0].data, cmap=plt.cm.gray)
plt.axis('off')
plt.subplot(1,2,2)
plt.imshow(pool2_out_im[1].data, cmap=plt.cm.gray)
plt.axis('off')
plt.show()
#运行结果

pool2_out.shape: 
 torch.Size([1, 2, 254, 254])

                               ( a )                                                                         ( b )

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

(3)自适应平均值池化

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

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

pool2_out.shape: 
 torch.Size([1, 2, 100, 100])

                                ( a )                                                                         ( b )

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

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

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旗狼-回不去的明天

您的支持是对创作的最大鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值