机器学习:神经网络实现中的技巧

矩阵展开与复原

展开

当我们不想自己手写梯度下降或者别的什么算法,而是想直接调用已有函数的话,都要考虑兼容性问题。比如matlab自带的fminunc函数,它可以比梯度下降更快的找到使函数值最小的参数,但它要求使用者提供代价-梯度函数,且返回的代价、梯度和作为自变量的参数都要是向量形式。但在神经网络原理部分,参数、梯度都是矩阵形式,这个时候就需要我们对矩阵进行展开,使其变成向量。

对于单个矩阵A,要将它变成列向量,直接使用A=A(:)即可。若想把多个矩阵合并为一个列向量,将它们分别展开为列向量后再沿列组合即可:

A=[A1(:);A2(:);A3(:)];

复原

用列向量形式求出了优化值,但要在神经网络中运算的话,还是矩阵形式更方便,于是我们还需要把矩阵从列向量中复原回来。我们利用reshape函数,把列向量中对应的部分提取出来,按照给定的参数构成矩阵:

A1=reshape(A(k+1:k+n*m),n,m);

梯度检验

反向传播计算梯度是一个效率很高、很精妙的算法,但精妙意味着容易写错,有时候我们想确认我们写出来的反向传播算法是否有错误,我们可以写一个虽然效率低但更容易实现的算法计算梯度,将两个算法的结果放在一起比较,若每个元素都基本一致,就可以放心的使用了。

这个低效率的算法就是利用定义去计算梯度,对于函数 J ( Θ ) J(\Theta) J(Θ),它的偏导数为
∂ ∂ Θ j J ( Θ ) ≈ J ( Θ 1 , ⋯   , Θ j + ε , ⋯   , Θ n ) − J ( Θ 1 , ⋯   , Θ j − ε , ⋯   , Θ n ) 2 ε \frac{\partial}{\partial \Theta_j}J(\Theta)\approx\frac{J(\Theta_1,\cdots,\Theta_j+\varepsilon,\cdots,\Theta_n)-J(\Theta_1,\cdots,\Theta_j-\varepsilon,\cdots,\Theta_n)}{2\varepsilon} ΘjJ(Θ)2εJ(Θ1,,Θj+ε,,Θn)J(Θ1,,Θjε,,Θn)
为了使这个值比较精确, ε \varepsilon ε一般取 1 0 − 4 10^{-4} 104,我们对每个参数都执行一遍该过程,就可以得到梯度矩阵。

可以发现,这个方法的确很慢,每计算一个导数就要得到两个代价函数值,意味着要做两次向前传播,而反向传播计算所有单元的偏差值只需要反向传播一次,高下立判。

随机初始化

在前面的算法中,我们一般都将参数初始化为全0,但这在神经网络中是不可行的。
在这里插入图片描述
考虑上图所示的神经网络,若参数都为0,那么输入值和参数矩阵相乘后还是0,则隐藏层的值都为 g ( 0 ) = 0.5 g(0)=0.5 g(0)=0.5,以此类推,所有的隐藏层单元都会是 0.5 0.5 0.5。相应地,在计算偏差的时候它们也会保持一致,之后计算出的梯度也会一致,这样隐藏层的多个单元都没有意义,因为它们更新之后都是一样的值。

所以,在初始化的时候,我们会采用随机初始化的办法对参数进行赋值,用rand(n,m)就可以生成一个 n × m n\times m n×m的随机矩阵,元素的值都在 [ 0 , 1 ] [0,1] [0,1]之间。若想要改变取值范围为 [ − a , a ] [-a,a] [a,a],使用

A=rand(n,m)*(2*a)-a;

即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值