大白话版本
知乎上有一个很不错的解释,大家应该都能理解:
假设一个城市治安混乱,很快,这个城市里就会出现无数的小偷。在这些小偷中,有的可能是盗窃高手,有的可能毫无技术可言。假如这个城市开始整饬其治安,突然开展一场打击犯罪的「运动」,警察们开始恢复城市中的巡逻,很快,一批「学艺不精」的小偷就被捉住了。之所以捉住的是那些没有技术含量的小偷,是因为警察们的技术也不行了,在捉住一批低端小偷后,城市的治安水平变得怎样倒还不好说,但很明显,城市里小偷们的平均水平已经大大提高了。
警察们开始继续训练自己的破案技术,开始抓住那些越来越狡猾的小偷。随着这些职业惯犯们的落网,警察们也练就了特别的本事,他们能很快能从一群人中发现可疑人员,于是上前盘查,并最终逮捕嫌犯;小偷们的日子也不好过了,因为警察们的水平大大提高,如果还想以前那样表现得鬼鬼祟祟,那么很快就会被警察捉住。
为了避免被捕,小偷们努力表现得不那么「可疑」,而魔高一尺、道高一丈,警察也在不断提高自己的水平,争取将小偷和无辜的普通群众区分开。随着警察和小偷之间的这种「交流」与「切磋」,小偷们都变得非常谨慎,他们有着极高的偷窃技巧,表现得跟普通群众一模一样,而警察们都练就了「火眼金睛」,一旦发现可疑人员,就能马上发现并及时控制——最终,我们同时得到了最强的小偷和最强的警察。
非大白话版本
生成对抗网络(GANs)由2个重要的部分构成:
- 生成器(Generator):通过机器生成数据(大部分情况下是图像),目的是“骗过”判别器
- 判别器(Discriminator):判断这张图像是真实的还是机器生成的,目的是找出生成器做的“假数据”
下面详细介绍一下过程:
第一阶段:固定「判别器D」,训练「生成器G」
我们使用一个还 OK 判别器,让一个「生成器G」不断生成“假数据”,然后给这个「判别器D」去判断。
一开始,「生成器G」还很弱,所以很容易被揪出来。
但是随着不断的训练,「生成器G」技能不断提升,最终骗过了「判别器D」。
到了这个时候,「判别器D」基本属于瞎猜的状态,判断是否为假数据的概率为50%。
第二阶段:固定「生成器G」,训练「判别器D」
当通过了第一阶段,继续训练「生成器G」就没有意义了。这个时候我们固定「生成器G」,然后开始训练「判别器D」。
「判别器D」通过不断训练,提高了自己的鉴别能力,最终他可以准确的判断出所有的假图片。
到了这个时候,「生成器G」已经无法骗过「判别器D」。
循环阶段一和阶段二
通过不断的循环,「生成器G」和「判别器D」的能力都越来越强。
最终我们得到了一个效果非常好的「生成器G」,我们就可以用它来生成我们想要的图片了。
下面的实际应用部分会展示很多“惊艳”的案例。
手把手DEMO:
本例是基于PaddleGAN实现的First Order Motion model, 实现让任何人唱起「蚂蚁呀嘿」的旋律,若是大家喜欢这个教程,请到Github PaddleGAN主页点击star呀!下面就让我们一起动手实现吧!
整体实现只有三步:
- 下载PaddleGAN代码
- 运行First Order Motion model的命令
- 给视频加上声音
看~~ 是不是相当简单!!接下来让我们一步步开始吧!
First Order Motion model原理
First Order Motion model的任务是image animation,给定一张源图片,给定一个驱动视频,生成一段视频,其中主角是源图片,动作是驱动视频中的动作,源图像通常包含一个主体,驱动视频包含一系列动作。
通俗来说,First Order Motion能够将给定的驱动视频中的人物A的动作迁移至给定的源图片中的人物B身上,生成全新的以人物B的脸演绎人物A的表情的视频。
以人脸表情迁移为例,给定一个源人物,给定一个驱动视频,可以生成一个视频,其中主体是源人物,视频中源人物的表情是由驱动视频中的表情所确定的。通常情况下,我们需要对源人物进行人脸关键点标注、进行表情迁移的模型训练。
但是这篇文章提出的方法只需要在同类别物体的数据集上进行训练即可,比如实现太极动作迁移就用太极视频数据集进行训练,想要达到表情迁移的效果就使用人脸视频数据集voxceleb进行训练。训练好后,我们使用对应的预训练模型就可以达到前言中实时image animation的操作。
下载PaddleGAN代码
代码语言:javascript复制# 从github上克隆PaddleGAN代码
!git clone https://gitee.com/paddlepaddle/PaddleGAN
代码语言:javascript复制# 安装所需安装包
� PaddleGAN/
!pip install -r requirements.txt
!pip install imageio-ffmpeg
� applications/
代码语言:javascript复制!mkdir output
执行命令
大家可以上传自己准备的视频和图片,并在如下命令中的source_image参数和driving_video参数分别换成自己的图片和视频路径,然后运行如下命令,就可以完成动作表情迁移,程序运行成功后,会在ouput文件夹生成名为result.mp4的视频文件,该文件即为动作迁移后的视频。本项目中提供了原始图片和驱动视频供展示使用。具体的各参数使用说明如下
- driving_video: 驱动视频,视频中人物的表情动作作为待迁移的对象
- source_image: 原始图片,视频中人物的表情动作将迁移到该原始图片中的人物上
- relative: 指示程序中使用视频和图片中人物关键点的相对坐标还是绝对坐标,建议使用相对坐标,若使用绝对坐标,会导致迁移后人物扭曲变形
- adapt_scale: 根据关键点凸包自适应运动尺度
!export PYTHONPATH=$PYTHONPATH:/home/aistudio/PaddleGAN && python -u tools/first-order-demo.py --driving_video ~/work/fullbody.MP4 --source_image ~/work/秃头乔哥.png --relative --adapt_scale
使用moviepy为生成的视频加上音乐
上述模型,一次只能处理一个头像,然后进行后期拼接即可,demo是形成一个两行两列的DEMO。
代码语言:javascript复制# add audio
!pip install moviepy
代码语言:javascript复制from moviepy.editor import *
tmpClip = [] #用于保存所有需要参与合成视频文件的剪辑对象
clipArrays = []
tmpClipArray = []
videoclip_1_1 = VideoFileClip("maimai.mp4")
videoclip_1_2 = VideoFileClip("doudou.mp4")
videoclip_2_1 = VideoFileClip("m1.mp4")
videoclip_2_2 = VideoFileClip("d2.mp4")
tmpClip = [videoclip_1_1, videoclip_1_2, videoclip_2_1, videoclip_2_2]
lines = 2
columns = 2
column = 0
for clip in tmpClip: # 按行列将视频排列
tmpClipArray.append(clip)
column = 1
if column == columns:
clipArrays.append(tmpClipArray)
column = 0
tmpClipArray = []
destClip = clips_array(clipArrays) # 进行同屏播放合成
outputFileName = 'c.mp4'
print(f"内存视频合成完成,准备输出到文件:{outputFileName}.")
destClip.write_videofile(outputFileName)
print(f"输出到文件:{outputFileName} 成功!")
参考链接:
http://xiaoqiang.me/?p=4592
https://aistudio.baidu.com/aistudio/projectdetail/1586056?channelType=0&channel=0