代价函数
在神经网络中,我们需要定义一些新的参数来表示代价函数。
L = total number of layers in the network
$s_l$ = number of units (not counting bias unit) in layer l
K = number of output units/classes
在上一章的神经网络的介绍中,我们有多个输出的节点。这里我们定义 $h_\Theta(x)_k$ 来表示第k个输出结果。神经网络的代价函数应当和之前说过的Logistic Regression的代价函数的一般形式一样,如下所示:
$$
J(\theta) = -\frac{1}{m}\sum_{i=1}^{m}[y^(i)log(h_\theta(x^(i)))+(1-y^(i))log(1-h_\theta(x^(i)))] + \frac{\lambda}{2m}\sum_{j=1}^{n}\theta_j^2
$$
对于一个神经网络来说,我们的代价函数是这个式子的一般化形式,这里不再是仅有一个逻辑回归输出单元,取而代之的是K个。因此我们的代价函数长这样:
这是一个很复杂的函数,(复杂的我懒得用latex表达式写出来了),我们添加了一些嵌套的求和来计算多个输出节点。在函数的第一部分中括号前面我们额外添加了求出各个节点的代价函数的求和,在正则化部分,需要计算多元的矩阵运算,当前$\Theta$矩阵中的列数等于我们当前层中的节点数(包括偏差单元) ,在当前的$\Theta$矩阵中,行数等于下一层的节点数(不包括偏置单元) ,在逻辑回归之前,将每一项都进行平方。
注意(原课后笔记中的,不翻译了):
the double sum simply adds up the logistic regression costs calculated for each cell in the output layer
the triple sum simply adds up the squares of all the individual Θs in the entire network.
the i in the triple sum does not refer to training example i
反向传播
反向传播是神经网络中用于最小化代价函数的一个方法,类似于在logistic回归和线性回归中使用的梯度下降,目标都是计算$min_\Theta(J(\Theta))$。也就是说,我们需要找到一个最佳的参数来最小化$J$,则需要计算$J(\Theta)$的偏导数$\frac{\partial}{\partial\Theta_{i,j}^(l)}J(\Theta)$。
从只有一个训练样本的情况下来看,因此先假设整个训练集只有只包含一个训练样本$(x,y)$,也就是实数对。
我们大致看一下使用这个训练样本来计算的顺序,首先使用前向传播来计算一下在给定输入的时候,假设函数是否会真的输出结果,如上图。具体地说,这里的$a^(1)$就是第一层的激励值,也就是输入层所在的地方,所以设定它为$x$。则可以得出后续的$a^(2),a^(3),a^(4)$。
接下来,为了计算导数项,将采用反向传播的算法。反向传播算法从直观上说,就是对每一个节点,我们计算 $\delta_j^(l)$,代表了第$l$层的第$j$个节点的误差。之前说的$a_j^(l)$代表的是第$l$层第$j$个单元的激励值,所以这个$\delta$在某种程度上就捕捉到了在这个神经节点的激励值的误差,所以我们可能希望这个节点激励值稍微不一样。如下图,用这个有四层的神经网络结构做例子:
对于第四层,也就是$\delta_j^(4) = a_j^(4) - y_j$,这个很好理解,即第四层第$j$个节点激励值与实际值的误差,用向量方式表示就是$\delta^(4) = a^(4) - y$,向量的维数就是输出单元的个数。那么对于第三层,实际上是$\delta_j^(3) = (\Theta^(3))^T\delta^(4).*g'(z^(3))$,点乘指的是两个向量元素间对应相乘,其中的导数项其实是对激励函数g在输入值为$z(3)$的时候所求的导数,用微积分知识计算这个$g'(z^(3)) = a^(3).*(1-a^(3))$,这里$a^(3)$是一个对那一层的激励向量,1是以1为元素的向量(这一块没看懂)。同样后面的$\delta_j^(2) = (\Theta^(2))^T\delta^(3).*g'(z^(2))$,$g'(z^(2)) = a^(2).*(1-a^(2))$。这里没有$\delta_j^(1)$项,因为第一层是输入层,即实际的训练集观察到的,因此不会有误差。利用反向传播算法,在忽略正则化项时,我们可以得出$\frac{\partial}{\partial\Theta_{ij}^(l)}J(\Theta) = a_j^(l)\delta_i^(l+1)$。通过反向传播,可以计算出这些$\delta$项进而计算出所有参数的偏导数项。
接下来说说当我们有一个非常大的训练样本时如何来计算关于这些参数的偏导数,使用下面的算法:
首先假设有一组训练集$\{(x^(1),y^(1)),...(x^(m),y^(m))\}$,假设对于所有的$l,i,j$都有$\Delta_{ij}^(l) = 0$,这个实际上是用来计算$\frac{\partial}{\partial\Theta_{ij}^(l)}J(\Theta) $的,这些$\Delta$会被作为累加项慢慢的增加以算出这些偏导数。如上图所示,先循环我们的训练集,设定$a^(1) = x^(i)$,其中$a^(1)$指的是输入层的激励函数,$x^(i)$指的是第i个训练样本的输入值,然后使用前向传播来计算所有的$a^(l)$直到最后一层L,接下来再使用这个样本的输出值$y^(i)$来计算这个输出值对应的误差项$\delta^(L)$,即假设输出减去目标输出,接着使用反向传播算法计算$\delta^(L-1),\delta^(L-2),\delta^(L-3),....,\delta^(2)$,最后将大写的$\Delta$来累计我们在前面写好的偏导数项,即:$\Delta_{ij}^(l) := \Delta_{ij}^(l) + a_j^(l)\delta_i^(l+1)$。如果把$\Delta_{ij}$看作一个矩阵,i,j代表矩阵中的位置,那么该等式可以用向量的方式表示为$\Delta^(l) = \Delta^(l) + \delta^(l+1)(a^(l))^T$。结束循环后,根据$j$是否等于0来分两种情况计算,如上图所示,当$j=0$时对应偏差项,因此没有加上额外的标准化项。这样,得到的就是代价函数对每一个参数的偏导数,这样就可以使用梯度下降法或是其他高级算法了。