1. 爲什麼選擇Pytorch?

在深度學習領域,Pytorch是近年來非常流行的框架,它以靈活、直觀、易上手著稱,特別適合初學者。相比TensorFlow等框架,Pytorch的語法更接近Python原生,代碼可讀性強,調試方便,能快速將想法轉化爲代碼。

2. 張量(Tensor):Pytorch的基石

2.1 什麼是張量?

張量可以理解爲多維數組,是Pytorch中數據的基本單位。它與NumPy的數組類似,但支持GPU加速,並且內置自動求導功能。

2.2 創建張量

import torch

# 1. 直接從數據創建
x = torch.tensor([1, 2, 3])
print(x)  # tensor([1, 2, 3])

# 2. 創建全0/全1張量
zeros = torch.zeros(2, 3)  # 2行3列全0
ones = torch.ones(2, 3)    # 2行3列全1
print(zeros, ones)

# 3. 創建隨機張量(正態分佈)
random = torch.randn(2, 3)  # 標準正態分佈(均值0,方差1)
print(random)

# 4. 從NumPy數組轉換(反之亦然)
import numpy as np
arr = np.array([[1, 2], [3, 4]])
tensor_from_np = torch.from_numpy(arr)
np_from_tensor = tensor_from_np.numpy()

2.3 張量的基本操作

# 1. 形狀操作
x = torch.tensor([[1, 2], [3, 4]])
print(x.shape)    # torch.Size([2, 2])
x_reshaped = x.view(4, 1)  # 轉換爲4行1列(-1表示自動推斷維度)
print(x_reshaped)

# 2. 算術運算
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
print(a + b)      # 元素相加:tensor([5, 7, 9])
print(a * b)      # 元素相乘:tensor([4, 10, 18])
print(torch.matmul(a, b))  # 矩陣乘法(內積):1*4 + 2*5 + 3*6 = 32

# 3. 設備轉換(CPU/GPU)
if torch.cuda.is_available():
    x = x.to('cuda')  # 轉移到GPU
    y = y.to('cuda')

3. 自動求導:PyTorch的核心

Pytorch通過autograd包實現自動微分,即自動計算梯度。這是訓練神經網絡的關鍵!

3.1 關鍵概念:requires_grad

設置requires_grad=True的張量會被追蹤其計算歷史,用於後續梯度計算。

# 定義需要計算梯度的張量
x = torch.tensor(2.0, requires_grad=True)  # 初始值2.0,需要梯度
y = x ** 2 + 3 * x - 5  # 定義函數 y = x² + 3x -5

# 計算梯度(調用backward())
y.backward()  # 反向傳播,計算所有requires_grad=True的張量的梯度

# 查看梯度:x.grad 存儲了 dy/dx
print(x.grad)  # 輸出4.0(因爲 dy/dx = 2x + 3,代入x=2得7?等下,這裏算錯了?
# 修正:y = x² + 3x -5,導數 dy/dx = 2x + 3,當x=2時,導數是2*2+3=7,所以x.grad應該是7.0?
# 哦對,我剛纔算錯了,重新計算:
x = torch.tensor(2.0, requires_grad=True)
y = x**2 + 3*x -5
y.backward()
print(x.grad)  # 應該是7.0,正確!

原理y.backward()會觸發反向傳播,計算從y到所有requires_grad=True的張量的梯度,並存儲在張量的.grad屬性中。

4. 神經網絡構建:從層到模型

Pytorch的torch.nn模塊提供了構建神經網絡的基礎組件。

4.1 基礎組件

  • 線性層(nn.Linear):全連接層,實現 \( y = Wx + b \)
  • 激活函數:ReLU, Sigmoid, Tanh等,引入非線性
  • 損失函數:MSELoss(迴歸)、CrossEntropyLoss(分類)
  • 優化器:SGD, Adam等,更新模型參數

4.2 定義簡單網絡

import torch.nn as nn

# 定義一個簡單的2層神經網絡
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        # 第一層:輸入層(20)→ 隱藏層(10),使用ReLU激活
        self.fc1 = nn.Linear(20, 10)  # 輸入維度20,輸出維度10
        self.relu = nn.ReLU()         # 激活函數
        # 第二層:隱藏層(10)→ 輸出層(1)
        self.fc2 = nn.Linear(10, 1)   # 輸出維度1

    def forward(self, x):
        # 前向傳播:x → fc1 → ReLU → fc2
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

# 實例化模型
model = SimpleNet()
print(model)

# 測試前向傳播
x_test = torch.randn(1, 20)  # 輸入:1個樣本,20個特徵
output = model(x_test)
print(output.shape)  # 輸出:torch.Size([1, 1])

4.3 組合網絡(nn.Sequential)

對於簡單的順序網絡,可以用nn.Sequential快速組合:

model = nn.Sequential(
    nn.Linear(20, 10),
    nn.ReLU(),
    nn.Linear(10, 5),
    nn.Sigmoid(),
    nn.Linear(5, 1)
)

5. 實戰:訓練線性迴歸模型

現在,我們用Pytorch訓練一個簡單的線性迴歸模型,擬合 \( y = 2x + 3 + \text{噪聲} \)

5.1 準備數據

import torch
import numpy as np
import matplotlib.pyplot as plt

# 生成模擬數據:y = 2x + 3 + 0.5*噪聲
np.random.seed(42)
x = np.random.rand(100, 1)  # 100個樣本,1個特徵
y = 2 * x + 3 + 0.5 * np.random.randn(100, 1)  # 噪聲

# 轉換爲PyTorch張量
x_tensor = torch.FloatTensor(x)
y_tensor = torch.FloatTensor(y)

5.2 定義模型、損失函數和優化器

# 1. 定義模型:線性迴歸只有一層全連接層
model = nn.Linear(in_features=1, out_features=1)  # 輸入1維,輸出1維

# 2. 定義損失函數:均方誤差(MSE)
criterion = nn.MSELoss()

# 3. 定義優化器:隨機梯度下降(SGD),學習率0.01
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

5.3 訓練模型

epochs = 1000  # 訓練輪數
for epoch in range(epochs):
    # 前向傳播:計算預測值
    y_pred = model(x_tensor)

    # 計算損失
    loss = criterion(y_pred, y_tensor)

    # 反向傳播 + 參數更新
    optimizer.zero_grad()  # 清空梯度(避免累積)
    loss.backward()        # 反向傳播,計算梯度
    optimizer.step()       # 更新參數(W和b)

    # 打印訓練過程
    if (epoch + 1) % 100 == 0:
        print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

# 訓練後,模型的參數應接近真實值 W=2, b=3
print("模型參數:")
print("W =", model.weight.item())  # 接近2
print("b =", model.bias.item())    # 接近3

5.4 可視化結果

# 繪製擬合直線
plt.scatter(x, y, label='真實數據')
plt.plot(x, model(x_tensor).detach().numpy(), 'r', label='擬合直線')
plt.legend()
plt.show()

6. 總結與進階

核心知識點回顧

  • 張量:Pytorch的基礎數據結構,支持GPU和自動求導
  • 自動求導requires_grad=True + backward()實現梯度計算
  • 神經網絡nn.Linear(全連接層)、nn.Sequential(組合網絡)、nn.Module(自定義模型)
  • 訓練流程:前向傳播→計算損失→反向傳播→參數更新

下一步學習方向

  • 數據集處理:使用torch.utils.data加載自定義數據
  • 高級優化器:嘗試Adam, RMSprop等優化算法
  • 卷積神經網絡:學習nn.Conv2d處理圖像數據
  • RNN/LSTM:處理序列數據(文本、時間序列)

推薦資源

  • 官方文檔:https://pytorch.org/docs/stable/
  • 教程:PyTorch官方教程(https://pytorch.org/tutorials/)
  • 實踐平臺:Google Colab(無需配置GPU,直接在線運行Pytorch代碼)

Pytorch的靈活性和易用性使其成爲入門深度學習的絕佳選擇。從張量開始,逐步掌握自動求導和模型構建,再通過實戰鞏固知識,你就能快速上手神經網絡訓練!

小夜