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

