Pytorch 實現簡單線性迴歸
問題描述:
使用 pytorch 實現一個簡單的線性迴歸。
受教育年薪與收入資料集
單變數線性迴歸
單變數線性迴歸演算法(比如,$x$ 代表學歷,$f(x)$ 代表收入):
$f(x) = w*x + b $
我們使用 $f(x)$ 這個函式來對映輸入特徵和輸出值。
目標:
預測函式 $f(x)$ 與真實值之間的整體誤差最小。
損失函式:
使用均方差作為作為成本函式。
也就是預測值和真實值之間差的平方取均值。
成本函式與損失函式:
優化的目標( $y$ 代表實際的收入):
找到合適的 $w$ 和 $b$ ,使得 $(f(x) - y)^{2}$越小越好
注意:現在求解的是引數 $w$ 和 $b$。
過程
1 匯入實驗所需要的包
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from torch import nn
#解決核心掛掉
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
2 讀取資料
data = pd.read_csv('dataset/Income1.csv')
print(type(data))
<class 'pandas.core.frame.DataFrame'>
3 檢視資料資訊
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 30 entries, 0 to 29
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0 30 non-null int64
1 Education 30 non-null float64
2 Income 30 non-null float64
dtypes: float64(2), int64(1)
memory usage: 848.0 bytes
檢視資料
data
檢視資料型別
type(data.Education)
pandas.core.series.Series
4 圖表顯示資料from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 雅黑字型
plt.scatter(data.Education,data.Income)
plt.xlabel("受教育年限")
plt.ylabel("工資")
plt.show()
5 轉換資料為 Tensor 型別
檢視特徵資料
data.Education
0 10.000000
1 10.401338
2 10.842809
3 11.244147
4 11.645485
5 12.086957
6 12.488294
7 12.889632
檢視特徵資料 index
data.Education.index
RangeIndex(start=0, stop=30, step=1)
檢視特徵資料 value
data.Education.values
array([10. , 10.40133779, 10.84280936, 11.24414716, 11.64548495,
12.08695652, 12.48829431, 12.88963211, 13.2909699 , 13.73244147,
14.13377926, 14.53511706, 14.97658863, 15.37792642, 15.77926421,
16.22073579, 16.62207358, 17.02341137, 17.46488294, 17.86622074,
18.26755853, 18.7090301 , 19.11036789, 19.51170569, 19.91304348,
20.35451505, 20.75585284, 21.15719064, 21.59866221, 22. ])
特徵資料變換形狀
data.Education.values.reshape(-1,1)
array([[10. ],
[10.40133779],
[10.84280936],
[11.24414716],
[11.64548495],
[12.08695652],
[12.48829431],
[12.88963211],
[13.2909699 ],
[13.73244147],
[14.13377926],
[14.53511706],
[14.97658863],
[15.37792642],
[15.77926421],
[16.22073579],
[16.62207358],
[17.02341137],
[17.46488294],
[17.86622074],
[18.26755853],
[18.7090301 ],
[19.11036789],
[19.51170569],
[19.91304348],
[20.35451505],
[20.75585284],
[21.15719064],
[21.59866221],
[22. ]])
檢視特徵資料變換後的形狀
data.Education.values.reshape(-1,1).shape
檢視特徵資料變換後的資料型別
type(data.Education.values.reshape(-1,1))
numpy.ndarray
修改特徵資料變換後的資料型別
X = data.Education.values.reshape(-1,1).astype(np.float32)
print(type(X))
X.shape
特徵資料和標籤轉換為Tensor
X = torch.from_numpy(data.Education.values.reshape(-1,1).astype(np.float32) ) #轉換資料型別
Y = torch.from_numpy(data.Income.values.reshape(-1,1).astype(np.float32) ) #轉換資料型別
6 定義模型
定義線性迴歸模型:
model = nn.Linear(1,1) #w@input+b 等價於model(input)
定義均方損失函式
loss_fn = nn.MSELoss() #定義均方損失函式
定義優化器
opt = torch.optim.SGD(model.parameters(),lr=0.00001)
7 模型訓練
for epoch in range(200):
for x, y in zip(X,Y):
y_pred = model(x) #使用模型預測
loss = loss_fn(y,y_pred) #根據預測計算損失
opt.zero_grad() #進行梯度清零
loss.backward() #求解梯度
opt.step() #優化模型引數
8 輸出權重和偏置
model.weight
model.bias
Tensor 型別資料帶梯度轉換為numpy需要先去梯度
type(model.weight.detach().numpy())
numpy.ndarray
9 獲取預測值 y_pred
model(X).data.numpy()
預測值型別
type(model(X).data.numpy())
numpy.ndarray
預測值size
model(X).data.numpy().shape
(30, 1)
10 繪製迴歸曲線
plt.scatter(data.Education,data.Income)
plt.plot(X.numpy(),model(X).data.numpy())
plt.xlabel("受教育年限")
plt.ylabel("工資")
plt.show()
完整程式碼:
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from torch import nn
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
data = pd.read_csv('dataset/Income1.csv')
print(type(data))
data.info()
data
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 雅黑字型
plt.scatter(data.Education,data.Income)
plt.xlabel("受教育年限")
plt.ylabel("工資")
plt.show()
X = torch.from_numpy(data.Education.values.reshape(-1,1).astype(np.float32) ) #轉換資料型別
Y = torch.from_numpy(data.Income.values.reshape(-1,1).astype(np.float32) ) #轉換資料型別
model = nn.Linear(1,1) #w@input+b 等價於model(input)
loss_fn = nn.MSELoss() #定義均方損失函式
opt = torch.optim.SGD(model.parameters(),lr=0.00001)
for epoch in range(200):
for x, y in zip(X,Y):
y_pred = model(x) #使用模型預測
loss = loss_fn(y,y_pred) #根據預測計算損失
opt.zero_grad() #進行梯度清零
loss.backward() #求解梯度
opt.step() #優化模型引數
print(f'epoch {epoch + 1}, loss {loss.sum():f}')
model.weight
model.bias
type(model.weight.detach().numpy())
plt.scatter(data.Education,data.Income)
plt.plot(X.numpy(),model(X).data.numpy())
plt.xlabel("受教育年限")
plt.ylabel("工資")
plt.show()
看完點個關注唄!!(總結不易)