目录
- 基本组成结构
-
- 一、卷积 Convolutional
-
- 1 传统的神经网络 VS 卷积神经网络
- 2 概念
- 3 卷积层的计算
-
- 卷积核如何工作?
- 二、池化
- 三、全连接
- 四、小结
- 卷积神经网络的典型结构
-
- 一、AlexNet
- 二、ZFNet
- 三、VGG
- 四、GoogleNet
- 五、ResNet
- 编程
-
- 一、MNIST 数据集分类:构建简单的CNN对 mnist 数据集进行分类。
- 二、CIFAR10 数据集分类:使用 CNN 对 CIFAR10 数据集进行分类
- 三、使用 VGG16 对 CIFAR10 分类
- 问题
前言
文章图片
基本组成结构 一、卷积 Convolutional 1 传统的神经网络 VS 卷积神经网络
2 概念
卷积是对两个实变函数的一种数学操作。
文章图片
3 卷积层的计算
由于图像是二维的,所以要对图像进行二维卷积。
文章图片
卷积核如何工作?
例1:输入:5x5当设定的步长(stride)和输入的图片尺寸不匹配时,可以对图片进行外部零填充,从而使输入图像尺寸变大。eg. 例1的padding为0,例2的padding为1~
?? ?? 卷积核:3x3 ?? [ 1 0 1 0 1 0 1 0 1 ] \begin{bmatrix}1&0&1\\0&1&0\\1&0&1\end{bmatrix} ? ??101?010?101?? ??
?? ? ?步长:1
?? ? ?特征图:3x3
?
3x3的卷积核作用于输入数据,对应数值相乘再相加,如下图所示:
例2:2个channel(2个filter,最后输出是2个feature map),padding=1【暑期深度学习入门|第二周学习(卷积神经网络)】有padding时输出的特征图大小(一个特征图的边长): ( N + p a d d i n g ? 2 ? F ) s t r i d e + 1 \frac{(N+padding*2-F)}{stride}+1 stride(N+padding?2?F)?+1
7x7x3,(3个不同的权重矩阵)
channel为生成的feature map的层数,此处为2
二、池化
- 池化保留了主要特征的同时减少参数和计算量,防止过拟合,提高模型泛化能力。
- 它一般处于卷积层与卷积层之间,全连接层与全连接层之间。
文章图片
- Max pooling:最大值池化(常用于分类任务)
- Average pooling:平均池化
文章图片
文章图片
四、小结
文章图片
卷积神经网络的典型结构 一、AlexNet AlexNe网络使深度学习重回历史舞台~
- 为防止过拟合
(1)使用了Dropout(随即失活),训练过程中随机关闭部分神经元,测试时整合所有神经元;
(2)数据增强:
?????· 反转、平移、对称:随机crop(对图片进行尺度变化)、水平翻转(样本数倍增);
?????· 改变RGB通道强度,对RGB空间做高斯扰动; - 使用了非线性激活函数ReLU(解决了梯度消失问题、计算速度很快只需2判断输入是否>0、收敛速度远大于sigmoid)
文章图片
文章图片
三、VGG VGG是一个更深的网络。加入了辅助分类器,解决由于深度过深而导致的梯度消失问题。
四、GoogleNet 设定Inception模块(多个Inception结构堆叠),在Inception中通过多卷积核增加特征多样性(下图左),但是最后的输出很大,会导致计算复杂度过高。
文章图片
解决思路是:插入1*1卷积核进行降维(上图右)
然后用小的卷积核代替大的卷积核,进一步降低参数量。
例如:使用两个3 * 3的卷积核来 替代 一个5 * 5的卷积核,可以降低参数量
文章图片
在卷积核与卷积核之间增加非线性激活函数,是网络产生更多的独立特,表征能力更强,训练更快。
文章图片
输出没有额外的全连接层(除了最后的类别输出层)
五、ResNet 深度152层。
残差学习网络(deep residual learning network)
残差的思想: 去掉相同的主体部分,从而突出微小的变化,可以被用来训练非常深的网络。
文章图片
设F(x) + x = f( g( h(x) + x ) + x ) + x,对式子求导,得 导数 = (f’ + 1)(g’ + 1)(h’ + 1)。即使函数求导为零或函数本身就为零,但加上1之后就不会存在梯度消失的情况。
编程
torchvision.datasets.MNIST(root, train=True, transform=None, target_transform=None, download=False)
- root 为数据集下载到本地后的根目录,包括 training.pt 和 test.pt 文件
- train,如果设置为True,从training.pt创建数据集,否则从test.pt创建。
- transform, 一种函数或变换,输入PIL图片,返回变换之后的数据。
- target_transform 一种函数或变换,输入目标,进行变换。
- download,如果设置为True, 从互联网下载数据并放到root文件夹下
- DataLoader是一个比较重要的类,提供的常用操作有:
- batch_size(每个batch的大小), shuffle(是否进行随机打乱顺序的操作),
- num_workers(加载数据的时候使用几个子进程)
transforms.Compose
Composes several transforms together. This transform does not support torchscript.
将几个变换组合在一起。这个转换不支持torchscript。
- 即组合几个变换方法,按顺序变换相应数据。
- 其中torchscript为脚本模块,用于封装脚本跨平台使用,若需要支持此情况,需要使用
torch.nn.Sequential
,而不是compose
- 对应于问题描述中代码,即先应用
ToTensor()
使[0-255]变换为[0-1],再应用Normalize
自定义标准化
transforms.ToTensor()
Convert a PIL Image or numpy.ndarray to tensor
转换一个PIL库的图片或者numpy
的数组为tensor
张量类型;转换从[0,255]->[0,1]
- 实现原理:针对不同类型进行处理,即各值除以255,最后通过
torch.from_numpy
将PIL库的图片或numpy.ndarray
针对具体数值类型比如Int32,int16,float
等转成torch.tensor
数据类型
transforms.Normalize()
Normalize a tensor image with mean and standard deviation一、MNIST 数据集分类:构建简单的CNN对 mnist 数据集进行分类。 笔记本链接
通过平均值和标准差来标准化一个tensor图像(对图像进行标准化),公式为:
output[channel] = (input[channel] - mean[channel]) / std[channel]
解释:transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
即映射到[-1,1]
- 第一个
(0.5, 0.5 ,0.5)
即三个通道的平均值- 第二个
(0.5, 0.5, 0.5)
即三个通道的标准差值
由于ToTensor()
已经将图像变为[0, 1],我们使其变为[-1, 1],以第一个通道为例,将最大与最小值代入公式:- (0-0.5)/0.5=-1
- (1-0.5)/0.5=1
二、CIFAR10 数据集分类:使用 CNN 对 CIFAR10 数据集进行分类 笔记本链接
三、使用 VGG16 对 CIFAR10 分类 笔记本链接
问题
- dataloader 里面 shuffle 取不同值有什么区别?
shuffle = true
时,可以打乱图片的顺序以增加多样性- 一般在
train
上设置shuffle=true
,在test
上设置shuffle=false
。- Pytorch的DataLoader中的shuffle是先打乱,再取batch。
如果训练集的shuffle不设置为true的话训练出来的模型不泛化,也就是只适合预测这一个数据集,换到别的数据集上效果不好也有可能在本数据集上预测的效果也不好。我们的shuffle的目的是为了增加模型的泛化能力,而测试集是用来评价我们训练的模型在未知数据上的表现。让测试集保持原有的顺序卷积好。
- transform里,取了不同值,这个有什么区别?
常用的数据预处理方法,例如下图,在训练部分的数据集对数据增强,利用随机裁剪以及随机翻转,以增强模型的泛化能力,防止过拟合。
- epoch 和 batch 的区别?
- 当一个完整的数据集经过神经网络一次,并返回一次,这个过程称为一个epoch。(需要多个epoch:在深度学习中,向神经网络传递整个数据集一次是远远不够的,而需要多次在神经网络上训练。)
- 当数据集很大的时候,对于每个epoch,很难将所有的数据集一次读入到内存中,这是需要将数据集分为几次读入,每次称为一个batch。
- bach_size:batch中样本的数量。
- 1x1的卷积和 FC 有什么区别?主要起什么作用?
数学原理上来看没有区别。但1x1的卷积核的输入尺寸大小不是固定的;而全连接是固定的。1*1卷积可以用于升维,FC通常在最后。
- residual leanring 为什么能够提升准确率?
解决了梯度消失的问题,可以用来训练比较深的网络
- 代码练习二里,网络和1989年 Lecun 提出的 LeNet有什么区别?
代码二用的ReLu作为激活函数,LeNet的激活函数是Sigmod
- 代码练习二里,卷积以后feature map 尺寸会变小,如何应用 Residual Learning残差学习?
可以选择使用1*1卷积、填充padding等方法来调整feature map尺寸
- 有什么方法可以进一步提升准确率?
防止过拟合:Dropout、在训练部分的数据集对数据增强(数据预处理)
适当增加模型的深度,使用更合适的激活函数,改变模型的网络结构
推荐阅读
- 学习日志|Python MINIST手写集的识别,卷积神经网络,CNN(最简单PyTorch的使用)
- 机器学习图像处理|从零开始实现一个简单的CycleGAN项目
- 人工智能|CV目标检测模型小抄(1)
- 神经网络|YOLO7 姿势识别实例
- 毕设题目|机器学习_深度学习毕设题目汇总——人脸A
- python|(七)PyTorch深度学习(全连接层网络)
- 深度学习|pytorch_YOLOX剪枝【附代码】
- libtorch|YOLOv4 libtorch推理【附代码】
- 分类|手部关键点识别+分类综合项目应用[附代码]