本教程將演示如何使用PyTorch框架對預訓練模型進行微調,實現熱狗與非熱狗圖像的分類任務。我們將從數據準備開始,逐步完成數據加載、可視化等關鍵步驟。
1. 環境配置與庫導入
%matplotlib inline
import os
import torch
from torch import nn
from d2l import torch as d2l
import torchvision
2. 熱狗數據集準備
# 熱狗數據集配置
d2l.DATA_HUB['hotdog'] = (d2l.DATA_URL + 'hotdog.zip','fba480ffa8aa7e0febbb511d181409f899b9baa5')# 下載并加載數據集
data_dir = d2l.download_extract('hotdog')
train_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'))
test_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'test'))
3. 數據可視化
# 可視化訓練集樣本
import matplotlib.pyplot as plt# 設置畫布大小
plt.figure(figsize=(12, 8))# 繪制前16張圖片
for i, (image, label) in enumerate(train_imgs[:16]):plt.subplot(4, 4, i+1)plt.imshow(image)plt.title('hotdog' if label == 0 else 'not hotdog')plt.axis('off')plt.tight_layout()
plt.show()
輸出結果:
array([<Axes: >, <Axes: >, <Axes: >, <Axes: >, <Axes: >, <Axes: >,<Axes: >, <Axes: >, <Axes: >, <Axes: >, <Axes: >, <Axes: >,<Axes: >, <Axes: >, <Axes: >, <Axes: >], dtype=object)
(實際運行時將顯示4x4網格排列的16張圖像,包含熱狗和其他食品的圖片)?
4.數據增強?
normalize = torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]
)train_augs = torchvision.transforms.Compose([torchvision.transforms.RandomResizedCrop(224),torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor(),normalize
])test_augs = torchvision.transforms.Compose([torchvision.transforms.Resize(256),torchvision.transforms.CenterCrop(224),torchvision.transforms.ToTensor(),normalize
])
5.定義并修改預訓練模型
# 使用預訓練的ResNet18模型
pretrained_net = torchvision.models.resnet18(pretrained=True)
print(pretrained_net.fc) # 最后一層全連接層查看
輸出結果:
Linear(in_features=512, out_features=1000, bias=True)
# 修改最后一層,以適應我們二分類任務
finetune_net = torchvision.models.resnet18(pretrained=True)
finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 2)
nn.init.xavier_uniform_(finetune_net.fc.weight)
6.微調模型
定義微調函數:
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolderdef train_fine_tuning(net, lr, batch_size=128, num_epochs=5, param_group=True):train_iter = DataLoader(ImageFolder(os.path.join(data_dir,'train'), transform=train_augs),batch_size=batch_size,shuffle=True)test_iter = DataLoader(ImageFolder(os.path.join(data_dir,'test'), transform=test_augs),batch_size=batch_size,shuffle=False)devices = d2l.try_all_gpus()loss = nn.CrossEntropyLoss(reduction='mean')if param_group:params_lx = [param for name, param in net.named_parameters()if name not in ['fc.weight', 'fc.bias']]optim = torch.optim.SGD([{'params': params_lx},{'params': net.fc.parameters(), 'lr': lr * 10}], lr=lr, weight_decay=0.001)else:optim = torch.optim.SGD(net.parameters(), lr=lr, weight_decay=0.001)d2l.train_ch13(net, train_iter, test_iter, loss, optim, num_epochs, devices)
使用小的學習率進行微調:
train_fine_tuning(finetune_net, 5e-5)
輸出:
loss 0.006, train acc 0.606, test acc 0.599
18.3 examples/sec on [device(type='cuda', index=0)]
為了進行比較,所有模型參數初始化為隨機值?
scratch_net=torchvision.models.resnet18() # 沒有預訓練參數
scratch_net.fc=nn.Linear(scratch_net.fc.in_features,2) # 修改最后一層全連接層,輸出為2
train_fine_tuning(scratch_net,5e-4,param_group=False) # param_group=False使得所有層的參數都為默認的學習率
輸出:
loss 0.005, train acc 0.752, test acc 0.750
10.6 examples/sec on [device(type='cuda', index=0)]
7.總結
本文完整展示了從數據準備到模型訓練的熱狗分類任務流程。關鍵步驟包括:
-
使用torchvision加載和預處理圖像數據
-
可視化數據集樣本
-
構建數據加載管道
-
修改預訓練模型進行微調
-
訓練和評估分類模型
實際應用中可以通過調整數據增強策略、嘗試不同網絡架構、優化超參數等方式進一步提升模型性能。后續可以擴展為部署到移動端的食品識別應用。
注意事項:
-
確保GPU環境加速訓練
-
根據顯存調整batch_size大小
-
適當調整學習率等超參數
-
添加早停機制防止過擬合
希望本教程能幫助您快速上手PyTorch模型微調任務!