1. 前言:PyTorch 與 CNN 概述
什麼是 PyTorch?
PyTorch 是由 Facebook(現為 Meta)開發的開源機器學習函式庫。它專為 Python 設計,能輕鬆構建、訓練與評估神經網路。由於程式碼直觀易懂,在研究人員與開發者之間非常受歡迎。
什麼是 CNN(卷積神經網路)?
CNN(Convolutional Neural Network,卷積神經網路)是一種專門用於圖像和影片辨識的神經網路。它模擬人類視覺的處理方式,能從資料中自動擷取特徵,廣泛應用於圖像分類與物體偵測等領域。
CNN 的基本結構
CNN 主要由以下幾層組成:
- 卷積層(Convolutional Layer)
用來擷取圖像的局部特徵(例如邊緣與顏色等),透過稱為「濾波器」的小型矩陣進行卷積運算。 - 池化層(Pooling Layer)
縮小特徵圖的尺寸以降低計算成本。常見方法為最大池化(Max Pooling),保留特徵中最明顯的部分。 - 全連接層(Fully Connected Layer)
利用前面提取的特徵進行最終的分類或預測。 - 激活函數(Activation Function)
進行非線性轉換,使網路能學習更複雜的模式。常用函數為 ReLU(修正線性單元)。
為什麼 PyTorch 與 CNN 是強大的組合?
PyTorch 採用動態計算圖的特性,使得撰寫與修改模型更加靈活,適合進行實驗性研究或原型開發。此外,還支援 GPU 加速運算,可應對大規模資料。
實際應用案例
PyTorch 與 CNN 可應用於以下領域:
- 圖像分類(如區分貓與狗)
- 人臉識別系統
- 自駕車的影像處理
- 醫療影像診斷(如 MRI 或 X 光分析)
- 風格轉換與影像修復
小結
本節介紹了 PyTorch 與 CNN 的基本概念,以及兩者結合所具備的強大優勢。
2. PyTorch 與 CNN 的準備工作:環境建置與安裝方法
PyTorch 的安裝方法與初始設定
1. 開發環境準備
使用 PyTorch 前需要先安裝 Python。推薦使用的整合開發環境(IDE)有 Visual Studio Code、Jupyter Notebook 或 Google Colab 等,能提升開發效率。
2. PyTorch 安裝步驟
以下是在本機端安裝 PyTorch 的基本步驟:
- 安裝 Python
- 前往 Python 官方網站(https://www.python.org/)下載並安裝最新版。
- 建立虛擬環境
python -m venv pytorch_env
source pytorch_env/bin/activate # Mac/Linux
pytorch_env\Scripts\activate # Windows
- 安裝 PyTorch
可透過 PyTorch 官方網站(https://pytorch.org/)產生對應環境的安裝指令。
以下為支援 GPU 的安裝範例:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
- 確認安裝成功
import torch
print(torch.__version__) # 顯示版本
print(torch.cuda.is_available()) # 檢查是否可使用 GPU
在 Google Colab 建立開發環境
1. 使用 Google 帳戶登入
前往 Google Colab(https://colab.research.google.com/)並使用 Google 帳戶登入。
2. 設定執行環境
點選上方選單的「執行階段」→「變更執行階段類型」,將硬體加速器設為「GPU」。
3. 確認 PyTorch 版本
import torch
print(torch.__version__)
如有需要也可安裝最新版:
!pip install torch torchvision torchaudio
準備資料集與前處理
1. 下載資料集
PyTorch 提供名為 torchvision 的套件來簡化資料集的使用。以下以 CIFAR-10 為例進行說明:
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
trainset = torchvision.datasets.CIFAR10(
root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(
trainset, batch_size=32, shuffle=True)
2. 資料前處理
- 正規化: 將資料縮放至 0~1 範圍,以穩定學習過程。
- 資料擴增: 利用隨機旋轉或翻轉等方法增加資料量,避免過擬合。
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomCrop(32, padding=4),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
3. 設定資料載入器
資料載入器可進行批次處理,將資料分批供應給模型訓練。
trainloader = torch.utils.data.DataLoader(
trainset, batch_size=32, shuffle=True, num_workers=2)
小結
本節說明了 PyTorch 的安裝流程與在 Google Colab 上建立開發環境的方式,並透過 CIFAR-10 展示了圖像資料的前處理與載入方式。
3. 使用 PyTorch 建構 CNN 模型【附程式碼範例】
CNN 模型的基本架構與自訂範例
1. CNN 模型的基本結構
CNN 模型會從圖像資料中提取特徵,並依此進行分類。其基本架構如下:
- 卷積層(Convolutional Layer) – 負責提取圖像特徵。
- 池化層(Pooling Layer) – 壓縮特徵數據,降低計算量。
- 全連接層(Fully Connected Layer) – 最終進行分類的層。
- 激活函數(Activation Function) – 應用非線性轉換,使模型能學習更複雜的模式。
本節將介紹如何在 PyTorch 中組合這些層來建立一個簡單的 CNN 模型。
使用 PyTorch 實作 CNN 的步驟
1. 匯入必要的函式庫
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
2. 準備資料集
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)
testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False)
3. 建立 CNN 模型
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 卷積層1
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
# 卷積層2
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 卷積層3
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
# 池化層
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 全連接層
self.fc1 = nn.Linear(128 * 4 * 4, 256)
self.fc2 = nn.Linear(256, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x))) # 卷積層1 → ReLU → 池化
x = self.pool(F.relu(self.conv2(x))) # 卷積層2 → ReLU → 池化
x = self.pool(F.relu(self.conv3(x))) # 卷積層3 → ReLU → 池化
x = x.view(-1, 128 * 4 * 4) # 將特徵圖展平為一維
x = F.relu(self.fc1(x)) # 全連接層1 → ReLU
x = self.fc2(x) # 全連接層2 → 輸出
return x
4. 建立模型實例並確認架構
model = SimpleCNN()
print(model)
5. 設定損失函數與最佳化器
criterion = nn.CrossEntropyLoss() # 損失函數:交叉熵
optimizer = optim.Adam(model.parameters(), lr=0.001) # 最佳化器:Adam
小結
本節介紹了如何使用 PyTorch 建立一個簡單的 CNN 模型,包括卷積層、池化層、全連接層等的實作方式。透過這個流程,你應該已能掌握 CNN 模型的基本結構與實作方式。
4. CNN 模型的訓練與評估【實際範例教學】
使用 PyTorch 訓練 CNN 模型的步驟
1. 訓練流程準備
在模型訓練過程中,通常會依以下步驟處理資料:
- 前向傳播(Forward Propagation): 將輸入資料傳入模型以計算預測結果。
- 損失計算: 比較預測結果與真實標籤的差異(誤差)。
- 反向傳播(Backward Propagation): 根據誤差更新模型中各層的參數。
- 使用最佳化器進行更新: 根據學習率調整參數,優化模型。
以下是上述流程的實作程式碼範例:
# 建立模型、損失函數與最佳化器
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 執行訓練
n_epochs = 10 # 訓練輪數
for epoch in range(n_epochs):
running_loss = 0.0
for inputs, labels in trainloader:
# 清除梯度
optimizer.zero_grad()
# 前向傳播
outputs = model(inputs)
# 損失計算
loss = criterion(outputs, labels)
# 反向傳播
loss.backward()
# 更新權重
optimizer.step()
# 紀錄損失
running_loss += loss.item()
# 顯示每輪的損失
print(f"Epoch {epoch+1}/{n_epochs}, Loss: {running_loss / len(trainloader):.4f}")
使用測試資料評估模型並分析結果
1. 評估模型的效能
利用測試資料來評估模型的分類準確度。以下為範例程式碼:
correct = 0
total = 0
# 切換為評估模式
model.eval()
with torch.no_grad(): # 關閉梯度計算
for inputs, labels in testloader:
outputs = model(inputs)
_, predicted = torch.max(outputs, 1) # 選取機率最高的類別
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f'Accuracy: {accuracy:.2f}%')
2. 評估指標的詳細說明
- 準確率(Accuracy): 預測正確的樣本比例。
- 損失(Loss): 代表模型預測誤差的數值,愈小愈好。
- 混淆矩陣(Confusion Matrix): 可視化每個類別的預測結果,幫助了解誤分類情況。
以下為混淆矩陣的實作範例:
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
# 建立混淆矩陣
all_labels = []
all_preds = []
with torch.no_grad():
for inputs, labels in testloader:
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
all_labels.extend(labels.numpy())
all_preds.extend(preds.numpy())
cm = confusion_matrix(all_labels, all_preds)
# 顯示混淆矩陣
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('預測類別')
plt.ylabel('真實類別')
plt.title('混淆矩陣')
plt.show()
小結
本節說明了如何使用 PyTorch 訓練 CNN 模型並進行評估。我們透過交叉熵損失與 Adam 最佳化器來優化模型,並以測試資料分析其效能,包含準確率與混淆矩陣等指標。
5. 應用範例:透過遷移學習提升模型效能
什麼是遷移學習?
遷移學習(Transfer Learning)是指利用已訓練好的模型,將其知識應用到新的任務中。在圖像辨識任務中,經過大型資料集(如 ImageNet)訓練的模型(如 VGG16 或 ResNet)可以透過微調(Fine-tuning)快速建立高準確度的模型。
遷移學習的優點
- 降低計算成本: 無需從頭訓練整個模型,可減輕 GPU 負擔。
- 適用於少量資料: 即使訓練資料有限,也能藉由預訓練模型的特徵抽取能力達到不錯的表現。
- 快速實作: 開發流程簡單,可迅速建立模型並投入應用。
使用 PyTorch 實作遷移學習的範例
1. 匯入必要的函式庫
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, models, transforms
2. 前處理與讀取資料
transform = transforms.Compose([
transforms.Resize(224), # 將影像調整為 224x224
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)
testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False)
3. 載入預訓練模型
model = models.resnet18(pretrained=True)
# 修改輸出層(CIFAR-10 有 10 個類別)
model.fc = nn.Linear(512, 10)
4. 凍結模型參數與微調
for param in model.parameters():
param.requires_grad = False # 凍結全部參數
# 僅訓練最後一層(輸出層)
model.fc = nn.Linear(512, 10)
5. 設定損失函數與最佳化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.fc.parameters(), lr=0.001)
6. 開始訓練模型
n_epochs = 10
for epoch in range(n_epochs):
running_loss = 0.0
for inputs, labels in trainloader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}/{n_epochs}, Loss: {running_loss / len(trainloader):.4f}")
CNN 不僅能做圖像分類!更多應用場景
1. 物體偵測(Object Detection)
- 應用: 自駕車的環境辨識、監視器影像分析等。
- 技術: 常用架構包括 YOLO、Faster R-CNN 等。
2. 圖像分割(Segmentation)
- 應用: 醫療影像分析,例如辨識腫瘤或異常部位。
- 技術: 常見架構包括 U-Net、Mask R-CNN。
3. 風格轉換(Style Transfer)
- 應用: 在藝術創作與影像特效應用中轉換圖像風格。
- 技術: CNN 可擷取風格與內容特徵並進行合成。
4. 異常偵測(Anomaly Detection)
- 應用: 製造業中的品質檢測或異常識別。
- 技術: 利用 CNN 提取特徵,區分正常與異常樣本。
小結
本節說明了遷移學習的基本概念與在 PyTorch 中的實作方式。我們也介紹了 CNN 除了圖像分類外,還可應用於物體偵測、圖像分割、風格轉換與異常偵測等多種場景。
6. 疑難排解指南:錯誤處理與除錯技巧
PyTorch 中常見錯誤與解決方法
1. 模組或套件匯入錯誤
錯誤訊息:
ModuleNotFoundError: No module named 'torch'
可能原因:
尚未安裝 PyTorch,或虛擬環境未正確啟用。
解決方法:
source pytorch_env/bin/activate # 適用於 Linux/Mac
pytorch_env\Scripts\activate # 適用於 Windows
pip install torch torchvision torchaudio
2. GPU 無法識別錯誤
錯誤訊息:
RuntimeError: CUDA error: device-side assert triggered
可能原因:
GPU 無法使用,或 CUDA 版本與 PyTorch 不相容。
解決方法:
import torch
print(torch.__version__) # 顯示 PyTorch 版本
print(torch.cuda.is_available()) # 檢查是否支援 GPU
3. 張量尺寸不一致錯誤
錯誤訊息:
RuntimeError: shape '[N, C, H, W]' is invalid for input of size X
可能原因:
輸入資料的尺寸與模型所期望的不同。
解決方法:
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
除錯技巧與日誌紀錄活用
1. 在訓練過程中輸出日誌
for epoch in range(n_epochs):
running_loss = 0.0
for i, (inputs, labels) in enumerate(trainloader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if i % 100 == 99:
print(f"[Epoch {epoch+1}, Batch {i+1}] Loss: {loss.item():.4f}")
2. 使用 TensorBoard 可視化
安裝:
pip install tensorboard
程式碼範例:
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
for epoch in range(n_epochs):
running_loss = 0.0
for i, (inputs, labels) in enumerate(trainloader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
writer.add_scalar('Loss/train', loss.item(), epoch * len(trainloader) + i)
writer.close()
啟動 TensorBoard:
tensorboard --logdir=runs
錯誤排查檢查表
錯誤內容 | 檢查項目 | 解決方式 |
---|---|---|
模組匯入失敗 | 確認套件是否已安裝與虛擬環境啟用 | 重新安裝所需模組 |
GPU 無法使用 | 確認 CUDA 與 PyTorch 的版本相容性 | 更新驅動與重新安裝相容的 PyTorch |
資料尺寸不符 | 檢查輸入尺寸與模型預期尺寸是否一致 | 調整圖像尺寸或修改模型架構 |
準確率無提升 | 檢查學習率、批次大小與資料正規化 | 嘗試調整超參數與資料擴增 |
過擬合問題 | 觀察訓練損失與測試準確率 | 加入 Dropout 層或正則化技巧 |
小結
本節介紹了 PyTorch 中常見錯誤的解決方式,並說明如何透過日誌輸出與 TensorBoard 進行除錯與視覺化。開發深度學習模型時,這些技巧有助於快速發現與修正問題。
7. 模型的保存與部署:實務應用方式
如何保存已訓練完成的模型
1. 儲存狀態字典(State Dict)
torch.save(model.state_dict(), 'cnn_model.pth')
優點:
- 只需重新定義模型架構即可載入參數,具高度彈性。
- 檔案體積較小,便於管理與部署。
2. 儲存整個模型
torch.save(model, 'cnn_complete_model.pth')
優點:
- 不需再次定義模型架構,可直接載入使用,較為方便。
缺點:
- 依賴 PyTorch 的版本相容性,可能在不同版本間出現錯誤。
載入已保存模型並進行推論
1. 從狀態字典載入模型
model = SimpleCNN()
model.load_state_dict(torch.load('cnn_model.pth'))
model.eval()
2. 直接載入完整模型
model = torch.load('cnn_complete_model.pth')
model.eval()
3. 執行推論
import numpy as np
from PIL import Image
import torchvision.transforms as transforms
transform = transforms.Compose([
transforms.Resize(224),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
image = Image.open('sample_image.jpg')
image = transform(image).unsqueeze(0)
output = model(image)
_, predicted = torch.max(output, 1)
print(f'預測類別: {predicted.item()}')
部署模型到雲端或 Web 應用
1. 使用 Flask 建立 API 服務
安裝必要套件:
pip install flask
Flask 範例程式碼:
from flask import Flask, request, jsonify
import torch
from torchvision import transforms
from PIL import Image
app = Flask(__name__)
model = torch.load('cnn_complete_model.pth')
model.eval()
def preprocess_image(image):
transform = transforms.Compose([
transforms.Resize(224),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
image = transform(image).unsqueeze(0)
return image
@app.route('/predict', methods=['POST'])
def predict():
file = request.files['file']
image = Image.open(file.stream)
image = preprocess_image(image)
output = model(image)
_, predicted = torch.max(output, 1)
return jsonify({'prediction': predicted.item()})
if __name__ == '__main__':
app.run(debug=True)
使用 API 的方法:
curl -X POST -F "file=@sample_image.jpg" http://127.0.0.1:5000/predict
範例回傳結果:
{"prediction": 3}
模型部署時的重點建議
- 模型輕量化: 可透過量化(Quantization)或剪枝(Pruning)減少模型大小。
- 整合雲端平台: 可搭配 AWS Lambda 或 Google Cloud Functions 等無伺服器平台實現擴展性。
- 支援即時應用: 可使用 WebSocket 實現即時影像推論功能。
小結
本節介紹了如何將訓練完成的 PyTorch 模型保存、重新載入,以及如何透過 Flask API 進行部署。我們也說明了部署到實務專案或雲端環境時的重要注意事項。
8. 總結
使用 PyTorch 與 CNN 展開機器學習的第一步!
在本教學中,我們從基礎到應用全面介紹了如何使用 PyTorch 建構、訓練與評估 CNN 模型,並延伸到實際應用與部署。以下是重點回顧:
1. PyTorch 與 CNN 概述
- CNN 是一種非常適合圖像識別任務的神經網路架構。
- PyTorch 提供直觀的語法與強大的 GPU 支援,廣泛應用於研究與開發。
2. 環境建置與安裝流程
- PyTorch 安裝簡單,可透過 Google Colab 快速開始。
- 使用 torchvision 可方便地處理與前處理影像資料集。
3. 建構與訓練 CNN 模型
- 介紹了如何組合卷積層、池化層與全連接層建立模型。
- 透過損失函數與最佳化器進行訓練,並使用測試集進行模型評估。
4. 遷移學習與應用延伸
- 透過使用預訓練模型(如 ResNet18),在少量資料下也能取得不錯效果。
- CNN 不只用於圖像分類,亦可應用於物體偵測、影像分割、風格轉換等。
5. 錯誤處理與除錯技巧
- 整理了常見的 PyTorch 錯誤訊息與對應解決方案。
- 介紹了 TensorBoard 等工具協助進行模型訓練與監控。
6. 模型保存與實務部署
- 說明如何保存模型與參數,並透過 Flask 提供 API 部署介面。
- 提供雲端整合與輕量化的實作建議。
未來進階方向
1. 學習更進階的模型
- 嘗試學習 YOLO、Faster R-CNN 等進階架構,挑戰物體偵測與分割任務。
2. 優化模型效能
- 調整學習率、批次大小等超參數,加入 Dropout 或正則化技巧來避免過擬合。
3. 應用於真實專案
- 將學到的技能應用於實際問題,如醫療影像分析、人臉辨識系統等。
4. 活用雲端平台
- 結合 AWS、Google Cloud 等雲端服務,建立可擴展的應用系統。
5. 持續學習與參與社群
- 透過 GitHub、Kaggle 等平台與他人合作,學習最新技術並參與實戰。
結語
PyTorch 與 CNN 是機器學習與深度學習中非常強大的組合。透過本教學,你已經掌握從模型建立、訓練到部署的完整流程,未來可將這些知識應用到實際的專案中,邁向更進階的領域。
現在,就從打造屬於你自己的模型開始挑戰吧!