代价函数
定义变量
- L是神经网络的总层数
- s l s_l sl为第 l l l层的单元数量(不包括偏置单元)
- K为输出层的单元数量/分类类型数量
表示式子
神经网络的代价函数是正则化逻辑回归的代价函数的概括:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
∑
k
=
1
K
[
y
k
(
i
)
log
(
h
θ
(
x
(
i
)
)
k
)
+
(
1
−
y
k
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
k
)
]
+
λ
2
m
∑
l
=
1
L
−
1
∑
i
=
1
s
l
+
1
∑
j
=
1
s
l
(
Θ
i
,
j
(
l
)
)
2
J(\theta) = -\frac{1}{m} \sum_{i=1}^m \sum_{k=1}^K[y^{(i)}_k\log(h_\theta(x^{(i)})_k) + (1-y^{(i)}_k)\log(1-h_\theta(x^{(i)})_k) ] + \frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_{l+1}}\sum_{j=1}^{s_l}(\Theta_{i,j}^{(l)})^2
J(θ)=−m1i=1∑mk=1∑K[yk(i)log(hθ(x(i))k)+(1−yk(i))log(1−hθ(x(i))k)]+2mλl=1∑L−1i=1∑sl+1j=1∑sl(Θi,j(l))2
其中,
h
θ
(
x
(
i
)
)
k
h_\theta(x^{(i)})_k
hθ(x(i))k表示第
k
k
k种类型的分类结果(概率),与样本中
y
k
(
i
)
y^{(i)}_k
yk(i)表示的第
k
k
k种类型的实际结果相对应。
反向传播(重点)
“反向传播”是用于最小化我们的代价函数的神经网络术语,就像我们在逻辑和线性回归中使用梯度下降一样。 我们的目标是计算 m i n Θ J ( Θ ) min_\Theta J(\Theta) minΘJ(Θ),也即计算得到能使代价函数最小的模型参数。
代价函数的偏导数
为了求 ∂ ∂ Θ i , j ( l ) J ( Θ ) \frac{\partial}{\partial\Theta^{(l)}_{i,j}}J(\Theta) ∂Θi,j(l)∂J(Θ),执行以下步骤:
- 获取训练集 { ( x ( 1 ) , y ( 1 ) ) … ( x ( m ) , y ( m ) ) } \{ (x^{(1)},y{(1)}) \dots (x^{(m)},y{(m)})\} {(x(1),y(1))…(x(m),y(m))},并设 Δ i , j ( l ) : = 0 \Delta^{(l)}_{i,j}:=0 Δi,j(l):=0(也即得到一个元素均为零的矩阵)
- 训练样本
t
=
1
t
o
m
t = 1\quad to\quad m
t=1tom,依次执行下列步骤:
2.1 设 a ( 1 ) : = x ( t ) a^{(1)}:=x^{(t)} a(1):=x(t)
2.2 通过向前传播算法计算 a ( l ) ( f o r l = 2 , 3 , … , L ) a^{(l)}\quad (for\quad l=2,3,\dots,L) a(l)(forl=2,3,…,L)
2.3 通过样本中的实际分类结果 y ( t ) y^{(t)} y(t),计算 δ ( L ) = a ( L ) − y ( t ) \delta(L)=a^{(L)}-y^{(t)} δ(L)=a(L)−y(t),其中, a ( L ) a^{(L)} a(L)也即输出层的输出结果(分类结果向量),该式实际为实际分类结果与向前传播计算得到的 a ( L ) a^{(L)} a(L)的差值。
2.4 计算 δ ( L − 1 ) , δ ( L − 1 ) , … , δ ( 2 ) \delta^{(L-1)},\delta^{(L-1)},\dots,\delta^{(2)} δ(L−1),δ(L−1),…,δ(2), δ ( 1 ) \delta^{(1)} δ(1)表示第一层输入层的误差:(第一层为训练样本中的输入特征,肯定没有误差,所以不用计算)
δ ( l ) = ( ( Θ ( l ) ) T δ ( l + 1 ) ) . ∗ a ( l ) . ∗ ( 1 − a ( l ) ) \delta^{(l)} = ((\Theta^{(l)})^T\delta^{(l+1)}).*a^{(l)}.*(1-a^{(l)}) δ(l)=((Θ(l))Tδ(l+1)).∗a(l).∗(1−a(l))
2.5 Δ i , j ( l ) : = Δ i , j ( l ) + a j ( l ) δ i ( l + 1 ) \Delta^{(l)}_{i,j}:=\Delta^{(l)}_{i,j}+a_j^{(l)}\delta_i^{(l+1)} Δi,j(l):=Δi,j(l)+aj(l)δi(l+1),或者用向量法: Δ ( l ) : = Δ ( l ) + δ i ( l + 1 ) ( a j ( l ) ) T \Delta^{(l)}:=\Delta^{(l)}+\delta_i^{(l+1)}(a_j^{(l)})^T Δ(l):=Δ(l)+δi(l+1)(aj(l))T
因此,上述步骤2.1-2.5可以不断更新矩阵 Δ \Delta Δ。
最终得到偏导数 ∂ ∂ Θ i , j ( l ) J ( Θ ) = D i , j ( l ) \frac{\partial}{\partial\Theta^{(l)}_{i,j}}J(\Theta)=D_{i,j}^{(l)} ∂Θi,j(l)∂J(Θ)=Di,j(l):
{ D i , j ( l ) = 1 m Δ i , j ( l ) if j = 0 D i , j ( l ) = 1 m ( Δ i , j ( l ) + λ Θ i , j ( l ) ) if j ≠ 0 \begin{cases} D_{i,j}^{(l)}=\frac{1}{m}\Delta^{(l)}_{i,j} &\text{if } j = 0 \\ D_{i,j}^{(l)}=\frac{1}{m}(\Delta^{(l)}_{i,j}+\lambda\Theta_{i,j}^{(l)}) &\text{if } j \ne 0 \end{cases} {Di,j(l)=m1Δi,j(l)Di,j(l)=m1(Δi,j(l)+λΘi,j(l))if j=0if j̸=0
原理剖析
关于
δ
j
(
l
)
\delta^{(l)}_j
δj(l)的计算。
J
(
θ
)
=
−
1
m
∑
t
=
1
m
∑
k
=
1
K
[
y
k
(
t
)
log
(
h
θ
(
x
(
t
)
)
k
)
+
(
1
−
y
k
(
t
)
)
log
(
1
−
h
θ
(
x
(
t
)
)
k
)
]
+
λ
2
m
∑
l
=
1
L
−
1
∑
i
=
1
s
l
+
1
∑
j
=
1
s
l
(
Θ
i
,
j
(
l
)
)
2
J(\theta) = -\frac{1}{m} \sum_{t=1}^m \sum_{k=1}^K[y^{(t)}_k\log(h_\theta(x^{(t)})_k) + (1-y^{(t)}_k)\log(1-h_\theta(x^{(t)})_k) ] + \frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_{l+1}}\sum_{j=1}^{s_l}(\Theta_{i,j}^{(l)})^2
J(θ)=−m1t=1∑mk=1∑K[yk(t)log(hθ(x(t))k)+(1−yk(t))log(1−hθ(x(t))k)]+2mλl=1∑L−1i=1∑sl+1j=1∑sl(Θi,j(l))2
令K=1,并忽略惩罚项,有:
c
o
s
t
(
t
)
=
y
k
(
t
)
log
(
h
θ
(
x
(
t
)
)
k
)
+
(
1
−
y
k
(
t
)
)
log
(
1
−
h
θ
(
x
(
t
)
)
k
)
cost(t)=y^{(t)}_k\log(h_\theta(x^{(t)})_k) + (1-y^{(t)}_k)\log(1-h_\theta(x^{(t)})_k)
cost(t)=yk(t)log(hθ(x(t))k)+(1−yk(t))log(1−hθ(x(t))k)
则,
δ
j
(
l
)
=
∂
∂
z
j
(
l
)
c
o
s
t
(
t
)
\delta^{(l)}_j=\frac{\partial}{\partial z^{(l)}_j}cost(t)
δj(l)=∂zj(l)∂cost(t)。
从上图可知,反向传播计算时,有
δ
2
(
2
)
=
Θ
1
,
2
(
2
)
∗
δ
1
(
3
)
+
Θ
2
,
2
(
2
)
∗
δ
2
(
3
)
\delta^{(2)}_2=\Theta_{1,2}^{(2)}*\delta^{(3)}_1+\Theta_{2,2}^{(2)}*\delta^{(3)}_2
δ2(2)=Θ1,2(2)∗δ1(3)+Θ2,2(2)∗δ2(3)和
δ
3
(
2
)
=
Θ
1
,
2
(
2
)
∗
δ
1
(
4
)
\delta^{(2)}_3=\Theta_{1,2}^{(2)}*\delta^{(4)}_1
δ3(2)=Θ1,2(2)∗δ1(4)
实操经验
多矩阵
在神经网络算法中,可能出现如下矩阵:
Θ
(
1
)
,
Θ
(
2
)
,
Θ
(
3
)
,
…
D
(
1
)
,
D
(
2
)
,
D
(
3
)
,
…
\Theta^{(1)},\Theta^{(2)},\Theta^{(3)},\dots \\ D^{(1)},D^{(2)},D^{(3)},\dots
Θ(1),Θ(2),Θ(3),…D(1),D(2),D(3),…
但是,如果我们才使用高级的优化算法,比如:fminunc(),那就需要把矩阵摊开成一个向量:
thetaVector = [Theta1(:); Theta2(:); Theta3(:)]; \\
deltaVector = [D1(:); D2(:); D3(:)];
如果矩阵Theta1的尺寸为1011,矩阵Theta2的尺寸为1011,矩阵Theta3的尺寸为1*11,我们可以通过以下步骤重获矩阵:
Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)
- 总结:
- 初始化模型参数: Θ ( 1 ) , Θ ( 2 ) , Θ ( 3 ) , … \Theta^{(1)},\Theta^{(2)},\Theta^{(3)},\dots Θ(1),Θ(2),Θ(3),…
- 将模型参数矩阵摊开为initialTheta,传到高级优化算法fminunc(@costFunction, initialTheta, options)
- 在function [jval,gradientVec] costFunction(thetaVec)中,先从thetaVec获取模型参数,然后计算 D ( 1 ) , D ( 2 ) , D ( 3 ) , … D^{(1)},D^{(2)},D^{(3)},\dots D(1),D(2),D(3),…,以及 J ( Θ ) J(\Theta) J(Θ),最后展开 D ( 1 ) , D ( 2 ) , D ( 3 ) , … D^{(1)},D^{(2)},D^{(3)},\dots D(1),D(2),D(3),…得到gradientVec。
梯度检查
为了检查反向传播算法工作符合预期,将代价函数的偏导数近似于:
α
α
Θ
J
(
Θ
)
≈
J
(
Θ
+
ϵ
)
−
J
(
Θ
−
ϵ
)
2
ϵ
\frac{\alpha}{\alpha\Theta} J(\Theta) \approx \frac{J(\Theta+\epsilon)-J(\Theta-\epsilon)}{2\epsilon}
αΘαJ(Θ)≈2ϵJ(Θ+ϵ)−J(Θ−ϵ)
对于多个模型参数矩阵,我们对于
Θ
j
\Theta_j
Θj的偏导数近似有:
α
α
Θ
j
J
(
Θ
)
≈
J
(
Θ
1
,
…
,
Θ
+
ϵ
,
…
,
Θ
n
)
−
J
(
Θ
1
,
…
,
Θ
−
ϵ
,
…
,
Θ
n
)
2
ϵ
\frac{\alpha}{\alpha\Theta_j} J(\Theta) \approx \frac{J(\Theta_1,\dots,\Theta+\epsilon,\dots,\Theta_n)-J(\Theta_1,\dots,\Theta-\epsilon,\dots,\Theta_n)}{2\epsilon}
αΘjαJ(Θ)≈2ϵJ(Θ1,…,Θ+ϵ,…,Θn)−J(Θ1,…,Θ−ϵ,…,Θn)
其中,
ϵ
\epsilon
ϵ的值取得较小,例如
1
0
−
4
10^{-4}
10−4,但是太小可能会遇到数值问题,也即电脑可能无法计算这么小的数值,或者计算时取小数点后四位而忽略了四位后的位数,造成计算错误。
在octave中,代码如下:
epsilon = 1e-4;
for i = 1:n,
thetaPlus = theta;
thetaPlus(i) += epsilon;
thetaMinus = theta;
thetaMinus(i) -= epsilon;
gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
end;
我们在计算得到gradApprox后,就可以将其与deltaVector( D ( 1 ) , D ( 2 ) , D ( 3 ) , … D^{(1)},D^{(2)},D^{(3)},\dots D(1),D(2),D(3),…)比较,检查两者之间是否近似。
PS:一旦验证了反向传播算法是正确的,则无需在下次迭代时继续计算gradApprox,因为gradApprox的计算效率低。
随机初始化
将神经网络的权重(模型参数)全都初始为零(或者满足对称性,比如
Θ
(
1
)
\Theta^{(1)}
Θ(1)全初始为零,
Θ
(
2
)
\Theta^{(2)}
Θ(2)全初始为1)的话,会使反向传播时,所有节点将重复更新为相同的值。因此,我们可以使用以下方法随机初始化权重:
在
[
−
ϵ
,
ϵ
]
[-\epsilon,\epsilon]
[−ϵ,ϵ]的范围内随机初始化权重,具体为:
If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.
Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
其中,rand函数的作用是在0到1之间进行初始化。
PS:上式中的
ϵ
\epsilon
ϵ与梯度检查中的
ϵ
\epsilon
ϵ无关。
总结
- 选择网络架构;选择神经网络的布局(每层有多少隐藏单元,以及总共需要有多少层)
- 输入层的单元数量等于输入特征的种数 ( x 0 , x 1 , …   ) (x_0,x_1,\dots) (x0,x1,…)
- 输出层的单元数量等于输出特征的种数(分类的类数)
- 隐藏层的单元数量越多越好(平衡计算成本)
- 如果有多个隐藏层,建议每个隐藏层的单元数量相等
- 训练神经网络
2.1 随机初始化权重
2.2 向前传播计算所有样本 x ( i ) x^{(i)} x(i)的输出 h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i))。
2.3 计算代价函数
2.4 通过反向传播计算代价函数的偏导数
2.5 使用梯度检查确认反向传播是否有效工作,然后去掉梯度检查步骤
2.6 使用梯度下降或者更高级的优化算法求得使代价函数最小化的权重(模型参数)
- 在向前和向后传播时,我们分别对个训练样本进行操作:
for i = 1:m,
Perform forward propagation and backpropagation using example (x(i),y(i))
(Get activations a(l) and delta terms d(l) for l = 2,...,L