cs231n 编程作业(2)学习心得——多种优化方法

来源:互联网 发布:sopcast ubuntu 编辑:程序博客网 时间:2024/05/21 18:39
cs231n编程作业确实厉害,这里记录一下学习心得

优化方法选择

普通梯度下降法

普通的梯度下降法是我们最为熟悉的优化方法,代码如下
x -=  learning_rate * dx
即是仅仅让权值沿着梯度最快下降的来减小虽然该方法原理很简单,但在实际应用中,却还是有很多的不足之处这里简单给出几点我的看法:
  • 收敛缓慢:在实际训练数据的时候,普通的梯度下降算法往往要经过多次迭代,才有可能收敛
  • 易收敛域局部极小值:相对于其他高级优化方法,其往往容易收敛到局部极小值中,这里的cs231n课程上有一副图很好的说明了这种情况http://cs231n.github.io/neural-networks-3/

普通梯度下降算法+动量法

代码十分简洁,但功能却十分强大,如下:
v = config['momentum'] * v - config['learning_rate'] * dwnext_w = w + v

其中v的初始值为0, config[‘momentum’]为我们设定的一个常量,一般值为0.9,其也是起到了一个系数随着迭代次数衰减的作用。
即每一次迭代的时候,到考虑到了config[‘momentum’] * v这个的作用,然后再结合梯度的因素,最后再更新相应的权值w

这里写图片描述

发现这个效果确实比不同的梯度下降算法要好很多,仅仅只需要改一行代码就可以实现!!

RMSProp算法

这个中文名字叫啥不知道,不过效果也是很好,cs231n上面说这个算法

是一个非常高效,但没有公开发表的适应性学习率方法,这个方法用一种很简单的方式修改了Adagrad方法,让它不那么激进,单调地降低了学习率。具体说来,就是它使用了一个梯度平方的滑动平均:
尝试的用了一下,很快很准确!!
代码如下:

cache =  decay_rate * cache + (1 - decay_rate) * dw**2w += - learning_rate * dw / (np.sqrt(cache) + eps)

在上面的代码中,decay_rate是一个超参数,常用的值是[0.9,0.99,0.999]
cache也是一开始初始化为0的矩阵,其维度和权值一样

cache = np.zeros_like(w)

Adam

cs231n对算法的评价如下:

Adam是最近才提出的一种更新方法,它看起来像是RMSProp的动量版。注意这个更新方法看起来真的和RMSProp很像,除了使用的是平滑版的梯度m,而不是用的原始梯度向量dx。在实际操作中,我们推荐Adam作为默认的算法,一般而言跑起来比RMSProp要好一点。

实现代码如下:

  #t为迭代次数  config['t'] += 1  #计算表达式m = beta1*m + (1-beta1)*dx  config['m'] = config['beta1'] * config['m'] + (1 - config['beta1']) * dx  #计算表达式v = beta2*v + (1-beta2)*(dx**2)  config['v'] = config['beta2'] * config['v'] + (1 - config['beta2']) * (dx**2)  #矫正,因为m,v两个矩阵初始为0,在没有完全热身之前存在偏差  mb = config['m'] / (1 - config['beta1']**config['t'])  vb = config['v'] / (1 - config['beta2']**config['t'])  next_x = x - config['learning_rate'] * mb / (np.sqrt(vb) + config['epsilon'])

一下是四个算法的比较这里写图片描述

目前最喜欢普通下降+动量法的方法!很酷很方便!!

0 0
原创粉丝点击