Chapter6视觉处理基础

6.1 卷积神经网络简介

在这里插入图片描述

# 图6-1是用一个比较简单的卷积神经网络对手写输入数据进行分类
# 由卷积层(conv2d), 池化层(MaxPool2d)和全连接层(Linear)叠加而成
import torch.nn as nn 
import torch.nn.functional as F 
# 这个地方的cuda:0 实际上并不是0号GPU,他取决于CUDA_VISIBLE_DEVICES
# 然后逻辑GPU和物理GPU有一个对应关系
# 如果CUDA_VISIBLE_DEVICES为2,1,3
# 那么CUDA:0就是2号GPU, CUDA:1 就是1号GPU CUDA:3 就是3号GPU

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class CNNNet(nn.Module):
    def __init__(self):
        super(CNNNet, self).__init__()
        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)
        # nn.Linear是一个类,使用时进行类的实例化
        # 实例化的时候,nn.Linear需要输入两个参数,
        # in_features为上一层神经元的个数,out_features为这一层的神经元个数
        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)
        # 其维度进行随意变化的话,可以使用view()方法,
        # 比如我想将其维度变化成:1*6,则使用方法view(1,6)即可。
        x = x.view(-1, 36*6*6)
        x = F.relu(self.fc2(F.relu(self.fc1(x))))
        return x 

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

6.2 卷积层

6.2.1 卷积核

卷积核是整个卷积过程的核心,比较简单的卷积核或过滤器有Horizontalfilter, Verticalfilter, Sobel Filter等,这些过滤器能够检测图像的水平边缘,垂直边缘,增强图像中心区域权重等

6.6.2步幅

卷积核的值在移动的过程中都是共享的,卷积神经网络采用参数共享的方法大大降低了参数的数量。
在这里插入图片描述

  • 假设输入数据大小为n, 过滤器为f*f, 步幅为s,填充为0
    则输出大小为(n-f)/s + 1
    n-f即得到余下有多少个列,除以s即得到还可以移动几次,如果不能整除,则向下取整,然后+1是指加上第一次卷积
  • 假设输入数据大小为n, 过滤器为f*f, 步幅为s,填充为p
    则输出大小为(n+2p-f)/s + 1

6.2.3 填充

要进行padding的原因:

  • 图像缩小
  • 和中间图像信息相比,边缘图像信息丢失。padding可以防止图像边缘部分的特征信息丢失
    根据是否拓展Padding又分为Same, Valid.
    采用Same方式时,对图片扩展并补0,(即保证输入和输出大小相同)
    采用Valid方式时,不对图片进行扩展(即no padding)
    在实际训练过程中一般选择Same方式,使用Same不会丢失信息。设补0的圈数为p,输入数据大小为n, 过滤器大小为f, 步幅大小为s,则有:
    在这里插入图片描述
    因为要保证输入n, 输出也为n,而经过填充p后的实际输出为n+2p-f+1
    n = n+2p-f+1 所以p = (f-1)/2
    f 一般为奇数,1.因为如果f是偶数,则填充不对称2.f为奇数,便于指出过滤器的中心位置(虽然用偶数的过滤器也许可以取得较好的结果)

6.2.4 多通道上的卷积

彩色图片就3通道,RGB,3通道图片的卷积运算与单通道图片的卷积运算基本一致,对于3通道的RGB图片,其对应的滤波器算子同样也是3通道的。
在这里插入图片描述
例如上图是663,表示高度height, 宽度width,通道数 channel。过程是将每个单通道(RGB)与对应的filter进行卷积运算求和,然后再将3通道的和相加,得到输出图片的一个像素值。
不同滤波器组卷积得到不同的输出,个数由滤波器组决定,图6-11中只有1个滤波器组,所以结果只有一个;如果有2个333的filter,则会得到442的输出

6.2.5 激活函数

卷积神经网络与标准的神经网络类似,为保证其非线性,也需要使用激活函数,即在卷积运算后,把输出值另加偏移量,输入到激活函数,然后作为下一层的输入
在这里插入图片描述
常见的激活函数为:nn.Sigmoid, nn.ReLU, nn.LeakyReLU, nn.Tanh

6.2.6 卷积函数

torch.nn.Conv2d
在这里插入图片描述
在这里插入图片描述

dilation:其默认值为1
在这里插入图片描述
在这里插入图片描述 这种情况实际为Pytorch中,dilation = 2的情况。
特别注意:在Pytorch中,dilation = 1等同于没有dilation的标准卷积。

参考博客

6.2.7 转置卷积

转置卷积(Transposed Convolution)也叫反卷积(Deconvolution)或部分跨越卷积(Fractionally-Strided Convolution)
通过卷积的正向传播的图像一般越来越小,记为下采样(Downsampled).卷积的方向传播实际上就是一种转置卷积,它是上采样(up-Sampling)
转置卷积详解1

B站转置卷积详解
转置卷积详解2
在这里插入图片描述

在这里插入图片描述
总结:
转置卷积的作用:上采样
在这里插入图片描述
这里不能使用 I = O C − 1 I = OC^{-1} I=OC1,因为不能保证C可逆,可逆只对方阵而言,但并不能保证C是方阵。所以放宽条件:不要求还原卷积前的数据,只要求还原卷积前的大小即可

torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1, padding_mode='zeros')

6.3 池化层

池化(Pooling)又称为下采样,通过卷积层获得图像特征后,理论上可以直接使用这些特征训练分类器。但这样计算量太大,且容易产生过拟合现象。
故要对卷积层进行池化处理,有3中方法:
1。最大池化Max Pooling:选择Pooling窗口中的最大值作为采样值
2。均值池化Mean Pooling:将Pooling窗口中的所有值相加取平均,以平均值作为采样值
3。全局最大(或均值)池化:与平常最大或最小池化相对而言,全局池化是对整个特征图的池化而不是在移动窗口范围内的池化
在这里插入图片描述
池化的作用:
在CNN中可用来减小尺寸,提高运算速度,减小噪声影响,让各特征更具有健壮性。
池化层比卷积层更简单,它没有卷积运算,只是在滤波器算子滑动区域内取最大值或平均值。
池化的作用则体现在降采样:保留显著特征,降低特征维度,增大感受野。
深度网络越往后面越能捕捉到物体的语义信息,这种语义信息是建立在较大的感受野基础上。

6.3.1 局部池化

在移动窗口内的池化被称为局部池化
nn.MaxPool2d
nn.AvgPool2d -----更常用

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

6.3.2 全局池化

全局池化也分为最大或平均池化。
全局平均池化(Global Average Pooling, GAP),不以窗口的形式取均值,而是以特征图为单位进行均质化,即一个特征图输出一个值

在这里插入图片描述
在这里插入图片描述
使用全局平均池化代替CNN中传统的全连接层。在使用卷积层的识别任务中,全局平均池化能够为每一个特定的类别生成一个特征图(Feature Map)
GAP的优势在于:

  • 各个类别与Feature Map之间的联系更加直观(相比于全连接层的黑箱来说),Feature Map被转化为分类概率也更加容易,因为在GAP中不用调参,避免了过拟合问题。
  • GAP汇总了空间信息,因此对输入的空间转换鲁棒性更强。所以目前卷积网络中最后几个全连接层,大都用GAP替换
  • 全局最大池化层(GlobalMaxPooling2D)在pytorch中没有对应名称的池化层,但可以使用pytorch中的自适应池化层(AdaptiveMaxPool2d(1)或nn.AdaptiveAvgPool2d(1))来实现

6.4 现代经典网络

6.4.1 LeNet-5 模型

(1)模型架构
输出层–卷积层–池化层–卷积层–池化层–全连接层–全连接层–输出
(2)模型特点

  • 每个卷积层包含3部分:卷积,池化,和非线性激活函数
  • 使用卷积提取空间特征
  • 采用降采样(Subsample)的平均池化层(Average Pooling)
  • 使用双曲正切(Tanh)的激活函数
  • 最后使用MLP作为分类器

Tanh比sigmoid函数晚诞生,sigmoid函数的一个缺点就是输出不以0为中心,使得收敛变慢。
而tanh则解决了这个问题,它是一个奇函数
tanh ⁡ ( x ) = sinh ⁡ ( x ) cosh ⁡ ( x ) = e x − e − x e x + e − x \tanh (x)=\frac{\sinh (x)}{\cosh (x)}=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} tanh(x)=cosh(x)sinh(x)=ex+exexex
在这里插入图片描述
尽管tanh函数和sigmoid函数存在梯度消失的问题,但是与之类似,如果函数的梯度过大又会导致梯度爆炸的问题,显然tanh和sigmoid的导函数非常有界,根据导数公式,很容易得出t a n h ′ ( x ) ∈ [ 0 , 1 ] 所以完全不用担心因为使用激活函数而产生梯度爆炸的问题。

  • LeNet-5论文阅读,博客编写
  • AlexNet论文阅读,博客编写
  • VGG论文阅读,博客编写
  • GoogleNet论文阅读,博客编写
  • ResNet论文阅读,博客编写
  • [ ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值