-
Notifications
You must be signed in to change notification settings - Fork 0
Lecture6.7 Training Neural Network
cqchu edited this page Jan 30, 2018
·
41 revisions
常见的一些激活函数
-
Sigmoid
- 已饱和的神经元(输出接近1或0),此时梯度接近于0,即梯度消失,会使训练很慢,且反向传播时通过链式法则,会使浅层的Neuron梯度也为零,难以训练;
- Sigmoid输出全为正数,而考虑Y = σ(W*X+b),所以dY/dW = X全为正数,反向传播经过时梯度的符号不会改变;
- exp()是compute expensive;
-
tanh(x)
- 虽然输出有正有负,但是仍然存在神经元饱和现象;
-
ReLU:Rectified Linear Unit
- 此时在正区间不会出现饱和现象,且计算成本低,所以收敛会比较快;
- 和生物上的神经元更有类似性;
- 但是其只能输出非负数;
- 其在负区间梯度为0,此时Neuron不会更新,被称为Dead ReLU,如果学习率设置的过高,这种情况发生的可能性会更大;
- 所以ReLU初始化很重要,一般在初始化中加一点点的正bias,如0.01;
-
Leaky ReLU
- 在负区间也不会饱和,所以不会出现dead neuron;
- 其一种变种Parameteric ReLU/PReLU:f(x) = max(αx,x),α也是一个可以学习的参数;
-
ELU:Exponential Linear Units
- 可以看成ReLU和Leaky ReLU的折中,在负区间构造了一个饱和,认为这样可以对Noise有更好的鲁棒性;
- 计算代价提升了许多
-
MaxOut
- ReLU和leaky ReLU就是Maxout的特殊情况
- 神经元的参数是正常的两倍;
通常的习惯是一个网络中只使用一种激活函数;
- Zero Centering:让所有的数据都减去其均值,这样可以使数据分布在原点附近,数据对于noise更鲁棒,CV领域一般用这个就够了;
- Normalize:使数据的各个维度尺度一致,提升梯度下降收敛速度,同时提高鲁棒性,比如说如果data的值比较大,则weight的一点变化就会造成后面层的较大的改变;
- PCA:首先进行zero centering,再计算数据的协方差矩阵,再去除数据的相关性(Decorrelate),之后使用SVD进行降维,减少数据的不必要的维度,提升计算效率;
- Whitening:对Decorrelate后的数据在每个维度上除以数据的特征值,进行归一化:XWhite = Xrot/np.sqrt(S + 1e-5)。
白化的缺点在于可能会夸大数据中的噪声。
- HINT:预处理策略只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。如先计算整个数据集图像的均值然后每张图片都减去平均值,最后将整个数据集分成训练/验证/测试集,这个做法是错误的。
- 全设为0:此时所有神经元输出一样,梯度也是一样,更新方式也是一样,所以训练最终得到的神经元也是一样的;
- 一组小随机数:如使用Zero-mean,0.01标准差的高斯分布
- 此时数据前向传播时,每一层的数据mean为0左右,activation输出为0,标准差不停缩小直到0;
- 反向传播时,各层梯度也为0左右;
- 当数据量较大时,随机初始化的神经元的输出数据的方差会增大,此时可使用 w = np.random.randn(n)/sqrt(n)来使初始化的神经元的输出有相同分布
- 大一点的随机数:
- 此时weight较大,很容易导致神经元的饱和现象,导致梯度也为0;
- Xavier初始化:每一层使用不同方差的高斯分布初始化,以确保输入数据的方差和输出数据的方差差距不大;
- bias通常初始化为0;
- 正常的Normalize:
- 通常归一化是对一组数据的每一维分别进行Normalization,如X是N*D的,代表N组数据,D个维度,则分别在每一列上进行归一化;
- 通常会在(1)全连接层前(2)卷积层前进行Normalization,但是卷积层一般为了维持数据间的,会在所有的dimension和spatial locations上统一的进行Normalization;
- Batch Normalization:
- 考虑一个tanh激活函数,想通过控制Normalization的方式来控制其输出的饱和度,即调整其自变量的范围;
- Batch Normalization算法:
- 其就是对于正常Normalization的数据在进行一次scale和shift;
- 其中γ和β是可以学习的参数,当γ为X的标准差,β是X的mean,则y_i就等于x_i;
- 相对于正常的Normalization,其具有更好的灵活性,而Normalization有时可能不太合适;
- 在test时,不用专门计算这组batch的mean和std,而是使用一个empirical的值(通常是训练时各个batch的mean/var的滑动平均);
- 优点:
- 改进了整个网络的梯度流(可能是使训练时,参数收敛的更快);
- 允许更大的学习率;
- 降低了训练对于特定Initialization方式的依赖;
- 可以视为一种regularization的方式,因为batch normalization中对于一个输入X,经过处理后数据就不确定,就相当于添加了一些数据的抖动;
- 最好使用一个合理的验证集而非交叉验证;
- 先选择几个粗糙的Hyperparameter的范围,在cross-validation上跑少量次数的训练,确定大概的范围;
- 在粗糙的范围(相同数量级,或者指数变化的数据集)中随机地(而非均匀的)选择一些数据,训练更多的次数,观察曲线,进行调整;
- 所以关键的问题,就是能根据相关曲线判断这些参数应该怎么调整;
- 通常设置学习率随时间衰减,如lr = lr_0 * exp(-kt), 或者lr = lr_0 / (1+kt);
- 通常会在Momentum当中使用学习率衰减,而在Adam中用的相对较少;
- 第一次训练时不要设置衰减率,先就用正常的学习率跑一跑,观察一下结果,当什么地方loss停止下降了,就将学习率乘以一个常数(如0.5)来降低学习率;
- 预处理数据;
- 选择合适的网络结构;
- 用初始化的model进行一次forward,再加上正则化项进行一次forward,得到两个初始的cost,比对两个值看是否符合预期;
- 在一个小训练集上进行训练,看能否达到过拟合的效果;
- 使用真正的数据集,通过validation来选择合适的hyperparameter;
- 权值矩阵W的各个维度的值的尺度差距比较大,从而导致下降过程中比较曲折;
- 存在局部极值点,以及鞍点(梯度为0的点,导致停止更新),事实上高维空间中,局部极值点的影响并不太大,反而是鞍点容易导致训练的停止;
- SGD由于其随机性(stochastic),也会导致下降过程比较曲折;
- 基本的Momentum
- 这样即使在鞍点/局部极小值点,梯度为0或接近0,凭借着Momentum都可以越过这个点(想象一个小球从山上滑下,到了一个小凹坑中,凭借着其下降过程的初速度,也可以越过这个小凹坑)
- 模拟物理过程中,梯度(加速度)只影响速度,速度影响位置,ρ即摩擦力对于此前速度的值的影响;
- Nesterov Momentum
- 参数向量位于某个位置时,动量部分(忽视带梯度的第二个部分)会通过ρ*v稍微改变参数向量
- 此时使用未来的近似位置x + ρ*v处来计算梯度,看做是“向前看”;
- AdaGrad:
- 考虑各个方向的梯度值数量级存在差距,通过累加历次的平方能够平衡/减小各个方向的值的差距:这个方向梯度一直比较小,累加的和就比较小,则dx就除以一个相对小的值,得到的结果相对dx较大,反之则会除以一个比较大的值,结果恰恰相反;
- 这样就相当于learning rate根据梯度的各个维度的值做了自适应的调整,再乘以dx;
- 当迭代次数很大时,grad_squared进过很多次的累加,会非常大,导致dx/(np.sqrt(grad_squared))接近0,x基本停止更新,尤其是遇到局部极小值;
- 加上平滑项1e-7是为了防止除以0;
- RMSProp:
- 考虑到AdaGrad的缺点,设置了一个decay参数进行加权相加;
- Adam:
- 本质是将Momentum和RMSProp结合起来,其中first_moment就是Momentum项,second_moment就是RMSProp项;
- 通常beta1=0.9, beta2=0.999, lr=0.001
- 传统的梯度下降是沿当前点的一阶导数(梯度)近似的方向(切线)进行移动
- 现在考虑二阶导数(Hessian矩阵),即用一个二次函数拟合这一条曲线,以此二次函数的最小值点作为此次位置更新的终点;
- 此时无需学习率;
- 但是Hessian矩阵所占空间非常大,对于深度学习来说,会很占空间;
- 此外还有一系列的Quasi-Newton methods,如BFGS,L-BFGS等,但是这些方法通常在full batch上运行的很好,在mini batch上运行效果一般;
- 训练多个独立的模型,然后将对其权值W,偏置b求均值,用于测试,一般会得到2%的性能提升,训练这些独立模型时超参数可能是不一样的;
- 训练一个模型时记录其多个snapshot,测试时将这些snapshot求均值;
- Cyclic Learning rate:训练一个模型时,每迭代多少次,就显著的改变一次learning rate,记录以下snapshot,这样学习率一会大一会小,可能会到达模型中不同的局部极小值点,将这些model进行融合;
- Polyak averaging,一次训练得到的多个snapshot使用一个带指数权的平均;
常见的有lecture2-3所说的L1, L2, Elastic Net(L1+L2)正则化,但神经网络中也有一些自己专有的方法
- Dropout
- 基本做法:在每一次前向传播时,随机地使网络中一些层(通常是全连接层,有时也会让卷积层某个filter对应的Channel全输出0)的一部分Nruron(通常50%)全输出0,就像这些节点被删了一样,但是这样每次更新只会更新一半的神经元,使训练变慢:
还有一种dropout connect,就是随即删除连接前后神经元的边(权值),本质和正常的dropout是一样的; - 原因:
- 一种解释是Dropout就是一种Model Ensemble方法,可能相关model间共享一部分参数;
- 还有一种解释是:强迫网络拥有更强的表达能力。即删除了一部分神经元输出的特征,还能获得想要的结果(redundant representation),避免特征之间的co-adaptation导致的过拟合;
- 测试:
- 某一层的前向传播:y = Σp_z*f_z(X, W, z) =drop_rate*f(X, W),z为一种dropout删除节点的一种情况,p_z是这种情况出现的概率,f_z是带有dropout的前向传播,f是不带有dropout的前向传播,drop_rate是dropout时这层删除的节点比例;
- Inverted dropout:正常测试时需要dropout的层会乘以drop_out,为了提高测试时效率,在训练时除以drop_rate,则训练得到的W就相当于已经乘过drop_out了,测试时就无需再乘以这个缩放参数;且无论是否使用dropout,预测的代码都可以保持不变;
- 基本做法:在每一次前向传播时,随机地使网络中一些层(通常是全连接层,有时也会让卷积层某个filter对应的Channel全输出0)的一部分Nruron(通常50%)全输出0,就像这些节点被删了一样,但是这样每次更新只会更新一半的神经元,使训练变慢:
- 正则化的一般思路:
-
其实质就是在网络中添加某种随机性
- dropout随机删除一些neuron
- batch normalization在数据中添加一些噪声
- data augmentation(数据增强),如对一幅图片的label不变,而对图片本身翻转,添加噪声,修改颜色,crop size等等
- Fractional Max Pooling,并不是在2*2的window内进行pooling;
- Stochastic Depth,训练时随机删除网络的一些层
-
其实质就是在网络中添加某种随机性
- 其是为了解决数据集不够大的问题,如CV领域很多都会现用ImageNet classification task来pre-train网络,收敛后根据实际需要调整网络,并用pre-train的model中init新网络中的前面若干层,再用自己的数据集进行fine-tuning后面调整后的相关层,此时会很快收敛;