让一张静态照片里的人物模仿视频中的表情和动作,这个听起来很科幻的效果,正是First Order Motion Model(一阶运动模型)要解决的核心问题。这项技术最早由阿里达摩院和Skoltech的研究者在NeurIPS 2019上提出,论文题目为First Order Motion Model for Image Animation。它只需要一张源图像和一段驱动视频,就能让源图像中的人物复现驱动视频里的动作,整个过程无需任何标注数据训练。目前流行的Avatarify、Deep Nostalgia等应用,底层都离不开这套方案。本文将从原理、网络结构到代码实战,全面拆解这一经典模型。

一、First Order Motion Model的核心思想与数学原理
要理解一阶运动模型,首先要明白它解决的是什么样的问题。给定一张源图像S和一帧驱动图像D,模型需要学习一个从S到D的变换,使得变换后的源图像尽可能接近驱动图像的形态。这个变换在论文中被建模为从关键点空间到图像空间的一阶泰勒展开。
具体来说,模型先用一个自监督训练的关键点检测网络,从图像中提取K个关键点以及每个关键点对应的局部仿射变换矩阵。仿射变换可以分解为旋转、缩放、平移三个部分,这就是所谓的一阶近似。之所以叫一阶,是因为泰勒展开只保留了一阶导数项,用来刻画关键点附近的局部形变。如果引入二阶项(后续的论文如Second Order Motion Model所做的那样),可以建模更复杂的弯曲形变,比如衣物的摆动、头发的飘动,但计算复杂度也会随之上升。
稀疏关键点运动估算是整个框架的第一步。检测网络从源图像和驱动图像中分别提取关键点集合,然后通过每个关键点附近的局部变换,推算出一张密集光流场(Dense Motion Map)。这张光流场告诉模型图像中每个像素应该如何移动,随后图像生成网络根据光流对源图像进行扭曲变形,再融合遮挡区域 inpainting 出完整结果。整个流程可以概括为:关键点提取、密集运动估计、图像生成三个阶段。
二、自监督训练机制:为什么不需要标注数据
一阶运动模型最巧妙的地方在于它的训练方式。它采用完全自监督的策略:从同一个视频里抽取两帧图像,一帧当作源图像,另一帧当作驱动图像,训练目标就是让生成结果尽可能还原驱动帧。这样训练数据只需要大量无标注的视频片段即可,完全省去了人工标注关键点的成本。
网络结构上,模型包含四个主要模块:关键点检测网络(通常用Hourglass架构)、稠密运动网络、遮挡预测网络和图像生成网络。关键点检测网络输出K组关键点坐标以及对应的2x2雅可比矩阵,雅可比矩阵描述了关键点局部的仿射变换特性。稠密运动网络将这些稀疏信息扩展为整幅图像的光流场,同时预测遮挡掩码,用于处理源图像中被遮挡而需要凭空补全的区域。
损失函数由三部分组成:重构损失(感知损失LPIPS或简单的L1)、关键点等变约束损失以及生成对抗损失。等变约束保证了关键点检测在几何变换下的一致性,这是自监督能够收敛的关键。以下是一段简化的伪代码,展示训练时的数据组织方式:
import torch # 从同一个视频中抽取两帧 frame_A = video[:, 0] # 源图像 frame_B = video[:, 1] # 驱动图像 # 关键点检测网络输出关键点和雅可比矩阵 kp_A, jac_A = kp_detector(frame_A) kp_B, jac_B = kp_detector(frame_B) # 根据稀疏关键点计算稠密光流 dense_motion = dense_motion_network(frame_A, kp_A, jac_A, kp_B, jac_B) # 生成网络重建驱动帧 prediction = generator(frame_A, dense_motion) # 感知损失衡量重建质量 loss = perceptual_loss(prediction, frame_B)
三、代码实战:用一段视频驱动静态照片
原理讲完,接下来上手实操。社区维护最完善的实现是AliaksandrSiarohin的first-order-model仓库,下面演示基本的使用流程。首先要准备预训练权重,仓库提供了VoxCeleb、Taichi、TED等数据集训练的多个版本,做人脸表情迁移一般选择vox-adv-cpk.pth这个权重。
from demo import load_checkpoints
from demo import make_animation
from skimage import io, img_as_ubyte
import imageio
# 加载预训练模型
generator, kp_detector = load_checkpoints(
config_path='config/vox-adv-256.yaml',
checkpoint_path='checkpoints/vox-adv-cpk.pth')
# 读取源图像和驱动视频
source_image = io.imread('photo.jpg')
driving_video = imageio.mimread('drive.mp4', memtest=False)
# 生成动画结果
predictions = make_animation(
source_image, driving_video,
generator, kp_detector, relative=True)
# 保存输出视频
imageio.mimsave('result.mp4',
[img_as_ubyte(frame) for frame in predictions])
这里有一个非常关键的参数relative。当它设为True时,模型采用相对运动模式,即驱动视频的关键点位移是相对于该视频第一帧计算的,这种模式对姿态差异的容忍度更高,驱动效果更自然。而绝对模式则直接使用驱动帧的关键点坐标,适合源图像和驱动对象外观高度相似的场景。如果发现生成的结果表情僵硬或者脸部错位,优先检查这个参数以及源图像中人脸的对齐情况。
显存方面,256x256分辨率下推理大约需要4GB显存,普通游戏显卡即可胜任。如果显存吃紧,可以把batch size设为1,或者降级到vox-cpk.pth权重配合较低分辨率使用。另外源图像建议裁剪为正方形并保证人脸居中,背景干扰过大会明显影响关键点检测的稳定性。
四、应用场景、局限与延伸方向
一阶运动模型的应用远不止人脸表情迁移。在虚拟主播领域,它可以让一张插画形象跟随真人视频做出动作,大幅降低虚拟形象的制作门槛;在老照片修复场景中,Deep Nostalgia用它让历史人物的照片重新动了起来,一度引发社交网络热潮;在电商和教育行业,也可以用它批量生成口播视频,节省真人出镜的拍摄成本。
当然,这个模型也存在明显局限。首先它本质上只建模局部仿射变换,遇到大角度侧脸、大幅度转头时容易出现形变失真;其次源图像和驱动对象类别差异过大时(比如用卡通脸驱动真人),关键点语义不匹配会导致效果崩坏;此外生成分辨率受训练数据限制,直接放大到高清视频会出现模糊,通常需要配合超分辨率模型做后处理。
从这条技术路线往后看,后续工作大致沿两个方向演进:一是引入二阶甚至更高阶的泰勒展开项,提升对复杂形变的建模能力;二是转向扩散模型和隐式三维表示,比如基于NeRF的头部重建方案以及近期的Stable Diffusion驱动方案,在保持身份一致性方面表现更好。不过就部署门槛和推理速度而言,一阶运动模型依然是轻量级表情迁移任务中最务实的选择之一,理解它的设计思想对学习后续更复杂的动画生成技术也大有帮助。
First Order Motion Model表情迁移视频驱动修改时间:2026-09-16 23:48:46