5.7. 神经网络的优化
本文最后更新于 2024年1月27日 下午
算法优化
参数展开
参数展开是一种将矩阵展开为向量的方法,常用于很多高级优化中。
例如如下的高级优化:
1
2
3function[jVal,gradient]=costFunction(theta)
...
optTheta=fminunc(@costFunction,initialTheta,options)
在神经网络中,很多参数并非是向量的形式,而是完整的矩阵,比如第l层的参数矩阵\(Θ^{(l)}\)和梯度矩阵\(D^{(l)}\)(见5.1.),这时就需要应用参数展开将这些矩阵展开为向量,方法是在Octave中应用[;]
表达将所有的元素从矩阵中取出,展开成一个长向量,并应用reshape
语法重新合成矩阵。
比如如下的10层神经网络:
## 梯度检测
反向传播算法的实现过程非常的繁琐,因此在与其他算法一同工作的时候可能会产生一些bug,这些bug可能本身不会影响程序的运行,但是最终输出的模型准确度可能会非常低。
因此需要引入梯度检测(Gredient
Check)来解决反向传播算法或类梯度下降算法中出现的这类问题。
- 从数值上近似梯度
要想求出代价函数\(J(\Theta)\)在某一点\(\theta\)的梯度(在二维内反映为该点的斜率),可以在\(\theta\)的两边取\(\theta \plusmn \epsilon, \epsilon \rightarrow
0\),\(\theta\)处的梯度可以近似的表示为(实数形式):
\[\frac{dJ(θ )}{dθ }≈ \frac{J(θ +ε )-J(θ -ε
)}{2ε }\] 称为双侧差分(Two-side difference)。
当\(\theta\)是\(\Theta^{(i)}\)的展开时,可以用双侧差分来估计所有的偏导数项:
\[\frac{∂ J(θ)}{∂ θ_k}≈ \frac{J(θ _k+ε
,θ_1,...,θ_n )-J(θ _k-ε ,\theta_1,...,θ_n )}{2ε }\]
在Octave中用如下的代码实现: 1
2
3
4
5
6
7
8for i=1:n,
thetaPlus=theta;
thetaPlus=thetaPlus(i)+epsilon;
thetaMinus=theta;
thetaMinus(i)=thetaMinus(i)-epsilon;
gradApprox(i)=(J(thetaPlus)-J(thetaMinus))/(2*epsilon);
end;
Check gradApprox≈DVec
4. 关闭双侧差分,利用反向传播进行训练(以提高训练时的算法效率)
随机初始化
在最开始执行高级优化或者是神经网络的梯度下降时,应当对\(Θ\)设置一些初始值,即初始化\(Θ\)。
在逻辑回归中,将参数全部初始化为0的做法会导致神经网络中一个单元出发的所有的参数都相等,导致神经网络中所有的隐藏单元都在计算相同的特征。正确的做法是对\(Θ\)随机地设定一些值来初始化它,具体的做法是:
设置某个区间\([-ϵ,ϵ]\),使得所有\(θ\)都在这个区间内随机取到,用Octave代码实现:
1
2theta1 = rand(10,11)*(2*init_epsilon)-init_epsilon;
#rand()的作用是随机生成一个mxn的矩阵,矩阵里面所有的元素值都介于0,1之间。