---
# System prepended metadata

title: 20251007 論文_HumanMAC
tags: [看論文]

---

## HumanMAC: Masked Motion Completion for Human Motion Prediction
[github](https://github.com/LinghaoChan/HumanMAC/tree/main)


### 前言
**擴散模型(Diffusion Model)**
![image](https://hackmd.io/_uploads/BJguZR1axe.png)
將原始圖片逐漸加入雜訊(Noise)，讓原本的圖片逐漸變成完全的雜訊狀態。然後再透過反轉這個過程，也就是Denoise去除雜訊來恢復圖片。讓它學習了雜訊圖和真實圖片之間的變換關係，最後使其能夠從雜訊中生成出像樣的圖片。
1. 正向過程(Forward Process/Diffusion Process)：對圖片逐步增加雜訊。
2. 反向過程(Reverse Process)：從雜訊中逐步恢復圖片。

---

### 概述
![image](https://hackmd.io/_uploads/Syrwz_A3eg.png =50%x)

以往的人體動作預測方法多採用 **encoder - decoder** 框架，雖然有不錯表現，但存在幾個問題：

-  多數先進方法需要多種損失函數才能獲得高品質的預測結果，例如APD、FDE，以及對抗損失，需要精心設計超參數來平衡不同損失，導致應用上相當繁瑣。
-  encoder/decoder 和 latent sampling 是在不同階段完成的，流程複雜。
-  受限於已觀測的動作序列，難以實現切換動作類別（如從走路到坐下），導致多樣性不足。 

---

### 內容
**Masked motion Completion, HumanMAC**
跳脫出 encoder/decoder 的方式來處理 HMP 問題。
- 訓練階段：將已觀測與預測的動作結合，學習一個從隨機噪聲生成動作的 **motion diffusion model**，從雜訊生成動作序列，只用單一 loss（噪聲預測 MSE loss）。
- 推論階段：提出 **DCT-Completion**，將觀測到的動作加雜訊，再透過 masking 機制與去噪過程結合，讓預測動作 **可控且連續**。
        
**架構特色**
-   僅需單一 loss，端到端訓練。
-   可自然完成動作轉換（motion switch），如坐下→站立。
-   支援部位可控預測 (part-body controllable prediction)。

---

### 流程 - 訓練階段
#### 1. 輸入完整的動作序列 $\mathbf{x} \in \mathbb{R}^{(H+F)\times 3J}$ （包含過去 $H$ 幀 + 未來 $F$ 幀），來預測接下來長度 $F$ 的未來序列
$$
\mathbf{x}^{(1:H)} = \big[ \mathbf{x}^{(1)} ; \mathbf{x}^{(2)} ; \ldots ; \mathbf{x}^{(H)} \big] 
\in \mathbb{R}^{H \times 3J}
$$
$$
\mathbf{x}^{(H+1:H+F)} = 
\big[ \mathbf{x}^{(H+1)} ; \mathbf{x}^{(H+2)} ; \ldots ; \mathbf{x}^{(H+F)} \big] 
\in \mathbb{R}^{F \times 3J}
$$
* $𝐻$：觀測到的歷史幀數
* $J$：關節數量
* $\mathbf{x}^{(h)} \in \mathbb{R}^{3J}$ ：第 $h$ 個影格中所有關節的三維座標


#### 2. 將動作序列透過 DCT 轉換投影到頻域
$$
\mathbf{y} = \mathrm{DCT}(\mathbf{x}) = \mathbf{D}\mathbf{x}
$$

* $\mathbf{y} \in \mathbb{R}^{(H+F)\times 3J}$：經過 DCT 轉換的已觀測到動作序列
* $\mathbf{D} \in \mathbb{R}^{(H+F)\times(H+F)}$：預先定義的 DCT 基底矩陣
* $\mathbf{x} \in \mathbb{R}^{(H+F)\times 3J}$：完整序列(過去 $H$ 幀 + 未來 $F$ 幀真值)，時間長度 $(H+F)$ 幀
$$
\mathbf{x} = \big[ \mathbf{x}^{(1:H)} ; \underbrace{\mathbf{x}^{(H+1:H+F)}}_{\text{未來真值}} \big] \; (\text{完整真值序列})
$$

>鑑於人體動作在**時間上平滑**的特性，採用**截斷版 DCT/iDCT**：只取 $\mathbf{D}$ 與 $\mathbf{D}^\top$ 的前 $L$ 列 ( 分別記為 $\mathbf{D}_L$ 、 $\mathbf{D}_L^\top$ )
$$
\mathbf{c} \approx \mathbf{D}_L \mathbf{x}, 
\qquad 
\mathbf{x} \approx \mathbf{D}_L^\top \mathbf{c}
$$
取前 $L$ 個頻率分量（低頻）能捕捉**長期趨勢與平滑性**，對於保證預測的**連續 / 不抖動**尤為關鍵，同時節省運算量。在不致混淆的情況下，後文以 $\mathbf{D}_L$ 取代 $\mathbf{D}$ 記號。
$$
\mathbf{c} \equiv \mathbf{y}_0 = \mathbf{D}_L \mathbf{x}
$$
>* $\mathbf{y}_0 \in \mathbb{R}^{L \times 3J}$：取前 $L$ 個頻率之後的頻譜
>* $\mathbf{D}_L \in \mathbb{R}^{L \times (H+F)}$：只取 $\mathbf{D}$ 的前 $L$ 個低頻的 DCT 基底矩陣
>* $\mathbf{x} \in \mathbb{R}^{(H+F)\times 3J}$：完整序列(過去 $H$ 幀 + 未來 $F$ 幀真值)，時間長度 $(H+F)$ 幀

>**為什麼不直接在時間域做擴散？**
DCT 能同時保留當前與週期性的時間性質，且低頻對連續動作更關鍵，所以在頻域學去噪更穩、更省算。

#### 3. 前向加噪 (Forward noising)
將乾淨的動作頻譜逐步轉化為高斯噪聲，建立一條從「真實序列」到「純噪聲」的馬可夫鏈，讓模型在訓練時學會如何反向去噪。
對於低頻的 DCT 特徵 $\mathbf{y}_0 \in \mathbb{R}^{L \times 3J}$ ，在第 $t$ 步的帶噪表達式為：
$$
\mathbf{y}_t=\sqrt{\overline{\alpha}_t}\,\mathbf{y}_0+\sqrt{1-\overline{\alpha}_t}\,\epsilon,\quad
\epsilon\sim\mathcal{N}(0,\mathbf{I})
$$
* $t$：前向加噪過程的總長度
* $\mathbf{y}_t \in \mathbb{R}^{L \times 3J}$：在時間步 $t$ 的帶噪特徵，隨著 $t$ 增加會越來越接近純噪聲
* $\mathbf{y}_0 \in \mathbb{R}^{L \times 3J}$：乾淨的低頻特徵
* $\bar{\alpha}_t=\displaystyle\prod_{i=1}^{t}\alpha_i \in \mathbb{R}$：為**累積訊號保留率** (cumulative product)，表示從第 1 步到第 $t$ 步過程中訊號還剩下多少比例
    >當 $t$ 小：$\bar{\alpha}_t \approx 1$，訊號幾乎沒破壞
    >當 $t$ 大：$\bar{\alpha}_t \approx 0$，訊號幾乎消失，只剩噪聲
* $\epsilon\sim\mathcal{N}(0,\mathbf{I}),\ \epsilon\in\mathbb{R}^{L\times 3J}$：與 $\mathbf{y}_0$ 同形狀的高斯白噪聲
* $\sqrt{\overline{\alpha}_t}\,\mathbf{y}_0$：保留訊號的一部分，隨 $t$ 增加會縮小
* $\sqrt{1-\overline{\alpha}_t}\,\epsilon$：逐步加入的隨機噪聲，隨 $t$ 增加會變大

#### 4. 噪聲預測 (Noise Prediction)
在第 $t$ 步，模型輸入帶噪的 DCT 特徵 $\mathbf{y}_t$，並輸出對應的噪聲預測。
$$
\epsilon_{\theta}(\mathbf{y}_t,t)
$$
- $\theta$：可學習參數的神經網路（HumanMAC 採用 TransLinear 結構）
- $\mathbf{y}_t$：在時間步 $t$ 的帶噪特徵
- $t$：噪聲步數，用來告知網路目前的加噪強度

>目的：網路學習去預測真實加入的噪聲 $\epsilon$，也就是 diffusion model 的標準訓練方式

#### 5. 損失函數 (Loss Function)
採用單一的 MSE 損失，用來度量模型預測噪聲與真實噪聲之間的誤差。
讓模型學會在任意時間步 $t$，輸入帶噪樣本 $\mathbf{y}_t$ 後，正確地預測出當時加進去的真實噪聲 $\epsilon$。
$$
\mathcal{L}
=\mathbb{E}_{\epsilon,t}\!\left[\left\|\,\epsilon-\epsilon_{\theta}(\mathbf{y}_t,t)\,\right\|_2^{2}\right]
$$
- $\epsilon\sim\mathcal{N}(0,\mathbf{I})$：真實加入的高斯白噪聲
- $\epsilon_{\theta}(\mathbf{y}_t,t)$：模型的噪聲預測
- $\mathbb{E}_{\epsilon,t}[\cdot]$：表示對「不同的噪聲樣本 $\epsilon$」與「不同的步數 $t$」做期望（取平均）

**總結**
![image](https://hackmd.io/_uploads/B12Tix1Tlg.png =70%x)

---

### 流程 - 推理階段
#### 1. 輸入僅有觀測到的過去序列$\mathbf{x}^{(1:H)}$ （不是完整序列），目的是讓模型生成接下來的 $F$ 幀。
$$
\mathbf{x}^{(1:H)} = \big[ \mathbf{x}^{(1)} ; \mathbf{x}^{(2)} ; \ldots ; \mathbf{x}^{(H)} \big] 
\in \mathbb{R}^{H \times 3J}
$$
* $𝐻$：觀測到的歷史幀數
* $\mathbf{x}^{(h)} \in \mathbb{R}^{3J}$ ：第 $h$ 個影格中所有關節的三維座標

#### 2. 序列補長 + DCT 轉換
模型只有過去序列 $\mathbf{x}^{(1:H)}$，但要生成長度 $H+F$ 的完整序列，因此要先把序列補長。
將最後一幀 $\mathbf{x}^{(H)}$ 重複 $F$ 幀，把序列補到長度 $H+F$ 後做 DCT 轉換。
$$
\mathbf{x}=\left[\mathbf{x}^{(1:H)},\ \underbrace{\mathbf{x}^{(H)},\ldots,\mathbf{x}^{(H)}}_{\text{ }F\text{ 幀}}\right]\in\mathbb{R}^{(H+F)\times 3J}
$$
$$
\mathbf{c} \equiv \mathbf{y}_0 = \mathbf{D}_L \mathbf{x}
$$
* $\mathbf{y}_0 \in \mathbb{R}^{L \times 3J}$：取前 $L$ 個頻率之後的頻譜
* $\mathbf{D}_L \in \mathbb{R}^{L \times (H+F)}$：只取$\mathbf{D}$ 的前 $L$ 個低頻的 DCT 基底矩陣
* $\mathbf{x} \in \mathbb{R}^{(H+F)\times 3J}$：完整序列(過去 $H$ 幀 + 未來 $F$ 幀真值)，時間長度 $(H+F)$ 幀

#### 3. 初始化生成噪聲 (Initialization)
模型要從「純噪聲」開始逐步去噪，所以初始化時會直接生成一個與輸入形狀相同的隨機噪聲。
$$\mathbf{y}_T \sim \mathcal{N}(0, I)$$
* $\mathbf{y}_T \in \mathbb{R}^{L \times 3J}$：diffusion 過程的最後一步 (最強噪聲狀態)，是演算法的起點，跟 DCT 特徵 $\mathbf{y}_0$ 相同。
>為什麼要初始化成純噪聲？
在 diffusion 生成模型裡，推理必須從高斯白噪聲開始，透過反向過程一步步還原訊號。
這樣才能保證生成過程具有「隨機性 → 多樣性」。

#### 4. DCT-Completion - 反向迭代，從純噪聲 $\mathbf{y}_T$ 開始，逐步還原訊號
傳統的擴散式方法：完成訓練後透過 $T$ 次去噪步驟來生成序列，但此流程無法利用觀測幀，因此生成結果不可控。
→ 不需重新訓練的演算法 DCT-Completion：能在推論時以觀測動作為條件來補齊未來動作。

* 每個時間步範圍：
$$t=T,T-1,\ldots,1$$

>DDIM steps：推論時實際使用的步數

**(a) 對觀測序列加噪 (保持過去 $H$ 幀條件)** 左支
在反向過程中「鎖住」過去 $H$ 幀不讓它們被改變，確保模型生成的序列會「連續且符合觀測」。
把觀測序列用最後一幀補到長度 $H+F$，再投影到 DCT 域得到 $y$。接著在時間步 $t−1$ 對 $y$ 加噪以取得「觀測端的帶噪頻譜」：
$$\mathbf{y}^{n}_{t-1}=\sqrt{\overline{\alpha}_{t-1}}\,\mathbf{y}+\sqrt{1-\overline{\alpha}_{t-1}}\,\mathbf{z},\ \ \mathbf{z}\sim\mathcal{N}(0,\mathbf{I})$$
$$\mathbf{y}^{n}_{t-1}\sim q(\mathbf{y}_{t-1}\mid \mathbf{y})$$
* $\mathbf{y}^{n}_{t-1} \in \mathbb{R}^{L \times 3J}$：在 第 $t−1$ 步的觀測端帶噪聲頻譜，「訊號 + 噪聲」的混合體
* $\bar{\alpha}_{t-1} \in[0,1]$：是純量，代表累積訊號保留率，表示訊號在第 $t−1$ 步還剩多少比例
* $\mathbf{y} \in \mathbb{R}^{L \times 3J}$：補齊序列 (長度 $H+F$) 之後投影到 DCT 領域的頻譜表示
* $\mathbf{z} \in \mathbb{R}^{L \times 3J}$：高斯白噪聲
* $\sqrt{\overline{\alpha}_{t-1}}\,\mathbf{y} \in \mathbb{R}^{L \times 3J}$：保留訊號的一部分，隨 $t$ 增加會縮小
* $\sqrt{1-\overline{\alpha}_{t-1}}\,\mathbf{z} \in \mathbb{R}^{L \times 3J}$：逐步加入的隨機噪聲，隨 $t$ 增加會變大

**(b) 生成端去噪** 右支 [.](https://hackmd.io/@q_bRZRi5Q2iTv2zdBQYQHg/SkEF3wWTxg)
利用網路去掉噪聲，還原訊號。
由 $\mathbf{y}_t$ 得到「預測端的去噪頻譜」 $\mathbf{y}^{d}_{t-1}$
$$\mathbf{y}^{d}_{t-1}=\dfrac{1}{\sqrt{\alpha_t}}\!\left(\mathbf{y}_t-\dfrac{1-\alpha_t}{\sqrt{1-\overline{\alpha}_t}}\;\epsilon_{\theta}(\mathbf{y}_t,t)\right)+\sigma_t\mathbf{z}$$
$\text{其中 } t=1:\ \mathbf{z}\sim\mathcal{N}(0,\mathbf{I});\ \text{否則 } \mathbf{z}=\mathbf{0}$
$$
\mathbf{y}^{d}_{t-1}\sim p_{\theta}(\mathbf{y}_{t-1}\mid \mathbf{y}_t)
$$
* $\mathbf{y}^{d}_{t-1} \in \mathbb{R}^{L \times 3J}$：第 $t−1$ 步生成端的去噪後頻譜
* $\mathbf{y}_t \in \mathbb{R}^{L \times 3J}$：在第 $t$ 步的帶噪聲頻譜
* $\alpha_t$：變異數排程參數 (variance schedule)，是純量，決定該步保留多少訊號
* $\epsilon_{\theta}(\mathbf{y}_t,t) \in \mathbb{R}^{L \times 3J}$：噪聲預測網路的輸出
* $\sigma_t$：決定隨機性，若取 0 則生成是確定性的 (DDIM)，若取非 0 則生成有隨機性 (DDPM)
* $\mathbf{z} \in \mathbb{R}^{L \times 3J}$：高斯白噪聲

**( c ) 用 iDCT 把頻域的結果轉回時間域然後輸出動作序列**
每一步迭代裡的 iDCT
$$
\mathrm{iDCT}(\mathbf{y}^{n}_{t-1}), \quad \mathrm{iDCT}(\mathbf{y}^{d}_{t-1})
$$
最後一步的 iDCT
$$
\hat{\mathbf{x}} = \mathrm{iDCT}(\mathbf{y}_0) = \mathbf{D}^\top \mathbf{y}_0, \quad \hat{\mathbf{x}} \in \mathbb{R}^{(H+F)\times 3J}
$$
* $\mathbf{y}_0\in\mathbb{R}^{L\times 3J}$：diffusion 完成後得到的乾淨頻譜
* $\mathbf{D}_L^\top \in \mathbb{R}^{(H+F) \times L}$：只取 $\mathbf{D}$ 的前 $L$ 個低頻的 IDCT 基底矩陣
* $\hat{\mathbf{x}}$：長度 $H+F$ 的輸出結果

**(d)遮罩式補全 (Mask Completion)**
在已訓練好的擴散模型中，$\mathbf{y}^{n}_{t-1}$ （觀測端）與 $\mathbf{y}^{d}_{t-1}$ （生成端）在分佈上近似一致；因此把兩者投回時間域（iDCT）後，用遮罩 $M$ 逐幀組合，再送回 DCT 域，確保輸出既符合條件又能生成合理的未來。
$$
\mathbf{y}_{t-1}
=\mathrm{DCT}\!\Big(
\mathbf{M}\odot \mathrm{iDCT}(\mathbf{y}^{n}_{t-1})
+\big(\mathbf{1}-\mathbf{M}\big)\odot \mathrm{iDCT}(\mathbf{y}^{d}_{t-1})
\Big)
$$
* $\mathbf{y}_{t-1} \in \mathbb{R}^{L \times 3J}$：在 $t−1$ 步的最終更新頻譜
* $\mathbf{y}^{n}_{t-1} \in \mathbb{R}^{L \times 3J}$：用「觀測（加噪後）回到時域」的訊號
* $\mathbf{y}^{d}_{t-1} \in \mathbb{R}^{L \times 3J}$：用「模型去噪預測」的訊號
* $⊙$：元素對應相乘
* $\mathbf{M}
=\big[\underbrace{1,\ldots,1}_{H},\underbrace{0,\ldots,0}_{F}\big]^{\top}
\in\mathbb{R}^{H+F}$：遮罩向量
   * 前 $H$ 幀（已觀測的過去動作）：$M=1$，保留觀測（加噪後）的訊號
   * 後 $F$ 幀（未來要預測的動作）：$M=0$，因此在這段區域不採用觀測，而是由模型去噪預測提供訊號。

![image](https://hackmd.io/_uploads/BkgJOdW6xg.png)

**總結**
![image](https://hackmd.io/_uploads/ByC2-Nlalg.png =70%x)

---

### 附加流程 - Motion Switch
讓生成的序列不只延續觀測幀，還能在推理過程中 插入一段「目標動作」（target motion），實現動作類別的切換。
公式裡的遮罩向量 $M$：
$$\mathbf{M}=[\underbrace{1,1,\ldots,1}_{H},\ \underbrace{0,0,\ldots,0}_{F-M},\ \underbrace{1,1,\ldots,1}_{M}]^{\top}$$
* 預測長度：$F$ 幀
* 前 $H$ 幀：保持觀測幀 → $M=1$
* 中間 $F−M$ 幀：讓模型自由生成，平滑過渡到新動作 → $M=0$
* 後 $M$ 幀：強制套用「目標動作 (target motion)」 → $M=1$

---


### TransLinear
HumanMAC 裡的核心噪聲預測網路，在每一步迭代裡幫忙把目前的帶噪頻譜 $y_t$ 去噪。
輸入是 $(\mathbf{y}_t,\,t)$，輸出是 $\epsilon_{\theta}(\mathbf{y}_t,\,t)$。
Human3.6M 用 8 層 TransLinear block，HumanEva-I 用 4 層 TransLinear block。
:::spoiler HumanMAC/models/transformer.py
```javascript=198
class TemporalDiffusionTransformerDecoderLayer(nn.Module):

    def __init__(self,
                 latent_dim=32,
                 time_embed_dim=128,
                 ffn_dim=256,
                 num_head=4,
                 dropout=0.5,
                 ):
        super().__init__()
        self.sa_block = TemporalSelfAttention(
            latent_dim, num_head, dropout, time_embed_dim)
        self.ffn = FFN(latent_dim, ffn_dim, dropout, time_embed_dim)

    def forward(self, x, emb):
        x = self.sa_block(x, emb)
        x = self.ffn(x, emb)
        return x
```
:::
每層都包含兩個模塊且按順序執行：
1. TemporalSelfAttention：先處理輸入，建立時序依賴關係
:::spoiler HumanMAC/models/transformer.py **TemporalSelfAttention**
```javascript=129
class TemporalSelfAttention(nn.Module):

    def __init__(self, latent_dim, num_head, dropout, time_embed_dim):
        super().__init__()
        self.num_head = num_head
        self.norm = nn.LayerNorm(latent_dim)
        self.query = nn.Linear(latent_dim, latent_dim, bias=False)
        self.key = nn.Linear(latent_dim, latent_dim, bias=False)
        self.value = nn.Linear(latent_dim, latent_dim, bias=False)
        self.dropout = nn.Dropout(dropout)
        self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout)

    def forward(self, x, emb):
        """
        x: B, T, D
        """
        B, T, D = x.shape
        H = self.num_head
        # B, T, 1, D
        query = self.query(self.norm(x)).unsqueeze(2)
        # B, 1, T, D
        key = self.key(self.norm(x)).unsqueeze(1)
        query = query.view(B, T, H, -1)
        key = key.view(B, T, H, -1)
        # B, T, T, H
        attention = torch.einsum('bnhd,bmhd->bnmh', query, key) / math.sqrt(D // H)
        weight = self.dropout(F.softmax(attention, dim=2))
        value = self.value(self.norm(x)).view(B, T, H, -1)
        y = torch.einsum('bnmh,bmhd->bnhd', weight, value).reshape(B, T, D)
        y = x + self.proj_out(y, emb)
        return y
```
![image](https://hackmd.io/_uploads/r1Q06Lball.png =50%x)
:::
2. FFN：接著對注意力輸出進行特徵變換
:::spoiler HumanMAC/models/transformer.py **FFN**
```javascript=113
class FFN(nn.Module):

    def __init__(self, latent_dim, ffn_dim, dropout, time_embed_dim):
        super().__init__()
        self.linear1 = nn.Linear(latent_dim, ffn_dim)
        self.linear2 = zero_module(nn.Linear(ffn_dim, latent_dim))
        self.activation = nn.GELU()
        self.dropout = nn.Dropout(dropout)
        self.proj_out = StylizationBlock(latent_dim, time_embed_dim, dropout)

    def forward(self, x, emb):
        y = self.linear2(self.dropout(self.activation(self.linear1(x))))
        y = x + self.proj_out(y, emb)
        return y
```
![image](https://hackmd.io/_uploads/HyiZ0LZTex.png =50%x)

:::


---

### 資料集
- 主要資料集

|    名稱    |           主體／頻率            | 關節數(V) |                    任務                     |
|:----------:|:-------------------------------:|:------:|:-------------------------------------------:|
| Human3.6M  | 11 位受試者，約 360 萬幀，50 Hz/s |   17   | 給定過去 25 幀(0.5秒)，預測未來 100 幀(2秒) |
| HumanEva-I |        3 位受試者，60 Hz/s        |   15   | 給定過去 15 幀(0.25秒)，預測未來 60 幀(1秒) |

|           參數            |                   設定                    |
|:-------------------------:|:-----------------------------------------:|
|           epoch           |     Human3.6M：1001，HumanEva-I：501      |
|        batch size         |                    64                     |
| 每個 epoch 處理的訓練樣本 | 50000 |
|        DCT 係數(M)        | Human3.6M：前 20 個，HumanEva-I：前 10 個 |

- 額外驗證：CMU-MoCap、AMASS（含 zero-shot 評估）

---

### 實驗結果
[github](https://github.com/LinghaoChan/HumanMAC/tree/main)
**(a) 與 SOTA 比較**
- HumanMAC 在 **ADE、FDE**（準確性）達到 SOTA，且動作更合理。   
- 在 **APD（多樣性）** 指標略低，但避免了 baseline 常見的「失敗案例造成假多樣性」。 
![image](https://hackmd.io/_uploads/BkTOMDWple.png)

**(b) 可視化結果**
- HumanMAC 較少出現物理不合理的預測（如浮空、突然彎曲）。

**( c ) 動作切換 Motion Switch**
- 能順暢轉換稀有或未見過的動作（如坐下 → 站立、轉身）。


**(d) 部分身體可控預測 Part-body Controllable Prediction**
- 可固定下半身，生成合理的上半身動作。
- 基線方法 GSPS 和 DLow 僅能實現上下半身的控制，因為它們需要顯式地解耦上下半身的動作。而且在解耦後，這些方法還需要重新訓練模型，才能實現部分身體可控能力。相比之下，我們的方法不依賴於模型的重新訓練，即可對身體的任意部分進行可控預測。
    

**(e) 消融實驗 (Ablation Studies)**
1. DCT/iDCT 中 L 的取值
![image](https://hackmd.io/_uploads/r1sV8v-plg.png)
2. 噪聲預測網路層層數的設計
![image](https://hackmd.io/_uploads/HJ4c8PZ6ge.png)
3. 擴散模型的設定
探討去噪步數長度，以及不同的擴散方差排程方式（如 Linear、Cosine 和 Sqrt）對實驗結果的影響
[擴散方差排程方式](https://hackmd.io/@q_bRZRi5Q2iTv2zdBQYQHg/SkEF3wWTxg)
![image](https://hackmd.io/_uploads/Hy8QwP-Txl.png)
預設加噪與採樣的步數分別設為 1000 與 100，如果將加噪與採樣的步數同時縮減 10 倍，生成動作的真實性會明顯下降。此外步數的減少會導致視覺化結果中出現「抖動」的動作。
![image](https://hackmd.io/_uploads/BkPHDvZagl.png)

**(f) 零樣本動作預測 Zero-shot Evaluation**
在 Human3.6M 數據集上訓練 HumanMAC 模型，並利用給定的 AMASS 數據集中的觀測動作進行動作預測。結果表現合理且多樣，生成未見過的動作（如 kneeling），展現了 HumanMAC 框架良好的泛化能力。

**(g) 在其他資料集上的評估**
將 HumanMAC 與以 VAE 與以擴散模型為基礎的方法，在 CMU-MoCap 與 AMASS 兩個資料集上進行比較。
HumanMAC 在兩個資料集上都展現出更優越的表現，顯示其遮罩補全機制（mask-completion）具有強大的預測能力。
![image](https://hackmd.io/_uploads/ByHrJub6xx.png)

**(h) DCT 設計的消融實驗**
未使用 DCT 的模型會出現嚴重抖動，使用DCT 能讓預測更為準確。
![image](https://hackmd.io/_uploads/BkdJWdbaxl.png =50%x)![image](https://hackmd.io/_uploads/ryYe-O-axg.png =50%x)

**(i) 長序列預測**
將最後 $H$ 幀的預測視為觀測，並不斷遞迴地預測後續動作。基線方法傾向於預測過度平滑、幾乎靜止的動作，HumanMAC 生成的動作比 baseline 多樣且不會過度平滑。
![image](https://hackmd.io/_uploads/r1ob-_-agl.png)

---

### 缺點
- **效率限制**：需要約 100 步 DDIM 取樣，速度不足以應用於即時系統。
- **多樣性指標問題**：作者指出現有的 APD 衡量方式可能誤導（高分可能來自錯誤樣本），仍需更合理的多樣性評估指標。
- **未測試大規模資料集**：目前僅在中型數據集評估，未在大規模全身動作庫進行完整驗證。
- **網路結構仍偏複雜**：未來計劃簡化模型與演算法。
