手刻 Deep Learning — 第零章 — 線性回歸

Deep Learning 屬於 Machine Learning 的一種,在我們開始手刻 Deep Learning 之前,我們需要瞭解最基本的概念

Seachaos
Published in
7 min readMar 28, 2021

--

前言

關於此系列教學

此教學會是一系列(如果本人有空會慢慢撰寫(很慢的速度)… ),我們透過萬丈高樓平地起的方式來講解 Deep Learning 如何運作,我們不講奇怪的數學公式,或是高深莫測的數學符號,希望只要有加減乘除的概念就可以理解

另外,雖然我們標題叫做手刻,但是在我們暸解原理後還是會使用現成的函數 ( PyTorch 為主 ) 來協助 ( 省時 )

基礎知識

要了解本篇內容,理論上只要知道加減乘除與國中數學的概念就夠,還有 Python 的基本知識,本文使用 NumPy 為主

關於線性回歸

Deep Learning 之前我們要先了解 Machine Learning,又在 Machine Learning 之前要先知道 Linear Regression (線性回歸),因為這是 Machine Learning 中相當重要的基礎;就像是我們做化學實驗之前要先知道分子,了解分子之前要先知道原子。

我們今天的重點就是國中數學教過的 y = ax + b

y = ax + b 畫成圖片

數學家喜歡用奇妙的符號混淆人們的視聽,猶如法條喜歡使用令人費解的詞彙 ( 也可能是本人資質愚鈍,無法領悟那些高深的符號與詞彙)

線性問題

線性這個詞說來抽象,其實就是問題是用簡單”乘法””加法”就可以解決的
例如把數學公式畫成圖片就如上圖是一條直直的線

這邊用白話文來講什麼是 y = ax + b
我們用蘋果與購物袋在賣場結帳為例:
1 顆蘋果,每顆 10 元,購物袋5 元,總價就是 15 元
2 顆蘋果,每顆 10 元,購物袋 5 元,總價就是 25 元
3 顆蘋果,每顆 10 元,購物袋 5 元,總價就是 35 元

套入 y = ax + b 的概念 :
y = 總價
x = 蘋果數量
a = 蘋果每顆價格
b = 購物袋價格

所以是 總價 = 10 * 蘋果數量 + 5

我們要解決的問題大多是已經知道蘋果的數量(x) 和 總價 (y),但是不知道蘋果的單價與購物袋的價格,要找的就是 a 與 b

例如今天有兩個賣場,我們去結帳分別得到不同的價格

賣場A [23, 26, 29]
賣場B [14, 23, 32]

以上分別是蘋果 1, 2, 3 顆的結帳價格,線性回歸就是要找出賣場 A 與賣場B 的蘋果售價/購物袋方法

使用 NumPy 解決問題

我們知道概念後,接下來就來寫程式找出 y = ax + b
套上面的範例,就是找出蘋果與購物袋價格

基本上 y = ax + b 可以解決任何簡單的線性問題
我們練習透過自創資料的方式 :

def gen_data(X, a, b):
return X * a + b
X = np.array(range(1, 10))
y = gen_data(X, a=8, b=20)

X 是蘋果數量, y 是商店個結帳價格
a 與 b 是我們要找的蘋果單價與購物袋價格
(雖然上述程式碼我們輸入 a = 8, b = 20,但我們先假裝不知道 )

因為不知道 a 與 b,所以我們先假定各為 1 , p_y 就是我們預測的價格

# 我們的預測圖,綠色
a = 1
b = 1
p_y = a * X + b

然後我們用視覺化的方式來看看誤差

價格預測

我們的目標就是要將綠色和藍色線碰再一起,如果碰在一起就表示我們已經成功猜到 a 與 b 了

print("商店價格:", y)
print("我們預測價格:", p_y)
# 商店價格: [28 36 44 52 60 68 76 84 92]
# 我們預測價格: [ 2 3 4 5 6 7 8 9 10]

開始 Linear Regression (線性回歸)

練習投藍的時後,我們需要知道籃筐位置,誤差多少,做出丟球的修正;做 Machine Learning 也是一樣道理,我們需要 :
1. 找出誤差
2. 做出修正

所以我們這邊帶入兩個觀念:
1. loss function (誤差計算,找出誤差)
2. optimizer (最佳化方法,做出修正)

我們用程式碼來看

def loss_func(y_true, y_predict):
return y_true - y_predict
def optimizer(d, loss):
return np.mean(d * loss * 0.01)

其中 loss_func 的 y_true 表示商店的真實價格,y_predict 是我們預測的價格,我們這邊採用 真實價格 減去 預測價格,就是預測的誤差

optimizer 就比較特別了,我們這邊有個參數叫做 d ,其實他是 partial derivative ,這是微積分的概念,但是我們今天只講國中數學,所以日後我們有機會再來探討這個數值怎麼計算,繼續看以下訓練範例

N = 1000
for i in range(N):
p_y = a * X + b
loss = loss_func(y, p_y)
a -= optimizer(-2 * X, loss)
b -= optimizer(-2, loss)
if i % int(N/10) == 0:
print('誤差: {:.2f}'.format(np.mean(loss)), '目前 a: {:.2f}, b: {:.2f}'.format(a, b))

上面就是我們的訓練用程式碼,跑 1000 次訓練,每 100 次 ( N/10 ) 我們印出一次誤差讓我們看看過程
其中:
a -= optimizer(-2 * X, loss)
b -= optimizer(-2, loss)
這邊就是每次的訓練我們都在調整 a 與 b,就像是我們投籃丟歪球了,每次練習都在調整力道

看一下我們訓練過程的動畫 ( 為了動畫效果,參數有調整過)

綠色是我們預測的價格,逐漸往藍色逼近

輸出如下 :

誤差: 54.00 目前 a: 7.33, b: 2.08
誤差: 2.37 目前 a: 9.83, b: 8.49
誤差: 1.57 目前 a: 9.21, b: 12.37
誤差: 1.04 目前 a: 8.80, b: 14.95
誤差: 0.69 目前 a: 8.53, b: 16.65
誤差: 0.46 目前 a: 8.35, b: 17.78
誤差: 0.30 目前 a: 8.23, b: 18.53
誤差: 0.20 目前 a: 8.15, b: 19.03
誤差: 0.13 目前 a: 8.10, b: 19.35
誤差: 0.09 目前 a: 8.07, b: 19.57
預測的 a: 8.05, b: 19.72
商店價格: [28 36 44 52 60 68 76 84 92]
我們預測價格: [27.75966319 35.80507609 43.85048899 51.89590188 59.94131478 67.98672768
76.03214058 84.07755348 92.12296638]

可以看到我們誤差正在縮小,最後的價格也越來越逼近答案

這邊附上程式碼貼圖 :

各位可以試看看將 a 與 b 改成任意數值 ( 不要太過極端以免 overflow ),在這個訓練過程中,不管 a, b 初始是多少,都會逐漸往我們正確答案靠近,為什麼會這樣呢?

這就是微積分的力量

大多的 Machine Learning 也是類似這種方法,不停的 Training ( 訓練 ) 找到答案,微積分這部分日後有空再來解說 XD

結語

今天只說到簡單的線性回歸,上面只是簡單概念,實務上會更複雜。

本文範例特別強調 loss function 與 optimizer 這兩個用法,因為這是往後 Machine Learning / Deep Learning 在實作上常用的慣例

另外還有很多基礎要談,我們才能夠開始講解 Deep Learning,希望本系列可以持續透過簡單明瞭(不使用奇妙的數學符號)的方式來解釋 Deep Learning 如何運作

下一篇:微分觀念

--

--