【数字人】8、EAT | 为数字人引入表情(ICCV2023)

在这里插入图片描述

论文:Efficient Emotional Adaptation for Audio-Driven Talking-Head Generation

代码:https://yuangan.github.io/eat/

出处:ICCV2023

特点:能引入表情,但无法眨眼,需要音频 + pose + 图片 同时作为输入来合成数字人,合成的嘴型比较准确,但清晰度较低,人物略有抖动

一、背景

Audio-driven talking head 生成任务中,如果可以引入表情,则会提升数字人的保真性和多样性,但这样就会需要考虑很多方便,如头部、表情、声音、动作等,加大生成任务的难度

GC-AVT 和 EAMM 算法使用 driven emotional video 和 pose-guiding video 来同时驱动视频的生成

但现有的方普遍有以下两个问题:

  • 网络结构的高效问题:当有多个子任务时,训练或者微调一个 talking head 生成网络的代价就比较大。而且与表情无关的训练数据更多,所以如何高效的重利用这些数据就很重要
  • 提示的多样性:之前的方法一般都是使用一个表情驱动视频,而不是直接将表情特征学习到网络中,所以在实际使用时,需要考虑驱动视频的分辨率、遮挡率、长度等,但没有考虑嘴唇的形状,所以表情并不是很真实

为了解决上面这些问题,就需要能够方便且高效的将预训练好的无表情 talking head 模型迁移到 emotional talking head 模型,且值需要很轻量的 emotional guidance,如图 1 所示。

在这里插入图片描述

先介绍一下 3D latent keypoints 是什么:

  • 表示这些关键点不仅包含二维平面上的位置信息,还包含深度信息,这使得它们能够更加精确地表示面部的三维结构和运动。
  • latent 意味着这些关键点是在模型的隐空间(latent space)中学习到的,通常是通过网络内部的隐藏层表达的,而不是直接在输入数据中标注的。
  • 总结来说,unsupervised 3D latent keypoints representation 在 face-vid2vid 技术中指的是一种无需人工标注,能够自动学习并表示面部三维结构和动态的方法,它对于实现更加自然和真实的面部视频生成具有重要作用。

因此,本文提出了一个高效的两阶段网络:

  • 第一阶段:先提升 face-vid2vid 得到的 3D 关键点,得到修正后的关键点,然后让模型 A2ET 来学习

    • 第一步:进行 3D 关键点增强

      增强无监督的 3D 潜在关键点表示:这里的 unsupervised 3D latent keypoints representation 就是 face-vid2vid 中的方法,也就是作者首先会使用 face-vid2vid 训练好的模型来提取 3D latent 关键点特征,然后作者会将提取到的特征重新增强,也就是重新训练一下得到更好的 3D latent keypoints representation。

    • 第二步:训练声音到表情的 transformer(这里的表情指的是 3D latent 的表情形变,也就是当前表情相对标准无表情时候的关键点的形变哦)

      引入音频到表情变换器(Audio-to-Expression Transformer,A2ET):这是一个模型,它学习如何将音频信号映射到上述提到的增强的 3D 潜在关键点。

  • 第二阶段:

    提出可学习的引导和适应模块:这些模块用于引导情感表达的生成。具体来说,包括:

    深度情感 Prompt(Deep Emotional Prompts):参数高效的情感适应方法,用于调整和控制生成模型的情感输出,就是对情感通过一个 mapper 得到对应的 prompt 特征

    轻量级情感变形网络(Emotional Deformation Network,EDN):用于学习面部潜在表示的情感变形的网络,会改变面部表情的3D模型以匹配给定的情感状态。也就是给表情形变 E i E_i Ei 再加一个情感的形变 Δ E \Delta E ΔE

    即插即用的情感适应模块(Emotional Adaptation Module,EAM):用于提高视觉质量的模块,可能会在不降低输出质量的前提下,增强模型生成的面部表情的真实感,使用网络学习两个参数 β \beta β γ \gamma γ 来调节。

二、方法

在这里插入图片描述

2.1 第一阶段:与表情无关的预训练

1、增强隐空间 3D 关键点

在这里插入图片描述

给定一个 talking head 图像帧 i i i, vid2vid 提取到的 3D 隐空间关键点 K i K_i Ki,具体包括以下四个部分:

  • identity-specific canonical keypoints K c K_c Kc

    代表特定个体身份的标准化关键点。这些关键点定义了面部的基本结构,不受表情或视角变化的影响。它们是面部的一个“基础”表示,可以想象成是一个中性表情的3D面部模型,包含了个体独特的面部特征。

  • rotation matrix R i R_i Ri

    旋转矩阵是用于描述图像帧( i )中头部相对于这个标准化位置的旋转。在3D空间中,旋转矩阵通常是一个3x3的矩阵,用于将关键点从一个方向旋转到另一个方向。这意味着如果头部在视频帧中向左转或向右转,旋转矩阵就会相应地改变关键点的方向。

  • translation T i T_i Ti

    平移向量描述了头部位置的偏移量。在3D空间中,平移通常由一个三维向量表示,指示了头部在每个轴向上移动的距离。如果头部在视频帧中上下或左右移动,平移向量就会相应地改变关键点的位置。

  • expression deformation E i E_i Ei

    表情变形是指由于表情变化导致的关键点位置的改变。这些变形是相对于标准化关键点( K_c )的,用于捕捉从中性表情到当前表情的过渡。例如,当一个人微笑或皱眉时,面部的关键点会相应地移动,以反映这些表情的变化。

    将这些组件组合起来,就可以得到每一帧图像中头部的完整3D关键点表示( K_i ),它包含了个体特定的面部结构、头部的方向、位置以及当前的表情变化。这种表示对于生成新的 talking head 视频帧非常有用,因为它允许精确地控制和再现面部的动态。

这四部分组合方式如下:

在这里插入图片描述

基于这些 3D 隐空间关键点,RePosition Network (RePos-Net) [56] (也就是 vid2vid)可以将一个人的面部表情迁移到另一个人的面部,也就是提取 driving image 和 source image 的 3D latent keypoints,RePos-Net 能够预测 3D flow wrap matrix w w w 来将 source image 的 3D latent keypoints 进行变换,来得到变换后的图像

如图 3 所示,但是 RePos-Net 对眉毛、嘴角等没法很好的迁移,所以本文作者做了三点改进:

  • 移除了 deformation prior loss in OSFV [56]:这个 loss 会限制关键点形变的模值,移除了后会让隐空间的关键点捕捉到很多微小的表情
  • 使用 MEAD 数据集:来获得有表情标注、成对儿的人脸数据,能让网络学习更多的表情变化
  • 只计算人脸区域的 loss:这样能够避免背景等带来的影响,所以只计算了人脸区域的 loss

在这里插入图片描述

2、Audio-to-Expression Transformer(A2ET):将声音转换到 3D latent 关键点形变上

有了能表示面部特征的 3D latent 关键点后,就需要学习 audio-to-latent keypoint 的关系来实现 audio 的驱动

但是,由于 3D 隐空间关键点是和 source identity 关联的,且比 2D 的隐空间关键点更复杂,直接预测 3D 关键点序列很难。

作者观察到,面部表情主要是由 3D latent keypoint 中的 expression deformation E i E_i Ei 来表示的,所以,本文的 A2ET 学习的并非 3D latent 关键点,而是关键点的形变参数

Audio-visual Feature Extraction:声音到表情

  • 作者使用 Vox2 数据集训练这个 Transformer 网络,并且为了避免音频噪声,使用了 deepspeech 提取特征,同时使用了语音特征 S 1 : n S_{1:n} S1:n 和 声学特征 A 1 : n A_{1:n} A1:n

A2ET encoder 的输入 :

  • speech tokens :
    窗口大小为 w,则 speech tokens 就是当前帧 i 的左右各扩展 w,共 2w 的长度,作为当前帧的 speech feature S i − w : i + w S_{i-w:i+w} Siw:i+w 和 pose feature P i − w : i + w P_{i-w:i+w} Piw:i+w,这个两个 feature 共同作为 speech token,也就是说,当前帧的输出同时和 audio 以及 pose feature有关

  • pose token:当前帧的 6DoF 被编码成 pose token p p p

A2ET decoder 的输入(主要为了捕捉嘴唇的变化):

  • acoustic tokens,该 token 由下面两部分组成:
    • 使用 audio encoder 编码后的声学特征 A i − w : i + w A_{i-w:i+w} Aiw:i+w
    • 使用 keypoint detector D k D_k Dk进行编码后的source image 3D latent feature

A2ET encoder 的输出:

  • 这 2w+1 个 token 的特征

表情系数的预测:使用 PCA 后的特征作为学习 audio 到 表情的学习目标

表情形变系数 E i E_i Ei 是由 k 个 3D 偏移组成的,可以从当前帧 i i i 的特征中得到,直接优化这个 3D 运动会难以收敛。

作者发现通过 self-supervision 学习到的三维关键点之间存在着内在的相互依赖性,实际上只有少数关键点对面部表情有影响。因此作者采用了主成分分析(PCA)来处理 E i E_i Ei,这有助于减少数据的维度并去除那些不必要的信息。这样一来,就可以根据音频特征来预测面部的三维表情变形了。

A2ET 的结构(附录中的内容):

  • encoder:6 transformer layer + 8 heads
  • decoder:6 transformer layer + 8 heads

前向传播层的维度为 1024,每个 token 的维度是 128,给定一个 frame i i i,要预测的就是该帧对应的 E i E_i Ei ,但作者为了简化学习,使用了 PCA 将 E i E_i Ei 的维度从 45 降低到了 32

作者还会从训练集中计算主特征值矩阵(U)和均值向量(M),然后通过下面的方程将预测的PCA投影到表达变形向量上:

在这里插入图片描述

  • P E i PE_i PEi:预测的 PCA 结果
  • E i E_i Ei:将预测的 PCA 结果使用这两个矩阵投影,得到的表情形变系数,由于关键点的数量是 15,所以 E i E_i Ei 的形状是 (15, 3)

2.2 第二阶段:高效的表情调节

为了实现高效的表情调节,作者提出了一个方法用于很方便的调节 pre-trained A2ET 模型,这个方法包括了三个部分:

  • Deep Emotional Prompts(对表情的描述提取特征得到可用的 prompt)
  • Emotional Deformation Network (EDN),给 A2KP 的表情形变再加一个情感的形变
  • Emotional Adaptation Module (EAM),使用两个参数来让表情更保真

在这里插入图片描述

Emotional Guidance:

一个直接的想法是利用可学习的引导条件来生成带有情感的 talking head。作者认为每种情绪类型都属于潜在空间中的一个独特子域。正如图2(b)所示,所以,使用了一个映射网络 M 来提取带有 latent code z ∈ U 16 z ∈ U^{16} zU16 的 emotion-conditional guidance。这个 latent code 是从高斯分布中采样的,这是生成模型中常用的方法[29, 9]。这种情绪引导被用来指导情绪表情的生成。

Deep Emotional Prompt:

为了更高效的进行不同表情的调节,作者将这种 guidance 作为 A2ET 的一个输入,如图 2a

作者为 A2ET 分别引入了 deep 和 shallow emotional prompts,浅层的 prompt 是加到第一层上,深层的 prompt 是加到后面的其他层上

表 4 证明了,deep prompt 效果好,但同时使用的话更好

怎么生成 prompt 呢:emotion mapper

需要有一个 emotion mapper 来产生 emo taken,这个 emo taken 就是用于指导表情的生成的,如图 10 a

  • emotional mapper 包含多个共享参数和不共享参数的 MLP
  • 输入是 16-d 的 latent code z,输出是 7 个 emotional token
  • 第一个 token 是 emotional guidance for EAM,会修正 A2ET 输出的特征
  • 其余的 tokens 送入 A2ET 作为 deep emotional prompts,供 EDN 使用,EDN 会使用这些 token 和 latent source representation 来生成 Δ E \Delta E ΔE

在这里插入图片描述

Emotional Deformation Network:

作者观察到,公式 1 中解耦的三维隐式表示表现出线性可加性。此外,情感话语头部展示了传统话语头部所没有的情感形变。为了补充 E i E_i Ei,给表情形变加了一个情感形变:

在这里插入图片描述

其中, E ′ i E′i Ei 代表情感表达形变, E i E_i Ei代表由 A2ET 预测的与语音相关的表达形变, Δ E i ΔE_i ΔEi 代表与情感相关的表达形变。为了预测 Δ E i ΔE_i ΔEi,我们设计了一个名为情感形变网络(EDN)的子网络,如图2(b)所示。EDN 利用 A2ET 编码器架构,在情感指导和源潜在表示令牌的帮助下预测 Δ E i ΔE_i ΔEi。为了加速适应性,作者用预训练的 A2ET 编码器初始化了 EDN。为了用 E ′ i E′_i Ei更新 E i E_i Ei,可以使用公式1得到情感3D潜在关键点。

在这里插入图片描述

EDN 的结构如图 10b,其目标是学习一个 Δ E \Delta E ΔE,使用的结构和 A2ET encoder 一样,有 6 层 transformer layer

  • 输入:latent source representation d d d + emo token
  • 输出:得到的特征 f,这些 f 会使用全局平均池化和 MLP 得到最终的结果

Emotional Adaptation Module:

为了进一步提升视觉效果,作者设计了一个即插即用的调节模块 Emotional Adaptation Module (EAM),能够生成 emotion-conditioned features。如图 3 所示,这个模块的输入是 guidance embedding e e e,然后使用两个 FC 层来获得一系列的 channel weights γ \gamma γ 和 偏置 β \beta β,然后使用激活然后将其限制到 [-1,1]

在这里插入图片描述

一旦获得了 γ \gamma γ β \beta β,就可以输入特征 x x x 来得到 emotional feature 了:

在这里插入图片描述

  • F s F_s Fs 是通道上的乘

如图 2 所示,EAM 可以被插入 RePosNet、audio 特征提取器、image 特征提取器

在这里插入图片描述

EAM 的结构如图 10c:

  • 输入: x x x + emo token e 0 e_0 e0
  • 输出:经过学习到的参数 γ \gamma γ β \beta β 调节过后的特征

Zero-shot Expression Editing:

由于 EAT 能够很快的调节,所以可以实现 zero-shot text-guided 表情编辑,方法是从 CLIP 上蒸馏

为了利用 CLIP loss 来学习表情指导,作者使用 head pose、source audio、first frame from target video 作为输入,

为了利用 CLIP 损失(CLIP loss)来学习与文本描述的表情相关的情感引导。作者提取目标视频的头部姿势、原始音频以及第一帧作为输入。

此外,还采用了目标表情描述来进行微调。使用经过改进的EAT模型和我们的训练损失,增加了一个额外的CLIP损失来微调映射网络和EAM模块。

具体就是:使用 CLIP 的图像编码器从预测的说话面部提取图像嵌入,使用其文本编码器从描述中提取文本嵌入。然后,迭代优化图像和文本嵌入之间的距离,以使生成的说话面部与输入文本对齐。

2.3 目标函数

在这里插入图片描述

Latent loss 是用于优化预测的 latent keypoint 的

在这里插入图片描述

Sync loss 是用于评判嘴唇和声音的同步情况

在这里插入图片描述

Reconstruction loss 是为了提高面部区域的视觉合成效果

三、效果

3.1 实验设置

作者的 video 帧率都为 25FPS,audio 采样率都为 16kHz,视频大小为 256x256,mel-spectrogram window length 和 hop length 为 640

EAT 中 keypoints 的个数是 15

  • enhance 3D latent keypoints:48 小时(4个3090)
  • pretrain the A2ET with enhanced latent keypoints:48 小时(4个3090)
  • finetune the EAT architecture :6 小时(4个3090)

数据集:

  • VoxCeleb2:
  • MEAD:有 8 种情感表情,使用人物来划分训练和测试,和 EAMM 的划分一样

3.2 效果对比

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四、代码

4.1 数据下载

1、VoxCeleb2 数据集下载

官网:https://www.robots.ox.ac.uk/~vgg/data/voxceleb/vox2.html

百度云:https://zhuanlan.zhihu.com/p/588668145

我是从百度云下载的,下载后用下面的命令来解压,解压需要几十小时的时间。

zip -s 0 vox2_mp4_dev.zip --out unsplit.zip
unzip unslit.zip
  • vox2 数据集的 id 从 id00012 到 id09272(超过6,000名)
  • 视频数量为 1092017(约100w)
  • 61%的发言者为男性。发言者涉及各种不同的种族,口音,专业和语言。
  • 数据集中包含的视频是在大量具有挑战性的视觉和听觉环境中拍摄的。其中包括红地毯,室外体育馆和安静的室内工作室的采访,大量观众的演讲,专业拍摄多媒体的摘录,甚至是手持设备拍摄的粗略视频。

2、MEAD 数据集下载

MEAD 数据集作者上传了百度云(是本文使用的数据集,并非完整版 MEAD)

4.2 使用作者提供的音频+pose 来推理

首先,将想要推理的图片放入 /demo/imgs/ 中,代码会自动裁剪其中的图片到 demo/imgs_cropped/ 中,一定不是直接将 256x256 的图片放入 demo/imgs_cropped/,否则你推理出来的人脸会扭曲变形。

4.3 使用自己的视频来推理

使用自己的视频推理之前,要先对视频进行 pose 提取、音频特征(deepspeech)提取等等操作

将自己的视频放入preprocess/video,然后执行下面的代码:

cd preprocess
python preprocess_video.py

注意这里可能出现的问题哦

1、ImportError: No module named _tkinter

extract_lmks_eat.py 中的 from turtle import distance 注释即可

2、KeyError: "The name 'deepspeech/logits:0' refers to a Tensor which does not exist. The operation, 'deepspeech/logits', does not exist in the graph."

这里 AD-Nerf 的仓库中说将 tensorflow-gpu 版本改为 1.15.0 即可,但我从 branch 中没找到这个版本,所以进行了下面的修改:

#deepspeech_features.py line(107),注释掉的是原本的代码,改成去掉 deepspeech/ 即可
graph = tf.compat.v1.get_default_graph()
tf.import_graph_def(graph_def, name="deepspeech")
logits_ph = graph.get_tensor_by_name("logits:0")
input_node_ph = graph.get_tensor_by_name("input_node:0")
input_lengths_ph = graph.get_tensor_by_name("input_lengths:0")
# logits_ph = graph.get_tensor_by_name("deepspeech/logits:0")
# input_node_ph = graph.get_tensor_by_name("deepspeech/input_node:0")
# input_lengths_ph = graph.get_tensor_by_name("deepspeech/input_lengths:0")

3、np.float 不再支持,改成 np.float64 即可

4、numpy 不支持不同维度向量保存

# kc = kc['value'].cpu().numpy()
# for k in he:
#     he[k] = torch.cat(he[k]).cpu().numpy()
# np.save('./latents/'+os.path.basename(videoname), [kc, he])
kc = np.array(kc['value'].cpu().numpy())
for k in he:
    he[k] = np.array(torch.cat(he[k]).cpu().numpy())
objs = np.array([kc, he], dtype=object)
np.save('latents/'+os.path.basename(videoname)+'.npy', objs)

推理逻辑:

1、load 训练好的模型

  • generator
  • kp_detector
  • audio2kptransformer
  • sidetuning
  • emotionprompt

2、根据 config 和给定的 wav、pose、图片、emo 来处理数据,得到

  • audio_frames:每帧对应的声音 mel 特征:torch.Size([1495, 80, 11]),这里 1495 是声音 wav 的帧数
  • poseimgs:每帧对应的 pose 特征:torch.Size([1495, 11, 1, 64, 64])
  • deep_feature:每帧对应的声音 deepspeech 特征:torch.Size([1495, 11, 16, 29])
  • source_img:驱动图像,(3, 256, 256)
  • he_source:source 图片的俯仰角等特征,dict_keys(['yaw', 'pitch', 'roll', 't', 'exp'])
  • he_driving:driving 图片的俯仰角等特征,dict_keys(['yaw', 'pitch', 'roll', 't', 'exp'])
  • num_frames:声音帧数,1495
  • y_trg:5
  • z_trg:tensor([-1.5638, 0.2359, 1.6728, 0.2056, -0.1980, 0.3549, 0.1367, -0.7749, 1.4223, -1.0416, -0.2966, -0.8527, -1.4704, -0.8021, -0.3199, -1.3980])
  • latent_path_driving:latent 特征路径,'./demo/video_processed/xxx/latent_evp_25/4.npy'

3、将 x ={} # dict_keys(['mel', 'z_trg', 'y_trg', 'pose', 'deep', 'he_driving']) 输入 emotionprompt,得到 emoprompt

4、使用 kp_detector 对 source_img 提取特征 : kp_canonical: dict_keys(['value', 'prediction_map'])

5、设置 T=5,每 5 帧的 mel、pose、deepspeech、he_driving 特征提取出来,和 emoprompt、deepprompt 一起送入audio2kptransformer。得到这 5 帧中每帧对应的 emo

4.4 训练 vox2

下载并解压 vox2 数据集后,得到的是很多 .mp4 视频,然后需要对视频使用作者提供的代码进行预处理,这里有作者的说明

第一步:拆帧、扣脸、提取音频特征等,保存的格式如下

- vox_path
	- voxs_images
		- id00313_Zf0PTQEEHkU_00127
			- 00001.jpg
			- 00002.jpg
			- 00003.jpg
			- ...
		- id00693_TWx15G9mTEI_00065
		- id00195_ZgynYYQUhw4_00141
		- ...
		
	- voxs_wavs
		- id00313_Zf0PTQEEHkU_00127.wav
		- ...
	- deepfeature32
		- id00313_Zf0PTQEEHkU_00127.npy
		- ...
	- bboxs
		- id00313_Zf0PTQEEHkU_00127.npy
		- ...
	- voxselect
		- Angry.txt
		- Contempt.txt
		- ...

第二步:得到 voxs_images 之后,还需要利用 extract_bbox 提取人脸的 boundingbox

4.5 训练 MEAD

mead 数据格式

- mead
	- images_evp_25
		- train(10360)
		- test(985)
	- latent_evp_25
		- train(10360)
		- test(985)
	- deepfeature32(11346)
	- wav_16000(11346)
	- bboxs(11346)
	- poseimg(11346)
  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆呆的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值