当前位置:   article > 正文

Talking-Face-Generation系列之Wav2Lip模型_wav2lip_288x288预训练模型

wav2lip_288x288预训练模型

本次要分享的数字人论文是:A Lip Sync Expert Is All You Need for Speech to Lip Generation In the Wild,即Wav2Lip模型。

模型结构

Wav2Lip模型结构图
Wav2Lip模型是一个两阶段模型。第一阶段是:训练一个能够判别声音与嘴型是否同步的判别器 ;第二阶段是:采用编码-解码模型结构(一个生成器 ,两个判别器);也可基于GAN的训练方式,在一定程度上会影响同步性,但整体视觉效果稍好。

损失函数:

  • L1Loss:像素级
  • VggLoss:高维语义特征
  • GANLoss
  • SyncNetLoss

优势

  1. 嘴型与声音的同步性好,得益于嘴型判别器 的强有力监督信号。
  2. 任意人脸对象、不同语种音频也能正常驱动。
  3. 推理速度还行。

不足

  1. 虽然同步性好,但整体清晰度偏低,英文音频下的测试效果还好,中文音频中的牙齿部分还原度稍差,对中文的支持不够友好。
  2. Wav2Lip在发某些音的时候,嘴巴张开幅度忽然变大。
  3. 参考人脸图片侧脸时,脸部会不协调。主要是因为训练时将下半脸全都置0(显示是全黑区域),模型在预测时对于被mask掉的区域是没有参考信息的,上下半脸衔接就会出现瑕疵。

可优化的方向

  • 预处理用于训练的视频数据的清晰度。LRS2数据集的清晰度低(本人也没有LRS2/LRW数据集),如果训练数据都是模糊的,极大地限制模型复原牙齿部分。具体操作是利用超分模型提升脸部的清晰度,特别是嘴巴区域,可参考腾讯的超分模型GFPGAN。
  • 增加模型输入的分辨率,但会增加训练时间和推理时间。
    制作精细的下半脸mask,而不是像原论文直接mask掉下半脸的操作。具体操作是经过人脸关键点检测,然后根据关键点的点位得到固定大小的bbox,一个帧视频中所有下半脸的点位的最大最小值(如68个关键点,点位2、点位14、点位8),对于大批量数据,似乎又不太合适。
  • 对于驱动的人像,说话时频率过快,通过增加静默视频数据即可。静默视频是指嘴巴紧闭且不发出声音的视频片段。
  • 修改网络结构,可能更容易训练。
  • 以上观点,仅供参考,不一定正确。

收集视频数据

  • 各大短视频平台:B站、抖音、快手、小红书、youtube等;
  • 类型:演讲、介绍、电视剧、新闻联播等;
  • 编写批处理脚本:筛选、裁剪、图像增强、音频处理。

数据预处理

  • 视频:转换视频帧率为25fps(推荐),根据自己需求处理。使用ffmpeg裁剪得到的视频片段,会造成视频帧与音频出现不对齐。推荐使用cv2读取,再筛选合适的图像序列。
  • 网上收集的视频,有的会出现跳帧的情况,一定要筛选出最长的图片序列。
  • 音频:转换音频采样率为16000k。
# 预处理视频数据
1. 使用cv2读取视频
import cv2
import face_alignment # pip install face_alignment
fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._2D, device='cpu') 
# cpu or gpu

video_path = "demo.mp4"
cap = cv2.VideoCapture(video_path)
while cap.isOpened():
    ret, frame = cap.read()
    preds = fa.get_landmarks(frame)

# directly extract images from a video
# .png的清晰度比.jpg高
ffmpeg -y -i {./video_path/demo.mp4} -r 25 {./save_path/demo/%06d.png}
例如:ffmpeg -y -i D://videos//demo.mp4 -r 25 D://images//demo//%06d.png

# 预处理音频
# 使用ffmpeg将采样率转换为16000
ffmpeg -y -i {./demo.mp4} -async 1 -ac 1 -vn -acodec pcm_s16le -ar 16000 {xx.wav}

# 下面的操作就是将音频与视频对齐
syncnet_mel_step_size = 16  # 视频的一帧对应音频块的长度是16

def crop_audio_window(self, spec, start_frame):
    start_frame_num = self.get_frame_id(start_frame)  # 编号为 0, 1, 2, ..., n
    start_idx = int(80. * (start_frame_num / 25.))  # 对应视频帧率25fps下的音频块的起点位置
    end_idx = start_idx + syncnet_mel_step_size  # 长度为16
    return spec[start_idx : end_idx, :]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

训练SyncNet

  • SyncNet模型中的图像编码器和音频编码器从零开始训练的话,需要训练数据中不同对象的数量够多,不然损失函数loss一直徘徊在0.69附近。
  • 对象数量不多的前提下,中英文混合训练也是可行的(理论上分析)。
  • 推荐分别使用预训练的主网络作为图像和音频的编码器。
  • 没训练好的SyncNet模块会直接影响第二阶段的同步性效果,所以SyncNet的训练过程是痛苦的(一苦:没有数据;二苦:训练太慢,迟迟不出效果)。
  • 数据预处理、模型训练都是耗时的,收集视频数据也是。
  • 没有中文数据的前提下,如果你想速成,跳过Wav2Lip等类似的通用模型吧,至少可以减轻些许痛苦。
# 在color_syncnet_train.py中数据集部分
# H x W x 3 * T
x = np.concatenate(window, axis=2) / 255.
x = x.transpose(2, 0, 1)
x = x[:, x.shape[1]//2:] # 仅取下半脸区域(训练用于判断嘴唇与音频是否同步的分类器)
  • 1
  • 2
  • 3
  • 4
  • 5

测试SyncNet准确率

import torch.nn as nn
# 加载模型
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = SyncNet()
model.load_state_dict(torch.load("ckpt_path", map_location="cpu"))
model.to(device)
model.eval()

# 加载输入,选定一个视频,重复多次
vidname = self.all_videos[0] # Dataset.__getitem__()

acc = 0
for _, (x, mel, y) in enumerate(test_loader):
    x = x.to(device)
    mel = mel.to(device)
    y = y.to(device) # gt, 0 or 1
    a, v = model(mel, x) # a和v的特征
    av_sim = nn.functional.cosine_similarity(a, v) # a与v越相似,得分越高

    for i in range(a.size(0)):
        pred_label = 1 if av_sim[i] > 0.5 else 0
        if pred_label == y:
            acc += 1

avg_acc = acc / 总次数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

性能比较

  • Wav2Lip比DINet快
  • SadTalker是语音驱动单张图片,没有进行很多实验,不评论。

参考资料

[1] A Lip Sync Expert Is All You Need for Speech to Lip Generation In the Wild.

致读者

本人才疏学浅,未免有理解不到位之处;为方便总结与回顾,特以此方式记录学习过程。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/323404
推荐阅读
相关标签
  

闽ICP备14008679号