神经网络模型存在训练集:
{(x(1),y(1)),(x(2),y(2)),⋯,(x(m),y(m))}
{
(
x
(
1
)
,
y
(
1
)
)
,
(
x
(
2
)
,
y
(
2
)
)
,
⋯
,
(
x
(
m
)
,
y
(
m
)
)
}
常用的符号表示:
- L L :神经网络的层数;
- :第 l l 层的单元数(不包含偏置单元);
- :输出单元的数量。
神经网络有两种分类:
- 二元分类
y=0 y = 0 或 1 1 ,只有1个输出单元,是一个实数,即 SL=1 S L = 1 - 多类别分类(
K
K
个不同类)
个输出单元, hΘ(x) h Θ ( x ) 是一个 K K 维向量,即
神经网络的代价函数:
hΘ(x)∈Rk
h
Θ
(
x
)
∈
R
k
,
(hΘ(x))i
(
h
Θ
(
x
)
)
i
为第
i
i
个输出
当前
Θ
Θ
矩阵的列数等于当前层的单元数(包括偏置单元),当前
Θ
Θ
矩阵的行数等于下一层的单元数(不包括偏置单元)。
上式中的双重求和将输出层的每个单元的逻辑回归代价相加,三重求和将整个网络中的所有
Θ
Θ
的平方相加
反向传播算法:让代价函数最小化的算法。
最小化
J(Θ)
J
(
Θ
)
,我们需要计算
J(Θ)
J
(
Θ
)
,
∂∂Θ(l)ijJ(Θ)
∂
∂
Θ
i
j
(
l
)
J
(
Θ
)
。
如上图所示神经网络,当只有1个训练样本
(x,y)
(
x
,
y
)
时:
前向传播算法:
⇒a(1)=x
⇒
a
(
1
)
=
x
⇒Z(2)=Θ(1)a(1)
⇒
Z
(
2
)
=
Θ
(
1
)
a
(
1
)
⇒a(2)=g(Z(2))(add a(2)0)
⇒
a
(
2
)
=
g
(
Z
(
2
)
)
(
a
d
d
a
0
(
2
)
)
⇒Z(3)=Θ(2)a(2)
⇒
Z
(
3
)
=
Θ
(
2
)
a
(
2
)
⇒a(3)=g(Z(3))(add a(3)0)
⇒
a
(
3
)
=
g
(
Z
(
3
)
)
(
a
d
d
a
0
(
3
)
)
⇒Z(4)=Θ(3)a(3)
⇒
Z
(
4
)
=
Θ
(
3
)
a
(
3
)
⇒a(4)=hΘ(x)=g(Z(4))
⇒
a
(
4
)
=
h
Θ
(
x
)
=
g
(
Z
(
4
)
)
反向传播算法:
δ(l)j
δ
j
(
l
)
:
l
l
层第个单元的误差
以上图为例:
⇒δ(4)j=a(4)j−yj
⇒
δ
j
(
4
)
=
a
j
(
4
)
−
y
j
注:此处
a(4)j
a
j
(
4
)
等同于
(hΘ(x))j
(
h
Θ
(
x
)
)
j
,
yj
y
j
即输出向量的第
j
j
个元素值
将上式向量化:
⇒δ(3)=(Θ(3))Tδ(4).∗g′(Z(3))g′(Z(3))
⇒
δ
(
3
)
=
(
Θ
(
3
)
)
T
δ
(
4
)
.
∗
g
′
(
Z
(
3
)
)
g
′
(
Z
(
3
)
)
为
g(Z(3))
g
(
Z
(
3
)
)
的导数且
g′(Z(3))=a(3).∗(1−a(3))
g
′
(
Z
(
3
)
)
=
a
(
3
)
.
∗
(
1
−
a
(
3
)
)
⇒δ(2)=(Θ(2))Tδ(3).∗g′(Z(2))g′(Z(2))
⇒
δ
(
2
)
=
(
Θ
(
2
)
)
T
δ
(
3
)
.
∗
g
′
(
Z
(
2
)
)
g
′
(
Z
(
2
)
)
为
g(Z(2))
g
(
Z
(
2
)
)
的导数且
g′(Z(2))=a(2).∗(1−a(2))
g
′
(
Z
(
2
)
)
=
a
(
2
)
.
∗
(
1
−
a
(
2
)
)
⇒∂∂Θ(l)ijJ(Θ)=a(l)jδ(l+1)i
⇒
∂
∂
Θ
i
j
(
l
)
J
(
Θ
)
=
a
j
(
l
)
δ
i
(
l
+
1
)
(忽略
λ
λ
正则化项)
当有
m
m
个训练样本时:
设
Δ(l)ij=0(for all l,i,j)
Δ
i
j
(
l
)
=
0
(
f
o
r
a
l
l
l
,
i
,
j
)
(注:
Δ
Δ
是
δ
δ
的大写)
⇒fori=1tom:
⇒
f
o
r
i
=
1
t
o
m
:
⇒
⇒
设
a(1)=x(i)
a
(
1
)
=
x
(
i
)
⇒
⇒
利用前向传播算法计算
a(l)(for l=2,3⋯L)
a
(
l
)
(
f
o
r
l
=
2
,
3
⋯
L
)
⇒
⇒
用
y(i)
y
(
i
)
,计算
δ(L)=a(L)−y(i)
δ
(
L
)
=
a
(
L
)
−
y
(
i
)
⇒
⇒
计算
δ(L−1),δ(L−2),⋯,δ(2)
δ
(
L
−
1
)
,
δ
(
L
−
2
)
,
⋯
,
δ
(
2
)
(注:
δ(l)=((Θ(l))Tδ(l+1)).∗a(l).∗(1−a(l))
δ
(
l
)
=
(
(
Θ
(
l
)
)
T
δ
(
l
+
1
)
)
.
∗
a
(
l
)
.
∗
(
1
−
a
(
l
)
)
)
⇒Δ(l)ij:=Δ(l)ij+a(l)jδ(l+1)
⇒
Δ
i
j
(
l
)
:=
Δ
i
j
(
l
)
+
a
j
(
l
)
δ
(
l
+
1
)
向量化该式:
Δ(l):=Δ(l)+δ(l+1)(a(l))T
Δ
(
l
)
:=
Δ
(
l
)
+
δ
(
l
+
1
)
(
a
(
l
)
)
T
(注:此处应去掉
δ(l+1)0
δ
0
(
l
+
1
)
)
⇒
⇒
(跳出循环)
⇒ D(l)ij:=1m(Δ(l)ij+λΘ(l)ij)if j≠0
⇒
D
i
j
(
l
)
:=
1
m
(
Δ
i
j
(
l
)
+
λ
Θ
i
j
(
l
)
)
i
f
j
≠
0
⇒ D(l)ij:=1mΔ(l)ijif j=0
⇒
D
i
j
(
l
)
:=
1
m
Δ
i
j
(
l
)
i
f
j
=
0
⇒
⇒
(注:
Θ(l)
Θ
(
l
)
的第1列不正则化,上式可以向量化去掉
ij
i
j
)
⇒ ∂∂Θ(l)ijJ(Θ)=D(l)ij
⇒
∂
∂
Θ
i
j
(
l
)
J
(
Θ
)
=
D
i
j
(
l
)
对于只有一个输出单元的神经网络:
δ(l)j
δ
j
(
l
)
为
a(l)j
a
j
(
l
)
(
l
l
层第个单元)的代价误差;
更正式的表达:
δ(l)j=∂∂Z(l)jcost(i)(j⩾0)
δ
j
(
l
)
=
∂
∂
Z
j
(
l
)
c
o
s
t
(
i
)
(
j
⩾
0
)
其中,
cost(i)=y(i)log(hΘ(x(i)))+(1−y(i))log(1−hΘ(x(i)))
c
o
s
t
(
i
)
=
y
(
i
)
l
o
g
(
h
Θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
Θ
(
x
(
i
)
)
)
利用高级最优化算法最小化 J(Θ) J ( Θ ) :
function[jVal,gradient] = costFunction(theta)
...
optTheta = fminunc(@costFunction,initialTheta,options)
这种方法中, theta,gradient t h e t a , g r a d i e n t 值均为向量。
对于神经网络(4层为例):
Θ(1),Θ(2),Θ(3)
Θ
(
1
)
,
Θ
(
2
)
,
Θ
(
3
)
—-矩阵(
Theta1,Theta2,Theta3
T
h
e
t
a
1
,
T
h
e
t
a
2
,
T
h
e
t
a
3
)
D(1),D(2),D(3)
D
(
1
)
,
D
(
2
)
,
D
(
3
)
—-矩阵(
D1,D2,D3
D
1
,
D
2
,
D
3
)
为了使用优化算法,需要将矩阵展开成向量:
thetaVector = [Theta1(:);Theta2(:);Theta3(:)];
deltaVector = [D1(:);D2(:);D3(:)];
如果 Theta1 T h e t a 1 的维度为 10×11 10 × 11 , Theta2 T h e t a 2 的维度为 10×11 10 × 11 , Theta3 T h e t a 3 的维度为 1×11 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) Θ ( 1 ) , Θ ( 2 ) , Θ ( 3 ) ,展开后获得 initialTheta i n i t i a l T h e t a ,传值给:
fminunc(@costFunction,initialTheta,options)
function[jVal,gradientVec] = costFunction(thetaVec)
上面代价函数
costFunction
c
o
s
t
F
u
n
c
t
i
o
n
内的具体步骤如下:
⇒
⇒
从
thetaVec
t
h
e
t
a
V
e
c
中得到
Θ(1),Θ(2),Θ(3)
Θ
(
1
)
,
Θ
(
2
)
,
Θ
(
3
)
;
⇒
⇒
使用前向传播及反向传播算法计算
D(1),D(2),D(3)
D
(
1
)
,
D
(
2
)
,
D
(
3
)
及
J(Θ)
J
(
Θ
)
;
⇒
⇒
展开
D(1),D(2),D(3)
D
(
1
)
,
D
(
2
)
,
D
(
3
)
获得
gradientVec
g
r
a
d
i
e
n
t
V
e
c
。
梯度检测:可以减少梯度下降存在错误的风险。
θ∈Rn
θ
∈
R
n
(
θ
θ
是
Θ(1),Θ(2),Θ(3)
Θ
(
1
)
,
Θ
(
2
)
,
Θ
(
3
)
的展开向量)
θ=θ1,θ2,θ3,⋯,θn
θ
=
θ
1
,
θ
2
,
θ
3
,
⋯
,
θ
n
由于
∂∂ΘJ(Θ)≈J(Θ+ϵ)−J(Θ−ϵ)2ϵ
∂
∂
Θ
J
(
Θ
)
≈
J
(
Θ
+
ϵ
)
−
J
(
Θ
−
ϵ
)
2
ϵ
(
ϵ
ϵ
取
10−4
10
−
4
即可)
所以:
∂∂θ1J(Θ)≈J(θ1+ϵ,θ2,θ3,⋯,θn)−J(θ1−ϵ,θ2,θ3,⋯,θn)2ϵ
∂
∂
θ
1
J
(
Θ
)
≈
J
(
θ
1
+
ϵ
,
θ
2
,
θ
3
,
⋯
,
θ
n
)
−
J
(
θ
1
−
ϵ
,
θ
2
,
θ
3
,
⋯
,
θ
n
)
2
ϵ
∂∂θ2J(Θ)≈J(θ1,θ2+ϵ,θ3,⋯,θn)−J(θ1,θ2−ϵ,θ3,⋯,θn)2ϵ
∂
∂
θ
2
J
(
Θ
)
≈
J
(
θ
1
,
θ
2
+
ϵ
,
θ
3
,
⋯
,
θ
n
)
−
J
(
θ
1
,
θ
2
−
ϵ
,
θ
3
,
⋯
,
θ
n
)
2
ϵ
⋯
⋯
∂∂θnJ(Θ)≈J(θ1,θ2,θ3,⋯,θn+ϵ)−J(θ1,θ2,θ3,⋯,θn−ϵ)2ϵ
∂
∂
θ
n
J
(
Θ
)
≈
J
(
θ
1
,
θ
2
,
θ
3
,
⋯
,
θ
n
+
ϵ
)
−
J
(
θ
1
,
θ
2
,
θ
3
,
⋯
,
θ
n
−
ϵ
)
2
ϵ
Octave O c t a v e 中的实现代码如下:
EPSILON = 1e-4;
for i = 1:n,
thetaPlus = theta;
thetaPlus(i) = thetaPlus(i) + EPSILON;
thetaMinus = theta;
thetaMinus(i) = thetaMinus(i) + EPSILON;
gradApprox(i) = (J(thetaPlus)-J(thetaMinus))/(2*EPSILON);
end;
check gradApprox≈Dvec c h e c k g r a d A p p r o x ≈ D v e c
梯度检测总结:
- 利用反向传播算法计算 Dvec D v e c ( D(1),D(2),D(3) D ( 1 ) , D ( 2 ) , D ( 3 ) 的展开);
- 利用梯度检测算法计算 gradApprox g r a d A p p r o x ;
- 确保两者相近;
- 关闭梯度检测算法,用反向传播算法学习。
确保在开始训练模型之前关闭梯度检测算法,否则运算会很慢。
随机初始化:
当使用梯度下降或高级优化算法时,需要设置初始值:
optTheta = fminunc(@costFunction,initialTheta,options);
对于神经网络来说,若
θ
θ
全初始化为0,当进行反向传播算法时,所有的单元会更新成相同的值,故采用下列代码进行随机初始化:
θ(l)ij∈[−ϵ,ϵ]
θ
i
j
(
l
)
∈
[
−
ϵ
,
ϵ
]
如果
Theta1
T
h
e
t
a
1
为
10×11
10
×
11
矩阵,
Theta2
T
h
e
t
a
2
为
10×11
10
×
11
矩阵,
Theta3
T
h
e
t
a
3
为
1×11
1
×
11
矩阵:
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(x,y)
r
a
n
d
(
x
,
y
)
为生成
x×y
x
×
y
矩阵,元素值
∈(0,1)
∈
(
0
,
1
)
;
此处
EPSILON
E
P
S
I
L
O
N
与梯度检测时的不同,可以取
0.12
0.12
。
总体总结:
训练神经网络的步骤:
- 搭建网络架构(即神经元连接方式);
输入层单元数:特征集 x(i) x ( i ) 的维度
输出层单元数:分类的类别数
如果 y∈{1,2,3,⋯,10} y ∈ { 1 , 2 , 3 , ⋯ , 10 } ,要将其改写成向量 y=⎡⎣⎢⎢⎢⎢⎢⎢⎢100⋮0⎤⎦⎥⎥⎥⎥⎥⎥⎥or⎡⎣⎢⎢⎢⎢⎢⎢⎢010⋮0⎤⎦⎥⎥⎥⎥⎥⎥⎥or⎡⎣⎢⎢⎢⎢⎢⎢⎢001⋮0⎤⎦⎥⎥⎥⎥⎥⎥⎥⋯⎡⎣⎢⎢⎢⎢⎢⎢⎢000⋮1⎤⎦⎥⎥⎥⎥⎥⎥⎥ y = [ 1 0 0 ⋮ 0 ] o r [ 0 1 0 ⋮ 0 ] o r [ 0 0 1 ⋮ 0 ] ⋯ [ 0 0 0 ⋮ 1 ]
默认规则:推荐设置一个隐藏层,如果隐藏层 >1 > 1 ,则每个隐藏层包含相同数目的单元,对于单层的具体单元数,越多越好,但越多计算量越大,一般隐藏层单元数稍大于特征数都可以接受; - 随机初始化权重,将权重初始化为很小的值,接近于0;
- 执行前向传播算法,获取每个输入 x(i) x ( i ) 对应的 hΘ(x(i)) h Θ ( x ( i ) ) ;
- 利用代码计算代价函数 J(Θ) J ( Θ ) ;
- 执行反向传播算法计算
∂∂Θ(l)jkJ(Θ)
∂
∂
Θ
j
k
(
l
)
J
(
Θ
)
:
for i=1:m, f o r i = 1 : m ,
{ {
执行前向传播算法和反向传播算法利用 (x(i),y(i)) ( x ( i ) , y ( i ) ) 获取激励 a(l) a ( l ) 和误差 δ(l) (for l=2,⋯,L) δ ( l ) ( f o r l = 2 , ⋯ , L )
Δ(l):=Δ(l)+δ(l+1)(a(l))T Δ ( l ) := Δ ( l ) + δ ( l + 1 ) ( a ( l ) ) T
} }
计算 ∂∂Θ(l)jkJ(Θ) ∂ ∂ Θ j k ( l ) J ( Θ ) ; - 利用梯度检测比较反向传播算法计算得到的 ∂∂Θ(l)jkJ(Θ) ∂ ∂ Θ j k ( l ) J ( Θ ) 和通过 J(Θ) J ( Θ ) 梯度下降数值计算得到的 ∂∂Θ(l)jkJ(Θ) ∂ ∂ Θ j k ( l ) J ( Θ ) ,然后注释掉梯度检测的代码;
- 利用梯度下降或最优化算法最小化
J(Θ)
J
(
Θ
)
,得到参数
Θ
Θ
。
注:对于神经网络, J(Θ) J ( Θ ) 是一个非凸函数,通常得到局部最小值。