2025年4月23日 星期三

流程概述:IMU 姿勢分類(RNN-LSTM)

 資料格式(homework.csv,欄位包含 b1..b6 為 IMU 6軸數據,type 為動作類別)所設計的 LSTM 姿勢分類完整流程與步驟規範。這套流程可直接應用於姿勢分類模型訓練與驗證。


🧭 流程概述:IMU 姿勢分類(RNN-LSTM)

步驟作業內容說明工具/技術
Step 1資料讀取與預處理pandas, numpy
Step 2資料標準化(Zero-mean, Unit-std)sklearn.preprocessing.StandardScaler
Step 3切割序列樣本(Sliding Window)np.lib.stride_tricks.sliding_window_view 或手工實作
Step 4建立 PyTorch Dataset / DataLoadertorch.utils.data.Dataset
Step 5定義 LSTM 模型torch.nn.LSTM
Step 6模型訓練與驗證CrossEntropyLoss, Adam optimizer
Step 7驗證分類準確率與混淆矩陣sklearn.metrics.confusion_matrix

📝 改寫:使用 homework.csv

📁 資料格式假設

csv
time,b1,b2,b3,b4,b5,b6,type 0.00,0.15,-0.02,...,1 0.01,0.16,-0.01,...,1 ...

✅ 實作步驟

python
import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler from torch.utils.data import Dataset, DataLoader import torch import torch.nn as nn # Step 1: 讀取資料 df = pd.read_csv('homework.csv') imu_data = df[['b1', 'b2', 'b3', 'b4', 'b5', 'b6']].values labels = df['type'].values # Step 2: 資料標準化 scaler = StandardScaler() imu_data = scaler.fit_transform(imu_data) # Step 3: Sliding window 切割 def create_sequences(data, labels, seq_len=100): sequences, seq_labels = [], [] for i in range(len(data) - seq_len): seq = data[i:i+seq_len] label = labels[i+seq_len-1] # 最後時間點標籤 sequences.append(seq) seq_labels.append(label) return np.array(sequences), np.array(seq_labels) X_seq, y_seq = create_sequences(imu_data, labels, seq_len=100) # Step 4: PyTorch Dataset 定義 class IMUDataset(Dataset): def __init__(self, X, y): self.X = torch.tensor(X, dtype=torch.float32) self.y = torch.tensor(y, dtype=torch.long) def __len__(self): return len(self.X) def __getitem__(self, idx): return self.X[idx], self.y[idx] # 切分 train/val train_size = int(0.8 * len(X_seq)) train_dataset = IMUDataset(X_seq[:train_size], y_seq[:train_size]) val_dataset = IMUDataset(X_seq[train_size:], y_seq[train_size:]) train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=64)

🧠 LSTM 模型定義

python
class IMULSTMClassifier(nn.Module): def __init__(self, input_dim=6, hidden_dim=64, num_layers=2, num_classes=4): super().__init__() self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True) self.fc = nn.Linear(hidden_dim, num_classes) def forward(self, x): out, _ = self.lstm(x) out = self.fc(out[:, -1, :]) return out

🔁 模型訓練與驗證

python
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = IMULSTMClassifier().to(device) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) for epoch in range(20): model.train() for X_batch, y_batch in train_loader: X_batch, y_batch = X_batch.to(device), y_batch.to(device) optimizer.zero_grad() output = model(X_batch) loss = criterion(output, y_batch) loss.backward() optimizer.step() print(f"Epoch {epoch+1} done.")

📊 驗證與混淆矩陣

python
from sklearn.metrics import accuracy_score, confusion_matrix model.eval() all_preds, all_labels = [], [] with torch.no_grad(): for X_batch, y_batch in val_loader: X_batch = X_batch.to(device) preds = model(X_batch).argmax(dim=1).cpu().numpy() all_preds.extend(preds) all_labels.extend(y_batch.numpy()) acc = accuracy_score(all_labels, all_preds) print(f"Validation Accuracy: {acc:.2f}") print("Confusion Matrix:\n", confusion_matrix(all_labels, all_preds))

📌 小提醒

  • 可根據實際需要改變 sequence_lengthhidden_dim 或增減 Dropout, BatchNorm

  • 若你的 homework.csv 有其他欄位命名,請依實際名稱調整欄位選取。

  • 可進一步導入 TensorBoard 或 wandb 做可視化監控。


沒有留言:

張貼留言