線性回歸(WiKi)學校上過,不過從來也沒搞懂是做什麼用的。簡單的說就是為一堆散落的點,找出一個最小差距的公式。
網路上對線性迴歸的機器學習範例比較多,所以就從這篇開始學習。另外一個是分類問題,也會再後續有學習心得再記錄下來,本文是參考這個 Youtube 影片。
影片內的程式是對 x^2 做線性回歸,我自己練習是做加法的線性回歸。
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# -*- coding: utf-8 -*- import torch from torch import nn import torch.nn.functional as F device = "cuda" if torch.cuda.is_available() else "cpu" class NeuralNetwork(nn.Module): def __init__(self, n_feature, n_hidden, n_output): super(NeuralNetwork, self).__init__() self.hidden = torch.nn.Linear(n_feature, n_hidden) self.predict = torch.nn.Linear(n_hidden, n_output) def forward(self, k): k = F.relu(self.hidden(k)) k = self.predict(k) return k DIV=1000 n_batch=5000 model = NeuralNetwork(n_feature=2, n_hidden=10, n_output=1) model.to(device) optimizer = torch.optim.SGD(model.parameters(), lr=0.1) loss_func = torch.nn.MSELoss() # this is for regression mean squared loss def train(epoch): for i in range(100): output = model(x) loss = loss_func(output, y) optimizer.zero_grad() loss.backward() optimizer.step() print(f'Loss {loss} Epoch {epoch}') x = torch.randint(0, int(DIV/10)-1, (n_batch,2)).to(device).float() / DIV y = torch.zeros(n_batch,1).to(device) x[0][0] = 0.056 x[0][1] = 0.035 for i in range(n_batch): y[i][0] = x[i][0] + x[i][1] for epoch in range(100): train(epoch) with torch.no_grad(): q = torch.zeros(1,2).to(device) q[0][0] = 0.056 q[0][1] = 0.035 output2 = model(x) print(output2[0]) print("Device is " + device) |
幾個小筆記
- NeuralNetwork() 是主要的學習網路,輸入參數2個,中間層10個參數,輸出層1個。學傳統程式的人可能會看不懂這是在幹麻,只宣告了 input, output與 hidden 參數,怎麼可以得出結果。機器學習即是透過調整10個中間層參數,來對照出輸結果與正確結果的差距,來產生一組最佳參數,最貼近答案。
- foward() 即是丟進資料時的處理,先將資料丟入 hidden 層,得到結果。得到的結果會先呼叫一個 F.relu() 來將結果做處理,大於0則為原值,小於0則為0。然後處理後的結果餵給 predict 層,並將結果傳回。至於為什麼要 relu 這個動作,我也不太清楚,應該與模型的自動計算有關吧。
- optimizer() 是自動調整這些參數的功能,而 loss_func 則是計算正確答案與訓練結果的差距。
- Torch 對於資料的處理,似忽要以浮點數處理,才能有正確的結果,這邊還不是很瞭解。所以這邊都會將要處理的數字,先除1000。
- 最後訓練完後,會丟入一個 0.056 + 0.035 的測試,來看推論出來的結果是否貼結真實答案。這裡發現如果預先訓時就用過這個值,那最後測試時的結果都會很接近。但若訓練過程中沒出現這個數值,則會有較大的差距。這其實也是合理的,因為訓練時如果參數已有為這個數值做過調整,就可以有比較好的答案。
以上是自己的筆記,還有很多猜測的部份,請讀者參考即可。