为了计算 ∂C/∂w 需要对cost function的形式做两个假设,
cost function可以被写为 C=1n∑xCx ,这样做是因为backpropagation实际上是计算每个样本的偏导数,然后再把 Cx 合起来构成原来的 C ,∂C/∂w=1n∂Cx/∂w,如果不能写成和的形式则使用backpropagation也没什么用。C可以被写为 aL 的函数,即 C=C(aL) ,要注意在优化过程中输入的 x,y 都是固定的数,变量是 w .backprop室为了计算∂C/∂w,为了计算它,要引入中间变量 δlj ,表示第 l 层的j个神经元对C的偏导数。
如果在第 l 层的j个神经元上加上一个 Δzlj ,那么这个神经元的输出就是 σ(zlj+Δzlj) ,这个改变会传播到最后的 C ,近似值为∂C∂zljΔzlj。
定义:
δlj≡∂C∂zlj.为了最终计算 ∂C/∂w ,使用这个中间变量过渡。即先计算 C 对每个神经元的偏导数,然后把δ和 ∂C/∂w 联系起来。(这个思想就是利用链式求导把复杂的偏导数转化为两部分相对简单的来求解,这个过程中使用 δ 表示 ∂C/∂a 也可以,只不过这样的话数学上的形势会复杂一点。)
这个思想类似于求解 f(x)=ex2 的导数,写成神经网络的形式 x→x′=x2→x′′=ex′ 我们可以引入 δ=df/dx′ ,然后我们可以使用链式求导得出 df/dx=df/dx′⋅dx′/dx ,这样的计算更加方便、形式更加简洁。
这四个式子可以让我们计算error δ 和C的梯度: 一、输出层 δL 的error的等式: δLj=∂C∂aLjσ′(zLj).(BP1) (BP1)可由上面的假设和链式求导计算得出(利用不同输出神经元之间的独立性(所以有个元素间的乘法)), 向量形式: δL=∇aC⊙σ′(zL).(BP1a)
二、根据下一层的 δl+1 计算上一层的 δl : δl=((wl+1)Tδl+1)⊙σ′(zl),(BP2) 因为 zl+1=Wl+1⋅σ(zl)+bl+1 ,所以 δl=∂C/∂zl=∂C/∂zl+1⋅∂zl+1/∂z
根据(BP1)和(BP2)可以计算所有层的 δ ,即所有的C关于z的偏导数,接下来我们只需要找出 Wl,bl 和z之间的关系,然后继续使用链式求导即可。
三、每层中的偏置对C的影响: ∂C∂blj=δlj.(BP3)
四、每层中的权重对C的影响: ∂C∂wljk=al−1kδlj.(BP4)
当 ain 很小的时候,偏导数 ∂C/∂w 也会很小,学习就会很慢。
由(BP1)可知,要乘上 σ′(z) ,而当 z 很大或很小的时候导数会接近于零,学习会很慢(即使把1算成了0,向前传播的误差也会很小),此时这个神经元称为饱和了(saturated ).
总结:当前面的神经元输出很小,或后面的神经元饱和了(z很大或很小)时会导致学习变慢。
backprop的整体其实就是为了计算 ∂C/∂w ,但是直接计算太复杂,所以使用链式求导,而链式求导就需要选择好中间变量,这里选择的是 z 。 具体步骤: 先计算∂C/∂z,然后计算 ∂z/∂w ,然后再找出 w,z,C 之间的关系,代入链式求导公式即可。 整个过程中稍复杂的地方就是, ∂C/∂z 向前传播的地方,可以看做 C=Wσ(z)+const ,然后利用后面层的 ∂C/∂z 链式求导及可。
神经网络刚发明出来的时候,没人算出偏导数的解析解,大家使用数值计算方法,这种方法的缺点就是计算量过大,每个weight之间都是独立的,而backprop计算则简单得多,