梯度下降法的三种形式BGD、SGD以及MBGD (2)

随机梯度下降是通过每个样本来迭代更新一次,对比上面的批量梯度下降,迭代一次需要用到所有训练样本(往往如今真实问题训练数据都是非常巨大),一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。

随机梯度下降收敛图如下:

梯度下降法的三种形式BGD、SGD以及MBGD

我们可以从图中看出SGD迭代的次数较多,在解空间的搜索过程看起来很盲目。但是大体上是往着最优值方向移动。

min-batch 小批量梯度下降法MBGD

我们从上面两种梯度下降法可以看出,其各自均有优缺点,那么能不能在两种方法的性能之间取得一个折衷呢?即,算法的训练过程比较快,而且也要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷。

我们假设每次更新参数的时候用到的样本数为10个(不同的任务完全不同,这里举一个例子而已

更新伪代码如下:

梯度下降法的三种形式BGD、SGD以及MBGD

实例以及代码详解

这里参考他人博客,创建了一个数据,如下图所示:

梯度下降法的三种形式BGD、SGD以及MBGD

待训练数据A、B为自变量,C为因变量。

我希望通过这些训练数据给我训练出一个线性模型,用于进行下面数据的预测,test集合如下:

梯度下降法的三种形式BGD、SGD以及MBGD

比如我们给出(3.1,5.5)希望模型预测出来的值与我们给定的9.5的差别是多少?这不是重点,重点是我们训练模型过程中的参数更新方法(这是我们这篇文章的重点)批梯度下降以及随机梯度下降代码如何实现。下面分别来讲:

首先我们看批梯度下降法的代码如下:

梯度下降法的三种形式BGD、SGD以及MBGD

这里有可能还是比如抽象,为了让大家更好的弄懂理解这俩个重要的方法,我下面结合例子,一行一行代码解释:

梯度下降法的三种形式BGD、SGD以及MBGD

我们看随机梯度下降法的代码如下:

梯度下降法的三种形式BGD、SGD以及MBGD

与批梯度下降最大的区别就在于,我们这里更新参数的时候,并没有将所有训练样本考虑进去,然后求和除以总数,而是我自己编程实现任取一个样本点代码中random函数就能清楚看到),然后利用这个样本点进行更新!这就是最大的区别!

那么到这个时候,我们也非常容易知道小批量随机梯度下降法的实现就是在这个的基础上,随机取batch个样本,而不是1个样本即可,掌握了本质就非常容易实现!

下面给出这个线性模型所有代码,训练,预测以及结果供参考:

1 #coding=utf-8 2 import numpy as np 3 import random 4 5 #下面实现的是批量梯度下降法 6 def batchGradientDescent(x, y, theta, alpha, m, maxIterations): 7 xTrains = x.transpose() #得到它的转置 8 for i in range(0, maxIterations): 9 hypothesis = np.dot(x, theta) 10 loss = hypothesis - y 11 # print loss 12 gradient = np.dot(xTrains, loss) / m #对所有的样本进行求和,然后除以样本数 13 theta = theta - alpha * gradient 14 return theta 15 16 #下面实现的是随机梯度下降法 17 def StochasticGradientDescent(x, y, theta, alpha, m, maxIterations): 18 data = [] 19 for i in range(10): 20 data.append(i) 21 xTrains = x.transpose() #变成3*10,没一列代表一个训练样本 22 # 这里随机挑选一个进行更新点进行即可(不用像上面一样全部考虑) 23 for i in range(0,maxIterations): 24 hypothesis = np.dot(x, theta) 25 loss = hypothesis - y #注意这里有10个样本的,我下面随机抽取一个进行更新即可 26 index = random.sample(data,1) #任意选取一个样本点,得到它的下标,便于下面找到xTrains的对应列 27 index1 = index[0] #因为回来的时候是list,我要取出变成int,更好解释 28 gradient = loss[index1]*x[index1] #只取这一个点进行更新计算 29 theta = theta - alpha * gradient.T 30 return theta 31 32 def predict(x, theta): 33 m, n = np.shape(x) 34 xTest = np.ones((m, n+1)) #在这个例子中,是第三列放1 35 xTest[:, :-1] = x #前俩列与x相同 36 res = np.dot(xTest, theta) #预测这个结果 37 return res 38 39 trainData = np.array([[1.1,1.5,1],[1.3,1.9,1],[1.5,2.3,1],[1.7,2.7,1],[1.9,3.1,1],[2.1,3.5,1],[2.3,3.9,1],[2.5,4.3,1],[2.7,4.7,1],[2.9,5.1,1]]) 40 trainLabel = np.array([2.5,3.2,3.9,4.6,5.3,6,6.7,7.4,8.1,8.8]) 41 m, n = np.shape(trainData) 42 theta = np.ones(n) 43 alpha = 0.1 44 maxIteration = 5000 45 #下面返回的theta就是学到的theta 46 theta = batchGradientDescent(trainData, trainLabel, theta, alpha, m, maxIteration) 47 print "theta = ",theta 48 x = np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], [3.7, 6.7], [3.9, 7.1]]) 49 print predict(x, theta) 50 theta = StochasticGradientDescent(trainData, trainLabel, theta, alpha, m, maxIteration) 51 print "theta = ",theta 52 x = np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], [3.7, 6.7], [3.9, 7.1]]) 53 print predict(x, theta) 54 #yes,is the code

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwgxfd.html