之所以叫盒飯版算法,是希望能在最短時間講一些沒那么正式的東西。
在機器學習里,我們通常用優化方法來計算模型的未知參數,隨機梯度下降方法(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 有兩個參數(對標準型而言):學習率(Learning Rate)和迭代次數(Epochs)。計算參數是一個比較費時的工作,有點像學英語,一天肯定學不會,每天只能學會一點,這個大概就是學習率。既然忘了,就得反復學,這就是迭代,有些人聰明,學一兩年就學會了,有些人差一點,像我學了幾十年,還沒有訓練出一個好的語言模型。
上圖說,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的程序。
這個程序得在python3上運行,如果在python2運行的話,第一個迭代結束后,程序就結束了。我寫了一個類似的R語言腳本,運行后遇到了同樣的問題。折騰了很久之后,我問了阿澤,他看了一眼說:用py3。python這事解決了,但是R那個坑還在。
R語言腳本如下所示:
問題應該出在方框中的那三層循環里,稍微改了一下之后,還是把這個坑填了,只是走的路有點長,全局變量和局部變量,總是要在腦子里轉幾圈才行。
這就是今天的盒飯版算法之隨機梯度下降方法(SGD)。大家可以關注下大洋彼岸的這些博客,可以學英文,學算法,學編程,還可以找出一些小錯誤,例如這篇博客的程序更像是梯度下降方法,“隨機”那部分并沒有體現,還有其他小問題,不過用來展示原理的話,這些可以接受。
要不你們也贊賞一下我吧,看能不能湊足一個飯盒。