深度学习8:卷积神经网络

卷积神经网络,主要用于提取图像的特征,也称为特征提取网络。我们之前提到的全连接网络是根据提取的特征对样本进行分类,所以也称为分类网络。
卷积神经网络主要涉及到的几个操作包括:卷积(Convolution),池化(Pooling)和relu激活函数。

1 卷积操作

卷积是卷积神经网络中最重要的一步操作,作用是:提取局部特征。在PyTorch中,二维卷积操作是由nn.Conv2d()函数实现的。
真正的卷积操作之后是需要对卷积核K的左上角和右下角互翻转,右上角和左下角互翻转,在进行卷积。首先介绍一个概念:感受野。感受野就是在卷积神经网络中,每一层输出的特征图元素在原始输入图像上映射的区域大小称为该元素的感受野。

1.1 单通道卷积

输入数据只有1条通道的卷积操作我们较多单通道卷积。
在单通道卷积的情况下,卷积层的参数包括卷积核K中的所有参数,以及一个偏置项b,参数的个数为F×F(卷积核大小)+1(偏置项)。注意卷积中的参数完全由卷积核确定,与输出输出的节点无关。
这里想给出几个推导公式,是用来确定输入特征Y经过卷积核K之后输出的矩阵大小规模:
假设X的矩阵为:
W 1 × H 1 W_1×H_1 W1×H1
假设Y的矩阵为:
W 2 × H 2 W_2×H_2 W2×H2
①那么我们以Y的规模为例:
W 2 = W 1 − F + 1 W_2 =W_1- F+1 W2=W1F+1
H 2 = H 1 − F + 1 H_2 =H_1-F+1 H2=H1F+1
②如果我们想要加上步长的话,假设我们每次移动S行或者S列,我们计算Y的规模:
W 2 = W 1 − F S + 1 W_2 =\frac {W_1-F}{S}+1 W2=SW1F+1
H 2 = H 1 − F S + 1 H_2 =\frac {H_1- F}{S}+1 H2=SH1F+1
其中S是滑动的步长,F是卷积核大小
③如果我们需在矩阵X的外围加上几圈(扩大规模),在保证扩大的同时保持输出结果不变,我们就要考虑加上的数字为0,这种操作我们称作填充;将新填充上的0的圈数称作填充数,这里注意,我们填充P圈,每一行/列就会增加2个0值。所以,当我们加上填充P圈后,我们计算Y的规模变为:
W 2 = W 1 − F + 2 P S + 1 W_2 =\frac {W_1-F+2P}{S}+1 W2=SW1F+2P+1
H 2 = H 1 − F + 2 P S + 1 H_2 =\frac {H_1- F+2P}{S}+1 H2=SH1F+2P+1
其中P是填充圈数。

这里介绍两个概念,一个是参数共享,一个是局部连接。在全连接网络中,对于任意两个输入的节点和输出节点之间都有一条边相连。如果使用全连接的方式,输入节点和输出节点之间将会有巨大量的参数,但是如果我们采用的是卷积方式,再用一个3×3卷积核来回滑动连接,那么我们的参数一共才只有3×3+1=10个。所以,参数共享是卷积神经网络最重要的优点之一。
第二个概念是局部连接,对于全连接网络来说,一个输出节点是由所有输入节点连接而成,但是我们的卷积神经网络中一个输出节点是由卷积核与F×F个局部输入节点产生的。

1.2 多通道卷积

当输入的特征图由两个或者两个以上的我们将会对多个通道输入进行卷积操作。n个通道产生n个卷积核。这里需要注意的是:卷积核的深度和输入特征图的通道数永远是相等的,所以我们一般提到卷积核的时候默认说的是高和宽。每一个卷积核都带有一个偏置项(也可以不带),但是绝对不能多。对于n个深度为d的多通道的F×F卷积层中的所有参数我们可以用下列公式来进行计算:
n × d × F × F + n n×d×F×F+n n×d×F×F+n

1.3 代码实现多通道卷积计算

1.3.1 实例分析

给出三条通道的特征图X(都是5×5),同时构造2个卷积核K1,和K2(都是3×3),他们的偏置项分别为1,3,要求利用两个卷积核对X进行卷积,步长为2。

我们可以先套入到1.1中的公式中计算
W 2 = W 1 − F + 2 P S + 1 = 5 − 3 + 2 × 0 2 + 1 = 2 W_2 =\frac {W_1-F+2P}{S}+1=\frac {5-3+2×0}{2}+1=2 W2=SW1F+2P+1=253+2×0+1=2
H 2 = H 1 − F + 2 P S + 1 = 5 − 3 + 2 × 0 2 + 1 = 2 H_2 =\frac {H_1- F+2P}{S}+1=\frac {5-3+2×0}{2}+1=2 H2=SH1F+2P+1=253+2×0+1=2
所以Y为2×2的矩阵

1.3.2 代码实现

输入卷积层的批量数据必须具有4维的张量:(batch_size,in_channels,height,width)
其中:
batch_size:批量大小
in_channels:一个样本的输入通道
height:行数(高度)
width:列数(宽度 )
关于nn.Conv2d()核函数使用方法:

nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0)

in_channels:输入的通道数,卷积核深度
out_channel:输出的通道数,卷积核数量
kernel_size:卷积核大小
stride:卷积步长
padding:填充0的圈数

2 池化操作

池化操作的主要功能是下采样,提取特征图局部区域的显著特征,减少特征图的规模,从而减少计算量。注意:池化层中不包含任何的待优化参数。
这里介绍几种池化的化方法。

2.1 最大池化(Max Pooling)

最大池化方法中,这里要设置一个池化核,按照池化窗口的大小对特征图进行分割。将窗口从左往右,从上往下将特征图划分为与池化核大小一样的多个区域,最后从每个区域中选择一个最大值作为这个区域的大小,然后重新构成新的特征图,这个新的特征图就是池化结果。

2.2 平均池化(Mean Pooling)

平均池化方法中,这里要设置一个池化核,按照池化窗口的大小对特征图进行分割。将窗口从左往右,从上往下将特征图划分为与池化核大小一样的多个区域,最后从每个区域中选择一个平均值作为这个区域的大小,然后重新构成新的特征图,这个新的特征图就是池化结果。
因为使用的池化核越大,特征图就缩减的越多,一般情况下,通常使用2×2池化核。

2.3池化层实现代码

最大池化用torch.max_pool2d()函数实现。
平均池化用nn.AvgPool2d()函数实现。
input:接收输入池化层的特征图,特征图的的形状为(batch_size,in_channels,height,width);
kernel_size:池化核窗口大小,如果是单个整数,则表示窗口大小为a×a;
stride:池化核窗口移动步长,向右2个,向下2个元素位置,如果是单个整数,则向下或向右都移动单个整数。默认与最大池化窗口大小一样;
padding:填充0的圈数,默认不填充。

torch.max_pool2d(input=x,kernel_size=(2,3),tride=(2,2),padding=0)
#最大池化,下面两句等价
y = torch.max_pool2d(x,(2,2),(2,2),0)
y = torch.max_pool2d(x,2)
#平均池化
avgPool = nn.AvgPool2d(2)
y = avgPool(x)

3 relu激活函数

我们之前已经提过relu()激活函数,relu函数的数学定义如下:
f ( x ) = { x , 当 x ≥ 0 0 ,其他 f(x)=\left\{ \begin{aligned} x & , 当x≥0\\ 0 &,其他 \end{aligned} \right. f(x)={x0,x0,其他

3.1 relu激活函数作用

这个函数的作用是将小于0的元素变换为0,而大于等于0的元素保持不变,在[0,+∞]上的导数为1。
因为relu()在范围内的的导数永远等于1,所以他不会出现sigmoid()和tanh()由于梯度过小而反向传播距离远,梯度信息小,低层网络层上的参数无法得到更新的情况。

3.2 relu激活函数代码实现

以下,我将用两种方式实现relu函数,一种方式可以选择x是否被覆盖,另一种是默认覆盖

x = torch.randint(-9,9,[1,1,4,4])
y = torch.relu(x)#被覆盖
from torch import nn as nn
y = nn.ReLU(inplace = True)(x)#被覆盖,inplace默认False未覆盖

以上,本文内容参考自蒙祖强,欧元汉编著的《深度学习理论与应用》。

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值