简介:

线性分类中,我们使用CS231n(五)Neural Nets Notes1-LMLPHP来计算不同图片类别的评分,CS231n(五)Neural Nets Notes1-LMLPHP是一个包含了图像的全部像素数据的[3072x1]列向量,而CS231n(五)Neural Nets Notes1-LMLPHP是一个[10x3072]的矩阵,所以输出的评分·是一个包含10个分类评分的向量。

神经网络中 ,我们使用CS231n(五)Neural Nets Notes1-LMLPHP

其中CS231n(五)Neural Nets Notes1-LMLPHP(举例)是一个[100x3072]的矩阵,作用是将图像转化为一个100维的过渡向量。

函数CS231n(五)Neural Nets Notes1-LMLPHP是非线性的(有多种选择),它会作用到每个元素。简单设置阈值,将所有小于0的值变为0.

矩阵CS231n(五)Neural Nets Notes1-LMLPHP的尺寸是[10x100],因此将得到10个数字,这10个数字可以解释为是分类的评分。

非线性函数max是改变的关键点,CS231n(五)Neural Nets Notes1-LMLPHP将通过随机梯度下降学习得到,他们的梯度在反向传播过程中通过链式法则求导得出。

一个三层的神经网络可以类比地看做CS231n(五)Neural Nets Notes1-LMLPHP,其中CS231n(五)Neural Nets Notes1-LMLPHP是需要进行学习的参数,中间隐层的尺寸是网络的超参数。

 

下图是单个神经元前向传播的示例:

编码实现单个神经元前向传播:

import numpy as np
class Neuron(object):

  def forward(inputs):
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid激活函数
    return firing_rate


每个神经元都对它的输入和权重进行点积,然后加上偏差,最后使用非线性函数(或称为激活函数)。本例中使用的是sigmoid函数CS231n(五)Neural Nets Notes1-LMLPHP

 

常用的激活函数:

每个激活函数(非线性函数)的输入都是一个数字,然后对其进行某种固定的数学操作。

上图左边是Sigmoid非线性函数,将实数压缩到[0,1]之间。右边是tanh函数,将实数压缩到[-1,1]。

Sigmoidsigmoid非线性函数的数学公式是CS231n(五)Neural Nets Notes1-LMLPHP,函数图像如上图的左边所示。在前一节中已经提到过,它输入实数值并将其“挤压”到0到1范围内。更具体地说,很大的负数变成0,很大的正数变成1。然而现在sigmoid函数已经不太受欢迎,实际很少使用了,这是因为它有两个主要缺点:

  • Sigmoid函数饱和使梯度消失。sigmoid神经元有一个不好的特性,就是当神经元的激活在接近0或1处时会饱和:在这些区域,梯度几乎为0。回忆一下,在反向传播的时候,这个(局部)梯度将会与整个损失函数关于该门单元输出的梯度相乘。因此,如果局部梯度非常小,那么相乘的结果也会接近零,这会有效地“杀死”梯度,几乎就有没有信号通过神经元传到权重再到数据了。还有,为了防止饱和,必须对于权重矩阵初始化特别留意。比如,如果初始化权重过大,那么大多数神经元将会饱和,导致网络就几乎不学习了。
  • Sigmoid函数的输出不是零中心的。这个性质并不是我们想要的,因为在神经网络后面层中的神经元得到的数据将不是零中心的。这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数(比如在CS231n(五)Neural Nets Notes1-LMLPHP中每个元素都CS231n(五)Neural Nets Notes1-LMLPHP),那么关于CS231n(五)Neural Nets Notes1-LMLPHP的梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数(具体依整个表达式CS231n(五)Neural Nets Notes1-LMLPHP而定)。这将会导致梯度下降权重更新时出现z字型的下降。然而,可以看到整个批量的数据的梯度被加起来后,对于权重的最终更新将会有不同的正负,这样就从一定程度上减轻了这个问题。因此,该问题相对于上面的神经元饱和问题来说只是个小麻烦,没有那么严重。

Tanhtanh非线性函数图像如上图右边所示。它将实数值压缩到[-1,1]之间。和sigmoid神经元一样,它也存在饱和问题,但是和sigmoid神经元不同的是,它的输出是零中心的。因此,在实际操作中,tanh非线性函数比sigmoid非线性函数更受欢迎。注意tanh神经元是一个简单放大的sigmoid神经元,具体说来就是:CS231n(五)Neural Nets Notes1-LMLPHP

左边是ReLU(校正线性单元:Rectified Linear Unit)激活函数,当CS231n(五)Neural Nets Notes1-LMLPHP时函数值为0。当CS231n(五)Neural Nets Notes1-LMLPHP函数的斜率为1。右边是从 Krizhevsky等的论文中截取的图表,指明使用ReLU比使用tanh的收敛快6倍。

(最常用)ReLU在近些年ReLU变得非常流行。它的函数公式是CS231n(五)Neural Nets Notes1-LMLPHP。换句话说,这个激活函数就是一个关于0的阈值(如上图左侧)。使用ReLU有以下一些优缺点:

  • 优点:相较于sigmoid和tanh函数,ReLU对于随机梯度下降的收敛有巨大的加速作用( Krizhevsky 等的论文指出有6倍之多)。据称这是由它的线性,非饱和的公式导致的。
  • 优点:sigmoid和tanh神经元含有指数运算等耗费计算资源的操作,而ReLU可以简单地通过对一个矩阵进行阈值计算得到。
  • 缺点:在训练的时候,ReLU单元比较脆弱并且可能“死掉”。举例来说,当一个很大的梯度流过ReLU的神经元的时候,可能会导致梯度更新到一种特别的状态,在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生,那么从此所以流过这个神经元的梯度将都变成0。也就是说,这个ReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。例如,如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。

Leaky ReLULeaky ReLU是为解决“ReLU死亡”问题的尝试。ReLU中当x<0时,函数值为0。而Leaky ReLU则是给出一个很小的负数梯度值,比如0.01。所以其函数公式为其中CS231n(五)Neural Nets Notes1-LMLPHP是一个小的常量。有些研究者的论文指出这个激活函数表现很不错,但是其效果并不是很稳定。Kaiming He等人在2015年发布的论文Delving Deep into Rectifiers中介绍了一种新方法PReLU,把负区间上的斜率当做每个神经元中的一个参数。然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。

Maxout一些其他类型的单元被提了出来,它们对于权重和数据的内积结果不再使用CS231n(五)Neural Nets Notes1-LMLPHP函数形式。一个相关的流行选择是Maxout(最近由Goodfellow等发布)神经元。Maxout是对ReLU和leaky ReLU的一般化归纳,它的函数是:CS231n(五)Neural Nets Notes1-LMLPHP。ReLU和Leaky ReLU都是这个公式的特殊情况(比如ReLU就是当CS231n(五)Neural Nets Notes1-LMLPHP的时候)。这样Maxout神经元就拥有ReLU单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的ReLU单元)。然而和ReLU对比,它每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。

 

神经网络结构:

最普通的层的类型就像上图一样为全连接层(fully-connected layer) 也就是神经元与其前后两层的神经元是完全成对连接的,但是在同一层的神经元之间没有连接。上图左边是一个2层神经网络,隐层由4个神经元(也可称为单元(unit))组成,输出层由2个神经元组成,输入层是3个神经元。右边是一个3层神经网络,两个含4个神经元的隐层。注意:层与层之间的神经元是全连接的,但是层内的神经元不连接。

输出层。和神经网络中其他层不同,输出层的神经元一般是不会有激活函数的(或者也可以认为它们有一个线性相等的激活函数)。这是因为最后的输出层大多用于表示分类评分值,因此是任意值的实数,或者某种实数值的目标数(比如在回归中)。

确定网络尺寸。用来度量神经网络的尺寸的标准主要有两个:一个是神经元的个数,另一个是参数的个数。第一个网络有4+2=6个神经元(输入层不算),[3x4]+[4x2]=20个权重,还有4+2=6个偏置,共26个可学习的参数。

一个三层神经网路的前向传播代码示例:

全连接层的前向传播一般就是先进行一个矩阵乘法,然后加上偏置并运用激活函数。

f = lambda x: 1.0/(1.0 + np.exp(-x)) # 激活函数(用的sigmoid)
x = np.random.randn(3, 1) # 含3个数字的随机输入向量(3x1)
h1 = f(np.dot(W1, x) + b1) # 计算第一个隐层的激活数据(4x1)
h2 = f(np.dot(W2, h1) + b2) # 计算第二个隐层的激活数据(4x1)
out = np.dot(W3, h2) + b3 # 神经元输出(1x1)

在上面的代码中,W1,W2,W3,b1,b2,b3都是网络中可以学习的参数。注意x并不是一个单独的列向量,而可以是一个批量的训练数据(其中每个输入样本将会是x中的一列),所有的样本将会被并行化的高效计算出来。注意神经网络最后一层通常是没有激活函数的(例如,在分类任务中它给出一个实数值的分类评分)。

 

理论基础:已经证明,给出任意连续函数CS231n(五)Neural Nets Notes1-LMLPHP和任意,均存在一个至少含1个隐层的神经网络CS231n(五)Neural Nets Notes1-LMLPHP(并且网络中有合理选择的非线性激活函数,比如sigmoid),对于,使得CS231n(五)Neural Nets Notes1-LMLPHP。换句话说,神经网络可以近似任何连续函数。

正则化强度是控制神经网络过拟合的好方法。不应该因为害怕出现过拟合而使用小网络。相反,应该进尽可能使用大网络,然后使用正则化技巧来控制过拟合。

 

 总结:

  • 讨论了几种不同类型的激活函数,其中ReLU是最佳推荐;
  • 介绍了神经网络,神经元通过全连接层连接,层间神经元两两相连,但是层内神经元不连接;
  • 理解了分层的结构能够让神经网络高效地进行矩阵乘法和激活函数运算;
  • 理解了神经网络是一个通用函数近似器,但是该性质与其广泛使用无太大关系。之所以使用神经网络,是因为它们对于实际问题中的函数的公式能够某种程度上做出“正确”假设。
  • 讨论了更大网络总是更好的这一事实。然而更大容量的模型一定要和更强的正则化(比如更高的权重衰减)配合,否则它们就会过拟合。在后续章节中我们讲学习更多正则化的方法,尤其是dropout。

10-03 17:08