Neural Networks and Deep Learning(二)BP网络
这一讲介绍误差反向传播(backpropagation)网络,简称BP网络。 以上一讲介绍的MNIST手写数字图片分类问题为研究对象,首先明确输入输出:输入就是一张28×28的手写数字图片,展开后可以表示成一个长度为784的向量;输出可以表示为一个长度为10的one-hot向量,比如输入是一张“3”的图片,则输出向量为(0,0,0,1,0,0,0,0,0,0,0)。 然后构造一个如下的三层全连接网络。第一层为输入层,包含784个神经元,正好对应输入的一张28×28的图片。第二层为隐藏层,假设隐藏层有15个神经元。第三层为输出层,正好10个神经元,对应该图片的one-hot结果。 全连接网络表示上一层的每个神经元都和下一层的每个神经元有连接,即每个神经元的输入来自上一层所有神经元的输出,每个神经元的输出连接到下一层的所有神经元。每条连边上都有一个权重w。 每个神经元执行的操作非常简单,就是把跟它连接的每个输入乘以边上的权重,然后累加起来。 比如上面的一个神经元,它的输出就是: $$\begin{eqnarray}\mbox{output} = \left\{ \begin{array}{ll}0 & \mbox{if} \sum_j w_j x_j \leq \mbox{ threshold} \\1 & \mbox{if} \sum_j w_j x_j > \mbox{threshold}\end{array}\right.\tag{1}\end{eqnarray}$$其中的threshold就是该神经元激活的阈值,如果累加值超过threshold,则该神经元被激活,输出为1,否则为0。这就是最原始的感知机网络。感知机网络也可以写成如下的向量形式,用激活阈值b代替threshold,然后移到左边。神经网络中,每条边具有权重w,每个神经元具有激活阈值b。 $$\begin{eqnarray}\mbox{output} = \left\{ \begin{array}{ll} 0 & \mbox{if } w\cdot x + b \leq 0 \\1 & \mbox{if } w\cdot x + b > 0\end{array}\right.\tag{2}\end{eqnarray}$$ 但是感知机网络的这种激活方式不够灵活,它在threshold左右有一个突变,如果输入或者某个边上的权重稍微有一点变化,输出结果可能就千差万别了。于是后来人们提出了用sigmoid函数来当激活函数,它在0附近的斜率较大,在两边的斜率较小,能达到和阶梯函数类似的效果,而且函数光滑可导。sigmoid的函数形式如下,其中\(z\equiv w \cdot x + b\)为神经元激活之前的值。 $$\begin{eqnarray} \sigma(z) \equiv \frac{1}{1+e^{-z}}\tag{3}\end{eqnarray}$$sigmmoid函数还有一个优点就是它的导数很好计算,可以用它本身来表示: $$\begin{eqnarray}\sigma'(z)=\sigma(z)(1-\sigma(z))\tag{4}\end{eqnarray}$$BP网络的参数就是所有连线上的权重w和所有神经元中的激活阈值b,如果知道这些参数,给定一个输入x,则可以很容易的通过正向传播(feedforward)的方法计算到输出,即不断的执行\(w \cdot x + b\)操作,然后用sigmoid激活,再把上一层的输出传递给下一层作为输入,直到最后一层。 1 2 3 4 5 def feedforward(self, a): """Return the output of the network if ``a`` is input.""" for b, w in zip(self.biases, self.weights): a = sigmoid(np.dot(w, a)+b) return a 同时,网络的误差可以用均方误差(mean squared error, MSE)表示,即网络在最后一层的激活值(即网络的输出值)\(a\)和对应训练集输入\(x\)的正确答案\(y(x)\)的差的平方。有\(n\)个输入则误差取平均,\(\dfrac{1}{2}\)是为了后续求导方便。 ...