深度学习笔记(一):卷积神经网络CNN

卷积层

卷积核Kernel

步幅Stride

填充Padding

多通道上的卷积

激活函数

卷积函数

转置卷积

池化层

池化的三种方式

局部池化

全局池化

💡卷积神经网络由一个或多个卷积层和顶端的全连通层(对应经典的神经网络)组成,通过也包括关联权重和池化层(Pooling Layer)

-用于手写识别的一个比较简单的卷积神经网络,由卷积层(Conv2d)、池化层(MaxPool2d)和全连接层(Linear)叠加而成

import torch.nn as nn
import torch.nn.functional as F
device = torch.device("cuda:0" if torch.cuda.is_avaliable() else "cpu")

class CNNNet(nn.Module):
    def __init__(self):
				# super().__init__()表示可以调用父类nn.module的属性和方法,没有这句话只能调用方法
        super(CNNNet, self).__init__()
				# 卷积层 in_channels输入通道, out_channels输出通道,kernel_size卷积核大小,stride步长
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(in_channels=16, out_channels=36, kernel_size=3, stride=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(1296, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(X)))
        x = self.pool2(F.relu(self.conv2(x)))
        # print(x.shape)
        x = x.view(-1,36*6*6)
        x = F.relu(self.fc2(F.relu(self.fc1(x))))
        return x

net = CNNNet()
net = nec.to(device)

卷积层

卷积层是CNN是核心层,而卷积Convolution又是卷积层的核心。两个函数的运算就是卷积运算

  

卷积运算:用卷积核中每个元素分别乘以对应输入矩阵的对应元素

卷积核Kernel

卷积核又称权重过滤器,简称过滤器filter
  • 类别:比较简单的卷积核有Horizontalfilter、Vecticalfilter、Sobel Filter等
  • 作用:这些过滤器通常能够检测图像的水平边缘、垂直边缘、增强图像中心区域权重等
    • 垂直边缘检测
    • 水平边缘检测
    • 效果图

步幅Stride

小窗口(实际上就是卷积核或过滤器)在输入窗口中每次移动的格数(无论是自左自右移动,或自上自下移动)称为步幅(strides),在图像中就是跳过的像素个数

在小窗口移动过程中,其值始终是不变的,都是卷积核的值。也可以说,卷积核的值在整个过程中都是共享的,所以又把卷积核的值称为贡献变量。神经网络采用参数共享的方法大大降低了参数的数量

填充Padding

当输入图片与卷积核不匹配或者卷积核超过图片边界时,可以采用边界填充的方法。即把图片进行拓展,拓展区域补0。当然,也可以不拓展

根据是否拓展Padding又分为Same、Valid。采用Same方式时,对图片拓展为0。采用Valid时,不对图片进行拓展,即只对输入窗口与移动窗口(卷积核)重叠的部分进行计算。一般选用Same,Same一般不会丢失信息

设补0的圈数为p,输入数据的大小为n,过滤器的大小为f,步幅为s,则有

p = \frac{f-1}{2}

卷积后的大小位:

\frac{n+2p-f}{s} + 1

多通道上的卷积

之前讲述的都是二维卷积,放在图像上来说这就是单通道的图片是灰色,并没有考虑彩色的图片

但在实际应用中,输入数据一般是多通道的,如彩色图片若是RGB颜色模型的话就是三通道,即R、G、B通道,对于多通道的卷积,相应的卷积核(滤波器算子)也是多通道的。

例如下图,图片是6x6x3,分别表示高度(Height)、宽度(Width)和通道(Channel)。过程是将每个单通道(RGB)与相应的filter进行卷积运算,然后将三通道的和相加,得到输出图片的一个像素值

多维卷积和示意图

激活函数

CNN与标准的神经网络类似,为保证其非线性,也需要使用激活函数,即在卷积后,把输出值另加偏移值(bias),输入到激活函数,作为下一层的输入

常用的激活函数有:

nn.Sigmoid
nn.ReLU
nnLeakyReLU
nn.Tanh

卷积函数

卷积函数是构建神经网络的重要支架,通常Pytorch的卷积运算是通过nn.Conv2d来完成的

  • nn.Conv2d
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1,
								groups=1, bias=True, padding_mode='zeros')
'''
param: in_channels(int):输入信号的通道
param: out_channels(int): 卷积产生的通道
param: kernel_size(int or tuple): 卷积核的尺寸
param: stride(int or tuple, optional): 卷积步长,可缺省
param: padding(int or tuple, optional): 输入的每一条边补充0的层数
param: dilation(int or tuple, optional): 卷积核元素之间的差距
param: groups(int, optional): 控制输入与输出的链接。group=1,输出是所有输入的卷积;group=2
			此时相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将两个输出连接起来
param: bias(bool, optional): 如果bias=True,则添加偏置
'''
其中参数kernel_size、stride、padding、dilation也可以是一个int数据,此时卷积height和width值相同
也可以是tuple数组,tuple的第一维度表示height的值,第二维度表示width的值
  • 输出形状

    \large \textnormal{input} :(\textnormal{Number}, \textnormal{Channel}_{in},\textnormal{Height}_{in},\textnormal{Width}_{in})

    \large \textnormal{Output}:(\textnormal{Number},\textnormal{Channel}_{out},\textnormal{Height}_{out},\textnormal{Width}_{out})

    \large \textnormal{Wight}:(\textnormal{outChannels}, \frac{inChannels}{groups},\textnormal{kernel[0],kernel[1]})

    注意\frac{inChannels}{groups}必须是整数

转置卷积

转置卷积(Transposed Convolution)在一些文献里也叫反卷积(Deconvolution)或部分跨越卷积(Fractionally-Strided Convolution)

通过卷积的正向传播的图像一般越来越小,记为下采样(Downsampled)。卷积的方向传播实际上就是一种转置卷积,它是上采样(Up-Sampling)

那么,反向传播又会如何?首先从卷积的反向传播算法开始。假设损失函数为L,则反向传播时,对L关系求导,利用链式法则得到:

转置卷积在生成式对抗网络(GAN)中很常见


池化层

池化又称下采样,通过卷积层获取获取图像的特征后,理论上可以直接使用这些特征训练分类器(如softmax)。但是这样仍然会面积巨大的计算量挑战,造成过拟合现象。为了进一步降低网络训练参数以及模型的过拟合程度,就要对卷积层进行池化(Pooling)处理。

池化的三种方式

  • 最大池化(Max Pooling):选择Pooling窗口中的最大值作为采样值
  • 均值池化(Mean Pooling):选择Pooling窗口中的所有值相加取平均,以平均值作为采样值
  • 全局最大(均值)池化:与平常最大或或最小池化相对而言,全局池化是对整个特征图的池化而不是在移动窗口内的池化
池化层在CNN中可以用来减小尺寸,提高运算速度以及减小噪音影响,让各特征更具健壮性。池化层比卷积层要简单,池化层没有卷积运算,只是在滤波器算子滑动区域内取最大值或平均值。而池化的作用则体现在降采样:保留显著特征、降低特征维度、增大感受野。

深度网络越往后面越能捕捉到物体的语义信息,这种语义信息建立在比较大的感受野基础上

局部池化

  • 定义:我们通常使用的最大或均值池化,是在特征图上(Feature Map)上以窗口的形式进行滑动(类似卷积的窗口滑动),操作为取窗口的最大或平均值作为结果,经过操作后,特征图降采样,减少了过拟合现象。其中在移动窗口内的池化称为局部池化

    在pytorch中,最大池化常使用nn.MaxPool2d,平均池化使用nn.AvgPool2d

    torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1,
    									return_indices=False, ceil_mode=False)
    '''
    param kernel_size(int):池化窗口大小,取一个四维向量,一般是[height, width],如果两者相等,可以是一个数字,如kernel_size=3
    param stride(int or tuple, optional): 窗口在每一个维度上滑动的步长,一般也是[stride_h,stride_w],如果两者相等,可以是一个数字,如stride=1
    param padding(int or tuple, optional): 与卷积类似
    param dilation(int or tuple, optional): 卷积对输入数据的空间间隔
    param return_indices(bool, optional): 是否返回最大值对应的下标
    param celi_mode(bool, optional): 使用一些方块代替层结构
    '''
  • 输入格式

    \large \textnormal{input} :(\textnormal{Number}, \textnormal{Channel}_{in},\textnormal{Height}_{in},\textnormal{Width}_{in})

    \large \textnormal{Output}:(\textnormal{Number},\textnormal{Channel}_{out},\textnormal{Height}_{out},\textnormal{Width}_{out})

    #池化窗口为正方形,size=3x3,stride=2
    m1 = nn.MaxPool2d(3, stride=2)
    #池化窗口为非正方形
    m2 = nn.MaxPool2d((3,2), stride=(2,1))
    input = torch.randn(20,16,50,32)
    output = m2(input)
    print(output.shape

全局池化

与局部池化相对的就是全局池化,全局池化也分为最大或平均池化。所谓的全局就是针对常用的平均池化而言,平均池化会有它的filter size,比如2x2,而全局池化就没有size,它针对的就是整个Feature Map

全局平均池化(Global Average Pooling, GAP)为例阐释全局池化的原理

下图左边把四个特征图,先用一个全连接层展平为一个向量,然后通过一个全连接层输出为4个分类节点。GAP可以把这两步合二为一,四个特征图通过GAP层时,求出每张Feature Map所有像素的均值,输出一个数据值,这样4个特征图就会输出4个数据点,这些数据点就组成一个1*4的向量

GAP的优势在于:各个类别与Feature Map之间的联系更加直观(相比全连接层的黑箱),Feature Map被转化为分类概率也更加容易,因为再GAP中没有参数许愿调,所以避免了过拟合问题。GAP汇总了空间信息,因此对输入的空间转换鲁棒性更强。所以卷积网络中最后几个全连接层,大都用GAP替换

总结学习于:《Python深度学习:基于Pytorch》

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

linengcs

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值