从深度神经网络(DNN)到卷积神经网络(CNN)

编程入门 行业动态 更新时间:2024-10-28 07:22:12

从深度<a href=https://www.elefans.com/category/jswz/34/1769690.html style=神经网络(DNN)到卷积神经网络(CNN)"/>

从深度神经网络(DNN)到卷积神经网络(CNN)

从深度神经网络(DNN)到卷积神经网络(CNN)

文章目录

  • 从深度神经网络(DNN)到卷积神经网络(CNN)
    • 基本概念介绍
      • 深度神经网络(CNN)长这样:
      • 神经网络训练目标:
      • 找出合适的权值和截距项,使得误差(损失函数最小)
  • 卷积神经网络
    • 什么是卷积?
      • 卷积层作用:
      • 感知野
      • 卷积层负责提取特征,采样层负责特征选择,全连接层负责分类
    • 池化层——数据降维,避免过拟合
    • 全连接层
    • 举例: LeNet-5
        • 1、INPUT层-输入层
        • 2、C1层-卷积层
        • 3、S2池化层(下采样层)
        • 4、C3层-卷积层
        • 5、S4层-池化层(下采样层)
        • 6、 C5卷积层-全连接层
        • 7、F6层-全连接层
        • 8、Output层-全连接层
          • LeNet5 特征能够总结为如下几点:
          • 卷积神经网络之训练算法
          • 卷积神经网络之优缺点
      • pytorch实现LeNet5进行mnist手写数字识别
      • keras
    • 总结

基本概念介绍


(涉及专业名称较多,如果中间看到某个名词陌生,记得往回翻看)

重要概念:
输入(x)输出(y)、标签(label)

  • 输入是指传入给网络处理的向量,相当于数学函数中的变量
  • 输出是指网络处理后返回的结果,相当于数据函数中的函数值
  • 标签是指我们期望网络返回的结果。

例如对于识别mnist图片而言,输入是大小为784(28 * 28)的向量,输出是大小为10的概率向量(概率最大的位置即为预测的数字)。


一个神经元长这样:

  • X叫神经元的输入,
  • Y叫神经元的输出,
  • W叫神经元的权值(权重)
  • θ: 表示偏置(截距项,阈值)
  • f : 激活函数(激励函数)

激活函数:
激活函数(Activation functions)对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。它们将非线性特性引入到我们的网络中。如图1,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘罢了。
也就是说没有激活函数,再多个神经元组合,y和x依然只能是线性关系,激活函数可以引入非线性因素

比较常用的有:
relu sigmoid tanh 函数

激活函数作用总结:
激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。


深度神经网络(CNN)长这样:

(多个神经元组合)
从左到右:

  • 输入层
  • 隐藏层(可以有多个隐藏层)
  • 输出层

一般来说,输出层中的神经元和输入层中各个输入是完全连接的。因此,输出层又叫全连接层(fully-connectedlayer)或稠密层(dense layer)。

  • 损失函数(loss function)或代价函数(cost function)
    预测值与真实值会存在差距,我们怎么衡量这个差距? 或者说我们如果评估一个网络的好坏?
    答案是损失函数:
    容易想到的自然就是真实值与预测值直接相减。

比较常用的是平方损失函数
(预测值-真实值的平方再求和再除样本数)

  • 梯度
    在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。对于在点(x0,y0)的具体梯度向量就是(∂f/∂x0, ∂f/∂y0)T.或者 ▽f(x0,y0),如果是3个参数的向量梯度,就是(∂f/∂x, ∂f/∂y,∂f/∂z)T,以此类推。
    那么这个梯度向量求出来有什么意义呢?他的意义从几何意义上讲是曲线斜率,就是函数变化增加最快的地方。具体来说,对于函数f(x,y),在点(x0,y0),沿着梯度向量的方向就是(∂f/∂x0, ∂f/∂y0)T的方向是f(x,y)增加最快的地方。或者说,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是 -(∂f/∂x0, ∂f/∂y0)T的方向,梯度减少最快,也就是更加容易找到函数的最小值。

在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。

  • 学习速率
    简单说,梯度即一个函数的斜率,找到函数的斜率,其实就知道了w和的θ值往哪个方向调整,能够让函数值(loss)降低得最快。那么方向知道了,往这个方向调整多少呢?这个数,神经网络中称之为学习速率。学习速率调得太低,训练速度会很慢,学习速率调得过高,每次迭代波动会很大。
    一般取值在(0,1)范围。

神经网络训练目标:

找出合适的权值和截距项,使得误差(损失函数最小)

做法:
反向传播,梯度下降(不讲)
请去看
吴恩达机器学习系列课程,-2.6梯度下降总结
(没有谁比吴恩达老师讲的更好了)
神经网络训练过程:

- 输入:训练集数据、学习速率yita
- 过程:在(0,1)范围内随机初始化网络中所有连接权值和截距项repeat根据网络输入和当前参数计算网络输出值y计算输出层神经元梯度项gj计算隐层神经元梯度项eh更新连接权值和截距项until达到停止条件输出:连接权值和截距项

卷积神经网络

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。

对卷积神经网络的研究始于二十世纪80至90年代,时间延迟网络和LeNet-5是最早出现的卷积神经网络 ;在二十一世纪后,随着深度学习理论的提出和数值计算设备的改进,卷积神经网络得到了快速发展,并被应用于计算机视觉、自然语言处理等领域 。

什么是卷积?

简单来说,卷积(或内积)就是一种先把对应位置相乘然后再把结果相加的运算。下图简要地展示卷积的运算过程:

图像的滤波操作

B为模糊图像( blurry image ),I为待估计的清晰图像( latent image ),K为模糊核( blur kernel ),N为附加的噪声,ⓧ为卷积操作。
(它们都是用矩阵表示,比如模糊核实际上就是一个矩阵,清晰图像与模糊核卷积后导致图像变得模糊,因此叫模糊核。模糊核是卷积核的一种。图像卷积操作的本质是矩阵卷积。某些特殊的卷积核会使图像产生特殊的效果。)

卷积核就是图像处理时,给定输入图像,输入图像中一个小区域中像素加权平均后成为输出图像中的每个对应像素,其中权值由一个函数定义,这个函数称为卷积核。

对于一个灰度图片(图3) 用sobel算子(图4)进行过滤,将得到如图5所示的图片

图4的矩阵值可以叫做权重(或者滤波器或者卷积核)。而权重(或卷积核)的大小(如图4的3×3)叫做接受域(也叫感知野或者数据窗口)
反正名字就是非常多

卷积层作用:

在抽象意义上来说

卷积这个过程我们可以理解为我们使用一个过滤器(卷积核)来过滤图像的各个小区域,从而得到这些小区域的特征值。

在具体应用中,往往有多个卷积核,可以认为,每个卷积核代表了一种图像模式,如果某个图像块与此卷积核卷积出的值大,则认为此图像块十分接近于此卷积核。如果我们设计了6个卷积核,可以理解:我们认为这个图像上有6种底层纹理模式,也就是我们用6中基础模式就能描绘出一副图像。以下就是25种不同的卷积核的示例:

卷积层的功能是对输入数据进行特征提取,其内部包含多个卷积核,组成卷积核的每个元素都对应一个权重系数和一个偏差量(bias vector),类似于一个前馈神经网络的神经元(neuron)。卷积层内每个神经元都与前一层中位置接近的区域的多个神经元相连,区域的大小取决于卷积核的大小,在文献中被称为“感受野(receptive field)”,其含义可类比视觉皮层细胞的感受野 。卷积核在工作时,会有规律地扫过输入特征,在感受野内对输入特征做矩阵元素乘法求和并叠加偏差量

  1. 滤波器的作用或者说是卷积的作用。卷积层的参数是有一些可学习的滤波器集合构成的。每个滤波器在空间上(宽度和高度)都比较小,但是深度和输入数据一致。直观地来说,网络会让滤波器学习到当它看到某些类型的视觉特征时就激活,具体的视觉特征可能是某些方位上的边界,或者在第一层上某些颜色的斑点,甚至可以是网络更高层上的蜂巢状或者车轮状图案。

  2. 可以被看做是神经元的一个输出。神经元只观察输入数据中的一小部分,并且和空间上左右两边的所有神经元共享参数(因为这些数字都是使用同一个滤波器得到的结果)。

  3. 降低参数的数量。这个由于卷积具有“权值共享”这样的特性,可以降低参数数量,达到降低计算开销,防止由于参数过多而造成过拟合。

感知野

在处理图像这样的高维度输入时,让每个神经元都与前一层中的所有神经元进行全连接是不现实的。相反,我们让每个神经元只与输入数据的一个局部区域连接。该连接的空间大小叫做神经元的感知野(receptive field),它的尺寸是一个超参数(其实就是滤波器的空间尺寸)。在深度方向上,这个连接的大小总是和输入量的深度相等。

其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进。比如下图中就多了许多传统神经网络没有的层次。


翻译:convolution 卷积 subsampling 子采样 Full connections 全连接
或者这个图:(卷积层和采样层可以重复)

最简单的卷积神经网络最终只是起到一个分类器的作用


卷积层负责提取特征,采样层负责特征选择,全连接层负责分类

与常规神经网络不同,卷积神经网络的各层中的神经元是3维排列的:宽度、高度和深度

卷积神经网络的层级结构

  • 数据输入层/ Input layer,原始图像预处理:1、去均值 2、归一化 3、主成分分析(Principal Component Analysis,PCA)
  • 卷积计算层/ CONV layer, 一组固定的权重和不同窗口内数据做内积: 卷积
  • 池化层(下采样层) / Pooling layer,如果输入是图像的话,那么池化层的最主要作用就是压缩图像,–Max pooling
  • 全连接层 / FC layer,全连接层,通俗的说就是前面一层的每个单元都与后面一层的相连接。

注:

  • 输入层

去均值一般是针对于图片,将输入网络的图片数据减去数据集的RGB通道的均值,使得数据的分布变为均值为0,方差为1的数据。


归一化使图像的某些特征在给定变换下具有不变性质的一种图像标准形式。图像的某些性质,例如物体的面积和周长,本来对于坐标旋转来说就具有不变的性质。在一般情况下,某些因素或变换对图像一些性质的影响可通过归一化处理得到消除或减弱,从而可以被选作测量图像的依据。例如对于光照不可控的遥感图片,灰度直方图的归一化对于图像分析是十分必要的。
灰度归一化、几何归一化和变换归一化是获取图像不变性质的三种归一化方法。

主成分分析也叫PCA降维
主成分分析(英语:Principal components analysis,PCA)是一种分析、简化数据集的技术。主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。

  • 卷积层 也叫C-层或Convolutions层或CONV层或特征提取层

池化层——数据降维,避免过拟合

  • 池化层 也叫S-层或子抽样局部平均层或下采样局部平均层或POOL层,
    主要作用是减小特征图,起到降维的作用。常用的方法是选取局部区域的最大值(Max Pooling)或者平均值

在卷积层进行特征提取后,输出的特征图会被传递至池化层进行特征选择和信息过滤。池化层包含预设定的池化函数,其功能是将特征图中单个点的结果替换为其相邻区域的特征图统计量。池化层选取池化区域与卷积核扫描特征图步骤相同,由池化大小、步长和填充控制。

通常在连续的卷积层之间会周期性地插入一个池化层。它的作用是逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。汇聚层使用 MAX 操作,对输入数据体的每一个深度切片独立进行操作,改变它的空间尺寸。

最常见的形式是汇聚层使用尺寸2x2的滤波器,以步长为2来对每个深度切片进行降采样,将其中75%的激活信息都丢掉。每个MAX操作是从4个数字中取最大值(也就是在深度切片中某个2x2的区域),深度保持不变。

如图,将特征图的尺寸变为原来的1/4,
输入:4x4
输出:2x2

全连接层

卷积神经网络中的全连接层等价于传统前馈神经网络中的隐含层。全连接层位于卷积神经网络隐含层的最后部分,并只向其它全连接层传递信号。特征图在全连接层中会失去空间拓扑结构,被展开为向量并通过激励函数。

通俗的说就是前面一层的每个单元都与后面一层的相连接。如下图的绿色 Hidden 层,Hidden 层的每个单元都与 Input 层的所有单元相连接,同理 Output 层的与 Hidden 层的也是如此。

即 Input 到 Hidden 这个全连接层中间的参数矩阵是 (3,4) 维的,Hidden 到 Output 的参数矩阵是 (4,2) 维。
(可能你会说:这不就是深度全连接 神经网络吗?
是的

总结一下:

举例: LeNet-5

典型的 CNN 并非只是上面提到的3层结构,而是多层结构,例如 LeNet-5 的结构就如下图所示:

卷积层 – 池化层- 卷积层 – 池化层 – 卷积层 – 全连接层

LeNet5 诞生于 1994 年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。自从 1988 年开始,在许多次成功的迭代后,这项由 Yann LeCun 完成的开拓性成果被命名为 LeNet5,有兴趣的小伙伴可去看一下原论文:Gradient-Based Learning Applied to Document Recognition,是一种用于手写体字符识别的非常高效的卷积神经网络。

LeNet5是最基本的卷积神经网络算法。包含2个5x5的卷积层,2个2x2的池化层和3个全连接层(最后一个为输出层)。

LeNet-5是一个应用于图像分类问题的卷积神经网络,其学习目标是从一系列由32×32×1灰度图像表示的手写数字中识别和区分0-9。LeNet-5的隐含层由2个卷积层、2个池化层构筑和2个全连接层组成,按如下方式构建:
(3×3)×1×6的卷积层(步长为1,无填充),2×2均值池化(步长为2,无填充),tanh激励函数
(5×5)×6×16的卷积层(步长为1,无填充),2×2均值池化(步长为2,无填充),tanh激励函数
2个全连接层,神经元数量为120和84。
1个输出层,神经元数量为10。

1、INPUT层-输入层

首先是数据 INPUT 层,输入图像的尺寸统一归一化为32x32。也就是说我们的图像尺寸为32x32x1单通道(黑白图像)。
这里我们把输入层也当作为一层。

2、C1层-卷积层

在LeNet网络中,卷积核的大小为5×5×1。卷积核每进行完一次卷积之后,还要再加上一个偏置量,然后,我们就会得到28×28×1的特征图,当我们使用六个卷积核对图像进行卷积操作,就会得到6个特征图,把这六个特征图合到一起,就是卷积层,卷积层的尺寸为28×28×6。

输入图片:32*32
卷积核大小:5*5
卷积核个数:6
输出featuremap大小:28*28 (32-5+1)=28
神经元数量:28*28*6

可训练参数:(5*5+1) * 6(每个滤波器5*5=25个unit参数和一个bias参数,一共6个卷积核)
连接数:(5*5+1)*6*28*28=122304

一个神经元是感受野经过卷积核的卷积操作之后加上一个偏置量再进行激活后得到的一个像素位置,就是一个神经元。

神经元计算示意图

3、S2池化层(下采样层)

这一层是池化层,将特征图的尺寸变为原来的1/4,在这里采用的是最大池化,即找区域为2×2正方形窗口中的最大值。经过池化操作后,特征图个数没有变化,只是每个特征图的大小变为了14×14的特征图。

总结一下,在池化层中:

输入特征图:28×28×6
池化窗口(采样区域):2×2
池化方式:最大池化(max pooling)
输出特征图:14×14×6

第一次卷积之后紧接着就是池化运算,使用 2*2核 进行池化,于是得到了S2,6个14*14的 特征图(28/2=14)。S2这个pooling层是对C1中的2*2区域内的像素求和乘以一个权值系数再加上一个偏置,然后将这个结果再做一次映射。同时有5x14x14x6=5880个连接。

4、C3层-卷积层

输入:S2中所有6个或者几个特征map组合
卷积核大小:5*5
卷积核个数:16
输出featureMap大小:10*10 (14-5+1)=10
训练参数:6*(3*5*5+1)+6*(4*5*5+1)+3*(4*5*5+1)+1*(6*5*5+1)=1516

第一次池化之后是第二次卷积,第二次卷积的输出是C3,16个10x10的特征图,卷积核大小是 5*5. 我们知道S2 有6个 14*14 的特征图,怎么从6 个特征图得到 16个特征图了? 这里是通过对S2 的特征图特殊组合计算得到的16个特征图。具体如下:


C3的前6个feature map(对应上图第一个红框的6列)与S2层相连的3个feature map相连接(上图第一个红框),后面6个feature map与S2层相连的4个feature map相连接(上图第二个红框),后面3个feature map与S2层部分不相连的4个feature map相连接,最后一个与S2层的所有feature map相连。卷积核大小依然为5*5,所以总共有6*(3*5*5+1)+6*(4*5*5+1)+3*(4*5*5+1)+1*(6*5*5+1)=1516个参数。而图像大小为10*10,所以共有151600个连接。

C3与S2中前3个图相连的卷积结构如下图所示:

上图对应的参数为 3*5*5+1,一共进行6次卷积得到6个特征图,所以有6*(3*5*5+1)参数。 为什么采用上述这样的组合了?论文中说有两个原因:
1)减少参数,降低计算量。
2)这种不对称的组合连接的方式有利于提取多种组合特征。将不同的特征图像卷积得到新的一个特征图,就可以把这几个特征图中的特征融合到一起。

5、S4层-池化层(下采样层)

输入特征图:10×10×16
池化窗口(采样区域):2×2
池化方式:最大池化
输出特征图:5×5×16

采样方式:4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过激活函数
采样种类:16
神经元数量:5*5*16=400
连接数:16*(2*2+1)*5*5=2000

S4是池化层,与上面的S2池化层的操作是一致的,只不过因为输入不同,所以输出也不同,同样将特征图的尺寸变为上一层(C3)的1/4,在这里采用的是最大池化,即找区域为2×2正方形窗口中的最大值。经过池化操作后,特征图个数没有变化,只是每个特征图的大小变为了5×5的特征图。窗口大小仍然是2x2,共计16个feature map,C3层的16个10x10的图分别进行以2x2为单位的池化得到16个5x5的特征图。有5x5x5x16=2000个连接。连接的方式与S2层类似。

6、 C5卷积层-全连接层

这一次卷积跟前两次的卷积也依然有区别,但是跟前一次的最后一个卷积是一样的,就是将前一层的所有特征值全部卷积,然后加上偏置量进行激活,然后我们发现,因为特征图的尺寸是5×5的,卷积核也是5×5的,所以我们得到的是一个1×1的输出。然后我们使用120个卷积核,我们就可以得到120个特征图。因为上一层的深度是16,所以我们这一层采用的卷积核的深度也是16,也就是说我们卷积核的尺寸为:5×5×16,再加上一个偏置量,本层的可训练参数有 120×(5×5×16+1) = 48120 个。

输入图像大小:5×5×16(与s4全相连)
卷积核大小:5×5×16
新特征图大小:1×1×120

可训练参数/连接:120*(16*5*5+1)=48120

7、F6层-全连接层

输入:c5 120维向量

计算方式:计算输入向量和权重向量之间的点积,再加上一个偏置,结果通过sigmoid函数输出。

可训练参数:84*(120+1)=10164

详细说明:6层是全连接层。F6层有84个节点,对应于一个7x12的比特图,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。该层的训练参数和连接数是(120 + 1)x84=10164。

在上一层,我们得到了一个尺寸为1×1×120的新特征图,在下一层,是我们所有要分类的图片,一共有84个,包括所有的数字,字母(英文大小写)和常见的标点符号:

F6层连接方式:

8、Output层-全连接层

Output层也是全连接层,共有10个节点,分别代表数字0到9,且如果节点i的值为0,则网络识别的结果是数字i。采用的是径向基函数(RBF)的网络连接方式。假设x是上一层的输入,y是RBF的输出,则RBF输出的计算方式是:

上式w_ij 的值由i的比特图编码确定,i从0到9,j取值从0到7*12-1。RBF输出的值越接近于0,则越接近于i,即越接近于i的ASCII编码图,表示当前网络输入的识别结果是字符i。该层有84x10=840个参数和连接。

上图是LeNet-5识别数字3的过程。

总结一下,在Output全连接层中:

输入大小:84×1
输出:物体的标签
训练参数个数:48120

LeNet5 特征能够总结为如下几点:
  • 卷积神经网络使用 3 个层作为一个序列:卷积、池化、非线性 → 这可能是自从这篇 paper 起图像深度学习的关键特征!

  • 使用卷积提取空间特征

  • 使用映射到空间均值下采样(subsample)

  • 双曲正切(tanh)或 S 型(sigmoid)形式的非线性

  • 多层神经网络(MLP)作为最后的分类器

  • 层与层之间的稀疏连接矩阵避免大的计算成本

总体来看,这个网络是大量卷积神经网络架构的起点,并且也给这个领域的许多带来了灵感。

卷积神经网络之训练算法
  1. 同一般机器学习算法,先定义Loss function,衡量和实际结果之间差距。
  2. 找到最小化损失函数的W和b, CNN中用的算法是SGD(随机梯度下降)。
卷积神经网络之优缺点

优点
  • 共享卷积核,对高维数据处理无压力
  • 无需手动选取特征,训练好权重,即得特征分类效果好
缺点
  • 需要调参,需要大样本量,训练最好要GPU

pytorch实现LeNet5进行mnist手写数字识别

# -*- coding: utf-8 -*-
"""
Created on Wed May 27 10:55:54 2020@author: Lemon
"""
'''
流程
0. 获取数据
1. 定义网络模型  
2. 定义优化器`optimizer`和损失函数`criterion`  
3. 遍历`dataloader`,每次取一个batch训练。计算loss,计算梯度,优化器更新参数。    
4. 使用测试集计算准确率。  
5. 保存模型 
6. 使用模型
'''
import torch
import torch.nn as nn
import torch.nn.functional as F
#import torch.optim as optim
from torchvision import datasets, transforms
import os
#定义batch size
batch_size = 64#下载MNIST数据集
#训练集,如需在线下载把download = True
train_dataset = datasets.MNIST(root='./data/',train=True,transform=transforms.ToTensor(), download=False)
print('测试集大小:',train_dataset.train_data.size())#测试集
test_dataset = datasets.MNIST(root='./data/',train=False,transform=transforms.ToTensor())#将MNIST数据导入到dataloader中
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)#这里可查看第一张图片
'''
import matplotlib.pyplot as pltplt.figure()
plt.imshow(train_loader.dataset.train_data[0].numpy())
plt.show()
'''#定义网络
#采用LeNet5作为模型。LeNet5包含2个5x5的卷积层,2个2x2的池化层和3个全连接层
#如果出现过拟合现象可添加dropout()层
class LeNet5(nn.Module):def __init__(self):super(LeNet5, self).__init__()#卷积层,卷积核个数为6,卷积核大小为5x5,步长为1,padding(边缘填充)=2self.conv1 = nn.Conv2d(1, 6, 5, padding=2)#卷积层,卷积核个数为16,卷积核大小为5x5,no paddingself.conv2 = nn.Conv2d(6, 16, 5)#全连接层,neuron:400->120self.fc1 = nn.Linear(16*5*5, 120)#全连接层,120->84self.fc2 = nn.Linear(120, 84)#全连接层,84->10,输出层self.fc3 = nn.Linear(84, 10)def forward(self, x):#池化层,滤波器尺寸为2x2,输入:28*28,输出:14*14x = F.max_pool2d(torch.tanh(self.conv1(x)), (2,2))#池化层,滤波器尺寸为2x2,输入:10*10,输出:5*5x = F.max_pool2d(torch.tanh(self.conv2(x)), (2,2))x = x.view(-1, self.num_flat_features(x))x = F.tanh(self.fc1(x))x = F.tanh(self.fc2(x))x = self.fc3(x)return xdef num_flat_features(self, x):size = x.size()[1:]num_features = 1for s in size:num_features *= sreturn num_featuresmodel = LeNet5()
#查看模型结构
print(model)#定义优化器`optimizer`和损失函数`criterion` 
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
criterion = nn.CrossEntropyLoss()#训练模型from torch.autograd import Variable
from time import timemax_epoch = 20model_path = './checkpoints/model.pth'	#模型存放路径
if not os.path.exists('./checkpoints'):os.mkdir('./checkpoints')def train(model, num_epoch):Loss = []model.train(True)for i in range(num_epoch):start_t = time()running_loss = 0running_corrects = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = Variable(data), Variable(target)output = model(data)pred = output.data.max(1, keepdim=True)[1]running_corrects += pred.eq(target.data.view_as(pred)).cpu().sum()loss = criterion(output, target)optimizer.zero_grad()loss.backward()optimizer.step()            running_loss += loss.data.item()epoch_loss = running_loss / len(train_loader)epoch_acc = running_corrects.data.item() / len(train_dataset)print("Epoch:", i,"running_loss:", running_loss, "Loss:", epoch_loss)print("Epoch:", i,"running_corrects:", running_corrects.data.item(), "acc:", epoch_acc)print('Epoch cost of time:{:.4f}',format(time()-start_t))Loss.append(epoch_loss)return Loss#测试网络
def test():model.eval()test_loss = 0correct = 0for data, target in test_loader:data, target = Variable(data), Variable(target)output = model(data)#将每个batch的loss加和test_loss += criterion(output, target).data.numpy()pred = output.data.max(1, keepdim=True)[1]correct += pred.eq(target.data.view_as(pred)).cpu().sum()test_loss /= len(test_loader.dataset)print("test_loss:",test_loss)acc = correct.item()/len(test_dataset)print("test accuracy:", acc)if __name__ == 'main':LOSS = train(model, max_epoch)    #保存模型torch.save(model.state_dict(), model_path)test()#查看损失函数曲线import matplotlib.pyplot as pltplt.plot(LOSS)plt.xlabel('epoch')plt.ylabel('loss')

运行结果:


可以看到在测试集的精度为98.6%左右

keras

参考资料:
keras官方中文文档
/

keras 搭建神经网络的基本流程:
一、设计你的网络结构(add)
二、将设计好模型进行编译(compile)
三、对训练数据进行拟合训练(fit)
四、对训练好的模型进行评估(evaluate)

是不是非常简单
哒哒!!!深度学习中的hello world!!!
mnist手写数字识别

利用 keras 实现手写数字识别

实际上mnist数据集包括60000张28×28的训练集和10000张28×28的测试集及其对应的目标数字。
也就是
X_trian.shape : (60000, 28, 28)
y_trian.shape : (60000,) ,也就是一个60000维的向量。

to_categorical(y,num_classes=None,dtype='float32')

函数解释:
将整型的类别标签转为onehot编码。y为int数组,num_classes为标签类别总数,大于max(y)(标签从0开始的)。
返回:如果num_classes=None,返回len(y)x[max(y)+1](维度,mxn表示m行n列矩阵,下同),否则为len(y) x num_classes。
这里也就是(60000,10)(即60000x10的矩阵,因为有十个数字)

由于这个在线下载实在太慢了,所以我是把mnist.npz下载到了本地再导入的,当然你也可以去掉相关注释后运行下面的代码

# _*_ coding: utf-8 _*_
# Classifier mnist
import numpy as np
f =np.load('mnist .npz')
X_train=f['x_train']
y_train=f['y_train']
X_test=f['x_test']
y_test=f['y_test']
#import numpy as np
np.random.seed(1337)  
#from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Activation, Flatten
from keras.optimizers import RMSprop# 下载数据集
#(X_train, y_train), (X_test, y_test) = mnist.load_data()# 数据预处理
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1) / 255. 
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1) / 255.  
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)# 1、设计你的网络结构(add),这里采用LeNet-5
model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(5, 5), padding='valid', input_shape=(28,28,1), activation='tanh')) #C1
model.add(MaxPooling2D(pool_size=(2, 2)))#S2
model.add(Conv2D(filters=16, kernel_size=(5, 5), padding='valid', activation='tanh'))#C3
model.add(MaxPooling2D(pool_size=(2, 2)))#S4
model.add(Flatten())
model.add(Dense(120, activation='tanh'))#C5
model.add(Dense(84, activation='tanh'))#F6
model.add(Dense(10, activation='softmax'))#F7,output
model.summary()# 定义优化器
rmsprop = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
#2、将设计好模型进行编译(compile)
modelpile(optimizer=rmsprop,loss='categorical_crossentropy',metrics=['accuracy']) # metrics赋值为'accuracy',会在训练过程中输出正确率# 3、对训练数据进行拟合训练(fit)
print('Training ------------')
model.fit(X_train, y_train, epochs=4, batch_size=32)print('\nTesting ------------')
# 4、对训练好的模型进行评估(evaluate)
loss, accuracy = model.evaluate(X_test, y_test)print('test loss: ', loss)
print('test accuracy: ', accuracy)



或者我们可以使用一个简单一点的网络:
在Keras中输入多为(nb_samples, input_dim)的形式:
即(样本数量,输入维度),所以这里的X_trian及X_test的格式需要从(60000, 28, 28)转为:(60000, 28x28)也就是(60000, 784)

import numpy as np
f =np.load('mnist .npz')
X_train=f['x_train']
y_train=f['y_train']
X_test=f['x_test']
y_test=f['y_test']# _*_ coding: utf-8 _*_
# Classifier mnist#import numpy as np
np.random.seed(1337)  
#from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import RMSprop# 下载数据集
#(X_train, y_train), (X_test, y_test) = mnist.load_data()# 数据预处理
X_train = X_train.reshape(X_train.shape[0], -1) / 255. 
X_test = X_test.reshape(X_test.shape[0], -1) / 255.  
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)# 不使用model.add(),用以下方式也可以构建网络
model = Sequential([Dense(400, input_dim=784),Activation('relu'),Dense(10),Activation('softmax'),
])# 定义优化器
rmsprop = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
modelpile(optimizer=rmsprop,loss='categorical_crossentropy',metrics=['accuracy']) # metrics赋值为'accuracy',会在训练过程中输出正确率# 这次我们用fit()来训练网路
print('Training ------------')
model.fit(X_train, y_train, epochs=4, batch_size=32)
#   batch_size:对总的样本数进行分组,每组包含的样本数量
#   epochs :训练次数print('\nTesting ------------')
# 评价训练出的网络
loss, accuracy = model.evaluate(X_test, y_test)print('test loss: ', loss)
print('test accuracy: ', accuracy)

运行结果:


你可以对比这keras,pytorch的实现方式

总结

CNN 的价值:

  • 能够将大数据量的图片有效的降维成小数据量(并不影响结果)
  • 能够保留图片的特征,类似人类的视觉原理

CNN 的基本原理:

  1. 卷积层 – 主要作用是保留图片的特征
  2. 池化层 – 主要作用是把数据降维,可以有效的避免过拟合
  3. 全连接层 –根据不同任务输出我们想要的结果

CNN 的实际应用:

  1. 图片分类、检索
  2. 目标定位检测
  3. 目标分割
  4. 人脸识别
  5. 骨骼识别

如果你想知道:
什么叫

  1. 线性回归:找到一条直线来预测目标值
  2. 逻辑回归:找到一条直线来分类数据
  3. K-近邻:用距离度量最相邻的分类标签
  4. 朴素贝叶斯:选择后验概率最大的类为分类标签
  5. 决策树:构造一棵熵值下降最快的分类树
  6. 支持向量机(SVM):构造超平面,分类非线性数据
  7. K-means:计算质心,聚类无标签数据
  8. 关联分析:挖掘啤酒与尿布(频繁项集)的关联规则
  9. PCA降维:减少数据维度,降低数据复杂度
  10. 人工神经网络:逐层抽象,逼近任意函数
  11. 深度学习:赋予人工智能以璀璨的未来

请看
拥抱人工智能–机器学习
————————————————
致谢
参考资料:
.html
.html

以及百度百科
以及各种还没提到的一些资料

更多推荐

从深度神经网络(DNN)到卷积神经网络(CNN)

本文发布于:2024-03-09 13:05:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1725036.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:神经网络   卷积   深度   DNN   CNN

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!