1.优化算法
为了说明梯度下降法、随机梯度下降法、批量梯度下降法三者区别,我们通过一组数据来拟合
梯度下降(gradient descent):在梯度下降中,对于 θ 的更新,所有的样本都有贡献,也就是所有样本参与调整
随机梯度下降(stochastic gradient descent):可以看到多了随机两个字,随机也就是说我用样本集合中的一个样本来近似我所有的样本,来调整 θ ,因而随机梯度下降是会带来一定的问题,因为计算得到的并不是准确的一个梯度,容易陷入到局部最优解中。一次迭代,只随机选一个样本来进行权值更新。使用随机梯度下降法虽然简单有效,但是它需要非常细心地调节模型hyper-parameters,特别是学习率(learning rate),以及模型参数的初始化值。
小批量梯度下降(mini-batch gradient descent):其实批量的梯度下降就是一种折中的方法,他用了一些小样本来近似全部的,用minibatch size个样本,这样比随机的要准不少了吧,而且批量的话还可以反映样本的一个分布情况的。此外,还有批量梯度下降,它是计算全部训练集样本梯度的平均,然后更新梯度。对于大规模数据集来说,比如ILSVRC,可以包含几百万个样本,若采用批量梯度下降的话,需要计算几百万次梯度计算,然后计算平均,才能更新一次参数,无论从时间效率还是内存占用来说都是不可取的,一种常用的做法将训练数据分批(batch)进行训练,称为小批量梯度下降。比如对于卷积神经网络来说,每次在训练集中选择包含256个样本的一批数据,然后使用这批数据计算梯度,完成参数更新。
损失函数在minibatch上的梯度是其在整个训练集上的估计,质量随着minibatch size的增加而提高。此外,在batch上计算更有效,数据并行计算。
在神经网络训练过程中,很少使用随机梯度下降,因为小批量梯度下降可以利用矩阵和向量计算进行加速。通常我们讲随机梯度下降(SGD)时,也可以指代小批量梯度下降。
#Python3
import random
# matrix_A 训练集
matrix_A = [[1,4], [2,5], [5,1], [4,2]]
Matrix_y = [19,26,19,20]
theta = [2,5]
#学习速率
leraing_rate = 0.005
minibatch=3;
loss = 50
iters = 1
Eps = 0.0001
#随机梯度下降
while loss>Eps and iters <1000 :
loss = 0
i = random.randint(0, 3)
h = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1]
theta[0] = theta[0] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][0]
theta[1] = theta[1] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][1]
Error = 0
Error = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1] - Matrix_y[i]
Error = Error*Error
loss = loss +Error
iters = iters +1
print ('theta=',theta)
print ('iters=',iters)
#梯度下降
while loss>Eps and iters <1000 :
loss = 0
for i in range(4):
h = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1]
theta[0] = theta[0] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][0]
theta[1] = theta[1] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][1]
for i in range(4):
Error = 0
Error = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1] - Matrix_y[i]
Error = Error*Error
loss = loss +Error
iters = iters +1
print ('theta=',theta)
print ('iters=',iters)
#小批量梯度下降
while loss>Eps and iters <1000 :
loss = 0
sampleindex = random.sample([0,1,2,3],minibatch)
for i in sampleindex :
h = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1]
theta[0] = theta[0] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][0]
theta[1] = theta[1] + leraing_rate*(Matrix_y[i]-h)*matrix_A[i][1]
for i in sampleindex :
Error = 0
Error = theta[0]*matrix_A[i][0] + theta[1]*matrix_A[i][1] - Matrix_y[i]
Error = Error*Error
loss = loss +Error
iters = iters +1
print ('theta=',theta)
print ('iters=',iters)
2.加速训练
2.1 Batch Normalization
网络训练过程中参数不断改变导致后续每一层输入的分布也发生变化,而学习的过程又要使每一层适应输入的分布,因此我们不得不降低学习率、小心地初始化,这种现象称之为 internal covariate shift.为了解决这个问题,Sergey Ioffe和Christian Szegedy在2015年提出了一个方法——Batch Normalization.
首先我们来说说Batch Normalization的好处:
(1)可以利用更高的学习速率(learning rate),
(2)不用小心翼翼初始化权重参数
(3)可以在网络中去掉Dropout,减少
(4)不需要使用使用Local Response Normalization(局部响应归一化是2012的Alexnet网络中使用)
(5)把训练数据(shuffle)打乱得更彻底(防止每批训练的时候,某一个样本都经常被挑选到,还可以提高1%的精度)
(6)最显著的好处就是加速了算法收敛速度,作者用实验证明了这一点,如下图:
算法本质:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。该归一化层,是一个可学习、有参数的网络层,不同我们一前学到的数据归一化方法。
2.2Batch Normalization算法原理
对于每层的输入:d-维向量 x=(x(1),...,x(d)) ,我们标准化每维:
这里的期望和方差都是在每个minibatch数据集合上计算的,这样的标准化可以加速算法收敛,但特征没有去相关。
这里的参数 γ 和 β 与原始模型中的参数一起学习。
m = K.mean(X, axis=-1, keepdims=True)#计算均值
std = K.std(X, axis=-1, keepdims=True)#计算标准差
X_normed = (X - m) / (std + self.epsilon)#归一化
out = self.gamma * X_normed + self.beta#重构变换
关于在实战中使用Batch Normalization可以详细阅读文献《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
3.损失函数
在监督学习问题中,用损失函数(loss function)或代价函数(cost funtion)来度量预测错误的程度,即模型 f 输出的预测值
机器学习中常见的损失函数如下:
(1)0-1损失函数(0-1 loss function)
(2)平方损失函数(quadratic loss fuction)
(3)绝对损失函数(absolute loss function)
(4)对数损失函数(logarithmic loss function),或称对数似然损失函数
Note:损失函数是度量模型一次预测的好坏,而风险函数度量平均意义下模型预测的好坏。
损失函数值越小,模型就越好,由于模型输入,输出 (X,Y) 为随机变量,遵循联合分布 P(X,Y) ,所以损失函数的期望是
上式是理论上模型 f(X) 关于联合分布 P(X,Y) 的平均意义下的损失,称为风险函数(risk function).理论上,我们机器学习的目标就是悬着期望风险最小的模型。但通常联合分布 P(X,Y) 是未知的,所以我们在对给定数据集的学习问题,我们通常做模型 f(X) 关于训练数据集的平均损失,称之为经验风险(empirical risk)或者经验损失(empirical losss),记作 Remp
由大数定律我们可以知道,当样本容量趋于无穷大时,经验风险 Remp 趋于期望风险 Rexp .但是我们在实际处理机器学习问题是,现实情况,我们获得的训练样本总是有限的,所以我们用经验分析去估计期望风险常常不是非常理想,要对经验风险进行一定修整。即在经验风险上加上模型复杂度的正则化项 Rsrm(f) ,