今天將帶你進一步實作一個手勢辨識的 CNN 模型,從資料前處理、模型架構設計,到訓練與評估,一步步帶你打造屬於自己的手勢辨識模型,為未來即時應用打下基礎。
使用的是 Kaggle 上公開的 Sign Language MNIST 資料集,其特點如下:
這個資料集適合用來進行基礎的圖像分類訓練,能有效協助我們開發初版的手勢辨識模型。
使用 torchvision 與自定義 Dataset 類別來處理圖像資料:
import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
import numpy as np
train_df = pd.read_csv("sign_mnist_train.csv")
test_df = pd.read_csv("sign_mnist_test.csv")
class SignLanguageDataset(Dataset):
def __init__(self, dataframe, transform=None):
self.labels = dataframe['label'].values
self.images = dataframe.drop('label', axis=1).values.reshape(-1, 28, 28).astype(np.uint8)
self.transform = transform
def __len__(self):
return len(self.labels)
def __getitem__(self, idx):
image = self.images[idx]
label = self.labels[idx]
if self.transform:
image = self.transform(image)
return image, label
加入簡單的資料增強策略:
transform = transforms.Compose([
transforms.ToPILImage(),
transforms.RandomRotation(10),
transforms.ToTensor()
])
train_dataset = SignLanguageDataset(train_df, transform=transform)
test_dataset = SignLanguageDataset(test_df, transform=transforms.ToTensor())
用 DataLoader 建立批次資料:
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
設計了一個 2 層卷積 + 1 層全連接的基本 CNN 架構:
import torch.nn as nn
class GestureCNN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 7 * 7, 256),
nn.ReLU(),
nn.Linear(256, 25)
)
def forward(self, x):
return self.net(x)
使用 CrossEntropyLoss 作為分類任務的損失函數,並以 Adam 優化器進行參數更新:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = GestureCNN().to(device)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
執行訓練迴圈 10 個 epoch:
for epoch in range(10):
model.train()
total_loss = 0
for X, y in train_loader:
X, y = X.to(device), y.to(device)
pred = model(X)
loss = loss_fn(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss:.4f}")
完成訓練後,進行測試集準確率評估:
model.eval()
correct = 0
total = 0
with torch.no_grad():
for X, y in test_loader:
X, y = X.to(device), y.to(device)
pred = model(X)
predicted = pred.argmax(1)
correct += (predicted == y).sum().item()
total += y.size(0)
print(f"Test Accuracy: {correct / total:.4f}")
藉由今天的內容,帶領你一步步實作出一個簡潔而實用的 靜態手勢辨識 CNN 模型,此篇涵蓋了:
✅ Kaggle 資料集載入與前處理
✅ PyTorch 自定義 Dataset 與 DataLoader
✅ 卷積神經網路(CNN)模型構建
✅ 模型訓練流程與準確率評估
從公開資料中提取影像特徵,成功建立了能分類 24 種英文字母手勢的初步模型,這個過程正是「讓電腦讀懂手勢語意」的第一步。
📌 下一篇文章預告:
把模型從「圖像」推進到「鏡頭」——整合 OpenCV 與 MediaPipe,實現即時的手勢辨識互動,讓你的模型真正看見並理解你!