cs231阅读笔记(2)—— 优化方法、正则化、迁移学习、软硬件
优化方法
随机梯度下降SGD
随机梯度下降(SGD, stochastic gradient descent):名字中已经体现了核心思想,随机选取一个店做梯度下降,而不是遍历所有样本后进行参数迭代。因为梯度下降法的代价函数计算需要遍历所有样本,而且是每次迭代都要遍历,直至达到局部最优解,在样本量庞大时就显得收敛速度比较慢了,计算量非常庞大。
随机梯度下降仅以当前样本点进行最小值求解,通常无法达到真正局部最优解,但可以比较接近。属于大样本兼顾计算成本的折中方案。
- 缺点
- 当梯度方向不指向最小值,会在更敏感的方向上震荡
- 局部最小值和鞍点及其附近(高维空间上,后者更容易发生)
SGD+momentum(带动量的SGD)
用“在速度方向上步进”替代“在原始梯度方向上步进”
可以解决上面的两个问题:相当于一定程度上保留了惯性
momentum初始化:初始化到0
AdaGrad & RMSProp
1. AdaGrad 一般不用
- 思想:累加每一步的梯度平方和,并在梯度下降时用梯度除以平方和
- 原因:在梯度陡峭的地方降低迭代步长,在梯度平滑的地方提升迭代步长
- 优点:避免问题一(即在每个维度上做出相同程度的优化),且步长越来越小(在凸函数的情况下符合期待)
- 缺点:非凸时困在局部最优点
2. RMSProp
- 思想:在平方和这一项中加入动量(decay_rate设置到0.9~0.99合适)
Adam
- 思想:SGD with momentum和RMSProp的结合
- 问题:第二动量的平方和项以0初始化,导致开始时步长很大 ==> Bias correction
二阶优化
一阶优化的思想:用一阶泰勒展开来逼近原函数,在一阶逼近上移动一个步长来降低损失函数
↓二阶优化的思想:用二阶泰勒展开来逼近原函数,直接降到二阶逼近的最低点(但在实际过程中也会仅降一个步长)
问题:维数较高,N * N内存压力大,且难以求逆
进一步:L-BFGS拟牛顿法,逼近hessian矩阵,但对分batch和非凸的情形效果不好,用得不多
learning rate decay
- SGD with momentum常用,Adam不常用
- 衰减率属于二阶超参数,不建议在开始时就用上
过拟合
- model ensemble —— 2%到3%的提升
- 保存同一个模型在不同时刻的状态(ICLR一篇文章,lr忽大忽小,使其在不同的局部最优点收敛,保存多次模型,进行集成)
正则化(防止过拟合)
损失函数中加入正则项
dropout
- 方法:在每次前项传递时,随机选择一些神经元置0(将经过**函数后的activation置0),反向传播时也只更新没有被丢弃的部分。测试时用dropout的丢弃概率p乘输出。 深度学习中Dropout原理解析
- 全连接层——随机置0神经元;卷积层——随机置0几个feature map
- 原理:组合多个零散特征(个人理解:避免某些特征占主导地位,以提高泛化性能)& model ensemble
- inverted dropout:测试时不乘p,而是训练时除以p(GPU算力强)
-
特点:训练时间长,但鲁棒性强
batch normalization
- 和dropout类似,在训练时引入某种随机性,但是测试时抵消掉
- 用了bn一般就不用dropout了,但是dropout更优一些,因为可以通过p来调节正则化的强度
其他
- data augmentation
- 翻转、裁剪
- 训练时引入随机性,测试时淡化
-
dropconnect
随机将权重置零 -
fractional max pooling
-
stochastic depth
使用的大多是bn,bn一般就够用了。不够的话再加dropout之类的方法。
transfer learning 迁移学习
硬件&软件
硬件GPU & CPU
GPU更擅于处理高度并行处理的算法(典型例子:矩阵乘法、卷积操作)
软件
在运行数据之前,把所有的东西转换成cuda数据类型
TensorFlow
- 定义图(定义输入、定义计算)=> run session
- 图一会使w1和w2在cpu和gpu间被频繁copy,因此引入variable,加入dummy node使得权重更新也被计算但实际并不返回到CPU中
- Keras对TensorFlow和Theano进行更高层次的封装
Pytorch
- pytorch中,tensor = numpy + GPU,不仅可以用在深度学习中
Caffe
将数据转换为特殊的格式,使用prototxt定义网络结构与训练参数,然后直接linux运行,提供python接口
比较
- 静态图:TensorFlow,建图 + 跑多个循环,可以图优化,方便部署(不需要调用最初的代码,可以部署到比如C++的环境)
- 动态图:pytorch,每次循环都是新的graph,TensorFlow几乎用计算图重构了所有的编程语言,例如,pytorch对于conditional的情况更好(即流控制,每次重新决定走哪条流),而tf需要tf.cond