文章目录
神经网络:学习(Netural NetWorks:Learning)
1.代价函数(Cost Function)
神经网络的多元分类:
神经网络的代价函数公式
J
(
Θ
)
=
−
1
m
∑
i
=
1
m
∑
k
=
1
K
[
y
k
(
i
)
l
o
g
(
h
θ
(
x
(
i
)
)
k
)
+
(
1
−
y
k
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
(
i
)
)
k
)
]
+
λ
2
m
∑
l
=
1
L
−
1
∑
i
=
1
s
l
∑
j
=
1
s
l
+
1
(
Θ
j
,
i
(
l
)
)
2
J{(\Theta)}=- \frac{1}{m}\displaystyle\sum_{i=1}^m\sum_{k=1}^K[y^{(i)}_klog(h_{\theta}(x^{(i)})_k)+(1-y^{(i)}_k)log(1-h_{\theta}(x^{(i)})_k)]+\frac{\lambda}{2m}\displaystyle\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_l+1}(\Theta_{j,i}^{(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∑slj=1∑sl+1(Θj,i(l))2
L L L:神经网络的总层数
K K K:输出层的分类数
y y y:K维向量
y k ( i ) y_k^{(i)} yk(i):第i个训练样本的第k个分量值
h Θ ( x ) k h_\Theta(x)_k hΘ(x)k:分为第k个分类的概率 P ( y = k ∣ x ; Θ ) P(y=k|x;\Theta) P(y=k∣x;Θ)
s l s_l sl:第 l l l层激活单元的数量
说明:
神经网络代价函数的前一部分与逻辑回归中的代价函数类似,区别是,神经网络这里讨论的时候K分类问题,即公式会对每个样本特征都运行K次,并依次给出分为第k类的概率,
h
θ
(
x
)
∈
R
,
y
∈
R
h_\theta(x)\in\Reals,y\in\Reals
hθ(x)∈R,y∈R
后一部分是正则化项,对每一层的多维权重矩阵
Θ
(
l
)
∈
R
(
s
l
+
1
)
∗
s
l
+
1
\Theta^{(l)}\in\Reals^{(s_l+1)*s_{l+1}}
Θ(l)∈R(sl+1)∗sl+1平方后,去除偏置权重的部分,然后进行循环累加。
神经网络求代价函数的方法和逻辑回归是一样的,但是计算复杂,神经网络的代价函数其实是非凸函数,有局部最小值。不能用梯度下降算法求解代价函数的最小值。
- the double sum simply adds up the logistic regression costs calculated for each cell in the output layer
- the triple sum simply adds up the squares of all the individual Θs in the entire network.
- the i in the triple sum does not refer to training example i
2.反向传播算法(Backpropagation Algorithm)
为求解神经网络最优化的问题,需要计算
∂
∂
θ
J
(
Θ
)
\frac{\partial}{\partial\theta}J(\Theta)
∂θ∂J(Θ),求最优解。
在神经网络中
h
θ
(
x
)
h_\theta(x)
hθ(x)是前向传播算法得到的,需要从输入层开始,根据每层的权重矩阵
Θ
\Theta
Θ义词计算激活单元的值a,然后用a与权重矩阵
Θ
\Theta
Θ再去计算下一层的激活单元的值。
在优化代价函数的时候,我们其实是在优化每一层的权重矩阵,算法优化的是权重。
反向传播算法的具体过程如下
反向传播算法其实是计算每一层权重矩阵的偏导
∂
∂
θ
J
(
Θ
)
\frac{\partial}{\partial\theta}J(\Theta)
∂θ∂J(Θ),算法实际上是对代价函数求导的拆解。
-
对于给定训练集 ( x ( 1 ) , y ( 1 ) ) . . . ( x ( m ) , y ( m ) ) {(x^{(1)},y^{(1)})...(x^{(m)},y^{(m)})} (x(1),y(1))...(x(m),y(m)) ,初始化每层间的误差和矩阵 Δ \Delta Δ,即令所有的 Δ i , j ( l ) = 0 \Delta_{i,j}^{(l)}=0 Δi,j(l)=0 ,使得每个 Δ ( l ) \Delta^{(l)} Δ(l)为一个全零矩阵。
-
接下来遍历所有的样本实例,对于每一个样本实例有:
1.运行前向传播算法,得到初始预测 a ( L ) = h θ ( x ) a^{(L)}=h_\theta(x) a(L)=hθ(x)
2.运行反向传播算法,从输出层从后往前计算每一层的计算误差 δ ( l ) \delta^{(l)} δ(l),以此来求取偏导。
输出层的误差即为预测与训练集结果之间的差值:
δ
(
l
)
=
a
(
l
)
−
y
\delta^{(l)}=a^{(l)}-y
δ(l)=a(l)−y,
对于隐藏层中的每一层的误差,都由上一层的误差与对应的参数矩阵来计算:
δ
(
l
)
=
(
Θ
(
l
)
)
T
δ
(
l
+
1
)
.
∗
∂
a
(
l
)
∂
z
(
l
)
f
o
r
l
:
=
L
−
1
,
L
−
2
,
.
.
.
2
\delta^{(l)}= (\Theta^{(l)})^T\delta^{(l+1)}.*\frac{\partial a^{(l)}}{\partial z^{(l)}}\quad for \quad l:=L-1,L-2,...2
δ(l)=(Θ(l))Tδ(l+1).∗∂z(l)∂a(l)forl:=L−1,L−2,...2
隐藏层中,
a
(
l
)
a^{(l)}
a(l)即为增加偏置单元后的
g
(
z
(
l
)
)
g(z^{(l)})
g(z(l)) ,
a
(
l
)
a^{(l)}
a(l)与
Θ
(
l
)
\Theta^{(l)}
Θ(l)维度匹配,得以完成矩阵运算。
对于隐藏层,有
a
(
l
)
=
g
(
z
(
l
)
)
a^{(l)}=g(z^{(l)})
a(l)=g(z(l))添加偏置单元
a
0
(
l
)
=
1
a_0^{(l)}=1
a0(l)=1
解得:
∂
∂
z
(
l
)
g
(
z
(
l
)
)
=
g
′
(
z
(
l
)
)
=
g
(
z
(
l
)
)
.
∗
(
1
−
g
(
z
(
l
)
)
)
\frac{\partial }{\partial z^{(l)}}g(z^{(l)})=g'(z^{(l)})=g(z^{(l)}).*(1-g(z^{(l)}))
∂z(l)∂g(z(l))=g′(z(l))=g(z(l)).∗(1−g(z(l))),
则有
δ
(
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))
根据上面的公式可以计算
δ
(
L
)
,
δ
(
L
−
1
)
,
.
.
.
,
δ
(
2
)
\delta^{(L)},\delta^{(L-1)},...,\delta^{(2)}
δ(L),δ(L−1),...,δ(2)
3.依次求解并累加误差
Δ
i
,
j
(
l
)
:
=
Δ
i
,
j
(
l
)
+
a
j
(
l
)
δ
i
(
l
+
1
)
\Delta_{i,j}^{(l)}:=\Delta_{i,j}^{(l)}+a_j^{(l)}\delta_i^{(l+1)}
Δi,j(l):=Δi,j(l)+aj(l)δi(l+1),
向量化实现即:
Δ
(
l
)
:
=
Δ
(
l
)
+
δ
(
l
+
1
)
(
a
j
(
l
)
)
T
\Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a_j^{(l)})^T
Δ(l):=Δ(l)+δ(l+1)(aj(l))T
3.遍历全部样本实例,求解完 Δ \Delta Δ后,最后求得偏导: ∂ ∂ θ ( i , j ) ( l ) J ( Θ ) = D i , j ( l ) \frac{\partial}{\partial \theta_{(i,j)}^{(l)}}J(\Theta)=D_{i,j}^{(l)} ∂θ(i,j)(l)∂J(Θ)=Di,j(l)
- D i , j ( l ) = 1 m ( Δ i , j ( l ) + λ Θ i , j ( l ) ) , i f j ! = 0 D_{i,j}^{(l)}=\frac{1}{m}(\Delta_{i,j}^{(l)}+\lambda\Theta_{i,j}^{(l)}),\quad if j!= 0 Di,j(l)=m1(Δi,j(l)+λΘi,j(l)),ifj!=0
- D i , j ( l ) = 1 m Δ i , j ( l ) , i f j = 0 D_{i,j}^{(l)}=\frac{1}{m}\Delta_{i,j}^{(l)},\quad if j= 0 Di,j(l)=m1Δi,j(l),ifj=0
δ ( l ) \delta^{(l)} δ(l) : 第 l l l层的误差向量
δ i ( l ) \delta^{(l)}_i δi(l): 第 l l l层的第 i i i个激活单元的误差
Δ i , j ( l ) \Delta_{i,j}^{(l)} Δi,j(l): 从第 l l l层的第 j j j个单元映射到第 l + 1 l+1 l+1层的第 i i i个单元的权重代价的偏导(所有样本实例之和)
D i , j ( l ) D_{i,j}^{(l)} Di,j(l): Δ i , j ( l ) \Delta_{i,j}^{(l)} Δi,j(l)的样本均值与正则化项之和
这就是反向传播算法,即从输出层开始不断向前迭代,根据上一层的误差依次计算当前层的误差,以求得代价函数的偏导。
应用反向传播(BP)算法的神经网络被称为 BP 网络,也称前馈网络(向前反馈)。
神经网络中代价函数求导的推导过程,见参考1。
3.实现注意点: 参数展开(Implementation Note: Unrolling Parameters)
在 Octave/Matlab 中,如果要使用类似于 f m i n u n c fminunc fminunc 等高级最优化函数,其函数参数、函数返回值等都为且只为向量,而由于神经网络中的权重是多维矩阵,所以需要用到参数展开这个技巧。
这个技巧就是把多个矩阵转换为一个长长的向量,便于传入函数,之后再根据矩阵维度,转回矩阵即可。
Octave/Matlab 代码:
% 多个矩阵展开为一个向量
Theta1 = ones(11, 10); % 创建维度为 11 * 10 的矩阵
Theta2 = ones(2, 4) * 2; % 创建维度为 2 * 4 的矩阵
ThetaVec = [Theta1(:); Theta2(:)]; % 将上面两个矩阵展开为向量
% 从一个向量重构还原回多个矩阵
Theta1 = reshape(ThetaVec(1:110), 11, 10)
Theta2 = reshape(ThetaVec(111:118), 2, 4)
% Theta2 = reshape(ThetaVec(111:(111 + 2 * 4) - 1), 2, 4)
reshape(A,m,n): 将向量 A 重构为 m * n 维矩阵。
4.梯度检验(Gradient Checking)
由于神经网络模型中的反向传播算法较为复杂,在小细节非常容易出错,从而无法得到最优解,故引入梯度检验。
梯度检验采用数值估算(Numerical estimation)梯度的方法,被用于验证反向传播算法的正确性。
视
Θ
\Theta
Θ为一个实数,数值估算梯度的原理如上图所示,即有
∂
∂
Θ
J
(
Θ
)
≈
J
(
Θ
+
ϵ
)
−
J
(
Θ
−
ϵ
)
2
ϵ
\frac{\partial}{\partial\Theta}J(\Theta)\approx\frac{J(\Theta+\epsilon)-J(\Theta-\epsilon)}{2\epsilon}
∂Θ∂J(Θ)≈2ϵJ(Θ+ϵ)−J(Θ−ϵ)
其中,
ϵ
\epsilon
ϵ为极小值,由于太小时容易出现数值运算问题,一般取
1
0
−
4
10^{-4}
10−4 。
对于矩阵
Θ
\Theta
Θ,有
∂
∂
Θ
j
J
(
Θ
)
≈
J
(
Θ
1
+
,
.
.
.
,
Θ
j
+
ϵ
+
.
.
.
Θ
n
)
−
J
(
Θ
1
+
,
.
.
.
,
Θ
j
−
ϵ
+
.
.
.
Θ
n
)
2
ϵ
\frac{\partial}{\partial\Theta_j}J(\Theta)\approx\frac{J(\Theta_1+,...,\Theta_{ j + \epsilon}+...\Theta_n)-J(\Theta_1+,...,\Theta_{ j - \epsilon}+...\Theta_n)}{2\epsilon}
∂Θj∂J(Θ)≈2ϵJ(Θ1+,...,Θj+ϵ+...Θn)−J(Θ1+,...,Θj−ϵ+...Θn)
Octave/Matlab 代码:
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 梯度向量后,将其同之前计算的偏导 D D D比较,如果相等或很接近,即说明算法没有问题。
在确认算法没有问题后(一般只需运行一次),由于数值估计的梯度检验效率很低,所以一定要禁用它。
5.随机初始化(Random Initialization)
逻辑回归中,初始参数向量全为 0 没什么问题,在神经网络中,情况就不一样了。
初始权重如果全为 0,忆及 z ( l ) = Θ ( l − 1 ) a ( l − 1 ) z^{(l)}=\Theta^{(l-1)}a^{(l-1)} z(l)=Θ(l−1)a(l−1) ,则隐藏层除了偏置单元,都为 0,而每个单元求导的值也都一样,这就相当于是在不断重复计算同一结果,也就是算着算着,一堆特征在每一层都变成只有一个特征(虽然有很多单元,但值都相等),这样,神经网络的性能和效果都会大打折扣,故需要随机初始化初始权重。
随机初始化权重矩阵也为实现细节之一,用于打破对称性(Symmetry Breaking),使得 Θ i j ( l ) ∈ [ − ϵ , ϵ ] \Theta^{(l)}_{ij}\in[-\epsilon,\epsilon] Θij(l)∈[−ϵ,ϵ] 。当然,初始权重的波动也不能太大,一般限定在极小值 ϵ \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(m,n): 返回一个在区间 (0,1) 内均匀分布的随机矩阵。
ϵ : \epsilon: ϵ:和梯度下降中的 ϵ \epsilon ϵ没有联系,这里只是一个任意实数,给定了权重矩阵初始化值的范围。
6.综合起来(Putting It Together)
一般来说,应用神经网络有如下步骤:
- 神经网络的建模(后续补充)
.选取特征,确定特征向量 x x x的维度,输入单元的数量
.鉴别分类,确定预测向量的维度,输出单元的数量
.确定隐藏层的数量,以及每层有多少个激活单元
默认情况下,隐藏层至少要有一层,也可以有多层,层数越多一般意味着效果越好,计算量越大。
- 训练神经网络
- 随机初始化初始权重矩阵
- 应用前向传播算法计算初始预测
- 计算代价函数 J ( Θ ) J(\Theta) J(Θ)的值
- 使用后向传播算法计算 J ( Θ ) J(\Theta) J(Θ)的偏导数
- 使用梯度检测算法检查算法的正确性,用完禁用
- 让最优化函数最小化代价函数
由于神经网络的代价函数非凸,最优化时不一定会收敛在全局最小值处,高级最优化函数能确保收敛在某个局部最小值处。