首先介绍一个学习DL4NLP的一个网站WildML,英文的,有空我也整理一下中文版。
这篇讲的是神经网络的基础,没有RNN、CNN等结构。废话少说,直接上要推导的一个简单的神经网络结构图。
例子:三层神经网络
这个神经网络包含一个输入层、一个隐含层和一个输出层。
注意输出的神经元有两个(多个),这个经常用在一个二(多)分类任务上,代表着每一类的概率,相应的激活函数变成了softmax函数(相当于多分类逻辑回归)。当然,如果用在其他任务上,输出结点的值含义可能不同,取值范围也可能不同。
softmax函数
σ(z)j=ezj∑Kk=1ezk
导数:
∂σ(z)j∂zi={σ(z)j(1−σ(z)j)−σ(z)iσ(z)ji=ji≠j
激活函数
常用的激活函数有tanh、sigmoid和ReLU。激活函数是一个学问,需要单独整理一块。
下面简单叙述一下各个函数的表达式:
tanh
tanh(x)=1−e−2x1+e−2x
sigmoid
sigmoid(x)=11+e−x
ReLU
y={x0if x ≥ 0if x < 0
前向传播公式
例子使用tanh激活函数,最后用softmax函数生成分布。
z2=xθ(1)
a2=tanh(z2)
z3=a2θ(2)
a3=ŷ =softmax(z3)
损失函数
这里使用cross entropy作为损失函数,表达式为:
J(θ)=CrossEntropy(y,ŷ )=−1N∑n∈N∑i∈Cyn,ilogŷ n,i
其中N是样本数量,C是类别集合。
反向传播中的梯度求解
这里定义第l层第i个单元的计算误差:
δ(l)i=∂J∂z(l)i
其中z(l)i代表第l层的第i个神经元的输入值。
我们的目标是要求参数的所有参数的梯度,即∂J∂θ
这里推导通用的情况。
我们对θ(l)i,j求导(l<L):
∂J∂θ(l)i,j=∂J∂z(l+1)i⋅∂z(l+1)i∂θ(l)i,j=∂J∂a(l+1)i⋅∂a(l+1)i∂z(l+1)i⋅∂z(l+1)i∂θ(l)i,j=∑k=1S(l+2)δ(l+2)kθ(l+1)k,i⋅g′(z(l+1)i)⋅a(l)i
根据δ的定义:
δ(l+1)i=∂J∂z(l+1)i=∑k=1Sl+2∂J∂z(l+2)k⋅∂z(l+2)k∂a(l+1)i⋅∂a(l+1)i∂z(l+1)i=∑k=1S(l+2δ(l+2)lθ(l+1)k,i⋅g′(z(l+1)i)
这里的
θ和
a都是已知变量,为当前迭代的参数和输出。
表达为矩阵形式,δl+1指第l+1层的所有单元的计算误差,则 δ(l+1)i是其第i个元素:
δ(l+1)=(θ(l+1))Tδ(l+2).∗g′(z(l+1))
注意.*为矩阵对应元素之间两两相乘。
这样就可以反向传播求所有神经元的计算误差。
最后,
∂J∂θl=δ(l+1)(a(l))T
代入例子中计算梯度
计算第三层第i单元的计算误差δ(3)i:
δ(3)i=∂J∂z(3)i=−∑k∈Cyk∂logŷ ∂z(3)i=−∑k∈Cyk1ŷ ∂ŷ ∂z(3)i=−yi1ŷ ŷ (1−ŷ )−∑k∈Candk¬iyk1ŷ (−ŷ kŷ i)=−yi(1−ŷ )+∑k∈Candk¬iykŷ i=ŷ i(∑k∈Cyk)−yi=ŷ i−yi
*第三层的所有计算误差用δ3表示。
计算δ2:
δ2=(θ(2))Tδ(3).∗g′(z(2))=(θ(2))Tδ(3).∗(1−tanh2z(2))
计算关于θ(2)的偏导:
∂J∂θ(2)=δ(3)(a(2))T
计算关于θ(1)的偏导:
∂J∂θ(1)=δ(2)(a(1))T=δ(2)(x)T
到此,所有的θ都已经可以求出来,最后代入梯度下降公式更新参数:
θ:=θ−λ∂J∂θ
参考资料:
http://www.wildml.com/2015/09/implementing-a-neural-network-from-scratch/