神经网络-梯度下降
对于一个神经网络,我们通过传入参数,经过中间层的θ切换,最后输出hθ结果。
下面是一个用makedown画的简易神经网络,感觉不是很好康,不过又懒的画图了,就这样吧。
正向传播
正向传播表示从输入x开始,根据中间层的θ来进行输出值。
下面给出一个四层神经网络的正向传递的步骤。
其中x为训练集,θ为层级之间的关系,z为中间变量,a为中间隐藏层作为下一层的输入集合
这里的用第二层的θ为参考
θ
(
2
)
=
[
θ
10
(
2
)
θ
11
(
2
)
θ
12
(
2
)
θ
20
(
2
)
θ
21
(
2
)
θ
22
(
2
)
]
\theta^{(2)}= \begin{bmatrix} &\theta_{10}^{(2)} &\theta_{11}^{(2)} &\theta_{12}^{(2)} \\ &\theta_{20}^{(2)} &\theta_{21}^{(2)} &\theta_{22}^{(2)} \end{bmatrix}
θ(2)=[θ10(2)θ20(2)θ11(2)θ21(2)θ12(2)θ22(2)]
可以看出这是一个2*3的矩阵,用到下面,
a ( 1 ) = x 读 入 第 一 层 训 练 集 开 始 进 行 第 二 层 计 算 z ( 2 ) = θ ( 1 ) a ( 1 ) 经 过 θ 计 算 获 得 中 间 参 数 z a ( 2 ) = g ( z ( 2 ) ) ( a d d a 0 ( 2 ) ) 使 用 g ( z ) 函 数 将 其 变 为 隐 藏 层 的 集 合 a , 并 且 加 入 a 0 第 三 层 计 算 z ( 3 ) = θ ( 2 ) a ( 2 ) a ( 3 ) = g ( z ( 3 ) ) ( a d d a 0 ( 3 ) ) 第 四 层 计 算 z ( 4 ) = θ ( 3 ) a ( 3 ) a ( 4 ) = g ( z ( 4 ) ) ( a d d a 0 ( 3 ) ) \begin{aligned} & a^{(1)}=x \ \ \ 读入第一层训练集\\ & 开始进行第二层计算\\ & z^{(2)}=\theta^{(1)}a^{(1)}\ \ \ 经过\theta计算获得中间参数z\\ & a^{(2)}=g(z^{(2)})\ \ (add\ a_0^{(2)})\ \ \ 使用g(z)函数将其变为隐藏层的集合a,并且加入a_0 \\ & 第三层计算\\ & z^{(3)}=\theta^{(2)}a^{(2)}\\ & a^{(3)}=g(z^{(3)})\ \ (add\ a_0^{(3)})\\ & 第四层计算\\ & z^{(4)}=\theta^{(3)}a^{(3)}\\ & a^{(4)}=g(z^{(4)})\ \ (add\ a_0^{(3)}) \\ \end{aligned} a(1)=x 读入第一层训练集开始进行第二层计算z(2)=θ(1)a(1) 经过θ计算获得中间参数za(2)=g(z(2)) (add a0(2)) 使用g(z)函数将其变为隐藏层的集合a,并且加入a0第三层计算z(3)=θ(2)a(2)a(3)=g(z(3)) (add a0(3))第四层计算z(4)=θ(3)a(3)a(4)=g(z(4)) (add a0(3))
最后根据最后一层的a集合来确定输出结果。
代价函数
因此,根据不同的θ得出的结果集可能不同,其代价函数是关于θ的函数。
首先是根据逻辑回归,因为多层神经网络的期望输出结果为只有一个1的其他全0的向量组,因此使用交叉熵来进行代价函数的优化
J
(
θ
)
=
−
1
m
[
∑
i
=
1
m
y
(
i
)
l
o
g
h
θ
(
x
(
i
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
(
i
)
)
)
]
+
λ
2
m
∑
j
=
1
n
θ
j
2
J(\theta)=-\frac{1}{m}[\sum_{i=1}^{m}y^{(i)}log\ h_\theta(x^{(i)})+(1-y^{(i)})log(1-h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^{n}\theta_j^2
J(θ)=−m1[i=1∑my(i)log hθ(x(i))+(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2
这里使用神经网络多层回归。(其实就是把多层的代价函数再加起来)
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
2
J(\theta)=-\frac{1}{m}[\sum_{i=1}^{m}\sum_{k=1}^{K}y_k^{(i)}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}\sum_{j=1}^{s_{l+1}}\theta_j^2
J(θ)=−m1[i=1∑mk=1∑Kyk(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θj2
我们要求得最小的代价函数。
梯度下降
使用梯度下降需要,需要知道代价函数J(θ)的对于各个分量的偏导数。
∂
∂
θ
i
j
(
l
)
J
(
θ
)
\frac{\partial}{\partial\theta_{ij}^{(l)}}J(\theta)
∂θij(l)∂J(θ)
我们需要求出其偏导,可以采用反向传播算法。
直接求取较为麻烦,所以我们考虑使用反向传播算法来优化计算速度。
反向传播
相对于正向传播,反向传播从结果出发,求取每一层的误差项,来获得其导数。
其求取过程参考神经网络反向传播算法 - 知乎 (zhihu.com)
这里的θ转置后,其形态参考上面的θ所示
θ
(
2
)
T
=
[
θ
10
(
2
)
θ
20
(
2
)
θ
11
(
2
)
θ
21
(
2
)
θ
12
(
2
)
θ
22
(
2
)
]
\theta^{(2)T}= \begin{bmatrix} &\theta_{10}^{(2)} &\theta_{20}^{(2)}\\ &\theta_{11}^{(2)} &\theta_{21}^{(2)}\\ &\theta_{12}^{(2)} &\theta_{22}^{(2)} \end{bmatrix}
θ(2)T=⎣⎢⎡θ10(2)θ11(2)θ12(2)θ20(2)θ21(2)θ22(2)⎦⎥⎤
δ ( 4 ) = a ( 4 ) − y ( i ) 根 据 输 出 和 训 练 集 , 获 取 误 差 集 合 这 里 使 用 同 样 的 θ , 只 是 因 为 连 线 不 同 , 所 以 要 注 意 θ 的 参 数 这 里 转 置 以 下 就 好 了 , 可 以 参 考 上 面 的 θ 得 出 第 三 层 δ ( 3 ) = θ ( 3 ) T δ ( 4 ) . ∗ g ′ ( z ( 3 ) ) 第 二 层 δ ( 2 ) = θ ( 2 ) T δ ( 3 ) . ∗ g ′ ( z ( 2 ) ) \begin{aligned} & \delta^{(4)}=a^{(4)}-y^{(i)}\ \ \ 根据输出和训练集,获取误差集合\\ & 这里使用同样的\theta,只是因为连线不同,所以要注意\theta的参数这里转置以下就好了,可以参考上面的\theta\\得出第三层\\ & \delta^{(3)}=\theta^{(3)T}\delta^{(4)}.*g'(z^{(3)})\\ & 第二层\\ & \delta^{(2)}=\theta^{(2)T}\delta^{(3)}.*g'(z^{(2)}) \end{aligned} 得出第三层δ(4)=a(4)−y(i) 根据输出和训练集,获取误差集合这里使用同样的θ,只是因为连线不同,所以要注意θ的参数这里转置以下就好了,可以参考上面的θδ(3)=θ(3)Tδ(4).∗g′(z(3))第二层δ(2)=θ(2)Tδ(3).∗g′(z(2))
这 里 的 g ′ ( z ( 3 ) ) 其 实 就 是 激 活 项 a 的 对 中 间 项 z 的 偏 导 , 可 以 证 明 g ′ ( z ( 3 ) ) = a ( 3 ) . ∗ ( 1 − a ( 3 ) ) 根 据 以 上 条 件 , 可 以 在 不 严 格 的 条 件 下 证 明 出 代 价 函 数 对 于 θ 的 偏 导 数 ∂ ∂ θ i j ( l ) J ( θ ) = a j ( l ) δ i ( l + 1 ) 这 里 忽 略 了 λ 这里的g'(z^{(3)})其实就是激活项a的对中间项z的偏导,可以证明\\ g'(z^{(3)})=a^{(3)}.*(1-a^{(3)})\\ 根据以上条件,可以在不严格的条件下证明出代价函数对于\theta的偏导数\\ \frac{\partial}{\partial\theta_{ij}^{(l)}}J(\theta)=a_j^{(l)}\delta_i^{(l+1)}这里忽略了\lambda 这里的g′(z(3))其实就是激活项a的对中间项z的偏导,可以证明g′(z(3))=a(3).∗(1−a(3))根据以上条件,可以在不严格的条件下证明出代价函数对于θ的偏导数∂θij(l)∂J(θ)=aj(l)δi(l+1)这里忽略了λ
这里的对δ进行解释
δ
j
(
l
)
是
第
a
j
(
l
)
个
激
活
项
中
的
误
差
δ
j
(
l
)
是
第
代
价
函
数
关
于
中
间
项
的
偏
导
数
即
δ
j
(
l
)
=
∂
∂
z
j
(
l
)
C
o
s
t
(
i
)
\delta^{(l)}_j是第a_j^{(l)}个激活项中的误差\\ \delta^{(l)}_j是第代价函数关于中间项的偏导数即\\ \delta^{(l)}_j=\frac{\partial }{\partial z_j^{(l)}}Cost(i)
δj(l)是第aj(l)个激活项中的误差δj(l)是第代价函数关于中间项的偏导数即δj(l)=∂zj(l)∂Cost(i)
衡量,为了影响中间值,我们要改变的神经网络中的权重的程度,导致影响神经网络中的输出h(x),并影响所有的代价函数。
实现过程
训 练 集 { ( x ( 1 ) , y ( 1 ) ) , . . . , ( x ( m ) , y ( m ) ) } 设 置 Δ i j ( l ) = 0 ( f o r a l l l , i , j ) 遍 历 训 练 集 F o r i = 1 t o m 设 置 a ( 1 ) = x ( i ) 正 向 传 播 计 算 后 面 的 a ( l ) 使 用 y 来 计 算 最 后 一 层 的 误 差 δ ( L ) = a ( L ) − y ( L ) 反 向 传 播 算 法 计 算 δ ( L − 1 ) , . . . , δ ( 2 ) 通 过 δ 和 a 计 算 Δ i j ( l ) : = Δ i j ( l ) + a j ( l ) δ i ( 2 ) D i j ( l ) : = 1 m Δ i j ( l ) + λ θ i j ( l ) i f j ≠ 0 D i j ( l ) : = 1 m Δ i j ( l ) i f j = 0 \begin{aligned} & 训练集\{(x^{(1)},y^{(1)}),...,(x^{(m)},y^{(m)})\}\\ & 设置\Delta_{ij}^{(l)}=0\ (for\ all\ l,i,j)\\ & 遍历训练集For\ i=1\ to\ m\\ & \ \ \ \ 设置 a^{(1)}=x^{(i)}\\ & \ \ \ \ 正向传播计算后面的a^{(l)}\\ & \ \ \ \ 使用y来计算最后一层的误差\delta^{(L)}=a^{(L)}-y^{(L)}\\ & \ \ \ \ 反向传播算法计算\delta^{(L-1)},...,\delta^{(2)}\\ & \ \ \ \ 通过\delta和a计算 \Delta_{ij}^{(l)}:=\Delta_{ij}^{(l)}+a_j^{(l)}\delta_i^{(2)}\\ & D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)}+\lambda\theta_{ij}^{(l)}\ if\ j\neq0\\ & D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)} if\ j=0\\ \end{aligned} 训练集{(x(1),y(1)),...,(x(m),y(m))}设置Δij(l)=0 (for all l,i,j)遍历训练集For i=1 to m 设置a(1)=x(i) 正向传播计算后面的a(l) 使用y来计算最后一层的误差δ(L)=a(L)−y(L) 反向传播算法计算δ(L−1),...,δ(2) 通过δ和a计算Δij(l):=Δij(l)+aj(l)δi(2)Dij(l):=m1Δij(l)+λθij(l) if j=0Dij(l):=m1Δij(l)if j=0
这 里 设 置 ∂ ∂ θ i j ( l ) J ( θ ) = D i j ( l ) 这里设置\frac{\partial}{\partial\theta_{ij}^{(l)}}J(\theta)=D_{ij}^{(l)} 这里设置∂θij(l)∂J(θ)=Dij(l)
高级函数优化
使用octave的内置函数来运行。
执行模板
f u n c t i o n [ j V a l , g r a d i e n t ] = c o s t F u n c t i o n ( t h e t a ) 首 先 确 定 代 价 函 数 . . . o p t T h e t a = f m i n u n c ( @ c o s t F u n c t i o n , i n i t i a l T h e t a , o p t i o n s ) 根 据 代 价 函 数 , 初 始 梯 度 , 优 化 标 记 \begin{aligned} & function [jVal,gradient]=costFunction(theta) \ \ \ \ 首先确定代价函数\\ & ... \\ & optTheta = fminunc(@costFunction,initialTheta,options)\ \ \ \ 根据代价函数,初始梯度,优化标记\\ \end{aligned} function[jVal,gradient]=costFunction(theta) 首先确定代价函数...optTheta=fminunc(@costFunction,initialTheta,options) 根据代价函数,初始梯度,优化标记
神经网络有4层,三组θ和三组偏导数
N
e
u
r
a
l
N
e
t
w
o
r
k
(
L
=
4
)
:
θ
(
1
)
,
θ
(
2
)
,
θ
(
3
)
−
m
a
t
r
i
c
e
s
(
T
h
e
t
a
1
,
T
h
e
t
a
2
,
T
h
e
t
a
3
)
D
(
1
)
,
D
(
2
)
,
D
(
3
)
−
m
a
t
r
i
c
e
s
(
D
1
,
D
2
,
D
3
)
"
U
n
r
o
l
l
"
i
n
t
o
v
e
c
t
o
r
s
\begin{aligned} & Neural\ Network(L=4):\\ & \ \ \ \ \theta^{(1)},\theta^{(2)},\theta^{(3)}\ -matrices(Theta1,Theta2,Theta3)\\ & \ \ \ \ D^{(1)},D^{(2)},D^{(3)}\ -matrices(D1,D2,D3)\\ & "Unroll"into\ vectors \end{aligned}
Neural Network(L=4): θ(1),θ(2),θ(3) −matrices(Theta1,Theta2,Theta3) D(1),D(2),D(3) −matrices(D1,D2,D3)"Unroll"into vectors
thetaVec = [ Theta1(:);Theta2(:);Theta3(:) ]; %矩阵θ合并
Dvec = [D1(:);D2(:);D3(:)]; %导数矩阵合并
Theta1 = reshape(thetaVec(1:110),10,11); %将矩阵前110项拆开,变为一个10*11的矩阵
Theta2 = reshape(thetaVec(111:220),10,11);
Theta3 = reshape(thetaVec(221:231),1,11);
学习算法
初 始 化 参 数 θ ( 1 ) , θ ( 2 ) , θ ( 3 ) . 展 开 i n i t i a l T h e t a 传 给 函 数 f m i n u n c ( @ c o s t F u n c t i o n , i n i t i a l T h e t a , o p t i o n s ) f u n c t i o n [ j V a l , g r a i e n t V e c ] = c o s t F u n c t i o n ( t h e t a V e c ) 函 数 执 行 以 下 功 能 从 t h e t a V e c 向 量 组 中 获 取 到 θ ( 1 ) , θ ( 2 ) , θ ( 3 ) ( 使 用 r e s h a p e 函 数 ) 使 用 反 向 传 播 算 法 计 算 D ( 1 ) , D ( 2 ) , D ( 3 ) , J ( Θ ) . 然 后 展 开 D ( 1 ) , D ( 2 ) , D ( 3 ) 获 得 g e t d i e n t V e c \begin{aligned} & 初始化参数\theta^{(1)},\theta^{(2)},\theta^{(3)}.\\ & 展开initialTheta传给函数fminunc(@costFunction,initialTheta,options)\\ \\ & function\ [jVal,graientVec]=costFunction(thetaVec)函数执行以下功能\\ & \ \ \ \ 从thetaVec向量组中获取到\ \theta^{(1)},\theta^{(2)},\theta^{(3)}(使用reshape函数)\\ & \ \ \ \ 使用反向传播算法计算D^{(1)},D^{(2)},D^{(3)},J(\Theta).\\ & \ \ \ \ 然后展开D^{(1)},D^{(2)},D^{(3)}获得getdientVec\\ \end{aligned} 初始化参数θ(1),θ(2),θ(3).展开initialTheta传给函数fminunc(@costFunction,initialTheta,options)function [jVal,graientVec]=costFunction(thetaVec)函数执行以下功能 从thetaVec向量组中获取到 θ(1),θ(2),θ(3)(使用reshape函数) 使用反向传播算法计算D(1),D(2),D(3),J(Θ). 然后展开D(1),D(2),D(3)获得getdientVec
梯度检测
上面我们使用了反向传播算法来计算了代价函数**J(θ)**对于θ的偏导数。
为了检验我们是否求得了正确的导数,我们使用另一种方法(拉格朗日中值定理)来求导数来验证一下。
公式如下:
∂
∂
θ
J
(
θ
)
=
lim
ε
→
0
J
(
θ
+
ε
)
−
J
(
θ
−
ε
)
2
ε
\frac{\partial}{\partial\theta}J(\theta)=\lim_{\varepsilon\to0}\frac{J(\theta+\varepsilon)-J(\theta-\varepsilon)}{2\varepsilon}
∂θ∂J(θ)=ε→0lim2εJ(θ+ε)−J(θ−ε)
在octave中编写代码:
gradApprox =(J(theta + EPSILON)-J(theta - EPSILON))/(2*EPSLION)
计算步骤
θ ( 1 ) , θ ( 2 ) , θ ( 3 ) 展 开 到 θ 中 θ = [ θ 1 , θ 2 , . . . , θ n ] ∂ ∂ θ 1 J ( θ ) = J ( θ 1 + ϵ , θ 2 , . . . , θ n ) − J ( θ 1 − ϵ , θ 2 , . . . , θ n ) 2 ϵ ∂ ∂ θ 2 J ( θ ) = J ( θ 1 , θ 2 + ϵ , . . . , θ n ) − J ( θ 1 , θ 2 − ϵ , . . . , θ n ) 2 ϵ . . . ∂ ∂ θ n J ( θ ) = J ( θ 1 , θ 2 , . . . , θ n + ϵ ) − J ( θ 1 , θ 2 , . . . , θ n − ϵ ) 2 ϵ \begin{aligned} & \theta^{(1)},\theta^{(2)},\theta^{(3)}展开到\theta中\\ & \theta = [\theta_1,\theta_2,...,\theta_n]\\ & \frac{\partial}{\partial\theta_1}J(\theta)=\frac{J(\theta_1+\epsilon,\theta_2,...,\theta_n)-J(\theta_1-\epsilon,\theta_2,...,\theta_n)}{2\epsilon}\\ & \frac{\partial}{\partial\theta_2}J(\theta)=\frac{J(\theta_1,\theta_2+\epsilon,...,\theta_n)-J(\theta_1,\theta_2-\epsilon,...,\theta_n)}{2\epsilon}\\ .\\ .\\ .\\ & \frac{\partial}{\partial\theta_n}J(\theta)=\frac{J(\theta_1,\theta_2,...,\theta_n+\epsilon)-J(\theta_1,\theta_2,...,\theta_n-\epsilon)}{2\epsilon} \end{aligned} ...θ(1),θ(2),θ(3)展开到θ中θ=[θ1,θ2,...,θn]∂θ1∂J(θ)=2ϵJ(θ1+ϵ,θ2,...,θn)−J(θ1−ϵ,θ2,...,θn)∂θ2∂J(θ)=2ϵJ(θ1,θ2+ϵ,...,θn)−J(θ1,θ2−ϵ,...,θn)∂θn∂J(θ)=2ϵJ(θ1,θ2,...,θn+ϵ)−J(θ1,θ2,...,θn−ϵ)
在octave中编写代码:
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;
计算求得的gradApprox集合即使用拉格朗日求导得出的导数集合。
比较验证
在梯度检测中求得的gradApprox与反向传播计算的DVec比较,相同即证明反向传播算法没有问题。
补充随机化
在初始化θ的时候,如果将其默认值设为0,可能会出现同步更新导致向量更新相等的情况。
例如
当
θ
i
j
(
l
)
=
0
的
时
候
由
于
a
1
(
l
)
=
θ
(
l
−
1
)
a
(
l
−
1
)
a
2
(
l
)
=
θ
(
l
−
1
)
a
(
l
−
1
)
这
里
会
导
致
a
1
(
l
)
=
a
2
(
l
)
=
=
>
δ
1
(
l
)
=
δ
2
(
l
)
进
而
发
现
∂
∂
θ
01
(
l
)
J
(
θ
)
=
∂
∂
θ
02
(
l
)
J
(
θ
)
当\theta_{ij}^{(l)}=0的时候\\ 由于a_1^{(l)}=\theta^{(l-1)}a^{(l-1)}\\ a_2^{(l)}=\theta^{(l-1)}a^{(l-1)}\\ 这里会导致a_1^{(l)}=a_2^{(l)} \ \ \ ==>\delta_1^{(l)}=\delta_2^{(l)}\\ 进而发现\frac{\partial}{\partial\theta_{01}^{(l)}}J(\theta)=\frac{\partial}{\partial\theta_{02}^{(l)}}J(\theta)
当θij(l)=0的时候由于a1(l)=θ(l−1)a(l−1)a2(l)=θ(l−1)a(l−1)这里会导致a1(l)=a2(l) ==>δ1(l)=δ2(l)进而发现∂θ01(l)∂J(θ)=∂θ02(l)∂J(θ)
因此我们需要一个随机化,来将默认梯度随机一下。
将θ的值取在[-ε,ε]之间
代码中表示
Theta1 = rand(10,11) *(2*INIT EPSILON)-INIT_EPSILON; % 10*11的矩阵,(0,1)之间的随机实数
Theta2 = rand(1,11)*(2*INIT_EPSILON)-INIT_EPSILON;
参考资料
B站吴恩达机器学习相关课程:https://www.bilibili.com/video/BV164411b7dx
神经网络反向传播算法 - 知乎:https://zhuanlan.zhihu.com/p/25609953