感知器是一种人工神经元,在 20 世纪五、六⼗年代由科学家Frank Rosenblatt发明。⼀个感知器接受⼏个二进制输⼊ x 1 , x 2 , . . . x_1, x_2, . . . x1,x2,...,并产⽣⼀个二进制输出:
⽰例中的感知器有三个输⼊: x 1 , x 2 , x 3 x_1, x_2, x_3 x1,x2,x3,引入权重 w 1 , w 2 , w 3 w_1, w_2, w_3 w1,w2,w3表⽰相应输⼊对于输出重要性的实数。输出值0或者1,则由分配权重后的总和 ∑ j w j x j \sum_jw_jx_j ∑jwjxj小于或者大于一些阈值决定。和权重⼀样,阈值是⼀个实数,⼀个感知器的参数。⽤更精确的代数形式:
把阈值移到不等式的另⼀边,并⽤感知器的偏置 b ≡ − t h r e s h o l d b ≡ −threshold b≡−threshold 代替。⽤偏置⽽不是阈值,那么感知器的规则可以重写为:
S 型神经元和感知器类似,但是被修改为权重和偏置的微⼩改动只引起输出的微⼩变化。正如⼀个感知器,S 型神经元有多个输⼊ x 1 , x 2 , . . . x_1, x_2, . . . x1,x2,...,但是这些输⼊可以取0和1中的任意值,如0.618…是⼀个 S 型神经元的有效输⼊,⽽不仅仅是二进制输入0或1。同样,S 型神经元对每个输⼊有权重 w 1 , w 2 , . . . w_1, w_2, . . . w1,w2,...和⼀个总的偏置 b b b,但输出不再是0或1,而是 σ ( w ⋅ x + b ) σ(w · x+b) σ(w⋅x+b),这⾥ σ σ σ 被称为S型函数,定义为:
σ ( z ) ≡ 1 1 + e − z σ(z) ≡ \frac1{1+e^{-z}} σ(z)≡1+e−z1
把它们放在⼀起来更清楚地说明,⼀个具有输⼊ x 1 , x 2 , . . . x_1, x_2, . . . x1,x2,...,权重 w 1 , w 2 , . . . w_1, w_2, . . . w1,w2,...和偏置 b b b 的S型神经元的输出是:
1 1 + e − ∑ j w j x j − b = 1 1 + e x p ( − ∑ j w j x j − b ) \frac1{1+e^{-\sum_jw_jx_j-b}} = \frac1{1+exp(-\sum_jw_jx_j-b)} 1+e−∑jwjxj−b1=1+exp(−∑jwjxj−b)1
t a n h tanh tanh 函数的定义为:
t a n h ( z ) ≡ e z − e ( − z ) e z + e ( − z ) tanh(z) ≡ \frac{e^z - e^(-z)}{e^z + e^(-z)} tanh(z)≡ez+e(−z)ez−e(−z) S型神经元和 t a n h tanh tanh 神经元之间的⼀个差异就是 t a n h tanh tanh 神经元的输出的值域是 (−1, 1) ⽽⾮ (0, 1)。这意味着如果你构建基于 t a n h tanh tanh 神经元,你可能需要正规化最终的输出(取决于应⽤的细节,还有你的输⼊),跟S型神经元略微不同。
输⼊为 x x x,权重向量为 w w w,偏置为 b b b 的 R e L U ReLU ReLU 神经元的输出是:
m a x ( 0 , w ⋅ x + b ) max\ (\ 0, w · x + b\ ) max ( 0,w⋅x+b )
本文我们讨论的神经⽹络,都是以上⼀层的输出作为下⼀层的输⼊。这种⽹络被称为前馈神经⽹络。这意味着⽹络中是没有回路的,信息总是向前传播,从不反向回馈。
上图⽹络中最左边的称为输⼊层,其中的神经元称为输⼊神经元。最右边的称为输出层,其中的神经元称为输出神经元,在本例中,输出层只有⼀个神经元。中间层既不是输⼊也不是输出,被称为隐藏层。
我们⾸先给出⽹络中权重的清晰定义。我们使⽤ w j k l w_{jk}^l wjkl 表⽰从 ( l − 1 ) t h (l − 1)^{th} (l−1)th 层的 k t h k^{th} kth 个神经元到 l t h l^{th} lth 层的 j t h j^{th} jth 个神经元的链接上的权重。例如,下图给出了⽹络中第⼆层的第四个神经元到第三层的第⼆个神经元的链接上的权重:
我们对⽹络的偏置和激活值也会使⽤类似的表⽰。显式地,我们使⽤ b j l b_j^{l} bjl 表⽰在 l t h l^{th} lth 层第 j t h j^{th} jth 个神经元的偏置,使⽤ a j l a_j^{l} ajl 表⽰ l t h l^{th} lth 层第 j t h j^{th} jth 个神经元的激活值(即神经元的输出)。下⾯的图清楚地解释了这样表⽰的含义:
有了这些表⽰, l t h l^{th} lth 层的第 j t h j^{th} jth 个神经元的激活值 a j l a_j^{l} ajl 就和 ( l − 1 ) t h (l − 1)^{th} (l−1)th 层的激活值通过⽅程关联起来了(其中 σ σ σ 称为激活函数,本文选用S型神经元进行讨论,即选择激活函数为S型函数)
a j l = σ ( ∑ k w j k l a k l − 1 + b j l ) {a_j}^l = σ(\sum_kw_{jk}^la_k^{l-1}+b_j^l) ajl=σ(k∑wjklakl−1+bjl) 其中求和是在 ( l − 1 ) t h (l − 1)^{th} (l−1)th 层的所有 k k k 个神经元上进⾏的。为了⽤矩阵的形式重写这个表达式,我们对每⼀层 l l l 都定义⼀个权重矩阵 w l w^l wl。权重矩阵 w l w^l wl 的元素正是连接到 l t h l^{th} lth 层神经元的权重,更确切地说,在第 j t h j^{th} jth ⾏第 k t h k^{th} kth 列的元素是 w j k l w_{jk}^l wjkl。类似的,对每⼀层 l l l,定义⼀个偏置向量, b l b^l bl,偏置向量的每个元素其实就是前⾯给出的 b j l b_j^{l} bjl,每个元素对应于 l t h l^{th} lth 层的每个神经元。最后,我们定义激活向量 a l a^l al,其元素是那些激活值 a j l a_j^{l} ajl。最后引入激活函数(如 σ)来按照矩阵形式重写上述公式,得
a l = σ ( w l a l − 1 + b l ) a^l = σ(w^la^{l−1} + b^l) al=σ(wlal−1+bl) 在计算 a l a^l al 的过程中,我们计算了中间量 z l ≡ w l a l − 1 + b l z^l ≡ w^la^{l−1} + b^l zl≡wlal−1+bl,我们称 z l z^l zl 为 l l l 层神经元的带权输⼊。同样要指出的是 z l z^l zl 的每个元素是 z j l ≡ ∑ k w j k l a k l − 1 + b j l {z_j}^l ≡ \sum_kw_{jk}^l{a_k}^{l-1}+b_j^l zjl≡∑kwjklakl−1+bjl,其实 z j l z_j^l zjl 就是第 l l l 层第 j j j 个神经元的激活函数的带权输⼊。
特别地,假设 s s s 和 t t t 是两个同样维度的向量。那么我们使⽤ s ⊙ t s ⊙ t s⊙t 来表⽰按元素的乘积。所以 s ⊙ t s ⊙ t s⊙t 的元素就是$ (s ⊙ t)_j = s_j t_j$。给个例⼦,
这种类型的按元素乘法有时候被称为 Hadamard 乘积,或者 Schur 乘积。我们这⾥取前者。好的矩阵库通常会提供 Hadamard 乘积的快速实现,在实现反向传播的时候⽤起来很⽅便。
在神经网络的代数形式中,我们希望有⼀个算法,能让我们找到权重和偏置,以⾄于⽹络的输出 y ( x ) y(x) y(x) 能够拟合所有的训练输⼊ x。为了量化我们如何实现这个⽬标,在使用神经网络做项目的时候,我们往往需要定义一个代价函数。
为了便于接下来的讨论,本文定义一个二次代价函数。 C ( w , b ) ≡ 1 2 n ∑ x ∣ ∣ y ( x ) − a L ( x ) ∣ ∣ 2 C(w, b) ≡ \frac1{2n}\sum_x||y(x)-a^L(x)||^2 C(w,b)≡2n1x∑∣∣y(x)−aL(x)∣∣2从上式可以看出,训练的⽬的,应该是最⼩化代价函数。我们使⽤梯度下降算法来最小化代价函数。
在线性模型一文已经详细介绍过梯度下降算法,这里只做简单描述。
梯度下降算法是一种迭代算法,选取适当的初值w和b,不断迭代,更新w和b的值,进行目标函数的极小化,直到收敛。由于负梯度方向是使函数值下降最快的方向,在迭代的每一步,以负梯度方向更新w和b的值,从而达到减少函数值的目的。即每一次迭代,新的w和b都会由旧的w和b减去梯度乘以步长(或称速率eta)得到,代数形式为:
新 w = 旧 w − ∂ C / ∂ w ∗ e t a 新w = 旧w - ∂C/∂w*eta 新w=旧w−∂C/∂w∗eta 新 b = 旧 b − ∂ C / ∂ b ∗ e t a 新b = 旧b - ∂C/∂b*eta 新b=旧b−∂C/∂b∗eta 而反向传播算法,可用于快速计算代价函数C梯度,从而能够更快地更新w和b的值。
反向传播的⽬标是计算代价函数 C C C 分别关于 w w w 和 b b b 的偏导数 ∂ C / ∂ w ∂C/∂w ∂C/∂w 和 ∂ C / ∂ b ∂C/∂b ∂C/∂b。为了让反向传播可⾏,我们需要做出关于代价函数的两个主要假设。
第一个假设是代价函数可以被写成⼀个在每个训练样本 x x x 上的代价函数 C x C_x Cx 的均值 C = 1 n ∑ x C x C = \frac1{n}\sum_xC_x C=n1∑xCx。以⼆次代价函数为例,其中对每个独⽴的训练样本其代价是 C x = 1 2 ∣ ∣ y ( x ) − a L ( x ) ∣ ∣ 2 C_x = \frac12||y(x)-a^L(x)||^2 Cx=21∣∣y(x)−aL(x)∣∣2。
第二个假设是代价可以写成神经⽹络输出的函数。例如对于一个单独的训练样本x,可以写作:
C = 1 2 ∣ ∣ y − a L ∣ ∣ 2 = 1 2 ∑ j ( y j − a j L ) 2 C = \frac12||y-a^L||^2 = \frac12\sum_j(y_j-a_j^L)^2 C=21∣∣y−aL∣∣2=21j∑(yj−ajL)2
反向传播其实是对权重和偏置变化影响代价函数过程的理解。最终极的含义其实就是计算偏导数 ∂ C / ∂ w j k l ∂C/∂w_{jk}^l ∂C/∂wjkl 和 ∂ C / ∂ b j l ∂C/∂b_j^l ∂C/∂bjl。但是为了计算这些值,我们⾸先引⼊⼀个中间量, δ j l δ_j^l δjl,这个我们称为在 l t h l^{th} lth 层第 j t h j^{th} jth 个神经元上的误差。
为了理解误差是如何定义的,假设在神经⽹络上有⼀个调⽪⻤:
这个调⽪⻤在 l l l 层的第 j t h j^{th} jth 个神经元上。当输⼊进来时,调⽪⻤对神经元的操作进⾏搅局。他会增加很⼩的变化 ∆ z j l ∆z_j^l ∆zjl 在神经元的带权输⼊上,使得神经元输出由 σ ( z j l ) σ(z_j^l) σ(zjl) 变成 σ ( z j l + ∆ z j l ) σ(z_j^l + ∆z_j^l) σ(zjl+∆zjl)。这个变化会向⽹络后⾯的层进⾏传播,最终导致整个代价产⽣ ∂ C ∂ z j l ∆ z j l \frac{∂C}{∂z_j^l}∆z_j^l ∂zjl∂C∆zjl 的改变。
现在,这个调⽪⻤变好了,试着帮助你来优化代价,它试着找到可以让代价更⼩的 ∆ z j l ∆z_j^l ∆zjl。假设 ∂ C ∂ z j l \frac{∂C}{∂z_j^l} ∂zjl∂C有⼀个很⼤的值(或正或负)。那么这个调⽪⻤可以通过选择与 ∂ C ∂ z j l \frac{∂C}{∂z_j^l} ∂zjl∂C 相反符号的 ∆ z j l ∆z_j^l ∆zjl 来降低代价。相反,如果 ∂ C ∂ z j l \frac{∂C}{∂z_j^l} ∂zjl∂C 接近 0,那么调⽪⻤并不能通过扰动带权输⼊ z j l z_j^l zjl 来改善太多代价。在调⽪⻤看来,这时候神经元已经很接近最优了。所以这⾥有⼀种启发式的认识, ∂ C ∂ z j l \frac{∂C}{∂z_j^l} ∂zjl∂C 是神经元的误差的度量。
按照上⾯的描述,我们定义 l l l 层的第 j t h j^{th} jth 个神经元上的误差 δ j l δ_j^l δjl 为:
δ j l ≡ ∂ C ∂ z j l δ_j^l ≡ \frac{∂C}{∂z_j^l} δjl≡∂zjl∂C
证明:
代价函数C是关于z的函数,此处不妨假设 C = ( 1 − z ) 2 C = (1 - z)^2 C=(1−z)2,函数图像如下图。 ∂ C ∂ z \frac{∂C}{∂z} ∂z∂C 为函数的斜率,则 z z z 带来的微小变化 ∆ z ∆z ∆z,会如图中所示,导致整个C产生 ∂ C ∂ z ∆ z \frac{∂C}{∂z}∆z ∂z∂C∆z 的变化。
① 输出层误差 δ L δ^L δL 的⽅程
δ L = ∇ a C ⊙ σ ′ ( z L ) δ^L = ∇_aC ⊙ σ′(z^L) δL=∇aC⊙σ′(zL)证明:
δ j L = ∂ C ∂ z j L = ∑ k ∂ C ∂ a k L ∂ a k L ∂ z j L δ_j^L = \frac{∂C}{∂z_j^L} = \sum_k\frac{∂C}{∂a_k^L}\frac{∂a_k^L}{∂z_j^L} δjL=∂zjL∂C=k∑∂akL∂C∂zjL∂akL因为
a k L = σ ( z k L ) a_k^L = σ(z_k^L) akL=σ(zkL)当 k ≠ j k ≠ j k̸=j, ∂ a k L ∂ z j L \frac{∂a_k^L}{∂z_j^L} ∂zjL∂akL 消失;当 k = j k = j k=j, ∂ a k L ∂ z j L = σ ′ ( z j L ) \frac{∂a_k^L}{∂z_j^L} = σ′(z_j^L) ∂zjL∂akL=σ′(zjL) 。
固输出层 L L L 层每个元素定义如下:
δ j L = ∂ C ∂ a j L σ ′ ( z j L ) δ_j^L = \frac{∂C}{∂a_j^L}σ′(z_j^L) δjL=∂ajL∂Cσ′(zjL)以矩阵形式定义 L L L 层误差得:
δ L = ∇ a C ⊙ σ ′ ( z L ) δ^L = ∇_aC ⊙ σ′(z^L) δL=∇aC⊙σ′(zL)
② 使⽤下⼀层的误差 δ l + 1 δ^{l+1} δl+1 来表⽰当前层的误差 δ l δ^l δl
δ l = ( ( w l + 1 ) T δ l + 1 ) ⊙ σ ′ ( z l ) δ^l = ((w^{l+1})^Tδ^{l+1}) ⊙ σ′(z^l) δl=((wl+1)Tδl+1)⊙σ′(zl)证明:
δ j l = ∂ C ∂ z j l = ∑ k ∂ C ∂ z k l + 1 ∂ z k l + 1 ∂ z j l = ∑ k ∂ z k l + 1 ∂ z j l δ k l + 1 δ_j^l = \frac{∂C}{∂z_j^l} = \sum_k\frac{∂C}{∂z_k^{l+1}}\frac{∂z_k^{l+1}}{∂z_j^l} = \sum_k\frac{∂z_k^{l+1}}{∂z_j^l}δ_k^{l+1} δjl=∂zjl∂C=k∑∂zkl+1∂C∂zjl∂zkl+1=k∑∂zjl∂zkl+1δkl+1因为
z k l + 1 = ∑ j w k j l + 1 a j l + b k l + 1 = ∑ j w k j l + 1 σ ( z j l ) + b k l + 1 z_k^{l+1} = \sum_jw_{kj}^{l+1}a_j^l + b_k^{l+1} = \sum_jw_{kj}^{l+1}σ(z_j^l) + b_k^{l+1} zkl+1=j∑wkjl+1ajl+bkl+1=j∑wkjl+1σ(zjl)+bkl+1做微分,得到
∂ z k l + 1 ∂ z j l = w k j l + 1 σ ′ ( z j l ) \frac{∂z_k^{l+1}}{∂z_j^l} = w_{kj}^{l+1}σ′(z_j^l) ∂zjl∂zkl+1=wkjl+1σ′(zjl)代入 δ j l δ_j^l δjl,得出当前层 l l l 层每个元素误差定义如下:
δ j l = ∑ k w k j l + 1 δ k l + 1 σ ′ ( z j l ) δ_j^l = \sum_kw_{kj}^{l+1}δ_k^{l+1}σ′(z_j^l) δjl=k∑wkjl+1δkl+1σ′(zjl)
③ 代价函数关于⽹络中任意偏置的改变率
∂ C ∂ b j l = δ j l \frac{∂C}{∂b_j^l} = δ_j^l ∂bjl∂C=δjl证明:
δ j l = ∂ C ∂ z j l = ∑ k ∂ C ∂ b k l ∂ b k l ∂ z j l δ_j^l = \frac{∂C}{∂z_j^l} = \sum_k\frac{∂C}{∂b_k^l}\frac{∂b_k^l}{∂z_j^l} δjl=∂zjl∂C=k∑∂bkl∂C∂zjl∂bkl因为
z j l = ∑ k w j k l a k l − 1 + b j l ⇒ b j l = z j l − ∑ k w j k l a k l − 1 z_j^l = \sum_kw_{jk}^la_k^{l-1} + b_j^l\ \ \ \ \ \Rightarrow \ \ \ \ \ b_j^l = z_j^l - \sum_kw_{jk}^la_k^{l-1} zjl=k∑wjklakl−1+bjl ⇒ bjl=zjl−k∑wjklakl−1当 k ≠ j k ≠ j k̸=j, ∂ b k l ∂ z j l \frac{∂b_k^l}{∂z_j^l} ∂zjl∂bkl 消失;当 k = j k = j k=j, ∂ b k l ∂ z j l = 1 \frac{∂b_k^l}{∂z_j^l} = 1 ∂zjl∂bkl=1 。
代入 δ j l δ_j^l δjl,得:
δ j l = ∂ C ∂ b j l δ_j^l = \frac{∂C}{∂b_j^l} δjl=∂bjl∂C
④ 代价函数关于任何⼀个权重的改变率
∂ C ∂ w j k l = a k l − 1 δ j l \frac{∂C}{∂w_{jk}^l} = a_k^{l-1}δ_j^l ∂wjkl∂C=akl−1δjl证明:
∂ C ∂ w j k l = ∑ i ∂ C ∂ z i l ∂ z i l ∂ w j k l \frac{∂C}{∂w_{jk}^l} = \sum_i\frac{∂C}{∂z_i^l}\frac{∂z_i^l}{∂w_{jk}^l} ∂wjkl∂C=i∑∂zil∂C∂wjkl∂zil因为
z i l = ∑ k w i k l a k l − 1 + b i l z_i^l = \sum_kw_{ik}^la_k^{l-1} + b_i^l zil=k∑wiklakl−1+bil当 i ≠ j i ≠ j i̸=j, ∂ z i l ∂ w j k l \frac{∂z_i^l}{∂w_{jk}^l} ∂wjkl∂zil 消失;当 i = j i = j i=j, ∂ z i l ∂ w j k l = a k l − 1 \frac{∂z_i^l}{∂w_{jk}^l} = a_k^{l-1} ∂wjkl∂zil=akl−1。再将 δ j l = ∂ C ∂ z j l δ_j^l = \frac{∂C}{∂z_j^l} δjl=∂zjl∂C代入得:
∂ C ∂ w j k l = a k l − 1 δ j l \frac{∂C}{∂w_{jk}^l} = a_k^{l-1}δ_j^l ∂wjkl∂C=akl−1δjl
算法1 (反向传播算法)
输入:输入层向量 x x x
输出:代价函数的梯度 ∂ C / ∂ w j k l ∂C/∂w_{jk}^l ∂C/∂wjkl 和 ∂ C / ∂ b j l ∂C/∂b_j^l ∂C/∂bjl
① 计算各层对应的激活值 a l a^l al
② 前向传播:对每个 l = 2 , 3 , . . . , L l = 2,3,...,L l=2,3,...,L 计算相应的 z l = w l a l − 1 + b l z^l = w^la^{l-1} + b^l zl=wlal−1+bl 和 a l = σ ( z l ) a^l = σ(z^l) al=σ(zl)
③ 输出层误差 δ L δ^L δL:计算向量 δ L = ∇ a C ⊙ σ ′ ( z L ) δ^L = ∇_aC ⊙ σ′(z^L) δL=∇aC⊙σ′(zL)
④ 反向误差传播:对每一个 l = L − 1 , L − 2 , . . . , 2 l = L-1,L-2,...,2 l=L−1,L−2,...,2,计算 δ l = ( ( w l + 1 ) T δ l + 1 ) ⊙ σ ′ ( z l ) δ^l = ((w^{l+1})^Tδ^{l+1}) ⊙ σ′(z^l) δl=((wl+1)Tδl+1)⊙σ′(zl)
⑤ 根据 ∂ C ∂ b j l = δ j l \frac{∂C}{∂b_j^l} = δ_j^l ∂bjl∂C=δjl 和 ∂ C ∂ w j k l = a k l − 1 δ j l \frac{∂C}{∂w_{jk}^l} = a_k^{l-1}δ_j^l ∂wjkl∂C=akl−1δjl 计算可得代价函数的梯度
增加训练样本的数量是⼀种减轻过度拟合的⽅法。另外的,本文要介绍的减轻过度拟合的方法为L1规范化和L2规范化。
L2规范化也叫权重衰减(weight decay)。L2 规范化的想法是增加⼀个额外的项到代价函数上,这个项叫做规范化项。下⾯是规范化的代价函数,其中 C 0 C_0 C0 是原始代价函数: C = C 0 + λ 2 n ∑ w w 2 C = C_0 + \frac{λ}{2n}\sum_ww^2 C=C0+2nλw∑w2 其中第⼀个项就是原始代价函数的表达式。第⼆个现在加⼊的就是所有权重的平⽅的和。然后使⽤⼀个因⼦ λ / 2 n λ/2n λ/2n 进⾏量化调整,其中 λ > 0 λ > 0 λ>0 可以称为规范化参数,⽽ n n n 就是训练集合的⼤⼩。
λ λ λ 越小,偏向于最小化原始代价函数,反之,倾向于小的权重。
L1规范化是在未规范化的代价函数上加上⼀个权重绝对值的和: C = C 0 + λ n ∑ w ∣ w ∣ C = C_0 + \frac{λ}{n}\sum_w|w| C=C0+nλw∑∣w∣
以上全部内容参考书籍如下:
Michael Nielsen《Neural Networks and Deep Learning》