# 新手用:Pytorch刻線性回歸 So ez~ ## Step1: 準備資料 這裡我們使用我做實驗([相關實驗請見](https://drive.google.com/file/d/1PdaeJwapg21c5v0arAUtoCz1GRB2zqaP/view?usp=sharing))做的資料如下: |間距/第n次實驗|EXP1|EXP2|EXP3|EXP4|EXP5|$\bar x$|$\sigma$|$u_A$| |------------|----|----|----|----|----|---------|--------|----| |5cm|0.85|1.00|1.00|0.95|1.05|0.97|0.14|0.06| |6cm|0.80|0.95|0.90|1.05|1.15|0.97|0.25|0.11| |7cm|1.00|0.95|0.75|0.75|0.60|0.81|0.28|0.13| |8cm|0.85|0.71|0.71|0.65|0.65|0.72|0.14|0.06| |9cm|0.85|1.00|1.00|0.60|1.00|0.88|0.11|0.05| 其中,我們就挑間距(5cm,6cm,7cm...)當作自變數($x$),而將$\bar x$設為因變數($y$)。 **下code!** ```python= import torch x = torch.tensor([[5],[6],[7],[8],[9]],dtype=torch.float32) y = torch.tensor([[0.97],[0.97],[0.81],[0.72],[0.88]],dtype=torch.float32) ``` ## 建置網路(線性模型) 在這裡,我們要使用到 ```python= import torch.nn as nn ``` 這個模組、要用class來進行模型建置 直接看code ```python= class linearRegression(nn.Module): def __init__(self): super(linearRegression,self).__init__() self.linear = nn.Linear(1,1) def forward(self,x): x = self.linear(x) return x Linalg = linearRegression() ``` 解釋一下: 首先先從nn.Module繼承用法下來,將self.linear設為nn.Linear(1 IN 1 OUT) ## 開始訓練 首先,要先選擇誤差函數,在這裡,我們選用了MSELOSS。 MSELOSS可以想像成[最小平方法](https://hackmd.io/R6aJC9brQ1mb-zVuYZ3dBQ) $MSE = \frac{1}{n} \sum^n_{i=1}(y_i-\hat y)^2$ ```python= loss_function = nn.MSELoss() ``` 接著在選擇優化器,這邊我們用了隨機梯度下降法(SGD)$\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t, x^{(i)}, y^{(i)})$ - $\theta_t$ 是在第 $t$ 次迭代的模型參數。 - $\eta$ 是學習率,一個控制參數更新幅度的正數。 - $\nabla L(\theta_t, x^{(i)}, y^{(i)})$是損失函數 $L$ 關於參數 $\theta_t$ 的梯度,這個梯度是基於隨機選取的單個數據點 $(x^{(i)}, y^{(i)})$計算得到的。 ```python= import torch.optim as optim optimizer = torch.optim.SGD(Linalg.parameters(), lr=0.1) ``` 開始訓練! ```python= epochs = 10 for epoch in range(epochs): # 前向傳播 y_hat = Linalg(x) # 計算損失 loss = loss_function(y_hat, y) # 清零梯度 optimizer.zero_grad() # 反向傳播 loss.backward() # 更新參數 optimizer.step() torch.save(Linalg,"linalg.pt") ``` 訓練完成! ```fix= 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:00<00:00, 316.48it/s] ``` ## 推論 ```python= import torch import torch.nn as nn import torch.optim as optim from tqdm import trange import matplotlib.pyplot as plt x = torch.tensor([[5], [6], [7], [8], [9]], dtype=torch.float32) y = torch.tensor([[0.97], [0.97], [0.81], [0.72], [0.88]], dtype=torch.float32) class LinearRegression(nn.Module): def __init__(self): super(LinearRegression, self).__init__() self.linear = nn.Linear(1, 1) def forward(self, x): return self.linear(x) model = LinearRegression() loss_function = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) epochs = 100 losses = [] for epoch in trange(epochs): # 前向傳播 y_pred = model(x) loss = loss_function(y_pred, y) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() torch.save(model, "linear_regression_model.pt") plt.figure(figsize=(10, 5)) plt.plot(range(epochs), losses) plt.xlabel('Epoch') plt.ylabel('MSE Loss') plt.title('Loss Over Time') plt.show() with torch.no_grad(): predictions = model(x) plt.scatter(x.numpy(), y.numpy(), label='Actual Data', color='red') plt.plot(x.numpy(), predictions.numpy(), label='Linear Regression Line', color='blue') plt.xlabel('X') plt.ylabel('Y') plt.title('Linear Regression Model') plt.legend() plt.show() ``` ![image](https://hackmd.io/_uploads/SkRWg5jWC.png) ![image](https://hackmd.io/_uploads/ryz-eciZC.png)