dYang1's picture
Release SignBridge-TSL-STGCN with compliance Model Card
3b18ebd verified
Raw History Blame Contribute Delete
4.6 kB
# -*- coding: utf-8 -*-
"""全域設定:訓練與即時推論共用,改這裡就好。"""
from pathlib import Path
# ---------------------------------------------------------------- 路徑
PROJECT_DIR = Path(__file__).resolve().parent
# 把 Google Drive 的 NPY_Dataset 下載到本機後,放在這個路徑
DATA_ROOT = PROJECT_DIR / "data" / "NPY_Dataset"
OUT_DIR = PROJECT_DIR / "runs"
# ---------------------------------------------------------------- 關鍵點佈局
# 每個 .npy 形狀為 (T, 55, 3)。55 = 12 上半身 pose + 21 左手 + 21 右手 + 1 虛擬頸點。
# ✓ 已與組員的 extract_features.py 核對過,完全一致。
NUM_POINTS = 55
POSE_SLICE = slice(0, 12) # 上半身 pose
LHAND_SLICE = slice(12, 33) # 左手 21 點
RHAND_SLICE = slice(33, 54) # 右手 21 點
CENTER_IDX = 54 # 虛擬頸點=雙肩中點(正規化原點)
LSHOULDER_IDX = 0
RSHOULDER_IDX = 1
# 從 MediaPipe Pose 的 33 點裡挑的 12 點(= extract_features.py 的 POSE_INDICES)。
POSE_MP_INDICES = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
# ---------------------------------------------------------------- 前處理
# 實際資料:影格數 min=55 / median=150 / max=179,所以重採樣到 64 格
# (約 2.3 倍下採樣,保留足夠的手部動作細節,又不會讓訓練太慢)
SEQ_LEN = 64
MIN_FRAMES = 8 # 少於這個影格數的樣本會先補到這個長度
USE_XY_ONLY = True # MediaPipe 的 z 噪音大,預設只用 x,y(設 False 則保留全部維度)
ADD_VELOCITY = True # 加入相鄰影格差分(動作速度),對手語很有幫助
ADD_MASK = True # 加入「這一點這一格有沒有被偵測到」的 0/1 通道
# --- 跨人泛化用的特徵(骨向量與關節角度對體型差異較不敏感)
ADD_BONE = True # 每個節點指向父節點的向量(長度隱含肢段比例)
ADD_ANGLE = True # 該節點在骨架樹上與父、祖父形成的夾角(純角度,與體型無關)
# ---------------------------------------------------------------- 訓練
SEED = 42
VAL_RATIO = 0.2
BATCH_SIZE = 32
EPOCHS = 120
LR = 1e-3
WEIGHT_DECAY = 1e-4
LABEL_SMOOTHING = 0.05
EARLY_STOP_PATIENCE = 25
# ---------------------------------------------------------------- 模型
ARCH = "stgcn"
DROPOUT = 0.3
# ST-GCN
GRAPH_STRATEGY = "spatial" # "spatial"(三組分割)或 "uniform"
STGCN_CHANNELS = (64, 64, 128, 128)
STGCN_STRIDES = (1, 1, 2, 1) # 2 代表時間軸下採樣一半
STGCN_EDGE_IMPORTANCE = True # 讓模型自己學每條骨架邊的重要性
# ---------------------------------------------------------------- 資料增強
# 目標不只是防過擬合,而是 domain randomization ——
# 用單一拍攝者的資料合成出「各種體型、各種取景、各種偵測品質」的假樣本,
# 讓模型不要依賴那些會隨人改變的線索。
AUG_SCALE = 0.20 # 隨機縮放 ±20%
AUG_ROTATE_DEG = 18.0 # 隨機旋轉 ±18 度
AUG_SHIFT = 0.10 # 隨機平移
AUG_NOISE = 0.015 # 高斯雜訊
AUG_TIME_WARP = 0.3 # 隨機加減速 ±30%
AUG_FRAME_DROP = 0.08 # 隨機丟影格比例
AUG_MIRROR = False # 左右鏡像:手語中左右手分工有意義,預設關閉
# --- 模擬跨人/跨環境的差異
AUG_LIMB_SCALE = 0.15 # 各肢段長度獨立隨機縮放 ±15%,模擬不同體型
AUG_JOINT_DROP = 0.15 # 隨機關節在隨機時段「偵測失敗」,模擬 MediaPipe 掉點
AUG_HAND_DROP = 0.15 # 整隻手短暫消失的機率(實測即時環境常發生)
AUG_TEMPORAL_CROP = 0.25 # 隨機裁掉頭尾最多 25%,模擬滑動視窗沒對齊完整動作
# ---------------------------------------------------------------- 即時推論
# ★ 關鍵:訓練時每支影片不管多長都被時間正規化成 SEQ_LEN 格,
# 所以模型學到的是「一個完整手語詞從頭到尾」的樣子。
# 即時推論的 sliding window 必須涵蓋**同樣長度的時間**(而不是同樣的影格數),
# 否則模型會看到一個被快轉 3 倍的動作,準確率直接崩掉。
#
# 訓練影片中位數 150 格。若原始影片是 30 fps → 一個詞約 5.0 秒。
# ★ 請跟組員確認原始 mp4 的 fps,再改這個數字:PRED_WINDOW_SECONDS = 150 / fps
PRED_WINDOW_SECONDS = 5.0
PRED_STRIDE = 4 # 每幾格推論一次
PRED_THRESHOLD = 0.75 # 信心門檻,低於此不輸出
PRED_SMOOTH = 3 # 連續幾次相同預測才確認