深度学习入门系列之doc

Posted pny01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习入门系列之doc相关的知识,希望对你有一定的参考价值。

这周老师让把深度学习的名词过一遍,小玛同学准备在过一遍Deep Learning名词的同时把基本的模型也过一遍。
感谢杰哥发我深度学习入门系列能让我有机会快速入门。
下面就来doc一些学到的东西

线性感知器

感知器(线性单元)有个问题就是当面对的数据集不是线性可分的时候,“感知器规则”可能无法收敛,这意味着我们永远无法完成一个感知器的训练。(即如果我们需要用感知器(神经元)拟合的映射不是线性的,那么需要用在拟合中添加非线性的函数)

SGD vs BGD

SGD: Stochastic Gradient Descent
BGD: Batch Gradient Descent
SGD 和 BGD 之间的主要区别在于每次迭代的更新步骤。BGD 在每一步都使用整个数据集计算梯度,而 SGD 在每一步都使用单个样本或一小批样本计算梯度。这使得 SGD 比 BGD 更快,计算成本更低。
然而,在凸集中,由于其随机性质,SGD 可能永远无法达到全局最小值,而是不断在接近全局最小值的区域内游荡。另一方面,BGD 只要有足够的时间和合适的学习率,就能保证找到全局最小值。
但是在非凸集中,随机性有助于我们逃离一些糟糕的局部最小值。

感知器 vs 神经元

一般情况下,说感知器的时候,它的激活函数是阶跃函数;当我们说神经元的时候,激活函数往往选择为sigmoid函数或者是tanh函数。

sigmoid函数

sigmoid函数的导数非常有趣,它可以用sigmoid函数自身来表示。这样,一旦计算出sigmoid函数的值,计算它的导数的值就非常方便。
\\(y = sigmoid(x)\\) , 则 \\(y^\\prime = y(1 − y)\\)

梯度检查

下面是梯度检查的代码。如果我们想检查参数 的梯度是否正确,我们需要以下几个步骤:

  1. 首先使用一个样本 \\(d\\) 对神经网络进行训练,这样就能获得每个权重的梯度。
  2. \\(w_ji\\) 加上一个很小的值( \\(10^-4\\) ),重新计算神经网络在这个样本 \\(d\\) 下的 \\(E_d+\\)
  3. \\(w_ji\\) 减上一个很小的值( \\(10^-4\\) ),重新计算神经网络在这个样本 \\(d\\) 下的 \\(E_d-\\)
  4. 根据下面的公式计算出期望的梯度值,和第一步获得的梯度值进行比较,它们应该几乎想等(至少4位有效数字相同)。

\\[\\frac\\partial E_d(w_ji)\\partial w_ji \\approx \\fracf(w_ji + \\epsilon) - f(w_ji - \\epsilon)2\\epsilon \\]

当然,我们可以重复上面的过程,对每个权重 \\(w_ji\\) 都进行检查。也可以使用多个样本重复检查。

卷积神经网络

CNN 更适合图像,语音识别任务,它儿孙辈的人才包括谷歌的GoogleNet、微软的ResNet。

梯度消失问题

减轻梯度消失问题 回忆一下计算梯度的公式 \\(\\nabla = \\sigma^\\prime\\delta x\\) 。其中,\\(\\sigma^\\prime\\) 是sigmoid函数的导数。在使用反向传播算法进行梯度计算时,每经过一层
sigmoid神经元,梯度就要乘上一个 \\(\\sigma^\\prime\\) 。从下图可以看出,\\(\\sigma^\\prime\\) 函数最大值是1/4。因此,乘一个 \\(\\sigma^\\prime\\) 会导致梯度越来越小,这对于深层网络的训练是个很大的问题。

ReLU 函数的优势

Relu函数作为激活函数,有下面几大优势:

  1. 速度快 和sigmoid函数需要计算指数和倒数相比,relu函数其实就是一个max(0,x),计算代价小很多。
  2. 减轻梯度消失问题 而relu函数的导数是1,不会导致梯度变小。当然,激活函数仅仅是导致梯度减小的一个因素,但无论如何在这方面relu的表现强于sigmoid。使用relu激活函数可以让你训练更深的网络。
  3. 稀疏性 通过对大脑的研究发现,大脑在工作的时候只有大约5%的神经元是激活的,而采用sigmoid激活函数的人工神经网络,其激活率大约是50%。有论文声称人工神经网络在15%-30%的激活率时是比较理想的。因为relu函数在输入小于0时是完全不激活的,因此可以获得一个更低的激活率。
卷积神经网络的实现

三大要点:

  1. 局部连接
  2. 权值共享
  3. 下采样 可以使用Pooling来减少每层的样本数,进一步减少参数数量,同时还可以提升模型的鲁棒性。


如图所示,一个卷积神经网络由若干卷积层、Pooling 层、全连接层组成。你可以构建各种不同的卷积神经网络,它的常用架构模式为:

\\[INPUT -> [[CONV]*N -> POOL ] * M -> [FC] * K \\]

也就是N个卷积层叠加,然后(可选)叠加一个Pooling层,重复这个结构M次,最后叠加K个全连接层。
对于图展示的卷积神经网络:

\\[INPUT -> CONV -> POOL -> CONV -> POOL -> FC -> FC \\]

按照上述模式可以表示为:

\\[INPUT -> [[CONV]*1 -> POOL]*2 -> [FC]*2 \\]

也就是:$$N=1, M=2, K=2$$。

从图1我们可以发现卷积神经网络的层结构和全连接神经网络的层结构有很大不同。全连接神经网络每层的神经元是按照一维排列的,也就是排成一条线的样子;而卷积神经网络每层的神经元是按照三维排列的,也就是排成一个长方体的样子,有宽度、高度和深度。

对于图1展示的神经网络,我们看到输入层的宽度和高度对应于输入图像的宽度和高度,而它的深度为1。接着,第一个卷积层对这幅图像进行了卷积操作(后面我们会讲如何计算卷积),得到了三个Feature Map。这里的"3"可能是让很多初学者迷惑的地方,实际上,就是这个卷积层包含三个Filter,也就是三套参数,每个Filter都可以把原始输入图像卷积得到一个Feature Map,三个Filter就可以得到三个Feature Map。至于一个卷积层可以有多少个Filter,那是可以自由设定的。也就是说,卷积层的Filter个数也是一个超参数。我们可以把Feature Map可以看做是通过卷积变换提取到的图像特征,三个Filter就对原始图像提取出三组不同的特征,也就是得到了三个Feature Map,也称做三个通道(channel) 。

普通NN的反向传播算法

我们先回忆一下上一篇文章零基础入门深度学习(3) - 神经网络和反向传播算法介绍的反向传播算法,整个算法分为三个步骤:

  1. 前向计算每个神经元的输出值 \\(a_j\\)\\(j\\) 表示网络的第 \\(j\\) 个神经元,以下同);
  2. 反向计算每个神经元的误差项 \\(\\delta_j\\) , 在有的文献中也叫做敏感度(sensitivity)。它实际上是网络的损失函数 \\(E_d\\) 对神经元加权输入 \\(net_j\\) 的偏导数,即 \\(\\delta_j = \\frac\\partial E_d\\partial net_j\\)
  3. 计算每个神经元连接权重 \\(w_ji\\) 的梯度( \\(w_ji\\) 表示从神经元 \\(i\\) 连接到神经元 \\(j\\) 的权重),公式为 \\(\\frac\\partial E_d\\partial w_ji = a_i \\delta_j\\),其中,\\(a_i\\) 表示神经元 \\(i\\) 的输出。
    最后,根据梯度下降法则更新每个权重即可。

对于卷积神经网络,由于涉及到局部连接、下采样等操作,影响到了第二步误差项 \\(\\delta\\) 的具体计算方法,而权值共享影响了第三步权重 \\(w\\) 的梯度的计算方法。 说白了就是涉及到反向传播时,在各层究竟应该怎么传递的问题

第二步误差项 \\(\\delta\\) 的具体计算方法

为了描述方便,我们用 \\(\\delta_i, j^l-1\\) 表示第 \\(l-1\\) 层第 \\(i\\) 行第 \\(j\\) 列的误差项;用 \\(w_m, n\\) 表示filter第 \\(m\\) 行第 \\(n\\) 列权重,用 \\(a_i,j^l-1\\)表示\\(l - 1\\)层第 \\(i\\) 行第 \\(j\\) 列的神经元的输出;用\\(net_i,j^l-1\\) 表示 \\(l - 1\\)层第\\(i\\)行第\\(j\\)列神经元的加权输入;用 \\(\\sigma_i,j^l\\) 表示第l层第i行第j列的误差项;用\\(f^l-1\\) 表示第 \\(l-1\\) 层的激活函数. 它们之间的关系如下:

\\[\\beginaligned & n e t^l=\\operatornameconv\\left(W^l, a^l-1\\right)+w_b \\\\ & a_i, j^l-1=f^l-1\\left(n e t_i, j^l-1\\right) \\endaligned \\]

上式中,\\(net^1 、 W^l 、 a^1-1\\) 都是数组, \\(W^l\\) 是由 \\(w_m, n\\) 组成的数组,conv表示卷积操作。

卷积层误差项传递的算法

\\[\\delta^l-1=\\sum_d=0^D \\delta_d^l * W_d^l \\circ f^\\prime\\left(n e t^l-1\\right) \\]

CNN在反向传播时,在各层究竟应该怎么传递的问题

留个坑在这里,看后面需要再说吧,感觉这个是成熟的算法,就是不知道跟我做的应用有没有什么关系

循环神经网络 Recurrent Neural Netwok (RNN)

我们介绍了全连接神经网络和卷积神经网络,以及它们的训练和使用。他们都只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列;当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。

"循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。权重矩阵 W就是隐藏层上一次的值作为这一次的输入的权重。" 给我的感觉就是加了个时间轴。。。

虽然老板跟我说RNN可以放放,但是我还是把基本的种类粘在这里吧。

双向循环神经网络 Bidirectional Recurrent Neural Network (BRNN)

深度循环神经网络 Deep Recurrent Neural Network (DRNN)

循环神经网络的训练算法 BPTT

BPTT算法是针对循环层的训练算法,它的基本原理和BP算法是一样的,也包含同样的三个步骤:

  1. 前向计算每个神经元的输出值;
  2. 反向计算每个神经元的误差项 \\(\\delta_j\\) 值,它是误差函数E对神经元j的加权输入 \\(net_j\\) 的偏导数;
  3. 计算每个权重的梯度。
RNN的梯度爆炸和消失问题

不幸的是,实践中前面介绍的几种RNNs并不能很好的处理较长的序列。一个主要的原因是,RNN在训练中很容易发生梯度爆炸和梯度消失,这导致训练时梯度不能在较长序列中一直传递下去,从而使RNN无法捕捉到长距离的影响。

梯度消失问题

梯度消失更难检测,而且也更难处理一些。总的来说,我们有三种方法应对梯度消失问题:

  1. 合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。
  2. 使用relu代替sigmoid和tanh作为激活函数。原理请参考上一篇文章零基础入门深度学习(4) - 卷积神经网络的激活函数一节。
  3. 使用其他结构的RNNs,比如长短时记忆网络(LTSM)和Gated Recurrent Unit(GRU),这是最流行的做法。
LSTM (Long Short-Term Memory)

长短时记忆网络的思路比较简单。原始RNN的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。那么,假如我们再增加一个状态,即c,让它来保存长期的状态,那么问题不就解决了么?
新增加的状态c,称为单元状态(cell state) 。我们把上图按照时间维度展开:

我们可以看出,在 \\(t\\) 时刻,LSTM的输入有三个:当前时刻网络的输入值 \\(x_t\\) 、上一时刻LSTM的输出值 \\(h_t-1\\)、以及上一时刻的单元状态 \\(c_t-1\\) ;LSTM的输出有两个:当前时刻LSTM输出值 \\(h_t\\) 、和当前时刻的单元状态 \\(c_t\\) 。注意 \\(x\\)\\(h\\)\\(c\\) 都是向量。
LSTM的关键,就是怎样控制长期状态 \\(c\\)。在这里,LSTM的思路是使用三个控制开关。第一个开关,负责控制继续保存长期状态 \\(c\\);第二个开关,负责控制把即时状态输入到长期状态 \\(c\\);第三个开关,负责控制是否把长期状态 \\(c\\) 作为当前的LSTM的输出。
LSTM用两个门来控制单元状态 \\(c\\) 的内容,一个是遗忘门(forget gate),它决定了上一时刻的单元状态 \\(c_t-1\\) 有多少保留到当前时刻 \\(c_t\\);另一个是输入门(input gate),它决定了当前时刻网络的输入 \\(x_t\\) 有多少保存到单元状态 \\(c_t\\) 。LSTM用输出门(output gate)来控制单元状态 \\(c_t\\) 有多少输出到LSTM的当前输出值 \\(h_t\\)

GRU (Gated Recurrent Unit)

前面我们讲了一种普通的LSTM,事实上LSTM存在很多变体,许多论文中的LSTM都或多或少的不太一样。在众多的LSTM变体中,GRU (Gated Recurrent Unit) 也许是最成功的一种。它对LSTM做了很多简化,同时却保持着和LSTM相同的效果。因此,GRU最近变得越来越流行。
GRU对LSTM做了两个大改动:

  1. 将输入门、遗忘门、输出门变为两个门:更新门(Update Gate)\\(z_t\\) 和重置门(Reset Gate)\\(r_t\\)
  2. 将单元状态与输出合并为一个状态:\\(h\\)
递归神经网络(Recursive Neural Network)

仅仅拥有处理序列的能力还不够,还需要处理比序列更为复杂的结构(比如树结构),这时候就需要用到另外一类网络:递归神经网络(Recursive Neural Network)
因为神经网络的输入层单元个数是固定的,因此必须用循环或者递归的方式来处理长度可变的输入。循环神经网络实现了前者,通过将长度不定的输入分割为等长度的小块,然后再依次的输入到网络中,从而实现了神经网络对变长输入的处理。
递归神经网络可以把一个树/图结构信息编码为一个向量,也就是把信息映射到一个语义向量空间中。这个语义向量空间满足某类性质,比如语义相似的向量距离更近。也就是说,如果两句话(尽管内容不同)它的意思是相似的,那么把它们分别编码后的两个向量的距离也相近;反之,如果两句话的意思截然不同,那么编码后向量的距离则很远。

哈哈哈哈哈终于把零基础入门深度学习的文档叨完了。准备写点作业之后继续去看the deep learning书。

深度学习和目标检测系列教程 4-300:目标检测入门之目标变量和损失函数

@Author:Runsen

目标定位

图像分类或图像识别模型只是检测图像中对象的概率。与此相反,对象定位是指识别图像中对象的位置。对象定位算法将输出对象相对于图像的位置坐标。在计算机视觉中,定位图像中对象的最流行方法是借助边界框来表示其位置。

图 1 显示了一个边界框的例子。
可以使用以下参数初始化边界框:

  • bx, by : 边界框中心的坐标
  • bw : 边界框的宽度 wrt 图像宽度
  • bh : 边界框的高度 wrt 图像高度

定义目标变量

多类图像分类问题的目标变量定义为:

其中, C i C_i Ci是第 i i i类的概率。 例如,如果有四个类,则目标变量定义


我们可以扩展这种方法来定义目标变量进行目标定位。目标变量定义为

  • p c p_c pc = 对象(即四个类)出现在边界框中的概率/置信度。
  • bx,by,bh,bw = 边界框坐标。
  • c i c_i ci= 对象所属第 i i i类的概率

例如,四个类别是“卡车”、“汽车”、“自行车”、“行人”,它们的概率表示为 c 1 , c 2 , c 3 , c 4 c1,c2,c3,c4 c1,c2,c3,c4

损失函数

让目标变量y的值表示为 y 1 , y 2 , … , y 9 y1,y2,…,y9 y1y2y9


目标定位的损失函数定义为


在实践中,我们可以在预测类 c 1 、 c 2 、 c 3 、 c 4 c1、c2、c3、c4 c1c2c3c4的情况下使用考虑softmax输出的log函数。而对于边界框坐标,我们可以使用平方误差,对于 p c p_c pc(物体的置信度),我们可以使用logistic回归损失。

由于我们已经定义了目标变量和损失函数,我们现在可以使用神经网络对目标进行分类和定位。

物体检测

构建对象检测的一种方法是首先构建一个分类器,该分类器可以对对象的紧密裁剪图像进行分类。下图显示了此类模型的一个示例,其中模型在经过紧密裁剪的汽车图像数据集上进行训练,并且该模型预测图像是汽车的概率。

现在,我们可以使用这个模型来检测使用滑动窗口机制的汽车。在滑动窗口机制中,我们使用滑动窗口(类似于卷积网络中使用的滑动窗口)并在每张幻灯片中裁剪图像的一部分。裁剪的大小与滑动窗口的大小相同。然后将每个裁剪后的图像传递给一个 ConvNet 模型(类似于上图 中所示的模型),该模型反过来预测裁剪后的图像是汽车的概率。

滑动窗口机制

在整个图像上运行滑动窗口后,调整滑动窗口的大小并再次在图像上运行。经过多次重复这个过程。由于之前裁剪了大量图像并通过 ConvNet 传递,因此这种方法在计算上既昂贵又耗时,使整个过程非常缓慢。滑动窗口的卷积实现有助于解决这个问题。

滑动窗口的卷积

在使用 convents 实现滑动窗口之前,分析如何将网络的全连接层转换为卷积层。

下面 显示了一个简单的卷积网络,具有两个完全连接的层,每个层的形状为 (400, )。

借助一维卷积层,可以将全连接层转换为卷积层。该层的宽度和高度等于 1,过滤器的数量等于全连接层的形状。

 将全连接层转换为卷积层

我们可以将全连接层转换为卷积层的概念应用到模型中,方法是将全连接层替换为一维卷积层。一维卷积层的滤波器数量等于全连接层的形状。此外,输出 softmax 层也是形状为 (1, 1, 4) 的卷积层,其中 4 是要预测的类数。 如下图 所示。

在这里插入图片描

现在,扩展上述方法来实现滑动窗口的卷积版本。首先,考虑在以下表示中我们已经训练的 ConvNet(没有完全连接的层)。

让我们假设输入图像的大小为16 × 16 × 3。如果我们使用滑动窗口方法,那么我们会将该图像传递给上面的 ConvNet 四次,每次滑动窗口都会裁剪一部分大小为14 × 14 × 3的输入图像并将其通过卷积网络。但不是这样,我们将完整图像(形状为16 × 16 × 3)直接输入到经过训练的 ConvNet 中(见图 7)。这导致形状为2 × 2 × 4的输出矩阵. 输出矩阵中的每个单元格表示可能裁剪的结果和裁剪图像的分类值。

例如,下图中输出的左侧单元格(绿色单元格)表示第一个滑动窗口的结果。其他单元格表示剩余滑动窗口操作的结果。

滑动窗口的步幅由 Max Pool 层中使用的过滤器数量决定。在上面的示例中,Max Pool 层有两个过滤器,因此滑动窗口以 2 的步幅移动,从而产生四个可能的输出。使用这种技术的主要优点是滑动窗口同时运行和计算所有值。因此,这种技术非常快。尽管这种技术的一个弱点是边界框的位置不是很准确。

YOLO

在使用卷积滑动窗口技术时解决预测准确边界框问题,效果最好的算法是YOLO 算法。由 Joseph Redmon、Santosh Divvala、Ross Girshick 和 Ali Farhadi 于 2015 年开发。YOLO 很受欢迎,因为它在实时运行的同时实现了高精度。之所以这样称呼该算法,是因为它只需要通过网络进行一次前向传播即可进行预测。

该算法将图像划分为网格,并对每个网格单元运行图像分类和定位算法。例如,我们有一个大小为256 × 256的输入图像。我们在图像上放置一个3 × 3 的网格。

在这里插入图片描述

接下来,我们在每个网格单元上应用图像分类和定位算法。对于每个网格单元,目标变量定义为

在这里插入图片描述

用卷积滑动窗口做一次。由于每个网格单元的目标变量的形状是1 × 9并且有 9 ( 3 × 3 ) 个网格单元,模型的最终输出将是:

YOLO 算法的优点是速度非常快,并且可以预测更准确的边界框。此外,在实践中为了获得更准确的预测,我们使用更精细的网格,比如19 × 19,在这种情况下,目标输出的形状为19 × 19 × 9。

以上是关于深度学习入门系列之doc的主要内容,如果未能解决你的问题,请参考以下文章

深度学习入门系列-神经网络

AI框架核心技术系列来啦!从入门到放弃!

深度学习入门基础CNN系列——批归一化(Batch Normalization)和丢弃法(dropout)

Docker入门系列之四:Docker映像

物体检测快速入门系列-Windows部署Docker GPU深度学习开发环境

推荐系统入门系列-深度排序模型之串型结构AFMNFMPNN