2025年4月21日 星期一

IMU 動作識別 by ConvNet 和 LSTM 的具體架構設計

針對 ConvNet 和 LSTM 的具體架構設計及其在 IMU 動作識別場景中的應用說明。

結合前述問題的背景(IMU 數據經過滑動窗口分割後進行特徵提取和時序建模),我會詳細說明這兩個模型的結構、參數選擇及其功能,並提供 PyTorch 實作範例。


一、ConvNet 具體架構與應用

1. ConvNet 架構設計

ConvNet(Convolutional Neural Network)用於從 IMU 數據的滑動窗口片段中提取局部特徵,例如動作的頻率、幅度變化等。它特別適合處理時間序列數據中的局部模式。

架構組成:

• 輸入層:假設每個窗口數據形狀為 (batch_size, num_channels, window_size),例如 (batch_size, 6, 128)。

• 卷積層(Conv1d):使用 1D 卷積提取局部特徵,適合時間序列數據。

• 激活函數(ReLU):增加非線性,提升模型表達能力。

• 池化層(MaxPool1d):降維,減少計算量,提取主要特徵。

• 全連接層(Linear):將卷積特徵展平後映射到特徵向量。

具體架構:

• 輸入:(batch_size, 6, 128)(6 通道,窗口大小 128)。

• 卷積層 1:Conv1d(in_channels=6, out_channels=16, kernel_size=5, padding=2),輸出 (batch_size, 16, 128)。

• 激活:ReLU。

• 池化層 1:MaxPool1d(kernel_size=2),輸出 (batch_size, 16, 64)。

• 卷積層 2:Conv1d(in_channels=16, out_channels=32, kernel_size=5, padding=2),輸出 (batch_size, 32, 64)。

• 激活:ReLU。

• 池化層 2:MaxPool1d(kernel_size=2),輸出 (batch_size, 32, 32)。

• 展平:(batch_size, 32 * 32)。

• 全連接層:Linear(32 * 32, 128),輸出特徵向量 (batch_size, 128)。

PyTorch 實作:

========================================

[python]:

import torch

import torch.nn as nn


class ConvNet(nn.Module):

    def __init__(self, num_channels=6, window_size=128, feature_dim=128):

        super(ConvNet, self).__init__()

        self.conv_layers = nn.Sequential(

            nn.Conv1d(num_channels, 16, kernel_size=5, padding=2),  # 第一層卷積

            nn.ReLU(),

            nn.MaxPool1d(2),

            nn.Conv1d(16, 32, kernel_size=5, padding=2),  # 第二層卷積

            nn.ReLU(),

            nn.MaxPool1d(2),

        )

        conv_output_size = window_size // 4  # 經過兩次池化

        self.fc = nn.Linear(32 * conv_output_size, feature_dim)  # 全連接層


    def forward(self, x):

        x = x.permute(0, 2, 1)  # (batch_size, window_size, num_channels) -> (batch_size, num_channels, window_size)

        x = self.conv_layers(x)

        x = x.view(x.size(0), -1)  # 展平

        features = self.fc(x)

        return features

# 測試模型

model = ConvNet()

x = torch.randn(32, 128, 6)  # 模擬輸入

features = model(x)

print(features.shape)  # 輸出形狀:(32, 128)


==================================================

2. 參數選擇與應用

• 卷積核大小(kernel_size=5):選擇較小的卷積核(3 或 5)以捕捉短時動作模式(如步伐週期)。

• 通道數(out_channels):逐層增加(6 → 16 → 32),提取更抽象的特徵。

• 池化層:每次池化減少時間維度(128 → 64 → 32),降低計算量,聚焦主要特徵。

• 特徵向量維度(feature_dim=128):輸出固定長度的特徵向量,供後續 LSTM 或分類器使用。

應用:

• ConvNet 提取每個窗口的局部特徵,例如加速度的尖峰、陀螺儀的旋轉模式。

• 在動作識別中,這些特徵可以用來區分不同動作的短期模式,例如「走路」和「跑步」的節奏差異。

二、LSTM 具體架構與應用

1. LSTM 架構設計

LSTM(Long Short-Term Memory)用於捕捉特徵向量序列的時序關係,特別適合處理連續動作之間的上下文,例如「走路」後「坐下」的模式。

架構組成:

• 輸入層:ConvNet 輸出的特徵向量序列,形狀為 (batch_size, sequence_length, feature_dim),例如 (batch_size, 10, 128)(10 個窗口,每個窗口特徵維度為 128)。

• LSTM 層:處理時序數據,捕捉長期依賴。

• 全連接層:將 LSTM 輸出映射到動作類別。

具體架構:

• 輸入:(batch_size, 10, 128)。

• LSTM 層:LSTM(input_size=128, hidden_size=64, num_layers=2, batch_first=True),輸出 (batch_size, 10, 64)。

• 取最後時間步的輸出:(batch_size, 64)。

• 全連接層:Linear(64, num_classes),輸出 (batch_size, num_classes),假設 num_classes=5。

================================================

PyTorch 實作:

[python]:

class LSTMClassifier(nn.Module):

    def __init__(self, input_size=128, hidden_size=64, num_layers=2, num_classes=5):

        super(LSTMClassifier, self).__init__()

        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)

        self.fc = nn.Linear(hidden_size, num_classes)


    def forward(self, x):

        # x 的形狀:(batch_size, sequence_length, feature_dim)

        out, (hn, cn) = self.lstm(x)  # out: (batch_size, sequence_length, hidden_size)

        out = out[:, -1, :]  # 取最後時間步的輸出

        logits = self.fc(out)  # 分類

        return logits


# 測試模型

model = LSTMClassifier()

x = torch.randn(32, 10, 128)  # 模擬輸入:10 個窗口的特徵序列

logits = model(x)

print(logits.shape)  # 輸出形狀:(32, 5)

=============================================

2. 參數選擇與應用

• 輸入維度(input_size=128):與 ConvNet 輸出的特徵向量維度一致。

• 隱藏層維度(hidden_size=64):控制 LSTM 的記憶容量,根據任務複雜度調整。

• 層數(num_layers=2):堆疊多層 LSTM 捕捉更複雜的時序模式。

• batch_first=True:確保輸入形狀為 (batch_size, sequence_length, feature_dim)。

應用:

• LSTM 接收 ConvNet 輸出的特徵序列,捕捉動作之間的時序關係。

• 例如,在「走路 → 坐下」的序列中,LSTM 可以學習到「走路」後的動作趨勢,區分單次動作和連續動作模式。



三、ConvNet + LSTM 結合應用

在動作識別中,ConvNet 和 LSTM 通常結合使用,形成一個端到端的模型。ConvNet 提取每個窗口的特徵,LSTM 建模特徵序列的時序關係。

1. 結合模型架構

輸入:IMU 數據分段後的序列,形狀為 (batch_size, sequence_length, window_size, num_channels),例如 (batch_size, 10, 128, 6)。

• ConvNet:對每個窗口提取特徵,輸出 (batch_size, sequence_length, feature_dim)。

• LSTM:接收特徵序列,輸出分類結果。

PyTorch 實作:

======================================

[python]

class ConvNetLSTM(nn.Module):

    def __init__(self, num_channels=6, window_size=128, feature_dim=128, 

                 hidden_size=64, num_layers=2, num_classes=5):

        super(ConvNetLSTM, self).__init__()

        self.convnet = ConvNet(num_channels, window_size, feature_dim)

        self.lstm = nn.LSTM(feature_dim, hidden_size, num_layers, batch_first=True)

        self.fc = nn.Linear(hidden_size, num_classes)


    def forward(self, x):

        # x 的形狀:(batch_size, sequence_length, window_size, num_channels)

        batch_size, seq_len, window_size, num_channels = x.size()

        # 對每個窗口應用 ConvNet

        x = x.view(batch_size * seq_len, window_size, num_channels)

        features = self.convnet(x)  # (batch_size * sequence_length, feature_dim)

        features = features.view(batch_size, seq_len, -1)  # (batch_size, sequence_length, feature_dim)

        # 應用 LSTM

        out, (hn, cn) = self.lstm(features)

        out = out[:, -1, :]  # 取最後時間步

        logits = self.fc(out)

        return logits


# 測試模型

model = ConvNetLSTM()

x = torch.randn(32, 10, 128, 6)  # 模擬輸入

logits = model(x)

print(logits.shape)  # 輸出形狀:(32, 5)

====================================================

2. 訓練與應用

• 數據準備:IMU 數據按滑動窗口分割後,組織成 (batch_size, sequence_length, window_size, num_channels) 的形狀。

• 訓練:使用交叉熵損失函數,優化器選擇 Adam,訓練過程與前述相同。

• 應用:模型可以用於實時動作識別,例如在可穿戴設備中檢測「走路」、「跑步」、「坐下」等動作。



四、應用場景與優化建議

1. 應用場景

• 健康監測:識別日常活動(如走路、跑步),計算運動量。

• 跌倒檢測:檢測老年人異常動作(如突然坐下或躺下)。

• 運動分析:分析運動員的動作模式(如步伐頻率、上下樓梯)。

2. 優化建議

• ConvNet: 

○ 增加卷積層數或使用殘差結構(如 ResNet)以提取更複雜特徵。

○ 添加 Dropout 層防止過擬合。

• LSTM: 

○ 使用雙向 LSTM(bidirectional=True)捕捉前後時序關係。

○ 調整 hidden_size 和 num_layers 平衡模型複雜度和計算量。

• 數據增強: 

○ 對 IMU 數據添加隨機噪聲或旋轉,增強模型魯棒性。

• 注意力機制: 

○ 在 LSTM 後添加注意力層,聚焦重要時間步,特別適用於長序列。



五、結論

• ConvNet:專注於提取每個窗口的局部特徵,適合捕捉動作的短期模式。

• LSTM:專注於特徵序列的時序建模,適合捕捉動作之間的上下文關係。

• 結合使用:ConvNet + LSTM 形成端到端模型,實現從原始數據到動作識別的完整流程。




沒有留言:

張貼留言