## HumanMAC: Masked Motion Completion for Human Motion Prediction
[github](https://github.com/LinghaoChan/HumanMAC/tree/main)
### 前言
**擴散模型(Diffusion Model)**

將原始圖片逐漸加入雜訊(Noise),讓原本的圖片逐漸變成完全的雜訊狀態。然後再透過反轉這個過程,也就是Denoise去除雜訊來恢復圖片。讓它學習了雜訊圖和真實圖片之間的變換關係,最後使其能夠從雜訊中生成出像樣的圖片。
1. 正向過程(Forward Process/Diffusion Process):對圖片逐步增加雜訊。
2. 反向過程(Reverse Process):從雜訊中逐步恢復圖片。
---
### 概述

以往的人體動作預測方法多採用 **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$」做期望(取平均)
**總結**

---
### 流程 - 推理階段
#### 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$,因此在這段區域不採用觀測,而是由模型去噪預測提供訊號。

**總結**

---
### 附加流程 - 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
```

:::
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
```

:::
---
### 資料集
- 主要資料集
| 名稱 | 主體/頻率 | 關節數(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 常見的「失敗案例造成假多樣性」。

**(b) 可視化結果**
- HumanMAC 較少出現物理不合理的預測(如浮空、突然彎曲)。
**( c ) 動作切換 Motion Switch**
- 能順暢轉換稀有或未見過的動作(如坐下 → 站立、轉身)。
**(d) 部分身體可控預測 Part-body Controllable Prediction**
- 可固定下半身,生成合理的上半身動作。
- 基線方法 GSPS 和 DLow 僅能實現上下半身的控制,因為它們需要顯式地解耦上下半身的動作。而且在解耦後,這些方法還需要重新訓練模型,才能實現部分身體可控能力。相比之下,我們的方法不依賴於模型的重新訓練,即可對身體的任意部分進行可控預測。
**(e) 消融實驗 (Ablation Studies)**
1. DCT/iDCT 中 L 的取值

2. 噪聲預測網路層層數的設計

3. 擴散模型的設定
探討去噪步數長度,以及不同的擴散方差排程方式(如 Linear、Cosine 和 Sqrt)對實驗結果的影響
[擴散方差排程方式](https://hackmd.io/@q_bRZRi5Q2iTv2zdBQYQHg/SkEF3wWTxg)

預設加噪與採樣的步數分別設為 1000 與 100,如果將加噪與採樣的步數同時縮減 10 倍,生成動作的真實性會明顯下降。此外步數的減少會導致視覺化結果中出現「抖動」的動作。

**(f) 零樣本動作預測 Zero-shot Evaluation**
在 Human3.6M 數據集上訓練 HumanMAC 模型,並利用給定的 AMASS 數據集中的觀測動作進行動作預測。結果表現合理且多樣,生成未見過的動作(如 kneeling),展現了 HumanMAC 框架良好的泛化能力。
**(g) 在其他資料集上的評估**
將 HumanMAC 與以 VAE 與以擴散模型為基礎的方法,在 CMU-MoCap 與 AMASS 兩個資料集上進行比較。
HumanMAC 在兩個資料集上都展現出更優越的表現,顯示其遮罩補全機制(mask-completion)具有強大的預測能力。

**(h) DCT 設計的消融實驗**
未使用 DCT 的模型會出現嚴重抖動,使用DCT 能讓預測更為準確。

**(i) 長序列預測**
將最後 $H$ 幀的預測視為觀測,並不斷遞迴地預測後續動作。基線方法傾向於預測過度平滑、幾乎靜止的動作,HumanMAC 生成的動作比 baseline 多樣且不會過度平滑。

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