WeHelp
PyTorch 是建置、訓練、佈署現代人工智慧、深度學習、神經網路模型的核心開發套件。
  1. 簡介、安裝、快速開始
  2. Tensor 張量
  3. 定義資料集、載入器
  4. 神經網路簡介
  5. PyTorch 定義模型
  6. PyTorch 激勵函式
  7. PyTorch 損失函式
  8. PyTorch 優化器
  9. 二元分類模型範例
二元分類模型範例
以下示範使用 PyTorch 建立一個簡單的二元分類模型: - 輸入特徵:標準化後的身高、體重 - 輸出標籤:男生為 `1`,女生為 `0` - 模型:兩個線性層,中間使用 ReLU - 損失函數:`BCEWithLogitsLoss` --- ## 1. 安裝 PyTorch ```bash pip install torch numpy ``` --- ## 2. 準備資料 假設身高與體重已經標準化,也就是大致符合平均值為 0、標準差為 1。 ```python import numpy as np import torch from torch.utils.data import TensorDataset, DataLoader, random_split ``` 以下資料僅作為示範: ```python # 每一列依序為:[標準化身高, 標準化體重] X = np.array([ [-1.2, -1.0], [-0.8, -0.7], [-0.5, -0.6], [-0.3, -0.4], [ 0.2, 0.1], [ 0.4, 0.3], [ 0.8, 0.7], [ 1.0, 1.1], [ 1.2, 0.9], [-0.7, -0.2], [ 0.6, 0.5], [-0.4, -0.8], ], dtype=np.float32) # 男生為 1,女生為 0 y = np.array([ 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0 ], dtype=np.float32) # 轉換為 PyTorch Tensor X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32).reshape(-1, 1) dataset = TensorDataset(X_tensor, y_tensor) # 切分訓練集與測試集 train_size = int(0.8 * len(dataset)) test_size = len(dataset) - train_size train_dataset, test_dataset = random_split( dataset, [train_size, test_size], generator=torch.Generator().manual_seed(42) ) train_loader = DataLoader(train_dataset, batch_size=4, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=4, shuffle=False) ``` --- ## 3. 建立模型 使用兩個線性層: ```text 身高、體重 ↓ Linear(2, 8) ↓ ReLU ↓ Linear(8, 1) ↓ 輸出 logit ``` ```python import torch.nn as nn class GenderClassifier(nn.Module): def __init__(self): super().__init__() self.network = nn.Sequential( nn.Linear(2, 8), # 2 個輸入特徵,8 個隱藏神經元 nn.ReLU(), nn.Linear(8, 1) # 輸出一個 logit ) def forward(self, x): return self.network(x) model = GenderClassifier() print(model) ``` 輸出的模型結構大致如下: ```text GenderClassifier( (network): Sequential( (0): Linear(in_features=2, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=1, bias=True) ) ) ``` ### 為什麼最後不直接使用 Sigmoid? 因為使用: ```python nn.BCEWithLogitsLoss() ``` 時,損失函數已經內含 Sigmoid,數值上通常比自行先使用 Sigmoid 更穩定。 --- ## 4. 設定損失函數與最佳化器 ```python loss_function = nn.BCEWithLogitsLoss() optimizer = torch.optim.Adam( model.parameters(), lr=0.01 ) ``` 主要設定: - `BCEWithLogitsLoss`:適合二元分類 - `Adam`:常用且容易使用的最佳化器 - `lr=0.01`:學習率,控制每次更新的幅度 --- ## 5. 訓練模型 ```python num_epochs = 100 for epoch in range(num_epochs): model.train() total_loss = 0.0 for inputs, labels in train_loader: # 前向傳播 logits = model(inputs) # 計算損失 loss = loss_function(logits, labels) # 清除上一輪的梯度 optimizer.zero_grad() # 反向傳播 loss.backward() # 更新模型參數 optimizer.step() total_loss += loss.item() * inputs.size(0) average_loss = total_loss / len(train_loader.dataset) if (epoch + 1) % 10 == 0: print( f"Epoch [{epoch + 1}/{num_epochs}], " f"Loss: {average_loss:.4f}" ) ``` 每一輪訓練的主要流程是: 1. 將輸入資料送入模型 2. 計算預測值與正確答案之間的損失 3. 清除舊梯度 4. 反向傳播計算梯度 5. 使用最佳化器更新權重 --- ## 6. 評估模型準確率 模型最後輸出的是 `logit`,需要先使用 Sigmoid 轉換成機率: ```python model.eval() correct = 0 total = 0 with torch.no_grad(): for inputs, labels in test_loader: logits = model(inputs) # 將 logit 轉換為機率 probabilities = torch.sigmoid(logits) # 機率 >= 0.5 判定為男生 1,否則為女生 0 predictions = (probabilities >= 0.5).float() correct += (predictions == labels).sum().item() total += labels.numel() accuracy = correct / total print(f"Test Accuracy: {accuracy:.2%}") ``` 判斷方式: ```python probability >= 0.5 -> 男生,1 probability < 0.5 -> 女生,0 ``` --- ## 7. 預測新資料 假設新資料的身高與體重也已經使用相同方式標準化: ```python # 一筆新資料:[標準化身高, 標準化體重] new_person = torch.tensor([[0.7, 0.6]], dtype=torch.float32) model.eval() with torch.no_grad(): logit = model(new_person) probability = torch.sigmoid(logit).item() prediction = 1 if probability >= 0.5 else 0 print(f"男生機率: {probability:.4f}") print(f"預測結果: {'男生' if prediction == 1 else '女生'}") ``` --- ## 重要設定與注意事項 ### 1. 輸入形狀 每筆資料有兩個特徵: ```text [身高, 體重] ``` 因此第一層必須設定為: ```python nn.Linear(2, 8) ``` 其中: - `2`:輸入特徵數量 - `8`:隱藏層神經元數量,可自行調整 ### 2. 輸出形狀 二元分類通常只需要輸出一個數值: ```python nn.Linear(8, 1) ``` 這個數值稱為 `logit`,再透過 Sigmoid 轉換成 0 到 1 之間的機率。 ### 3. 標籤格式 因為使用 `BCEWithLogitsLoss`,標籤應為浮點數: ```python 0.0 或 1.0 ``` 而不是整數類別索引。 ### 4. 標準化資料 如果原始資料尚未標準化,可以使用: ```python X_standardized = (X - mean) / std ``` 實務上應該只用訓練集計算 `mean` 和 `std`,再套用到驗證集、測試集及新資料,避免資料洩漏。 ### 5. 性別預測的實務限制 身高和體重未必能可靠判斷個人性別,實際資料可能存在大量重疊。因此此範例主要用來示範 PyTorch 的模型建置與訓練流程,不代表這是一個適合實務使用的性別分類方法。
相關學習地圖、教學課程
Python 人工智慧
建議完成「Python 資料工程」教程後,繼續學習以下課程。