---
# System prepended metadata

title: '新手用:Pytorch刻線性回歸'

---

# 新手用: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)
