一、深度学习平台介绍
流行框架
目前流行的主要深度学习框架如下:
![](https://i-blog.csdnimg.cn/blog_migrate/555a9e5b4937d1dd0e690c980c658959.jpeg)
对比不同的深度学习框架:
![](https://i-blog.csdnimg.cn/blog_migrate/a6431391fed8540e682c8224c9551589.jpeg)
PyTorch 简介
PyTorch是个Python深度学习库,最初由Facebook人工智能研究小组开发,优步的Pyro软件用于概率编程。
最初,PyTorch由Hugh Perkins开发,作为基于Torch框架的LusJIT的Python包装器。PyTorch在Python中重新设计和实现Torch,同时为后端代码共享相同的核心C 库。
除了Facebook外,Twitter、GMU和Salesforce等机构都采用了Pytorch。
到目前,据统计已有80%的研究采用PyTorch,包括Google。
PyTorch与TensorFlow2作对比
![](https://i-blog.csdnimg.cn/blog_migrate/be79a49abcedbebbd352b57b2f4a5545.jpeg)
PyTorch的基本使用
张量
张量是一个物理量,对高维(维数≥2)的物理量进行量纲分析的一种工具。简单理解为:一维数组称为矢量,二维数组称为二阶张量,三维数组称为三阶张量......
计算图
用节点(nodes)和线(edges)的有向图来描述数学计算的图像。节点一般用来表示施加的数学操作,也可以表示数据输入的起点或者输出的终点,或者读取/写入持久变量的终点。线表示节点之间的输入输出关系,线可以运输“size可动态调整的”多维数据数组,即张量。
使用tensor表示数据。
使用Dataset、Dataloader读取样本数据和标签。
使用变量(Variable)存储神经网络权值等参数。
使用计算图(computational graph)来表示计算任务。
在代码运行过程中同时执行计算图。
PyTorch的使用示例——线性回归
定义网络的类
import torch.nn as nn
import torch
import matplotlib.pyplot as plt
class LinerRegression(nn.Module):
def __init__(self):
super(LinerRegression, self).__init__()
self.linear = nn.Linear(1, 1)
def forward(self, x):
out = self.linear(x)
return out
在[-1, 1]区间定义100个散点,训练网络获得直线斜率和截距进行拟合。
model = LinerRegression()
params = list(model.named_parameters())
(_, w) = params[0]
(_, b) = params[1]
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.3)
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
y = 2*x + 10 + torch.rand(x.size())
for epoch in range(20):
inputs = x
target = y
out = model(inputs)
loss = criterion(out, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('epoch: {}, w: {:.4f}, b:{:.4f}'.format(epoch+1, float(w.data), float(b.data)))
x2 = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
y2 = float(w.data)*x2 + float(b.data)
plt.scatter(x, y)
plt.plot(x2, y2, color='red')
plt.show()
model.eval()
运行结果如下(迭代20次,只展示后半部分)
![](https://i-blog.csdnimg.cn/blog_migrate/c1c6ae27e485d7e3e40b777586d3e1b7.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/4b92d58f796f7d34072cb0d98f387f26.jpeg)
二、卷积神经网络
进化史
![](https://i-blog.csdnimg.cn/blog_migrate/613cc7515398f7edffd764e4f3ee75cc.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/06babeb1461bd68d426dc57393f1b87a.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/7b0158057b6e519a86f2684520c47371.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/f9b04e48fe38ac5019c677d757ac3cff.jpeg)
基本概念
全连接神经网络连接权重过多,运算量大,网络难以收敛,同时可能进入局部极小值,容易产生过拟合问题。
卷积神经网络常用于图像处理和分类领域。卷积神经网络不同层之间的节点只有局部连接,这种结构将会减小网络的参数量,能够提高运算速度和预防过拟合的出现。
卷积
卷积神经网络利用卷积核通过卷积层来获得样本特征,卷积核是一个m×m大小的正方形,每一个元素代表权重。进行卷积操作时每一步卷积核会作用在输入图像m×m大小的区域,卷积核每一个元素与该区域对应元素进行内积(相乘再相加)得到输出。之后卷积核会在图片上滑动s个单位距离,进行下一步卷积操作,s称为步长。有时进行卷积操作前会进行填充操作,填充操作即在原始输入图像四周补零。若n代表输入图像尺寸,n’代表输出图像尺寸,p代表填充值,则n’与n、p、m、s的关系如下式。
![](https://i-blog.csdnimg.cn/blog_migrate/8cff1679e0c197fa404f99d5208ba201.jpeg)
(注意:严格来讲,直接将核与图像对应区域的元素进行内积叫相关操作,卷积操作是需要将核旋转180°后再进行内积,如果核是中心对称的,则相关操作和卷积操作是等价的)
卷积与滤波
1、平均滤波
在一个小区域内进行像素平均(加权平均、高斯平均),保留图像的低频成分。
![](https://i-blog.csdnimg.cn/blog_migrate/c9253d2fd3430ae3e08cd633aa943e71.jpeg)
2、边缘检测
提取图像的边缘,保留图像高频成分
Sobel算子
![](https://i-blog.csdnimg.cn/blog_migrate/bd86fa510f42e059518964b9a4371f5b.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/cdf2a355ca1b4804ed0e988c3ca82fa5.jpeg)
Prewitt算子
![](https://i-blog.csdnimg.cn/blog_migrate/36c5cf0a53fb54545380855b0e3f31d8.jpeg)
常用的边缘检测算子还有拉普拉斯算子、LoG(高斯-拉普拉斯算子)和Canny算子等。
多通道卷积
卷积神经网络的每一个特征层往往是多层的,特征层的层数与作用在特征层上的卷积核维度有以下关系:特征层的层数等于作用于其上的卷积核的层数,卷积核的个数等于下一层特征层的层数。多层卷积的示意图如下(三层为例)。
![](https://i-blog.csdnimg.cn/blog_migrate/e4def651d5dabfb1c651b5391095c035.jpeg)
池化
很多情况下通过卷积得到的特征图的尺寸会比较大,尺寸大的特征图虽然会包含更丰富的信息,但有很多信息在后续处理中是不需要的,继续使用尺寸过大的特征图进行后续处理无疑会增加运算成本。池化层的作用是对特征图进行压缩,既能减小后续的计算量,又能增加深层次特征图每个点的感受野。池化操作主要有平均池化操作和最大池化操作,平均池化即对池化区域取均值,实现对该区域的平滑处理,最大池化则是取出池化区域中值最大的点,值越大说明该点在该区域充当的成分越重要。
![](https://i-blog.csdnimg.cn/blog_migrate/2dae6138d627972f85c9b5fecd701bbf.jpeg)
卷积神经网络基本结构
卷积神经网络的网络结构有相似之处,一般而言,卷积层后紧接一个BN层,BN层连接激活函数。将卷积层、BN层和激活函数层看成一个卷积单位,一个卷积神经网络中有若干个卷积单位串接后进行池化操作,当然池化层后可以继续串接卷积单位和池化层,卷积单位负责特征提取,池化层负责下采样。网络最后会接一个全连接层,用于实现分类预测等任务。
三、LeNet-5网络
网络介绍
LeNet-5是由Yann LeCun提出的用于识别手写数字的卷积神经网络,是卷积神经网络的早期代表。
![](https://i-blog.csdnimg.cn/blog_migrate/4b2ccfe5f9ff9ddf04b35b768754d387.jpeg)
网络结构
LeNet-5一共有7层,包括3个卷积层、2个下采样层和2个全连接层。
![](https://i-blog.csdnimg.cn/blog_migrate/aaf916e28ce04990d1ee61b46eb18209.jpeg)
卷积核的大小均为5×5,步长为1。
卷积层C1
C1层是卷积层,形成6个特征图。卷积核大小是5x5,每个特征图使用一个共同卷积核,卷积核有5x5个权重加上1个偏置共26个参数。由于步长为1,无填充,依据上面的公式计算特征层尺寸为(32-5)/1+1=28。
C1层共有26x6=156个训练参数,有(5x5+1)x28x28x6=122304个连接。
下采样层S2
S2层是一个池化层,C1层的6个28x28的特征图分别进行2x2下采样得到6个14x14的图,计算时将滤波器覆盖区域的4个值相加乘以权重w,再加上偏置b,该层有2×6=12个参数(w, b),共有5x14x14x6=5880个连接。
卷积层C3
C3层是一个卷积层,卷积核尺寸和步长与C1相同,C3有16个10x10的特征图,S2层与C3层的卷积核是部分连接,每个图与S2层的连接的方式如下表所示。
![](https://i-blog.csdnimg.cn/blog_migrate/8afe238056dec7d94f419fefe3038d39.jpeg)
以第一列为例,表示C3层的0号卷积核与S2层的0、1、2号特征图相连。用3层卷积核分别与0、1、2号特征图进行卷积操作,卷积结果相加再加上偏置,再通过sigmoid函数获得结果,该层有(5x5x3+1)x6+(5x5x4+1)x9+(5x5x6+1)x1=1516个训练参数,这样做使得C3层的特征层有所差别,共有1516x10x10=151600个连接。
下采样层S4
结构与S2相似,生成16个5×5的特征图,共有32个参数,5×5×5×16=2000个连接。
卷积层C5(全连接)
对S4层进行5×5的卷积操作,生成120层1×1的特征层。有(5×5×16+1)×120=48120个参数,也有48120个连接。
全连接层F6
共有84个神经元与C5全连接,共有(120+1)×84=10164个参数和连接。
输出(全连接层)层OUTPUT
输出层也是全连接层,有10个节点,代表数字0-9。利用径向基函数,将F6层的84个单元的输出作为节点i(i=0-9)的输入xj(j=0-83),计算欧氏距离yi,yi越小意味着识别的样本越符合节点代表的字符,共有84×10=840个参数和连接。
网络说明
LeNet-5与现代网络的差别:
不使用填充
池化选择平均池化而不是最大池化
选用sigmoid而非ReLU作为激活函数
层数较浅,参数量较小(约6万)
普遍规律
随着网络的深入,特征层宽高减小,通道数增加。
![](https://i-blog.csdnimg.cn/blog_migrate/da34333baa9e85c91769cca1b807d454.jpeg)
卷积神经网络的反向传播
卷积神经网络分为卷积层和池化层,在进行反向传播的时候需要分别考虑,具体细节可以参考以下博文。
https://www.cnblogs.com/pinard/p/6494810.html
LeNet-5的代码实现
代码使用的是李沐的《动手学深度学习》。
![](https://i-blog.csdnimg.cn/blog_migrate/9a05f627bd31b113cb6b1c95b9e4eb46.jpeg)
注意,代码在第一层卷积加了一个padding=2,由于书中将输入图片尺寸设置为28×28,并不是32×32,第一层卷积后为了保证输出特征图尺寸也是28×28进行2填充。其余和上述LeNet-5网络结构完全相同。
相关模块的含义:
![](https://i-blog.csdnimg.cn/blog_migrate/b46af6dd81948fd11f32d5c181a06ec4.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/9287d611ce3b9964fd59805fd1384c58.jpeg)