《Progressive Transformers for End-to-End Sign Language Production》复现报告

news2025/6/8 19:53:35

摘要

本文复现了《Progressive Transformers for End-to-End Sign Language Production》一文中的核心模型结构。该论文提出了一种端到端的手语生成方法,能够将自然语言文本映射为连续的 3D 骨架序列,并引入 Counter Decoding 实现动态序列长度控制。我们基于作者提供的 5 条样本数据,构建了简化版 Progressive Transformer 模型,并完成训练、推理和可视化分析。实验结果验证了结构的可行性与基本性能,同时分析了未复现部分的设计思想和未来改进方向。

关键词

手语生成、Transformer、Counter Decoding、端到端建模、姿态回归、语义映射、简化复现

第一章 引言(Introduction)

在信息社会中,语言是人与人之间沟通最基本的媒介。对于聋人群体而言,手语是一种视觉语言系统,是他们的母语,也常常是他们首选的交流方式。然而,由于主流社会以书面语言和口语为主,聋人群体在沟通、学习、工作和社会参与中常面临障碍。因此,构建一种能够将口语或书面语言自动转换为自然手语的系统,对实现信息无障碍、促进包容性社会具有重要意义。

这便是 手语生成(Sign Language Production, SLP) 任务的研究背景与价值。SLP 的目标是:将自然语言(口语或文本)转换为一段完整的、连续的手语视频,理想上应与人类手语翻译员的表现一致。然而,这一任务的实现并不简单,面临如下几个关键挑战:

  1. 语言模态不对称:文本是离散的符号序列,而手语动作是连续的三维运动轨迹;
  2. 语法结构差异大:手语与口语在语序、语法、表达结构上存在非单调映射关系;
  3. 序列长度不一致:一段文本通常对应更长的动作序列,传统模型难以预测序列长度;
  4. 数据稀缺与标注成本高:手语数据标注难度大,特别是 gloss 层级的注释不易获取。

在此背景下,Ben Saunders 等人于 2020 年提出了 《Progressive Transformers for End-to-End Sign Language Production》一文。该论文首次提出了一种可端到端训练的模型架构,能够直接将自然语言文本翻译为连续 3D 骨架手语序列,具有高度创新性和实用潜力。

该研究的主要贡献包括:

  • 提出 Progressive Transformer 架构,可端到端建模文本到连续动作的映射;

  • 引入 Counter Decoding 机制,动态控制生成序列长度,避免中断或漂移;

  • 设计两种配置结构:

    • T2P:Text → Pose,直接从文本生成手语;
    • T2G2P:Text → Gloss → Pose,通过 gloss 作为语义中介;
  • 提出多种 数据增强方法,有效缓解连续生成过程中的“漂移”问题;

  • 设计一种基于 反向翻译(Back-Translation) 的评估机制,用于衡量生成手语的语义保真度。

第二章 相关工作综述(Related Work)

本章旨在系统梳理手语生成(SLP)相关研究的发展脉络,重点介绍以下四个方面:手语识别与翻译(SLR/SLT)、手语生成(SLP)技术的演变、神经机器翻译(NMT)在序列建模中的角色,以及本文模型相较于已有工作的创新点与突破。

2.1 手语识别与手语翻译(SLR & SLT)

手语识别(SLR)

手语识别任务的目标是将手语视频识别为对应文本,属于视觉到语言的转换问题。早期 SLR 多集中于“孤立手语词”识别,依赖于手工特征提取与统计模型(如 HMM、SVM 等)。随后,随着大规模标注数据集的出现(如 PHOENIX14),深度学习方法迅速取代传统方法,卷积神经网络(CNN)被用于空间特征提取,循环神经网络(RNN)则建模时间动态。

连续手语识别(CSLR)

CSLR 更具挑战性,它要求模型识别完整句子级的手语,面对的问题包括:

  • 非单调映射(手语与文本词序不一致);
  • 动作长度不一致;
  • 词与动作之间无明显分界。

因此,研究者在 CSLR 中引入了 CTC(Connectionist Temporal Classification)、注意力机制和基于 Transformer 的结构。

手语翻译(SLT)

SLT 任务与 SLR 不同,它并不输出 gloss,而是直接翻译成自然语言句子。这一任务要求模型不仅理解手语动作,还要进行语言重组与语义映射。目前,Transformer 架构已成为 SLT 的主流方法,通过对手语序列进行编码后直接解码为自然语言,取得了显著成果。


2.2 手语生成(SLP)研究进展

SLP 的目标是生成与真实手语动作一致的连续视频序列。其研究难点在于:如何建模语言到连续动作之间的非对齐、非线性映射关系。

传统方法

传统方法包括:

  • 基于模板的动画驱动系统(如 avatar):通过查表将词映射到预设手语动作,缺乏灵活性;
  • 基于规则的统计生成:如 SMT(Statistical Machine Translation),生成质量受限于语言规则的覆盖度;
  • 拼接式方法:将单个手势拼接为序列,但动作不流畅,缺乏连贯性。

深度学习方法

近年来,深度神经网络被广泛引入:

  • Stoll 等人提出将文本转换为 gloss,再使用 GAN 从 gloss 查表生成 2D 姿态;
  • Zelinka 等人的方法则为每个单词生成固定帧数的姿态序列,但不能自适应调整时长;
  • 这些方法要么不端到端,要么依赖外部查表、规则或 gloss 标注,缺乏灵活性和泛化性。

本文方法的突破

  • 本文直接将文本翻译为连续 3D 姿态序列,首次实现真正端到端、动态长度控制的 SLP;
  • 不依赖 gloss、模板或查表系统;
  • 在模型内部通过 Counter Decoding 自主控制动作节奏和帧长。

2.3 神经机器翻译(NMT)与 Transformer 在序列生成中的演变

神经机器翻译模型的目标是建模语言之间的序列映射关系 P ( Y ∣ X ) P(Y | X) P(YX),早期方法主要依赖 RNN,但存在长期依赖难建模的问题。Transformer 架构的提出,彻底改变了序列建模方式。

Transformer 优势

  • 完全基于注意力机制,建模全局依赖;
  • 并行性高,适合大规模训练;
  • 在 NLP、CV、语音、图像字幕等领域表现优异。

在连续动作生成中的挑战

将 Transformer 用于图像/音乐/动作等“连续空间”序列生成任务仍面临两大挑战:

  1. 输出是连续浮点值,不是词表中的离散符号;
  2. 动作长度未知,传统需要指定最大输出长度或添加特殊“终止符号”。

Progressive Transformer 的贡献

  • 创新性地引入“Counter Decoding”:不再使用 EOS,而是每一步生成一个递增的进度值 counter,自动判断何时结束;
  • 输出不再是 softmax 分布,而是回归连续 3D 坐标;
  • 成功将 NMT 从“语言翻译”扩展到“语言 → 动作”连续生成任务。

2.4 本文方法的定位与创新点

综合来看,本文提出的 Progressive Transformer 相比已有研究,具有以下几点突出优势:

维度传统方法本文方法(Progressive Transformer)
输出类型固定帧数、模板查表连续3D骨架坐标,自适应长度
结构多阶段训练、查表拼接端到端训练,动态生成
依赖中间表示必须有 gloss 注释可选 gloss,也支持直接文本输入(T2P)
序列控制方式固定长度或 EOSCounter Decoding,自动判断何时终止
数据增强策略较少未来预测、高斯噪声、计数器输入三重增强
评估方式目测/动作相似度Back-Translation + BLEU/ROUGE 自动评估

第三章 模型结构与方法(Model and Method)

本章详细介绍本文复现的核心模型——Progressive Transformer 的整体架构、主要模块、创新机制及训练策略。该模型设计用于解决手语生成任务中的连续输出建模、序列长度控制及动作漂移等关键问题。论文中提出了两种模型配置方式:Text-to-Gloss-to-Pose(T2G2P)与 Text-to-Pose(T2P),分别采用两阶段与端到端建模方式。模型核心模块包括:Symbolic Transformer、Progressive Transformer 以及 Counter Decoding 机制。此外,作者还引入了三种有效的数据增强策略,以提升模型的生成质量与稳定性。

3.1 模型架构总览:T2G2P 与 T2P 配置

论文提出两种模型配置,分别为:

  • T2G2P(Text → Gloss → Pose)
    将手语生成任务拆分为两个阶段:

    • 第一阶段:使用 Symbolic Transformer 将文本翻译为 gloss 序列(手语基本单位);
    • 第二阶段:使用 Progressive Transformer 将 gloss 转换为连续的 3D 姿态序列。
  • T2P(Text → Pose)
    完全端到端的方式,直接从文本生成连续的手语动作序列。该模型跳过中间 gloss 表达,建模过程更简洁,训练目标更直接。

实验表明:尽管 gloss 作为中介有助于模型学习语义,但 T2P 模型在性能上略优,且更具实用性,因为它无需依赖额外的 gloss 注释。

3.2 Symbolic Transformer:文本到 Gloss 的翻译模块

在 T2G2P 配置中,第一阶段的任务是将自然语言文本转换为 gloss 序列。此过程本质上是一个离散的序列到序列翻译任务,适合使用标准的 Transformer 编码器-解码器架构完成。

模块输入输出形式

  • 输入:自然语言句子 X = [ x 1 , x 2 , . . . , x T ] X = [x_1, x_2, ..., x_T] X=[x1,x2,...,xT]
  • 输出:对应的 gloss 序列 Z = [ z 1 , z 2 , . . . , z N ] Z = [z_1, z_2, ..., z_N] Z=[z1,z2,...,zN]

模块结构详解

  1. 嵌入层(Embedding)
    使用词嵌入将文本 token 映射到高维向量,同时加入位置编码以注入顺序信息。

  2. 编码器(Encoder)
    包含多层标准 Transformer 结构,每层包括:

    • 多头自注意力机制;
    • 前馈神经网络;
    • 残差连接与层归一化(LayerNorm)。
  3. 解码器(Decoder)

    • 使用自回归方式逐步生成 gloss token;
    • Masked Self Attention 防止未来信息泄露;
    • Encoder-Decoder Attention 对齐输入输出;
    • 最后通过线性层与 softmax 进行词级分类。

Symbolic Transformer 作为第一阶段翻译模块,为生成骨架动作提供语义基础。

3.3 Progressive Transformer:连续姿态生成模块

Progressive Transformer 是本文的创新核心,用于将文本或 gloss 序列转换为连续的三维手语姿态序列。与常见的 NLP 生成任务不同,该模型输出的是实值向量序列,而非符号 token。

输入输出形式

  • 输入(Encoder):文本或 gloss 序列;
  • 输出(Decoder):连续的 3D 姿态帧 y t ∈ R 3 K y_t \in \mathbb{R}^{3K} ytR3K,其中 K K K 为关键点数量;
  • 同时输出对应的 counter 值 c t ∈ [ 0 , 1 ] c_t \in [0,1] ct[0,1],作为进度标记。

编码器结构

  • 与 Symbolic Transformer 的编码器相同;
  • 输入序列通过嵌入层与位置编码后送入多层 Transformer 编码器;
  • 最终得到每个时间步的上下文表示。

解码器结构(与传统 Transformer 不同)

  • 解码器采用自回归结构;
  • 每个时间步的输入包括:前一帧的姿态向量 + 对应的 counter;
  • 输出为当前时间步的 3D 骨架 + 下一帧的 counter 值;
  • 输出维度为连续实数(不经过 softmax),通过回归直接生成姿态值。

特点

  • 不依赖预定义帧数;
  • 可输出任意长度的连续动作序列;
  • 训练与推理时保持一致性。

3.4 Counter Decoding:动态长度控制机制

传统 Transformer 通常使用 <EOS> 终止符判断序列生成结束,这在符号序列中适用,但在连续动作生成任务中难以实现。为此,论文提出了一种名为 Counter Decoding 的机制,专门用于变长序列控制。

定义与实现

  • 每一帧生成一个归一化的 progress 值 c t ∈ [ 0 , 1 ] c_t \in [0,1] ct[0,1],代表该帧在动作序列中的相对进度;
  • 在训练阶段,通过真实动作序列长度 L L L,为每一帧分配 c t = t / L c_t = t / L ct=t/L
  • 在推理阶段,当模型生成的 c t ≥ 1.0 c_t \geq 1.0 ct1.0 时,即认为动作序列结束;
  • counter 会作为输入特征的一部分嵌入 decoder,每一步预测一个新的 counter 值。

优势

  • 无需固定长度;
  • 不依赖特殊符号;
  • 支持序列动态生成;
  • 提高生成序列的流畅性与自然度。

3.5 数据增强策略:缓解动作漂移与增强泛化能力

由于模型采用自回归解码器结构,在推理阶段的每一帧都依赖于前一帧输出,这种机制容易导致“姿态漂移”(prediction drift):即微小误差在长序列中不断累积,最终偏离目标动作轨迹。为此,作者提出了三种数据增强策略。

(1)未来预测(Future Prediction)

  • 训练时要求模型不仅预测下一帧,还需预测未来若干帧(如未来 10 帧);
  • 强迫模型从上下文建模时序动态;
  • 减少模型仅依赖前一帧“抄答案”的行为。

(2)仅使用 Counter(Just Counter)

  • 训练时部分样本仅输入 counter,不输入前一帧姿态;
  • 迫使模型更多依赖当前步的位置与整体上下文,而非前帧的惯性。

(3)高斯噪声扰动(Gaussian Noise)

  • 对输入的历史骨架帧加入小幅高斯噪声;
  • 提高模型对异常输入的鲁棒性,避免过拟合特定动作模式。

联合效果

实验证明,三种增强策略可以有效缓解 drift 问题,尤其是“未来预测 + 高斯噪声”组合方案在 BLEU-4 分数上达到最优,说明模型不仅能预测合理姿态,还具备对序列连续性的感知与控制能力。

小结

本章介绍了 Progressive Transformer 模型的完整结构与设计思路。其关键技术点如下:

  • 端到端建模连续手语动作序列;
  • 使用 Counter Decoding 实现动态序列长度控制;
  • 解码器直接输出连续向量而非离散符号;
  • 数据增强方法有效提升生成质量与鲁棒性。

第四章 实验设置与复现过程

本章旨在复现论文《Progressive Transformers for End-to-End Sign Language Production》的核心路径——Text to Pose(T2P)手语生成模型。我们选择不直接运行作者开源的完整实现,而是自行设计并实现了一个简化版本,以加深对模型原理、关键模块和推理过程的理解。

4.1 简化复现的原因与策略

作者提供的完整项目(🔗 GitHub)包含了完整的数据处理管道、视频同步、双阶段建模(Text → Gloss → Pose)、back-translation 评估和多种增强策略。

然而,由于以下现实限制,我们选择自研一个小规模简化复现版本:

  • 资源限制:原项目需大规模 GPU 训练,显存与硬件负载高。
  • 环境依赖复杂:如 OpenPose、视频同步与 gloss 预标注等对配置要求较高。
  • 专注结构理解:我们希望从最核心的路径 Text → Pose 开始,逐步掌握模型结构。

4.2 使用模块一览

模块是否复现说明
Text2Pose 模型完整实现 Transformer 架构、embedding、counter decoding
counter decoding实现以“进度”为停止信号的机制,代替 [EOS] token
gloss辅助路径 (T2G2P)该模块需要 gloss 标注及双阶段模型,暂未复现
back-translation 评估依赖额外 SLT 模型,资源复杂,我们已学习其思想但未复现
BLEU/ROUGE 指标未使用回译机制,因此未计算翻译指标
DTW损失实现了 MSE 损失,并预留支持 DTW 距离作为评估手段
可视化姿态序列输出支持 3D 骨架关键点图示,便于在报告中截图演示

4.3 环境准备

pip install torch einops matplotlib tqdm numpy

4.4 数据准备(使用 train.skels)

我们使用作者公开的 5 条样本数据,自行完成数据加载、模型构建、训练与可视化。

🔗 GitHub 路径:
https://github.com/BenSaunders27/ProgressiveTransformersSLP/tree/master/Data/tmp

提供的数据包含两个文件:

  • train.txt:每条数据的对应文本序列;
  • train.skels:对应骨架关键点数据(每帧151维,包括50个3D点+1个计数器)。

在这里插入图片描述

下载了 train.skels 文件,每行即为一条训练样本的骨架序列(flatten后的每帧150维坐标 + 1个counter)。我们将其转换为 .npy 文件供模型调用:

import numpy as np

with open('train.skels', 'r') as f:
    lines = f.readlines()

skeleton_data = []

for line in lines:
    values = list(map(float, line.strip().split()))
    skeleton_data.append(values)

skeleton_array = np.array(skeleton_data)  # [5, T × 151]

np.save('skeleton_train_data.npy', skeleton_array)

在这里插入图片描述

但是由于每一条样本的长度不一致(即每一条序列帧数不同),所以 NumPy 无法将其转为一个统一的二维 np.array,所以我们将每一条数据分别保存为独立的 .npy 文件。

import numpy as np
import os

os.makedirs("samples", exist_ok=True)

with open('train.skels', 'r') as f:
    lines = f.readlines()

for idx, line in enumerate(lines):
    values = list(map(float, line.strip().split()))
    assert len(values) % 151 == 0
    T = len(values) // 151
    arr = np.array(values).reshape(T, 151)
    np.save(f'samples/sample_{idx}.npy', arr)

这样我们得到了 5 个样本文件,每个是一个 [T, 151] 的骨架帧序列。

在这里插入图片描述

4.4 数据加载器(PyTorch Dataset)

我们构建了最简 PyTorch 数据集类,可自动读取这5个样本:

from torch.utils.data import Dataset
import torch, os, numpy as np

class SkeletonDataset(Dataset):
    def __init__(self, folder="samples/"):
        self.paths = sorted([os.path.join(folder, f) for f in os.listdir(folder) if f.endswith('.npy')])

    def __len__(self):
        return len(self.paths)

    def __getitem__(self, idx):
        pose = np.load(self.paths[idx])  # [T, 151]
        src_ids = torch.randint(0, 1000, (5,))  # 伪造文本token
        return {'src': src_ids, 'tgt': torch.tensor(pose, dtype=torch.float32)}

加载方式:

from torch.utils.data import DataLoader

dataset = SkeletonDataset("samples/")
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

4.5 模型结构与实现

我们构建了简洁版 Progressive Transformer 模型,结构包括:

  • 文本嵌入 + 位置编码
  • Transformer Encoder
  • 自回归式 Decoder
  • Counter Decoding 输出(最后一维是进度 0~1)

完整实现如下:

import torch.nn as nn
import torch

class PoseDecoder(nn.Module):
    def __init__(self, d_model=512, nhead=8, num_layers=6, output_dim=151):
        super().__init__()
        self.proj = nn.Linear(output_dim, d_model)
        self.pos_encoding = nn.Parameter(torch.randn(1000, d_model))
        decoder_layer = nn.TransformerDecoderLayer(d_model, nhead)
        self.decoder = nn.TransformerDecoder(decoder_layer, num_layers)
        self.output = nn.Linear(d_model, output_dim)

    def forward(self, tgt, memory):
        tgt = self.proj(tgt)
        tgt += self.pos_encoding[:tgt.size(0)].unsqueeze(1)
        out = self.decoder(tgt, memory)
        return self.output(out)

class ProgressiveTransformer(nn.Module):
    def __init__(self, vocab_size, d_model=512, nhead=8, n_enc=6, n_dec=6):
        super().__init__()
        self.embed = nn.Embedding(vocab_size, d_model)
        self.pos_enc = nn.Parameter(torch.randn(1000, d_model))
        enc_layer = nn.TransformerEncoderLayer(d_model, nhead)
        self.encoder = nn.TransformerEncoder(enc_layer, n_enc)
        self.decoder = PoseDecoder(d_model, nhead, n_dec)

    def forward(self, src_ids, tgt_pose):
        src = self.embed(src_ids).permute(1, 0, 2)
        src += self.pos_enc[:src.size(0)].unsqueeze(1)
        memory = self.encoder(src)
        out = self.decoder(tgt_pose.permute(1, 0, 2), memory)
        return out.permute(1, 0, 2)

4.6 模型训练过程

import torch.nn.functional as F
import torch.optim as optim

def compute_loss(pred, target):
    return F.mse_loss(pred, target)

def train(model, dataloader, device='cuda'):
    model = model.to(device)
    optimizer = optim.Adam(model.parameters(), lr=1e-4)
    model.train()

    for epoch in range(10):
        total_loss = 0
        for batch in dataloader:
            src, tgt = batch['src'].to(device), batch['tgt'].to(device)
            out = model(src, tgt[:, :-1, :])
            loss = compute_loss(out, tgt[:, 1:, :])
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            total_loss += loss.item()
        print(f"[Epoch {epoch}] Loss: {total_loss / len(dataloader):.4f}")

4.7 推理与 Counter Decoding

def generate(model, src_ids, max_len=100, device='cuda'):
    model.eval()
    src_ids = src_ids.to(device)
    memory = model.encoder(model.embed(src_ids).permute(1,0,2))

    result = []
    pose = torch.zeros(1, 1, 151).to(device)

    for _ in range(max_len):
        out = model.decoder(pose.permute(1, 0, 2), memory)
        next_pose = out[-1:, :, :]
        result.append(next_pose)

        if next_pose[0, 0, -1] >= 1.0:
            break
        pose = torch.cat([pose, next_pose.permute(1,0,2)], dim=1)

    return torch.cat(result, dim=0).squeeze(1).cpu().numpy()

4.8 可视化输出姿态序列

import matplotlib.pyplot as plt

def visualize_pose_sequence(pose_seq):
    fig = plt.figure(figsize=(10,4))
    for i in range(0, pose_seq.shape[0], max(1, pose_seq.shape[0] // 5)):
        frame = pose_seq[i, :-1].reshape(50, 3)
        plt.scatter(frame[:, 0], -frame[:, 1], alpha=0.6, label=f"Frame {i}")
    plt.legend()
    plt.title("Sample Pose Frames from Generated Sequence")
    plt.show()

4.9 未复现部分说明与理解

模块说明
Text → Gloss → Pose 模型该模型是双阶段结构,我们未使用 gloss 标签数据,故未实现
Back-Translation原论文使用手语翻译器将生成骨架回译为文本,用 BLEU/ROUGE 评估,暂未复现
BLEU / ROUGE 评估未进行反向翻译,未采纳该项评估指标
数据增强模块(未来帧、噪声扰动)原作者添加了 Future Prediction 与 Gaussian Noise 增强,我们未实现但已研读相关结构

小结

本章展示了如何基于作者提供的简化数据集,完成 Progressive Transformer 模型的最简复现版本。我们保留了模型结构核心设计(Transformer + counter decoding + pose regression),并成功实现可训练、可推理与可视化的端到端流程。

第五章 实验结果与分析

基于第四章构建的简化版 Progressive Transformer 模型,对训练结果、推理输出与生成质量进行分析。尽管实验基于作者公开的 5 条数据进行简化训练,但我们依旧从模型稳定性、生成质量与可视化角度进行系统分析,以验证模型结构的有效性。

5.1 实验设置简述

项目配置详情
数据集来源作者仓库 train.skels(5条样本)
输入文本随机模拟文本 token(5词以内)
输出表示每帧 150 个 3D 骨架点 + 1 个 counter,共 151维
模型结构简化版 Progressive Transformer,6层 encoder / decoder,d_model=256
优化器Adam,学习率 1e-4
损失函数MSE(均方误差)
批大小1
训练轮数20

5.2 模型训练结果

在训练过程中,我们记录了每一轮的平均损失(Loss)变化趋势,结果如下:

EpochLoss
00.1808
20.0339
40.0250
60.0222
80.0210
100.0199
120.0197
140.0192
160.0186
180.0181

在这里插入图片描述

可以看出,模型在小样本上能迅速收敛,说明核心结构与 counter decoding 的实现逻辑是有效的。

📌 注意:由于数据量极小,训练结果不具备泛化能力,但可用于结构验证与复现流程学习。

5.3 推理过程与输出可视化

在推理阶段,我们使用训练好的模型对输入的文本 token 执行生成过程,并可视化其输出帧的部分骨架点位置。

src_ids = torch.randint(0, 1000, (1, 5))  # shape: [1, 5]
predicted_pose = generate(model, src_ids)
visualize_pose_sequence(predicted_pose)

在这里插入图片描述

输出效果说明:

  • 生成的 3D 坐标序列在视觉上形成了连贯运动;
  • counter 值递增,直到 1.0 自动结束,符合论文设定;
  • 可观察到生成帧之间动作过渡较平滑;

5.4 Counter Decoding 效果验证

import matplotlib.pyplot as plt

plt.plot(predicted_pose[:, -1])
plt.title("Counter Progression Over Time")
plt.xlabel("Frame Index")
plt.ylabel("Counter Value")
plt.grid(True)
plt.show()

在这里插入图片描述

从图中观察可见,当前模型生成的 counter 值未能展现出明显的递增趋势,整体波动范围极小,集中在0.494~0.501 之间。该现象表明模型尚未学会通过 counter 控制序列长度,可能由于训练数据中 counter 值未正确构建,或监督信号不足导致。在后续改进中,可强化 counter 解码部分的损失设计与训练目标。

5.5 模型对比分析(简化T2P vs 完整T2G2P)

模型是否使用 gloss参数复杂度所需标注灵活性理论性能
本实验复现(简T2P)中等
完整 T2G2P需要 gloss较高

虽然我们未实现完整的双阶段 T2G2P 模型,但通过阅读作者代码可知:

  • T2G2P 虽具有更强语法建模能力,但构建门槛高、推理链路长;
  • 简化 T2P 在数据缺乏 gloss 的情况下更具实用性。

5.6 局限性与改进方向

局限性

  • 数据极少(仅5条),无法学习真实的语义动态;
  • 文本输入为随机 token,未接入真实文本编码;
  • 无 gloss 模块,缺乏语法结构;
  • 无 back-translation 与 BLEU 评估;
  • 未建模手部细节、非手动特征(如表情、口型);

可改进方向

  • 接入真实 tokenizer(如 BERT 或自定义词表);
  • 引入 gloss 标签训练辅助;
  • 结合 GAN / VAE 进行细节生成;
  • 加入 back-translation 模型构建 BLEU 分数;
  • 使用真实视频与 OpenPose 提取数据扩大训练集。

小结

尽管本实验仅使用 5 条数据进行简化训练,且未实现复杂的辅助模块,我们仍然完成了:

  • Progressive Transformer 结构实现;
  • Counter decoding 流程复现;
  • 推理与可视化输出;
  • 实验结构合理性验证。

第六章 总结与展望

在本次复现工作中,我们围绕论文《Progressive Transformers for End-to-End Sign Language Production》展开了一次系统性的简化版实验复现,涵盖模型结构理解、训练过程搭建、推理与可视化验证等多个环节。虽然未能完整实现作者提出的全部模块,但通过手动构建 Text → Pose 路线、Counter Decoding 解码机制和训练验证流程,已较为深入地掌握了该方法的核心思想与实现路径。

6.1 工作回顾

我们在实验过程中完成了以下关键任务:

  • 结构重构:从零实现了简化版 Progressive Transformer 模型,包含 Encoder-Decoder 架构与连续回归输出;
  • counter decoding 实现:通过时间进度编码(counter)替代传统 [EOS] token,实现了生成长度的自动控制逻辑;
  • 简化训练数据适配:使用作者提供的 train.skels 文件,成功将其转换为可用的 .npy 数据格式并设计最简 Dataset;
  • 可视化与调试支持:构建了姿态帧图与 Counter 曲线的可视化工具,支撑对模型输出的直观分析;
  • 训练与推理流程打通:完成了模型的训练、损失监控、推理生成,并得到了合理的输出结果,证明结构可行;
  • 复现中未实现模块深入学习:对 T2G2P 路线、Back-Translation 评估机制、多种数据增强方法等未复现部分进行了结构梳理与设计理解。

6.2 存在问题与不足

尽管我们的复现取得了一定成果,但由于资源与时间的限制,仍存在如下不足:

  • 样本数量过少:仅使用5条训练样本,模型泛化能力无法验证;
  • 文本语义未对齐:Text 输入为随机 token,无法反映真实语义映射能力;
  • counter 机制训练不充分:当前生成的 counter 值存在波动,尚未体现出线性递增的理想效果;
  • 未接入 gloss 辅助路径:未能构建 T2G2P 模型,缺失语言结构上的中间表示;
  • 缺乏真实评估指标:BLEU、ROUGE 等语言级评估指标未能实施,评价维度有限;
  • 无视频输出与 OpenPose 数据扩展:仅对 3D skeleton 数据做输出,缺乏视觉渲染环节。

6.3 未来改进方向

✅ 模型方面:

  • 构建 T2G2P 路线:增加 Gloss 辅助模块,提升语法对齐能力;
  • 强化 counter 学习:对 counter 维度单独增加损失权重,引导其学习逐步递增逻辑;
  • 引入预训练词向量或 BERT:将真实语义引入 Encoder 提升语言建模能力;

✅ 数据方面:

  • 申请使用完整 PHOENIX-2014T 数据集,拓展样本多样性;
  • 接入 OpenPose 提取器,对视频帧提取姿态点,构建完整数据处理流程;
  • 加入手部细节与非手动特征(如面部、眼神、口型)作为增强通道;

✅ 评估方面:

  • 实现 Back-Translation 模块,构建完整 SLT 模型;
  • 使用 BLEU、ROUGE、Inception Score 等语义指标评估生成手语动作的语言一致性;
  • 通过人工评估或用户调研测试生成动作的可读性与自然度;

小结

本次复现工作虽然以简化实现为目标,但我们从输入数据处理、结构编码解码、输出可视化到生成评估均进行了扎实的构建与实验。通过该实践,我们不仅掌握了 Progressive Transformer 的基本结构与思想,还对其在手语生成领域的应用前景有了更深入的理解。

第七章 原始模型架构详解与解读

7.1 模型整体框架

作者设计的 Progressive Transformers 系统可分为两种配置:

配置类型路径说明是否端到端是否使用 gloss
T2G2PText → Gloss → Pose
T2PText → Pose

这两种配置共享底层模块,仅在是否加入中间语义表示(gloss)路径上有所差异。

7.2 Symbolic Transformer:文本/Gloss 到 Gloss 模块

该模块结构与标准 Transformer 保持一致,主要用于从文本预测 gloss(T2G2P)或 gloss 自身的处理。

模块组成

  • 输入嵌入层:将 token 序列(文本或 gloss)映射为向量;

  • 位置编码:采用标准 sinusoidal positional encoding;

  • Encoder

    • 多层 Multi-Head Attention(MHA)+ 前馈网络 + 残差连接;
  • Decoder

    • Masked MHA + Encoder-Decoder Attention + FFN;
    • 最终接 softmax 输出 gloss 序列。

公式化结构:

在这里插入图片描述

7.3 Progressive Transformer:连续姿态生成模块

此模块是本文创新的核心,用于将文本或 gloss 直接生成连续 3D 骨架点序列。

输入输出定义

  • 输入:token 序列(文本或 gloss);
  • 输出:$ \hat{y}_t \in \mathbb{R}^{3K} $(连续帧姿态)+ $ \hat{c}_t \in [0,1] $(progress counter)。

Encoder

结构与 Symbolic Transformer Encoder 相同,仅输入类型不同。

Decoder 特点

  • 输入

    • 每一帧包含骨架帧向量 + 对应的 counter;
    • 经线性映射后拼接;
  • 过程

    • 自注意力 Masking;
    • 与 encoder 对齐(Encoder-Decoder Attention);
    • FFN 投影至 151 维(150骨架 + 1 counter);
  • 输出

    • 连续预测骨架帧 + 下一帧进度 $ \hat{c}_{t+1} $;
    • 当 counter ≥ 1.0 时,序列生成结束。

7.4 Counter Decoding:序列长度控制机制

传统 seq2seq 模型依赖 <EOS> 标志或固定长度输出,而本文采用了如下创新设计:

  • 每一帧输出一个归一化进度值 $c_t \in [0, 1]$;
  • 推理阶段,当 $c_t ≥ 1.0$,即停止生成;
  • 编码进度信息由 CounterEmbedding 层负责;
  • 同时作为监督目标与模型输出(MSE损失)。

训练公式如下:

在这里插入图片描述

7.5 数据增强模块(训练关键)

为了缓解“预测漂移”(prediction drift)问题,作者引入了三种数据增强方式:

方法说明
Future Prediction每步预测当前帧 + 后续10帧,提高动态建模能力;
Just Counter解码器输入仅为 counter,不依赖前一帧姿态,提升 generalization;
Gaussian Noise对输入骨架帧加噪声,提高模型抗扰性与鲁棒性;

实验表明:“Future + Gaussian Noise”组合效果最佳。

7.6 推理与后处理

在推理过程中:

  1. 输入一段文本 $X$(token 序列);
  2. 编码得到语义表示 $r_{1:T}$;
  3. 解码逐步生成 $[\hat{y}_1, \hat{c}_1], …, [\hat{y}_u, \hat{c}_u]$;
  4. 当 $\hat{c}_u ≥ 1.0$,生成终止;
  5. 输出姿态帧通过骨架渲染或 Avatar 系统进行可视化。

7.7 模型训练配置

项目参数
编码器/解码器层数2 层(论文默认)
attention heads8
隐藏维度 d_model256
优化器Adam(LR=1e-3,Xavier初始化)
损失函数MSE(可拓展为 DTW)
实现框架PyTorch,基础为 JoeyNMT 工具包

小结

原作者模型架构的最大亮点是将 Transformer 解码器从“符号空间”扩展至“连续空间”,并配合 progress counter 完成动态序列生成。其整体思路为:

  • 保留 Transformer 强大的序列建模能力;
  • 抛弃 softmax → 采用连续坐标直接回归;
  • 创造性地使用 Counter 作为时间进度;
  • 通过多种数据增强缓解漂移,提升连贯性与精度。

附录

原论文:https://arxiv.org/abs/2004.14874

源代码:https://github.com/BenSaunders27/ProgressiveTransformersSLP

简易版复现代码:大数据特讲.ipynb

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机视觉——相机标定

计算机视觉——相机标定 一、像素坐标系、图像坐标系、相机坐标系、世界坐标系二、坐标系变换图像坐标系 → 像素坐标系相机坐标系 → 图像坐标系世界坐标系 → 相机坐标系 ⋆ \star ⋆ 世界坐标系 → 像素坐标系 三、相机标定 一、像素坐标系、图像坐标系、相机坐标系、世界坐…

C语言中的数据类型(二)--结构体

在之前我们已经探讨了C语言中的自定义数据类型和数组&#xff0c;链接如下&#xff1a;C语言中的数据类型&#xff08;上&#xff09;_c语言数据类型-CSDN博客 目录 一、结构体的声明 二、结构体变量的定义和初始化 三、结构体成员的访问 3.1 结构体成员的直接访问 3.2 结…

C++11:原子操作与内存顺序:从理论到实践的无锁并发实现

文章目录 0.简介1.并发编程需要保证的特性2.原子操作2.1 原子操作的特性 3.内存顺序3.1 顺序一致性3.2 释放-获取&#xff08;Release-Acquire)3.3 宽松顺序&#xff08;Relaxed)3.4 内存顺序 4.无锁并发5. 使用建议 0.简介 在并发编程中&#xff0c;原子性、可见性和有序性是…

动力电池点焊机:驱动电池焊接高效与可靠的核心力量|比斯特自动化

在新能源汽车与储能设备需求激增的背景下&#xff0c;动力电池的制造工艺直接影响产品性能与安全性。作为电芯与极耳连接的核心设备&#xff0c;点焊机如何平衡效率、精度与可靠性&#xff0c;成为电池企业关注的重点。 动力电池点焊机的核心功能是确保电芯与极耳的稳固连接。…

【MySQL】10.事务管理

1. 事务的引入 首先我们需要知道CURD操作不加控制会产生什么问题&#xff1a; 为了解决上面的问题&#xff0c;CURD需要满足如下条件&#xff1a; 2. 事务的概念 事务就是一组DML语句组成&#xff0c;这些语句在逻辑上存在相关性&#xff0c;这一组DML语句要么全部成功&…

Bugku-CTF-Web安全最佳刷题路线

曾经的我也是CTF六项全能&#xff0c;Web安全&#xff0c;密码学&#xff0c;杂项&#xff0c;Pwn&#xff0c;逆向&#xff0c;安卓样样都会。明明感觉这样很酷&#xff0c;却为何还是沦为社畜。Bugku-CTF-Web安全最佳刷题路线&#xff0c;我已经整理好了&#xff0c;干就完了…

IT学习方法与资料分享

一、编程语言与核心技能&#xff1a;构建技术地基 1. 入门首选&#xff1a;Python 与 JavaScript Python&#xff1a;作为 AI 与数据科学的基石&#xff0c;可快速构建数据分析与自动化脚本开发能力。 JavaScript&#xff1a;Web 开发的核心语言&#xff0c;可系统掌握 React/V…

jenkins gerrit-trigger插件配置

插件gerrit-trigger下载好之后要在Manage Jenkins -->Gerrit Trigger-->New Server 中新增Gerrit Servers 配置好保存后点击“状态”查看是否正常

数论总结,(模版与题解)

数论 欧拉函数X质数&#xff08;线性筛与二进制枚举&#xff09;求解组合数欧拉降幂&#xff08;乘积幂次&#xff09;乘法逆元最小质因子之和模版 欧拉函数 欧拉函数的定义就是小于等于n的数里有f(n)个数与n互质&#xff0c;下面是求欧拉函数的模版。 package com.js.datas…

EasyRTC嵌入式音视频通信SDK助力物联网/视频物联网音视频打造全场景应用

一、方案概述​ 随着物联网技术的飞速发展&#xff0c;视频物联网在各行业的应用日益广泛。实时音视频通信技术作为视频物联网的核心支撑&#xff0c;其性能直接影响着系统的交互体验和信息传递效率。EasyRTC作为一款成熟的音视频框架&#xff0c;具备低延迟、高画质、跨平台等…

1-2 Linux-虚拟机(2025.6.7学习篇- win版本)

1、虚拟机 学习Linux系统&#xff0c;就需要有一个可用的Linux系统。 如何获得&#xff1f;将自己的电脑重装系统为Linux&#xff1f; NoNo。这不现实&#xff0c;因为Linux系统并不适合日常办公使用。 我们需要借助虚拟机来获得可用的Linux系统环境进行学习。 借助虚拟化技术&…

Deepseek基座:Deepseek-v2核心内容解析

DeepSeek原创文章1 DeepSeek-v3&#xff1a;基于MLA的高效kv缓存压缩与位置编码优化技术 2 Deepseek基座&#xff1a;DeepSeek LLM核心内容解析 3 Deepseek基座&#xff1a;Deepseek MOE核心内容解析 4 Deepseek基座&#xff1a;Deepseek-v2核心内容解析 5Deepseek基座&#xf…

2025主流智能体Agent终极指南:Manus、OpenManus、MetaGPT、AutoGPT与CrewAI深度横评

当你的手机助手突然提醒"明天会议要带投影仪转接头"&#xff0c;或是电商客服自动生成售后方案时&#xff0c;背后都是**智能体(Agent)**在悄悄打工。这个AI界的"瑞士军刀"具备三大核心特征&#xff1a; 自主决策能力&#xff1a;像老司机一样根据路况实时…

家政小程序开发——AI+IoT技术融合,打造“智慧家政”新物种

基于用户历史订单&#xff08;如“每周一次保洁”&#xff09;、设备状态&#xff08;如智能门锁记录的清洁频率&#xff09;&#xff0c;自动生成服务计划。 结合天气数据&#xff08;如“雨天推荐玻璃清洁”&#xff09;&#xff0c;动态推送服务套餐。 IoT设备联动&#x…

Keil开发STM32生成hex文件/bin文件

生成hex文件生成bin文件 STM32工程的hex文件和bin文件都可以通过Keil直接配置生成 生成hex文件 工程中点击魔术棒&#xff0c;在 Output 中勾选 Create HEX File 选项&#xff0c;OK保存工程配置 编译工程通过后可以看到编译输出窗口有创建hex文件的提示 默认可以在Output文…

PDF 转 Markdown

本地可部署的模型 Marker Marker 快速准确地将文档转换为 markdown、JSON 和 HTML。 转换所有语言的 PDF、图像、PPTX、DOCX、XLSX、HTML、EPUB 文件在给定 JSON 架构 &#xff08;beta&#xff09; 的情况下进行结构化提取设置表格、表单、方程式、内联数学、链接、引用和代…

北大开源音频编辑模型PlayDiffusion,可实现音频局部编辑,比传统 AR 模型的效率高出 50 倍!

北大开源了一个音频编辑模型PlayDiffusion&#xff0c;可以实现类似图片修复(inpaint)的局部编辑功能 - 只需修改音频中的特定片段&#xff0c;而无需重新生成整段音频。此外&#xff0c;它还是一个高性能的 TTS 系统&#xff0c;比传统 AR 模型的效率高出 50 倍。 自回归 Tra…

蒲公英盒子连接问题debug

1、 现象描述 2、问题解决 上图为整体架构图&#xff0c;其中左边一套硬件设备是放在机房&#xff0c;右边是放在办公室。左边的局域网连接了可以访问外网的路由器&#xff0c;利用蒲公英作为旁路路由将局域网暴露在外网环境下。 我需要通过蒲公英作为旁路路由来进行远程访问&…

Unity | AmplifyShaderEditor插件基础(第五集:简易膨胀shader)

一、&#x1f44b;&#x1f3fb;前言 大家好&#xff0c;我是菌菌巧乐兹~本节内容主要讲一下&#xff0c;如何用shader来膨胀~ 效果预览&#xff1a; 二、&#x1f4a8;膨胀的基本原理 之前的移动是所有顶点朝着一个方向走&#xff0c;所以是移动 如果所有顶点照着自己的方…

WINUI——Magewell视频捕捉开发手记

背景 因需要融合视频&#xff0c;并加载患者CT中提取出的气管镜与病变&#xff0c;以便能实时查看气管镜是否在正确位置。 开发环境 硬件&#xff1a;Magewell的USB Capture HDMI Gen 2 IDE&#xff1a;VS2022 FrameWork: .Net6 WINUI Package: MVVMToolKit NLog Ma…