梯度下降的三种形式——BGD、SGD、MBGD
機(jī)器學(xué)習(xí)里面,梯度下降法可以說是隨處可見,雖然它不是什么高大上的機(jī)器學(xué)習(xí)算法,但是它卻是用來解決機(jī)器學(xué)習(xí)算法的良藥。我們經(jīng)常會(huì)用到梯度下降法來對(duì)機(jī)器學(xué)習(xí)算法進(jìn)行訓(xùn)練。
BGD,SGD,MBGD。也就是批量梯度下降法BGD,隨機(jī)梯度下降法SGD,小批量梯度下降法MBGD。
下面這篇文章對(duì)這三個(gè)概念講解的很到位:
http://www.cnblogs.com/maybe2030/p/5089753.html#_label0
總結(jié)一下:
1、批量梯度下降每次更新使用了所有的訓(xùn)練數(shù)據(jù),最小化損失函數(shù),如果只有一個(gè)極小值,那么批量梯度下降是考慮了訓(xùn)練集所有的數(shù)據(jù),是朝著最小值迭代運(yùn)動(dòng)的,但是缺點(diǎn)是如果樣本值很大的話,更新速度會(huì)很慢。
2、隨機(jī)梯度下降在每次更新的時(shí)候,只考慮一個(gè)樣本點(diǎn),這樣會(huì)大大加快訓(xùn)練數(shù)據(jù),也恰好是批量梯度下降的缺點(diǎn),但是有可能由于訓(xùn)練數(shù)據(jù)的噪聲點(diǎn)較多,那么每一次利用噪聲點(diǎn)進(jìn)行更新的過程中,就不一定是朝著極小值方向更新,但是由于更新多輪,整體方向還是朝著極小值方向更新,又提高了速度。
3、小批量梯度下降法是為了解決批量梯度下降的訓(xùn)練速度慢,以及隨機(jī)梯度下降法的準(zhǔn)確性綜合而來,但是這里注意,不同問題的batch是不一樣的,要通過實(shí)驗(yàn)結(jié)果來進(jìn)行超參數(shù)的調(diào)整。
參考python代碼:
# coding=utf-8import numpy as np import matplotlib.pyplot as plt# 構(gòu)造數(shù)據(jù) def get_data(sample_num=1000):"""擬合函數(shù)為y = 5*x1 + 7*x2:return:構(gòu)造1000組數(shù)據(jù)集(x1,x2,y)"""'''生成具有sample_num=1000個(gè)等間隔元素的范圍是[0,9]的一個(gè)數(shù)列'''x1 = np.linspace(0, 9, sample_num)x2 = np.linspace(4, 13, sample_num)'''將x1,x2合并成2*sample_num的矩陣并轉(zhuǎn)置,最終是sample_num*2的矩陣'''x = np.concatenate(([x1], [x2]), axis=0).T'''x.dot(y) 等價(jià)于 np.dot(x,y) 兩個(gè)矩陣相乘'''y = np.dot(x, np.array([5, 7]).T)return x, y# 梯度下降法 def SGD(samples, y, step_size=0.1, max_iter_count=2000):""":param samples: 樣本:param y: 結(jié)果value:param step_size: 每一接迭代的步長(zhǎng):param max_iter_count: 最大的迭代次數(shù):param batch_size: 隨機(jī)選取的相對(duì)于總樣本的大小:return:"""# 確定樣本數(shù)量以及變量的個(gè)數(shù)初始化theta值m, var = samples.shape # m=1000是行,var=2是列theta = np.zeros(2)'''flatten,把y降到一維,默認(rèn)是按橫的方向降。y.flatten('F')按豎的方向降。此處就是將y進(jìn)行轉(zhuǎn)置'''y = y.flatten()# 進(jìn)入循環(huán)內(nèi)loss = 1iter_count = 0iter_list = []loss_list = []theta1 = []theta2 = []# 當(dāng)損失精度大于0.01且迭代此時(shí)小于最大迭代次數(shù)時(shí),進(jìn)行while loss > 0.01 and iter_count < max_iter_count:loss = 0# 梯度計(jì)算theta1.append(theta[0])theta2.append(theta[1])# 樣本維數(shù)下標(biāo)rand1 = np.random.randint(0, m, 1) # 生成大小在范圍[0,m]內(nèi)的一個(gè)隨機(jī)數(shù)h = np.dot(theta, samples[rand1].T) # samples[rand1]第rand1行# 關(guān)鍵點(diǎn),只需要一個(gè)樣本點(diǎn)來更新權(quán)值for i in range(len(theta)):theta[i] = theta[i] - step_size * (1/m) * (h - y[rand1]) * samples[rand1, i]"""# batch_size = np.random.randint(0, m, 1)batch_size = range(1, m)batch_size = np.array(batch_size)(si,) = batch_size.shapedev = 0for i in range(len(theta)):for j in batch_size:h = np.dot(theta, samples[j].T)dev = dev + (1 / si) * (h - y[j]) * samples[j, i]theta[i] = theta[i] - step_size * dev"""# 計(jì)算總體的損失精度,等于各個(gè)樣本損失精度之和for i in range(m):h = np.dot(theta.T, samples[i])# 每組樣本點(diǎn)損失的精度every_loss = (1 / (var * m)) * np.power((h - y[i]), 2)loss = loss + every_lossprint("iter_count: ", iter_count, "the loss:", loss)iter_list.append(iter_count)loss_list.append(loss)iter_count += 1plt.plot(iter_list, loss_list)plt.xlabel("iter")plt.ylabel("loss")plt.show()return theta1, theta2, theta, loss_listif __name__ == '__main__':samples, y = get_data()theta1, theta2, theta, loss_list = SGD(samples, y)print(theta) # 會(huì)很接近[5, 7]總結(jié)
以上是生活随笔為你收集整理的梯度下降的三种形式——BGD、SGD、MBGD的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Noise Contrastive Es
- 下一篇: 各类范数概念