盒飯版算法之隨機梯度下降方法(SGD)

之所以叫盒飯版算法,是希望能在最短時間講一些沒那么正式的東西。

在機器學習里,我們通常用優化方法來計算模型的未知參數,隨機梯度下降方法(SGD)是其中一種優化方法。

下面這篇博客介紹了如何用SGD來獲得一個線性模型。
https://machinelearningmastery.com/implement-linear-regression-stochastic-gradient-descent-scratch-python/

我截取其中一段來講。這篇文章講的SGD只能算是標準型,如果想了解更專業的,可以參考R語言的工具包sgd:
https://github.com/airoldilab/sgd/blob/master/README.md

SGD 的兩個參數

SGD 有兩個參數(對標準型而言):學習率(Learning Rate)和迭代次數(Epochs)。計算參數是一個比較費時的工作,有點像學英語,一天肯定學不會,每天只能學會一點,這個大概就是學習率。既然忘了,就得反復學,這就是迭代,有些人聰明,學一兩年就學會了,有些人差一點,像我學了幾十年,還沒有訓練出一個好的語言模型。

SGD之打鐵循環

上圖說,SGD有三個循環過程:1、把所有的迭代都循環一遍;2、每次迭代中把所有的訓練數據循環一遍;3、每次用到一條訓練數據時把所有的參數都更新一遍。

參數是怎么更新的呢?

參數更新依靠誤差。誤差從哪里來?今天想學100個單詞,結果只學會了50個,誤差就是沒學會的那50個,第二天想把沒學會的50個單詞學會,結果記下了10個,誤差縮小到40個,然后是第三天、第四天,運氣好的時候,10天記下100個單詞。像我把單詞記在大腦內存里,睡前總是忘了存盤,第二天一早發現大腦內存清空了,昨天記的單詞就都忘記了,偶爾我還是會存盤的,一年半載之后,還是會記住這100個單詞的。

參數更新

每次參數更新除了和誤差有關之外,還和學習率有關,而且每個參數是基于特定數據進行更新的,例如這里b1這個參數的更新基于某一輸入變量x1,因為是線性模型,所以只有x1,如果是非線性模型,就可能是x1、x2...了。

還有一個特殊參數

還有一個特殊參數,叫做截距或偏差(bias)。這個bias的更新和其他參數的更新類似,只是不依賴任何輸入變量。從這個角度講,這個bias和機器學習里的偏差-方差分解(bias-variance decomposition)是不同的,大家學習的時候,不要混淆了。

有了循環框架和參數更新的策略,我們就能得到下面 SGD的程序。

SGD程序標準型python版

這個程序得在python3上運行,如果在python2運行的話,第一個迭代結束后,程序就結束了。我寫了一個類似的R語言腳本,運行后遇到了同樣的問題。折騰了很久之后,我問了阿澤,他看了一眼說:用py3。python這事解決了,但是R那個坑還在。

R語言腳本如下所示:

食之無味,棄之可惜

問題應該出在方框中的那三層循環里,稍微改了一下之后,還是把這個坑填了,只是走的路有點長,全局變量和局部變量,總是要在腦子里轉幾圈才行。

結果和python一樣

這就是今天的盒飯版算法之隨機梯度下降方法(SGD)。大家可以關注下大洋彼岸的這些博客,可以學英文,學算法,學編程,還可以找出一些小錯誤,例如這篇博客的程序更像是梯度下降方法,“隨機”那部分并沒有體現,還有其他小問題,不過用來展示原理的話,這些可以接受。

要不你們也贊賞一下我吧,看能不能湊足一個飯盒。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容