【深度学习基础】2. 有监督的神经网络

多层神经网络

之前我们讨论的线性回归和逻辑回归都是对 进行线性关系建模的,如果我们希望对其进行非线性关系建模,神经网络是一个方法,而且它可以对比较复杂的非线性关系进行建模。

我们先来看神经网络最基本的单元“神经单元”的定义:

上面的例子中,有一个激活函数我们一般选择一个 sigmod 函数作为f的实现,比如 logistic 函数:当然我们也可以使用tanh函数,或者 Rectifier 激活函数(使用 Rectifier 作为激活函数的 Unit 叫做 Rectified Linear Units, ReLu )或者其他一些 Rectifier 的变种。三种函数的输入对比如下图所示:

tanh(z) 可以看做是 sigmoid 的拉伸版本,他的值域是 (-1,1),而 logistic 是 (0,1) 。 ReLU 则是当 Z 大于 0 时斜率为 1 的线性函数,小于 0 时始终输出 0 。

三种不同的激活函数在进行梯度求导的时候也是各不相同。Logistic 梯度是,tanh函数的梯度是  

Rectifier的梯度在 大于 的时候是 ,其他为 

理论上 Rectifier 在 点是不可导的,但是由于我们训练神经网络的时候用很大量的数据,梯度更新的时候是所有 instance 的梯度求和,一处 z=0 不至于影响整个梯度下降的过程,所以我们把 z=0 时的梯度也定义为 

另外一个需要注意的是,我们把 bias(也叫截距)这一项单独写出来了,定义为公式中的 ,而不是同一使用来定义。

神经网络模型

我们把很多的神经元串联起来,下一层的输入是上一层的输出,从而组成一个小型的网络,比如下图:

最左边一层我们叫输入层(input layer),最右边一层叫做输出层(output layer),中间部分都叫做隐藏层(hidden layer)。定义一些变量:

是神经网络的层数,比如这里是3

是第 层网络,比如是输入层,

是输出层是神经网络的参数,表示连接第l层的节点 与连接第 l+1 层的节点 之间的边的权重(注意下标和节点对应关系,因为 与 相乘时是转置过的)。

是连接到l+1层第i个节点的 bias

是第l层网络的节点个数(不包含 bias 节点)

是第l层第i个节点的输出值(activation),对于l=1的输入层

对于输入层,我们也统一到了这个参数上,如果引入一个新的定义 ,上式可以简化为:

我们把这个 l -> l+1 逐层计算输出的过程叫做前馈(forward propagation)。通过 blas 等向量和矩阵运算库,我们可以很方便的把前馈过程表达为向量矩阵的线性代数运算,从而提高计算速度。

神经网络可以定义很多中间层,从而使得网络很 deep(这也是 DNN 的来源),同时输出层还可以定义多个输出节点来预测多个值,比如下面的网络示意图:

上面这个网络中,。这种网络可以专门用来对多分类问题进行建模。

可以看到,如果不存在输入层,直接输入对输出,如果输出层节点为 1,且激活函数为 logistic ,其实就是逻辑回归。如果输出层节点多于 ,且激活函数为 softmax ,就是 softmax regression 

BP算法 backpropagation Algorithm

 

我们使用最小均方误差来定义代价函数,对于单条记录有:

对于所有的m条训练数据合并计算代价函数,可以得到如下的代价函数:

其中第一部分定义的是误差平方和的平均值,第二项是正则化因子,也叫权值衰减 (weight decay),专门用来惩罚数值太大的权值,防止训练过程中发生过拟合。正则化因子控制前后两项的相对权重。

上面的损失函数既可以用于分类问题,也可以用于回归问题。分类问题的时候认为 y=0 或者 ,回归问题的时候需要先把 值归一化到 [0,1] 然后进行训练。

现在目标转化为求一组值使得  的值最小化。虽然  是一个非凸函数,使用梯度下降的最优化求解可能会收敛到局部最优,而非全局最优,但是实际应用中,我们这么做并没用太大的问题。

需要注意的是, 一定要使用随机值来进行初始化,而不能统一设置为 或者其他的一模一样的数,因为这样的话会使得隐藏层每个节点的连接参数都是一样的,这样计算出来后隐藏层节点的结果也都是一样的,然后逐层向前计算,最后的结果就是 x 原封不动的传输到了最后一层。这会让训练程序直接停止,因为无法计算梯度。这个随机初始化的过程,目的就是消除对称性。

根据之前使用梯度下降法更新参数的经验,我们知道现在我们需要用  分别求偏导,用于更新参数。按照严格的数学求解应该是这样的:

为了能更方便的求解,我们都使用 BP 算法。关于 BP 算法先说一个不太好理解的版本:首先对每一个训练样例 (x, y) 先进行前向计算得到最后一层的激活输出 (activations) ,然后对隐藏层的每一层 的每个节点 ,依次计算一个误差项,用于评估最后一层的输出误差中有多少是这个节点产生的。再说一个我自己理解的版本:如果网络并没有隐藏层,输入直接对接到输出,那么就是普通的逻辑回归或者 softmax 回归的求偏导更新过程;现在网络有很多隐藏层,前向计算过程中,是输入一层层传递过来的,而传递过程中与连接权重矩阵相乘的过程,本质上是一次次的空间变换(矩阵乘法就是两侧空间的 transfer 过程,可降维,可升维,可旋转缩放,可非线性变换等等各种),那么现在最后一层的误差来了,我们应该干什么呢?应该通过矩阵的另外一端把误差重新进行空间变换映射回去,并层层传递到第一个隐藏层。后面我们对照公式再具体讲一下。

对于输出层的 可以通过计算输出与真实值之间的最小二乘的导数来得到,而对于隐藏层,我们可以认为是所有使用 作为输入的下一层的节点的误差项进行加权求和(反向的矩阵空间变换)的结果。

BP 算法描述如下:

1.      先使用前向计算,一直计算得到输出层的结果;

2.      对于输出层的每个节点 ,计算 

3.      对所有的隐藏层,l= nl-1, nl-2, …, 3, 2,给每个节点 计算:

4.      使用 计算偏导项:

注意以上的乘 操作都是按位操作的,而且 我们同样可以使用矩阵和向量运算来加速。假设 是 sigmoid 函数,根据前面的推导我们可以直接得到,这样可以直接代入上面的公式中使用。

使用 mini-batch 来进行数据的批量计算,我们可以把上面过程使用矩阵形式来表达,梯度下降的算法过程如下:

1.         对于所有层 ,设置梯度

注意:是矩阵,是向量,他们是用来存储梯度值的。与用来存储权重的 和 维度是一样的。

2.         对于所有训练样例 i=1,2,…,m

a.       使用 BP 算法计算梯度

 

注意:这里的 也是矩阵方式的表达,比如输出层,隐藏层 。这里的  就是把下一层误差反向映射回来的过程,那为什么还有 这一部分呢?因为我们要计算的实际上参数的梯度下降方向。

b.      更新Wb的梯度

3.         更新参数 和 

如此一直迭代训练,便可以不断减小代价函数  直到模型收敛或者达到一定的训练迭代次数。

softmax regression输出层

使用 softmax regression 作为输出层时,代价函数求导得到的误差项表表达应该如下式,后面的误差传递过程保持不变:

常见的激活函数求导

通过上面的内容,我们知道多层神经网络的 BP 算法求解,大体的公式都是固定的模式化的,有一个可变的地方就是激活函数求导 。一般常见的三种激活函数:  logistic ,  tanh ,  Rectifier ,我们可以简单的把它们记录下来以便直接使用。

注意:以下部分都用进行了简化,实际上应该是对 求偏导,需要多补充一部分函数内求导的部分。

Rectifierfor z<=0;  for z>0

logistic      

tanh

发表评论

电子邮件地址不会被公开。 必填项已用*标注