cs231n-学习笔记-06训练神经网络

训练神经网络

小批随机梯度下降

① 取一批样本数据

② 通过网络进行前向传播,得到损失函数

③ 方向传播计算梯度

④ 使用梯度更新参数

概览本章内容:

① 初始化设置

激活函数、数据预处理、权重初始哈、正则化、梯度检查

② 动态训练

监控学习率、参数更新、超参数优化

③ 评估

整体模型评估

第一部分

① 激活函数(使用relu)

② 数据预处理(对数据的每个特征都进行零中心化,然后将其数值范围都归一化到[-1, 1]范围之内)

③ 权重初始化(使用标准差为 2/n 2 / n 的高斯分布来初始化权重,其中 n n 是输入的神经元数)

④ 批处理(用)

⑤ 监控学习过程

⑥ 超参数优化(随机样本参数,)

1 激活函数

(1)Sigmoid:σ(x)=11+ex σ ( x ) = 1 1 + e − x

(2)tanh: tanh(x) t a n h ( x ) 其中, tanh(x)=2σ(2x)1 t a n h ( x ) = 2 σ ( 2 x ) − 1

(3)relu: max(0,x) m a x ( 0 , x )

(4)Leaky relu: max(0.1x,x) m a x ( 0.1 x , x ) 为解决relu死亡问题的尝试

(5)maxout: max(wT1x+b1,wT2x+b2) m a x ( w 1 T x + b 1 , w 2 T x + b 2 )

(6)elu: {xα(ex1)x0x<0 { x x ⩾ 0 α ( e x − 1 ) x < 0

实践:

(1)首选RELU,关注学习率的变化;

(2)尝试Leaky relu/maxout/elu;

(3)尝试tanh,但是不要有太多期望;

(4)不要使用sigmoid函数

2 数据预处理

均值减法:是预处理常用的形式。对数据中每个独立特征减去平均值,从几何上可以理解为,每个维度上都将数据云的中心迁置原点。

归一化:将所有的数据都归一化,使其数值范围都近似相等。实现归一化的两种常用方法:①先对数据做零中心化,然后每个维度都除以其标准差;②对每个维度做归一化,使得每个维度的最大和最小值是1和-1。(这个操作只有在确信不同的输入特征有不同的数值范围时才有意义)

PCA:先对数据做零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。

协方差矩阵的对角线上是方差,协方差矩阵是对称和半正定的。

通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能结果,同时还节省时间和存储器空间。

白化:白化操作的输入时特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。

记住:任何预处理策略(比如数据均值)都只能在训练集上进行计算,算法训练完毕后,在应用到验证集或者测试集上。

3 权重初始化

当权重用0初始化会发生什么?

全0初始化时一个错误的开始。如果网络中的每个神经元都计算出同样的输出,然后他们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新。换句话说,如果权重被初始化为同样的值,神经元之间就失去了不对称性的源头。

解决:小的随机数初始化,0均值和0.01的标准差的高斯分布

权重初始值要非常接近0又不能等于0,

这种方式对小的网络是可行的,但是对于深层网络会发生问题。

稀疏初始化:所有权重矩阵初始化为0,但每个神经元都同下一层固定数目的神经元随机连接。

偏置初始化:通常将偏置初始化为0,这是因为随机小数值权重矩阵已经打破了对称性。

初始化值太小,激活函数为0,梯度为0,不更新

初始化值太大,对于tanh,激活函数饱和,梯度为0,不学习

初始化刚刚好,所有层的激活函数很好地运行,学习过程非常好

4 批处理

1、为每个维度独立计算均值和方差;

2、标准化;

批处理通常放在全连接或者卷积层之后,在非线性函数之前。

1、使梯度升高,流向整个网络;

2、允许有更高的学习率;

3、在初始化时,减少依赖性;

4、充当正则化的形式,可能轻微的减少了dropout的需要

注;

在测试阶段,批处理层的函数功能完全不同;

均值和标准差不是基于批计算的,相反,在训练过程中使用单个固定的经验平均值;

标准化之前,分类损失对权重矩阵的改变非常敏感,很难优化。

标准化之后,权重矩阵的微小的改变对损失值不会产生很大的影响,实现优化非常容易

5 监控学习过程

一 数据预处理

二 选择网络结构

训练:以小的正则化项系数开始,并找到使损失函数下降的学习率,损失值不下降的话,是因为学习率太低。NAN代表学习率过高。

梯度检查

梯度检查就是把解析梯度很数值计算梯度进行比较。在实践中,使用中心化公式。

在使用有限差值近似计算数值梯度的时候,我们常见的公式是:

df(x)dx=f(x+h)f(x)h d f ( x ) d x = f ( x + h ) − f ( x ) h

但是,在实践中,我们通常不这么使用, h h 是一个很小的数字,近似为1e-5。在实践中证明,使用中心化公式效果更好:
df(x)dx=f(x+h)f(xh)2h d f ( x ) d x = f ( x + h ) − f ( x − h ) 2 h

在进行梯度检查时,记得关闭随机失活和梯度扩张

6 超参数优化

交叉验证策略

训练集和验证集精确度差距较大,代表过拟合,增加正则化项

训练集和验证集精确度差不多,增加模型容量

第二部分

① 优化(Momentum,RMSProp,Adam等)

② 正则化(使用L2正则化和dropout的倒置版本)

③ 转移学习(项目中使用)

1 优化

我们的梯度来自于小批处理,所以可以有一些噪声。

SGD+Momentum

AdaGrad: 根据每个维度的历史平方和添加元素的梯度缩放

AdaGrad的一个缺点就是,在深度学习中单调的学习率被证明通常过于激进且过早停止学习

RMSProp

Adam(使用最多)

实践中,Adam在大多数案例中是一个不错的恶魔人选择,

模型集成:① 训练多个独立地模型;②测试阶段,平均化他们的结果,

可以提高额外2%的性能。

不要独立地训练模型,在训练过程中,我们使用单个模型的简单样式。

2 正则化

正则化可以提高单个模型的性能。

正则化:在损失函数中,额外增加一项

Dropout正则化方法,在每个前向过程中,随机把一些神经元的权重置为0,通常把这个超参数设置为0.5

正则化,增加数据

在训练集中的所有像素应用PCA,

沿着原来的颜色方向,设置一个颜色偏移,

对训练图像的所有像素增加颜色偏移,

每层正则化:对于不同层进行不同的正则化很少见(除了输出层以外)

2 转移学习

如果你想要训练或者使用CNN,你将会使用许多数据。

少数据,相似数据集 -> 在最高层使用线性分类器

少数据,不同数据集 -> 这种情况不好处理,尝试在不同阶段使用线性分类器

多数据,相似数据集 -> 调整一些层

多数据,不同数据集 -> 调整层中的大部分数据

模型集成的几种方法:

(1)同一个模型,不同的初始化。使用交叉验证来得到最好的参数,然后用最好的参数来训练不同初始化条件的模型。这种方法的风险在于多样性只来自于不同的初始化条件。

(2)在交叉验证集中发现最好的模型。使用交叉验证来得到最好的超参数,然后取其中最好的几个模型来进行集成。这样就提高了集成的多样性,但是风险在于可能包含不够理想的模型。在实际操作中,这样操作起来比较简单,在交叉验证后就不需要额外的训练。

(3)一个模型设置多个记录点。如果训练非常耗时,那就在不同的训练时间对网络留下记录点,然后用他们来进行模型集成。这样做多样性不足,但是在实践中效果还是不错的,这种方法的优势就是代价比较小。

(4)在训练的时候跑参数的平均值。在训练过程中,如果损失值相较于前一次权重出现指数下降时,就在内存中对网络的权重进行一个备份。这样就对前几次循环中的网络状态进行了平均。

模型集成的一个劣势就是在测试数据的时候会花费更多的时间

3 总结

(1)利用小批量数据对实现进行梯度检查,还要注意各种错误;

(2)进行合理性检查,确认初始损失值是合理的,在小数据集上能得到100%的准确率

(3)在训练时,跟踪损失函数值,训练集合验证集准确率,如果愿意,还可以跟踪更新的参数量相对于总参数量的比例(一般在1e-3左右),然后如果是对于卷积神经网络,可以将第一层的权重可视化

(4)推荐的两个更新方法是SGD+Nesterov动量方法,或者Adam方法

(5)随着训练进行学习率衰减

(6)使用随机搜索来搜索最优的超参数

(7)进行模型集成来获得额外的性能提高

第三部分

① CPU vs GPU

② 深度学习框架

1 CPU vs GPU

CPU:更少的核,但每个核要快的多,能力更强,善于序列化执行任务;

GPU:更多的核,但每个核比较慢,善于并行任务;

GPU编程

CUDA(仅仅NVIDIA)

(1)编写类C代码,直接在GPU上运行;

(2)高级API,cuBLAS,cuFFT,cuDNN等;

OPENCL

(1)和CUDA类似,在CPU和GPU上都能运行;

(2)运行速度相对较慢;

CPU的性能往往没有得到好的优化。

cuDNN比没有优化的CUDA快。

若你不够小心,在读取数据并转移到GPU的时候,训练过程会遇到瓶颈。

解决办法,① 把所有的数据读到内存,② 使用固态硬盘不使用机械硬盘,③ 使用多个CPU进程预先取到数据。

2 深度学习框架

要点

(1)容易构建大的计算图;

(2)在计算图中容易计算梯度;

(3)在包裹了cuDNN,CUBLAS的GPU中高效运行;

计算图

使用numpy实现的程序,只能够自己计算梯度,不能够在GPU上加速。但是Tensorflow和PyTorch可以在GPU上运行

建议

(1)对大多数项目来说,Tensorflow是一个安全的选择,虽然它有不完美的地方,但是它的社区非常庞大,得到了广泛的使用,可以和高级的封装一起使用(Keras,Sonnet);

(2)PyTorch用作研究是非常好的,但是他比较新;

(3)在多个机器上使用Tensorflow计算一个图;

(4)发布产品时,考虑Caffe,Caffe2或者Tensorflow;

(5)在移动端使用,考虑Caffe2或者Tensorflow

你可能感兴趣的:(深度学习,cs231n)