教程全知识点简介:1.深度学习课程概述包括深度学习与机器学习区别、深度学习应用场景、深度学习框架介绍、项目演示、开发环境搭建(pycharm安装)。2. TensorFlow基础涵盖TF数据流图、TensorFlow实现加法运算、图与TensorBoard(图结构、图相关操作、默认图、创建图、OP)、张量(张量概念、张量的阶、张量数学运算)、变量OP(创建变量)、增加其他功能(命名空间、模型保存与加载、命令行参数使用)、逻辑回归案例。3. 神经网络基础包括playground使用、多个神经元效果演示、深层神经网络。4. 神经网络与tf.keras。5. 梯度下降算法改进涵盖指数加权平均、动量梯度下降法、RMSProp算法、Adam算法、TensorFlow Adam算法API、学习率衰减、标准化输入、神经网络调优、批标准化。6. 卷积神经网络包括CNN原理、CIFAR类别分类(API使用、步骤分析代码实现缩减版LeNet)、卷积神经网络学习特征可视化。7. 经典分类网络结构涵盖LeNet解析、AlexNet、卷积网络结构优化、Inception结构、pre_trained模型VGG预测(VGG模型使用、步骤代码)。8. CNN网络实战技巧。9. 迁移学习案例包括基于VGG的五种图片类别识别迁移学习(数据集迁移需求、思路步骤、训练时读取本地图片类别、特征图平均值输出替代全连接层)。10. 目标检测包括目标检测任务描述、目标定位实现思路、商品物体检测项目介绍、R-CNN(Overfeat模型、SPPNet)、Faster R-CNN(RPN原理)、YOLO(单元格grid cell、非最大抑制NMS、训练)、SSD。11. 商品检测数据集训练涵盖标注数据读取存储(xml读取本地文件存储pkl、解析结构、one_hot编码函数)、训练(案例训练结果、多GPU训练代码修改)、本地预测测试(预测代码)、模型导出(keras模型TensorFlow导出)。12. 模型部署包括Web与模型服务对接逻辑、Docker部署环境、TF Serving与Web开启服务(安装Tensorflow Serving、commodity模型服务运行)、TensorFlow Client对接模型服务、Web Server开启。

<!-- start:bj1 -->

👉👉👉   https://gitee.com/yinuo112/AI/blob/master/深度学习/嘿马深度学习笔记/note.md

<!-- end:bj1 -->

神经网络与tf.keras

1.4 深层神经网络

学习目标

  • 目标

    • 了解深层网络的前向传播与反向传播的过程
  • 应用

为什么使用深层网络

对于人脸识别等应用,神经网络的第一层从原始图片中提取人脸的轮廓和边缘,每个神经元学习到不同边缘的信息;网络的第二层将第一层学得的边缘信息组合起来,形成人脸的一些局部的特征,例如眼睛、嘴巴等;后面的几层逐步将上一层的特征组合起来,形成人脸的模样。随着神经网络层数的增加,特征也从原来的边缘逐步扩展为人脸的整体,由整体到局部,由简单到复杂。层数越多,那么模型学习的效果也就越精确。

通过例子可以看到,随着神经网络的深度加深,模型能学习到更加复杂的问题,功能也更加强大。

1.4.1 深层神经网络表示

1.4.1.1 什么是深层网络?

使用浅层网络的时候很多分类等问题得不到很好的解决,所以需要深层的网络。

1.4.2 四层网络的前向传播与反向传播

在这里首先对每层的符号进行一个确定,我们设置L为第几层,n为每一层的个数,L=[L1,L2,L3,L4],n=[5,5,3,1]

1.4.2.1 前向传播

首先还是以单个样本来进行表示,每层经过线性计算和激活函数两步计算

<span>z[1]=W[1]x+b[1],a[1]=g1z^{[1]} = W^{[1]}x+b^{[1]}, a^{[1]}=g^{[1]}(z^{[1]})z​[1]​​=W​[1]​​x+b​[1]​​,a​[1]​​=g​[1]​​(z​[1]​​)</span><span>xxx</span><span>a[1]a^{[1]}a​[1]​​</span>

<span>z[2]=W[2]a[1]+b[2],a[2]=g2z^{[2]} = W^{[2]}a^{[1]}+b^{[2]}, a^{[2]}=g^{[2]}(z^{[2]})z​[2]​​=W​[2]​​a​[1]​​+b​[2]​​,a​[2]​​=g​[2]​​(z​[2]​​)</span><span>a[1]a^{[1]}a​[1]​​</span><span>a[2]a^{[2]}a​[2]​​</span>

<span>z[3]=W[3]a[2]+b[3],a[3]=g3z^{[3]} = W^{[3]}a^{[2]}+b^{[3]},a^{[3]}=g^{[3]}(z^{[3]})z​[3]​​=W​[3]​​a​[2]​​+b​[3]​​,a​[3]​​=g​[3]​​(z​[3]​​)</span><span>a[2]a^{[2]}a​[2]​​</span><span>a[3]a^{[3]}a​[3]​​</span>

<span>z[4]=W[4]a[3]+b[4],a[4]=σ(z[4])z^{[4]} = W^{[4]}a^{[3]}+b^{[4]},a^{[4]}=\sigma(z^{[4]})z​[4]​​=W​[4]​​a​[3]​​+b​[4]​​,a​[4]​​=σ(z​[4]​​)</span><span>a[3]a^{[3]}a​[3]​​</span><span>a[4]a^{[4]}a​[4]​​</span>

我们将上式简单的用通用公式表达出来,<span>x=a[0]x = a^{[0]}x=a​[0]​​</span>

<span>z[L]=W[L]a[L−1]+b[L],a[L]=gLz^{[L]} = W^{[L]}a^{[L-1]}+b^{[L]}, a^{[L]}=g^{[L]}(z^{[L]})z​[L]​​=W​[L]​​a​[L−1]​​+b​[L]​​,a​[L]​​=g​[L]​​(z​[L]​​)</span><span>a[L−1]a^{[L-1]}a​[L−1]​​</span><span>a[L]a^{[L]}a​[L]​​</span>

  • m个样本的向量表示

<span>Z[L]=W[L]A[L−1]+b[L]Z^{[L]} = W^{[L]}A^{[L-1]}+b^{[L]}Z​[L]​​=W​[L]​​A​[L−1]​​+b​[L]​​</span>

<span>A[L]=gLA^{[L]}=g^{[L]}(Z^{[L]})A​[L]​​=g​[L]​​(Z​[L]​​)</span>

输入<span>a[L−1]a^{[L-1]}a​[L−1]​​</span><span>a[L]a^{[L]}a​[L]​​</span>

1.4.2.2 反向传播

因为涉及到的层数较多,所以我们通过一个图来表示反向的过程

  • 反向传播的结果(理解)

单个样本的反向传播:

<span>dZ[l]=dJda[l]da[l]dZ[l]=da[l]∗g[l]′(Z[l])dZ^{[l]}=\frac{dJ}{da^{[l]}}\frac{da^{[l]}}{dZ^{[l]}}=da^{[l]}*g^{[l]}{'}(Z^{[l]})dZ​[l]​​=​da​[l]​​​​dJ​​​dZ​[l]​​​​da​[l]​​​​=da​[l]​​∗g​[l]​​​′​​(Z​[l]​​)</span>

<span>dW[l]=dJdZ[l]dZ[l]dW[l]=dZ[l]⋅a[l−1]dW^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{dW^{[l]}}=dZ^{[l]}\cdot a^{[l-1]}dW​[l]​​=​dZ​[l]​​​​dJ​​​dW​[l]​​​​dZ​[l]​​​​=dZ​[l]​​⋅a​[l−1]​​</span>

<span>db[l]=dJdZ[l]dZ[l]db[l]=dZ[l]db^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{db^{[l]}}=dZ^{[l]}db​[l]​​=​dZ​[l]​​​​dJ​​​db​[l]​​​​dZ​[l]​​​​=dZ​[l]​​</span>

<span>da[l−1]=W[l]T⋅dZ[l]da^{[l-1]}=W^{[l]T}\cdot dZ^{[l]}da​[l−1]​​=W​[l]T​​⋅dZ​[l]​​</span>

多个样本的反向传播

<span>dZ[l]=dA[l]∗g[l]′(Z[l])dZ^{[l]}=dA^{[l]}*g^{[l]}{'}(Z^{[l]})dZ​[l]​​=dA​[l]​​∗g​[l]​​​′​​(Z​[l]​​)</span>

<span>dW[l]=1mdZ[l]⋅A[l−1]TdW^{[l]}=\frac{1}{m}dZ^{[l]}\cdot {A^{[l-1]}}^{T}dW​[l]​​=​m​​1​​dZ​[l]​​⋅A​[l−1]​​​T​​</span>

<span>db[l]=1mnp.sum(dZ[l],axis=1)db^{[l]}=\frac{1}{m}np.sum(dZ^{[l]},axis=1)db​[l]​​=​m​​1​​np.sum(dZ​[l]​​,axis=1)</span>

<span>dA[l]=W[l+1]T⋅dZ[l+1]dA^{[l]}=W^{[l+1]T}\cdot dZ^{[l+1]}dA​[l]​​=W​[l+1]T​​⋅dZ​[l+1]​​</span>

1.4.3 参数与超参数

1.4.3.1 参数

参数即是我们在过程中想要模型学习到的信息(模型自己能计算出来的),例如 W[l]W[l],b[l]b[l]。而**超参数(hyper parameters)**即为控制参数的输出值的一些网络信息(需要人经验判断)。超参数的改变会导致最终得到的参数 W[l],b[l] 的改变。

1.4.3.2 超参数

典型的超参数有:

  • 学习速率:α
  • 迭代次数:N
  • 隐藏层的层数:L
  • 每一层的神经元个数:n[1],n[2],...
  • 激活函数 g(z) 的选择

当开发新应用时,预先很难准确知道超参数的最优值应该是什么。因此,通常需要尝试很多不同的值。应用深度学习领域是一个很大程度基于经验的过程。

1.4.3.3 参数初始化
  • 为什么要随机初始化权重

如果在初始时将两个隐藏神经元的参数设置为相同的大小,那么两个隐藏神经元对输出单元的影响也是相同的,通过反向梯度下降去进行计算的时候,会得到同样的梯度大小,所以在经过多次迭代后,两个隐藏层单位仍然是对称的。无论设置多少个隐藏单元,其最终的影响都是相同的,那么多个隐藏神经元就没有了意义。

在初始化的时候,W 参数要进行随机初始化,不可以设置为 0。b 因为不存在上述问题,可以设置为 0。

以 2 个输入,2 个隐藏神经元为例:

W = np.random.rand(2,2)* 0.01
b = np.zeros((2,1))
  • 初始化权重的值选择

这里将 W 的值乘以 0.01(或者其他的常数值)的原因是为了使得权重 W 初始化为较小的值,这是因为使用 sigmoid 函数或者 tanh 函数作为激活函数时,W 比较小,则 Z=WX+b 所得的值趋近于 0,梯度较大,能够提高算法的更新速度。而如果 W 设置的太大的话,得到的梯度较小,训练过程因此会变得很慢。

ReLU 和 Leaky ReLU 作为激活函数时不存在这种问题,因为在大于 0 的时候,梯度均为 1。

总结

每日作业

神经网络与tf.keras

卷积神经网络

3.1 卷积神经网络(CNN)原理

学习目标

  • 目标

    • 了解卷积神经网络的构成
    • 记忆卷积的原理以及计算过程
    • 了解池化的作用以及计算过程
  • 应用

为什么需要卷积神经网络

计算机视觉领域,通常要做的就是指用机器程序替代人眼对目标图像进行识别等。那么神经网络也好还是卷积神经网络其实都是上个世纪就有的算法,只是近些年来电脑的计算能力已非当年的那种计算水平,同时现在的训练数据很多,于是神经网络的相关算法又重新流行起来,因此卷积神经网络也一样流行。

  • 1974年,Paul Werbos提出了误差反向传导来训练人工神经网络,使得训练多层神经网络成为可能。
  • 1979年,Kunihiko Fukushima(福岛邦彦),提出了Neocognitron, 卷积、池化的概念基本形成。
  • 1986年,Geoffrey Hinton与人合著了一篇论文:Learning representations by back-propagation errors。
  • 1989年,Yann LeCun提出了一种用反向传导进行更新的卷积神经网络,称为LeNet。
  • 1998年,Yann LeCun改进了原来的卷积网络,LeNet-5。
原因之一:图像特征数量对神经网络效果压力

假设下图是一图片大小为28 * 28 的黑白图片时候,每一个像素点只有一个值(单通道)。那么总的数值个数为 784个特征。

那现在这张图片是彩色的,那么彩色图片由RGB三通道组成,也就意味着总的数值有28 28 3 = 2352个值。

从上面我们得到一张图片的输入是2352个特征值,即神经网路当中与若干个神经元连接,假设第一个隐层是10个神经元,那么也就是23520个权重参数。

如果图片再大一些呢,假设图片为1000 1000 3,那么总共有3百万数值,同样接入10个神经元,那么就是3千万个权重参数。这样的参数大小,神经网络参数更新需要大量的计算不说,也很难达到更好的效果,大家就不倾向于使用多层神经网络了。

所以就有了卷积神经网络的流行,那么卷积神经网络为什么大家会选择它。那么先来介绍感受野以及边缘检测的概念。

注:另有卷积网络感受野的概念,也是为什么使用卷积的原因

3.1.1 卷积神经网络的组成

reportlab 文档

  • 定义

    • 卷积神经网络由一个或多个卷积层、池化层以及全连接层等组成。与其他深度学习结构相比,卷积神经网络在图像等方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他浅层或深度神经网络,卷积神经网络需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。

我们来看一下卷积网络的整体结构什么样子。

其中包含了几个主要结构

threading 文档

  • 卷积层(Convolutions)
  • 池化层(Subsampling)
  • 全连接层(Full connection)
  • 激活函数

3.1.2 卷积层

  • 目的

    • 卷积运算的目的是提取输入的不同特征,某些卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网路能从低级特征中迭代提取更复杂的特征。
  • 参数:

    • size:卷积核/过滤器大小,选择有1 1, 3 3, 5 * 5(为什么是奇数个)
    • padding:零填充,Valid 与Same
    • stride:步长,通常默认为1
  • 计算公式

3.1.2.1 卷积运算过程

对于之前介绍的卷积运算过程,我们用一张动图来表示更好理解些。一下计算中,假设图片长宽相等,设为N

  • 一个步长,3 X 3 卷积核运算

假设是一张5 X 5 的单通道图片,通过使用3 X 3 大小的卷积核运算得到一个 3 X 3大小的运算结果(图片像素数值仅供参考)

Python 语言参考

我们会发现进行卷积之后的图片变小了,假设N为图片大小,F为卷积核大小

相当于<span>N−F+1=5−3+1=3N - F + 1 = 5 - 3 + 1 = 3N−F+1=5−3+1=3</span>

如果我们换一个卷积核大小或者加入很多层卷积之后,图像可能最后就变成了1 X 1 大小,这不是我们希望看到的结果。并且对于原始图片当中的边缘像素来说,只计算了一遍,二对于中间的像素会有很多次过滤器与之计算,这样导致对边缘信息的丢失。

  • 缺点

    • 图像变小
    • 边缘信息丢失

3.1.3 padding-零填充

零填充:在图片像素的最外层加上若干层0值,若一层,记做p =1。

  • 为什么增加的是0?

因为0在权重乘积和运算中对最终结果不造成影响,也就避免了图片增加了额外的干扰信息。

这张图中,还是移动一个像素,并且外面增加了一层0。那么最终计算结果我们可以这样用公式来计算:

<span>5+2∗p−3+1=55 + 2 * p - 3 + 1 = 55+2∗p−3+1=5</span>

P为1,那么最终特征结果为5。实际上我们可以填充更多的像素,假设为2层,则

<span>5+2∗2−3+1=75 + 2 * 2 - 3 + 1 = 75+2∗2−3+1=7</span>

3.1.3.1 Valid and Same卷积

有两种两种形式,所以为了避免上述情况,大家选择都是Same这种填充卷积计算方式

  • Valid :不填充,也就是最终大小为

    • <span>(N−F+1)∗(N−F+1)(N - F + 1) * (N - F + 1)(N−F+1)∗(N−F+1)</span>
  • Same:输出大小与原图大小一致,那么<span>NNN</span><span>N+2PN + 2PN+2P</span>

    • <span>(N+2P−F+1)∗(N+2P−F+1)(N + 2P - F + 1) * (N + 2P - F + 1)(N+2P−F+1)∗(N+2P−F+1)</span>

那也就意味着,之前大小与之后的大小一样,得出下面的等式

<span>(N+2P−F+1)=N(N + 2P - F + 1) = N(N+2P−F+1)=N</span>

<span>P=F−12P = \frac{F -1}{2}P=​2​​F−1​​</span>

所以当知道了卷积核的大小之后,就可以得出要填充多少层像素。

3.1.3.2 奇数维度的过滤器

通过上面的式子,如果F不是奇数而是偶数个,那么最终计算结果不是一个整数,造成0.5,1.5.....这种情况,这样填充不均匀,所以也就是为什么卷积核默认都去使用奇数维度大小

  • 1 1,3 3, 5 5,7 7

  • 另一个解释角度

    • 奇数维度的过滤器有中心,便于指出过滤器的位置

当然这个都是一些假设的原因,最终原因还是在F对于计算结果的影响。所以通常选择奇数维度的过滤器,是大家约定成俗的结果,可能也是基于大量实验奇数能得出更好的结果。

3.1.4 stride-步长

以上例子中我们看到的都是每次移动一个像素步长的结果,如果将这个步长修改为2,3,那结果如何?

这样如果以原来的计算公式,那么结果

<span>N+2P−F+1=6+0−3+1=4N + 2P - F + 1 = 6 + 0 -3 +1 = 4N+2P−F+1=6+0−3+1=4</span>

但是移动2个像素才得出一个结果,所以公式变为

<span>N+2P−F2+1=1.5+1=2.5\frac{N + 2P - F}{2} + 1 = 1.5 + 1 = 2.5​2​​N+2P−F​​+1=1.5+1=2.5</span>

所以最终的公式就为:

对于输入图片大小为N,过滤器大小为F,步长为S,零填充为P,

<span>(N+2P−FS+1),(N+2P−FS+1)(\frac{N + 2P - F}{S} + 1),(\frac{N + 2P - F}{S} + 1)(​S​​N+2P−F​​+1),(​S​​N+2P−F​​+1)</span>

3.1.5 多通道卷积

当输入有多个通道(channel)时(例如图片可以有 RGB 三个通道),卷积核需要拥有相同的channel数,每个卷积核 channel 与输入层的对应 channel 进行卷积,将每个 channel 的卷积结果按位相加得到最终的 Feature Map。

3.1.5.1 多卷积核(多个Filter)

pathlib 文档

当有多个卷积核时,可以学习到多种不同的特征,对应产生包含多个 channel 的 Feature Map, 例如上图有两个 filter,所以 output 有两个 channel。这里的多少个卷积核也可理解为多少个神经元。

相当于我们把多个功能的卷积核的计算结果放在一起,能够检测到图片中不同的特征(边缘检测)

3.1.6 卷积总结

我们来通过一个例子看一下结算结果,以及参数的计算

  • 假设我们有10 个Filter,每个Filter3 X 3 X 3(计算RGB图片),并且只有一层卷积,那么参数有多少?

计算:每个Filter参数个数为:3 3 3 + 1 bias = 28个权重参数,总共28 * 10 = 280个参数,即使图片任意大小,我们这层的参数也就这么多。

  • 假设一张200 200 3的图片,进行刚才的FIlter,步长为1,最终为了保证最后输出的大小为200 * 200,需要设置多大的零填充

<span>(N+2P−Fs+1)=N(\frac{N + 2P - F}{s} + 1) = N(​s​​N+2P−F​​+1)=N</span>

<span>P=(N−1)∗s+F−N2=199+3−2002=1P = \frac{(N -1) * s + F - N}{2} = \frac{199 + 3 - 200}{2} = 1P=​2​​(N−1)∗s+F−N​​=​2​​199+3−200​​=1</span>

卷积层充当特征提取的角色,但是并没有减少图片的特征数量,在最后的全连接层依然面临大量的参数,所以需要池化层进行特征数量的减少

3.1.7 池化层(Pooling)

池化层主要对卷积层学习到的特征图进行亚采样(subsampling)处理,主要由两种

  • 最大池化:Max Pooling,取窗口内的最大值作为输出
  • 平均池化:Avg Pooling,取窗口内的所有值的均值作为输出

意义在于:

  • 降低了后续网络层的输入维度,缩减模型大小,提高计算速度
  • 提高了Feature Map 的鲁棒性,防止过拟合

对于一个输入的图片,我们使用一个区域大小为2 2,步长为2的参数进行求最大值操作。同样池化也有一组参数,<span>f,sf, sf,s</span> 2的大小。当然如果我们调整这个超参数,比如说3 * 3,那么结果就不一样了,通常选择默认都是<span>f=2∗2,s=2f = 2 * 2, s = 2f=2∗2,s=2</span>

池化超参数特点:不需要进行学习,不像卷积通过梯度下降进行更新。

如果是平均池化则:

3.1.8 全连接层

卷积层+激活层+池化层可以看成是CNN的特征学习/特征提取层,而学习到的特征(Feature Map)最终应用于模型任务(分类、回归):

  • 先对所有 Feature Map 进行扁平化(flatten, 即 reshape 成 1 x N 向量)
  • 再接一个或多个全连接层,进行模型学习

3.1.9 总结

  • 掌握卷积神经网路的组成

  • 掌握卷积的计算过程

    • 卷积过滤器个数
    • 卷积过滤器大小
    • 卷积过滤器步数
    • 卷积过滤器零填充
  • 掌握池化的计算过程原理