10行代碼入門機器學習

最近在嗶哩嗶哩刷到一位up主,僅用了10行代碼就實現了機器學習,真讓我歎爲觀止。看視頻戳這裏python

如下是個人學習總結。bash

開始

小強會去看電影嗎?網絡

如花,小倩,小明和小強,他們是好基友,常常相約去看電影。但小強不是每次都去,如下是他們前四次相約去看電影的狀況:(1 表示去看電影,0 表示沒去看電影)dom

如花 小倩 小明 小強
1 0 1 1
1 1 0 1
0 0 1 0
0 1 0 0

假如第五次相約看電影,如花不去,小倩和小明要去,那麼小強會去嗎?機器學習

如花 小倩 小明 小強
1 0 1 1
1 1 0 1
0 0 1 0
0 1 0 0
0 1 1

咱們人腦對以上數據進行分析,很容易看出,如花去,小強就去,如花不去,小強就不去,很明顯小強對如花有意思,因此得出結論,小強不去ide

人腦思考分析的過程,怎麼轉換成讓計算機思考呢?函數

上代碼

from numpy import array, exp, random, dot
X = array([[1,0,1],[1,1,0],[0,0,1],[0,1,0]])
y = array([[1,1,0,0]]).T
random.seed(1)
weights = 2 * random.random((3,1)) - 1
for _ in range(10000):
    output = 1/(1+exp(-dot(X, weights)))
    error = y - output
    delta = error * output * (1-output)
    weights += dot(X.T, delta)
    
p = 1/(1+exp(-dot([[1,0,0]], weights)))[0][0]
print("小強去不去:", "不去" if  p > 0.5 else "去")
複製代碼

不算用於打印的代碼,恰好10行。若是不多用Python進行科學計算的同窗可能會有點矇蔽,不要着急,下面我對每行代碼進行解釋。學習

導入類庫

from numpy import array, exp, random, dot
複製代碼

numpy 能夠說是 Python 科學計算的基石,用起來很是方便。 對於數學計算方便,咱們主要導入了 array、exp、random、dot優化

  • array: 建立矩陣
  • exp:以天然常數e爲底的指數函數
  • random: 生產0~1的隨機數
  • dot: 矩陣相乘

生成數據

X = array([
[1,0,1],[1,1,0],[0,0,1],[0,1,0]
])
y = array([[1,1,0,0]]).T
複製代碼

將上表四人相約看電影的數據生成代碼,注意第二行有個 .T 是轉置的意思,將行向量轉成列向量,以下:spa

[           [
  [1,0,1],    [1],
  [1,1,0],    [1],
  [0,0,1],    [0],
  [0,1,0],    [0],    
]           ]
複製代碼

生成隨機權重

# 設置隨機因子,讓每次生成的隨機數都同樣,方便代碼調試。
random.seed(1)
# 生成一個範圍爲 -1 ~ 1,3列的行向量。
weights = 2 * random.random((3,1))-1
複製代碼

爲何要設置權重?

以第一次看電影爲例,[1,0,1] 對應 [1],他們之間存在某種關聯,以下:

1*w1 + 0*w2 + 1*w3 = 1
複製代碼

w1w2w3,表示的就是權重。

若是咱們能求出w1w2w3,是否是就能夠把第五次([0,1,1])的代入,獲得小強去不去看電影。

0*w1 + 1*w2 + 1*w3 = 小強去嗎?
複製代碼

怎麼求出權重?

咱們把第一條數據求出的權重,很難代入後面三條數據。

因此咱們隨機一組權重,代入每一組數據,獲得偏差,再修改權重,獲得新的偏差,如此反覆,直至偏差最小化,咱們就把這個過程叫作機器學習

優化權重

for _ in range(10000):
    # 用 sigmoid函數將計算結果進行轉換
    output = 1/(1+exp(-dot(X, weights)))
    # 用真實值減去計算結果求出偏差
    error = y - output
    # 計算增量
    delta = error * output*(1-output)
    # 獲得新的權重
    weights += dot(X.T, delta)
複製代碼

循環往復 10000 次,讓偏差不斷變小,最終獲得最優的權重,將權重代入第五次的數據就能夠推算出小強去不去看電影了。

爲何要用 sigmoid 函數?

因爲計算結果的範圍是正無窮到負無窮,用 sigmoid 函數轉換成 0~1,方便進行分類,好比大於0.5 去看電影,小於0.5 不去看電影。

怎麼計算增量?

delta = error * output*(1-output)
複製代碼

將上面這句分拆成兩句代碼好理解一些:

# 計算斜率,也就是對計算結果進行求導
slope = output*(1-output)

# 基於 error 計算出 delta,用於更新權重
delta = error * slope
複製代碼

斜率是什麼?

因爲計算結果被 sigmoid 函數轉換後爲0~1的平滑曲線。 要想 error 越小,計算結果就要無線趨近於0或1,越趨近於0或者1斜率越小

爲何要用讓 error 乘以斜率?

在梯度降低法中,越靠近最優勢,斜率越小,因此在斜率最小的地方,咱們要減少 delta 的變化,以避免錯過最優勢。

預測結果

p = 1/(1+exp(-dot([[1,0,0]], weights)))[0][0]
print("小強去不去:", "不去" if  p > 0.5 else "去")
// => 不去
複製代碼

將通過10000次優化後的權重代入[1,0,0],計算出 p0.9999253713868242,大於 0.5 且無限接近於1,因此小明會去看電影。

總結

以上是這10行代碼所有解讀。

這10行代碼爲了最小化所需專業知識,沒有考慮局部最優,沒有考慮計算結果收斂等問題,因此代碼不夠嚴謹,但足夠體現機器學習的整個運行機制。

經過這10行代碼,能夠體會到機器是如何模擬人類學習的——即經過不斷試錯,不斷改正,最終獲得正解。

最後很是感謝視頻做者,視頻作的真好,讓晦澀的內容變得如此通俗易懂。強烈推薦各位看一看。大話神經網絡,10行代碼不調包,聽不懂你打我!

相關文章
相關標籤/搜索