FOMM模型的公式推导

GO

FOMM需要找到一个从源帧到驱动帧的映射关系,给出最终结果,文中提出:
T S ← D ( z ) ≈ T S ← R ( p k ) + ( d d p T S ← R ( p ) ∣ p = p k ) ( d d p T D ← R ( p ) ∣ p = p k ) ( z − T D ← R ( p k ) ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z) \approx \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}\left(p_{k}\right)+\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right)\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right) \quad\left(z-\mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}\left(p_{k}\right)\right) TSD(z)TSR(pk)+(dpdTSR(p) p=pk)(dpdTDR(p) p=pk)(zTDR(pk))
我每次看到这东西都头疼,所以在这里记录一下。
首先, T S ← D ( ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}() TSD()你要看作是一个函数,它是一个映射关系,传入一个 z z z值可以得到一个输出 z ′ z' z,如何我们能够找到一个这样的映射关系,就等同于我们找到了源帧到驱动帧的映射关系。

文章提出,我们找到这个函数的 T S ← D ( ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}() TSD(),因此,它对此进行了一阶泰勒展开,引出了它的名字,一阶动态模型。
对于一个函数 f ( x ) f(x) f(x),如果函数 f ( x ) f(x) f(x) x 0 x_0 x0处有 n n n阶导数,那么存在 x 0 x_0 x0的一个领域,对于该领域内任意一点 x x x,有
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + f ′ ′ ( x 0 ) 2 ! ( x − x 0 ) 2 + ⋯ + f ( n ) ( x 0 ) n ! ( x − x 0 ) n + o ( ( x − x 0 ) n ) . , \begin{array}{l} f(x)=f\left(x_{0}\right)+f^{\prime}\left(x_{0}\right)\left(x-x_{0}\right)+\frac{f^{\prime \prime}\left(x_{0}\right)}{2 !}\left(x-x_{0}\right)^{2}+\cdots+\frac{f^{(n)}\left(x_{0}\right)}{n !}\left(x-x_{0}\right)^{n}+o\left(\left(x-x_{0}\right)^{n}\right) . \end{array},\\ f(x)=f(x0)+f(x0)(xx0)+2!f′′(x0)(xx0)2++n!f(n)(x0)(xx0)n+o((xx0)n).,
我们对 T S ← D ( z ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z) TSD(z) z k z_k zk处进行一阶泰勒展开,则
T S ← D ( z ) = T S ← D ( z k ) + ( d d z T S ← D ( z ) ∣ z = z k ) ( z − z k ) + o ( ∥ z − z k ∥ ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z)=\mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}\left(z_{k}\right)+\left(\left.\frac{d}{d z} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z)\right|_{z=z_{k}}\right)\left(z-z_{k}\right)+o\left(\left\|z-z_{k}\right\|\right) TSD(z)=TSD(zk)+(dzdTSD(z) z=zk)(zzk)+o(zzk)
那就分成了求解两部分,其中一部分是 T S ← D ( z k ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z_k) TSD(zk),同样的,这里,我们要知道 T S ← D ( ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}() TSD()是一个函数。
那么我们其实可以很容易的理解:
T S ← D ( ) = T S ← R ( T D ← R − 1 ( ) ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}()=\mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(\mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}^{-1}()) TSD()=TSR(TDR1())
那么这里的 T S ← D ( z k ) = T S ← R ( T R ← D ( z k ) ) = T S ← R ( T D ← R − 1 ( z k ) ) = T S ← R ( T D ← R − 1 ( T D ← R ( p k ) ) ) = T S ← R ( p k ) \begin{aligned} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}\left(z_{k}\right) &=\mathcal{T}_{\mathbf{S}\leftarrow \mathbf{R}}( \mathcal{T}_{\mathbf{R} \leftarrow \mathbf{D}}\left(z_{k}\right)) \\ &=\mathcal{T}_{\mathbf{S}\leftarrow \mathbf{R}} ( \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}^{-1}\left(z_{k}\right)) \\ &=\mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}} ( \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}^{-1} ( \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}\left(p_{k}\right))) \\ &=\mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}\left(p_{k}\right) \end{aligned} TSD(zk)=TSR(TRD(zk))=TSR(TDR1(zk))=TSR(TDR1(TDR(pk)))=TSR(pk)
注意,上述式子符号很多,很乱,这里的 z k z_k zk其实是驱动帧中的关键点,通过一个映射关系 T S ← D ( ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}\left(\right) TSD()要能够得到源帧的关键点 p S p_S pS,那为什么最后写成 T S ← R ( p k ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}\left(p_{k}\right) TSR(pk),因为关键点 p k p_k pk是假设的参考帧的关键点。现在,其中一个我们已经求出来了,再看后面部分,后面的部分是对 T S ← D ( ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}\left(\right) TSD()求导,得到在点 z k z_k zk处的值。
我们可以通过对 T S ← D ( z ) = T S ← R ( T D ← R − 1 ( z ) ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z)=\mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(\mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}^{-1}(z)) TSD(z)=TSR(TDR1(z))求导,根据链式法则求导得到:
( d d z T S ← D ( z ) ∣ z = z k ) = ( d d p T S ← R ( p ) ∣ p = T R ← D ( z k ) ) ( d d z T D ← R − 1 ( z ) ∣ z = z k ) \left(\frac{d}{d z} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z) \mid z=z_{k}\right)=\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(p)\right|_{p=\mathcal{T}_{\mathbf{R} \leftarrow \mathbf{D}}\left(z_{k}\right)}\right)\left(\frac{d}{d z} \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}^{-1}(z) \mid z=z_{k}\right) (dzdTSD(z)z=zk)=(dpdTSR(p) p=TRD(zk))(dzdTDR1(z)z=zk)
T R ← D ( ) \mathcal{T}_{\mathbf{R} \leftarrow \mathbf{D}}\left(\right) TRD()代表的是从驱动帧到参考帧的映射,那么输入驱动帧的关键点 z k z_k zk很显然就会得到参考帧的关键点 p k p_k pk
p k = T R ← D ( z k ) p_k=\mathcal{T}_{\mathbf{R} \leftarrow \mathbf{D}}\left(z_{k}\right) pk=TRD(zk)
因此,最终得到: ( d d z T S ← D ( z ) ∣ z = z k ) = ( d d p T S ← R ( p ) ∣ p = p k ) ( d d p T D ← R ( p ) ∣ p = p k ) − 1 \left(\frac{d}{d z} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z) \mid z=z_{k}\right)=\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right)\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right)^{-1} (dzdTSD(z)z=zk)=(dpdTSR(p) p=pk)(dpdTDR(p) p=pk)1
分别代入,得:
T S ← D ( z ) ≈ T S ← R ( p k ) + ( d d p T S ← R ( p ) ∣ p = p k ) ( d d p T D ← R ( p ) ∣ p = p k ) − 1 ( z − T D ← R ( p k ) ) \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{D}}(z) \approx \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}\left(p_{k}\right)+\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{S} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right)\left(\left.\frac{d}{d p} \mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}(p)\right|_{p=p_{k}}\right)^{-1}\left(z-\mathcal{T}_{\mathbf{D} \leftarrow \mathbf{R}}\left(p_{k}\right)\right) TSD(z)TSR(pk)+(dpdTSR(p) p=pk)(dpdTDR(p) p=pk)1(zTDR(pk))

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
除了 FaceSwap 库外,还有一些其他的 Python 库可以实现 AI 换脸,例如 DeepFaceLab 和 First Order Motion Model for Image Animation (FOMM) 等。 这里以 FOMM 库为例,介绍一下使用 FOMM 实现 AI 换脸的步骤: 1. 安装 FOMM 库 可以通过以下命令使用 pip 安装 FOMM 库: ``` pip install git+https://github.com/AliaksandrSiarohin/first-order-model.git ``` 2. 准备源图像和目标图像 分别准备需要换脸的源图像和目标图像,并将它们放在不同的文件夹中。 3. 提取源图像和目标图像的人脸 使用 OpenCV 库提取源图像和目标图像中的人脸,并将人脸保存为单独的图像文件。 4. 训练模型 使用 FOMM 提供的训练脚本 `train.py` 来训练模型: ``` python train.py \ --config config/vox-adv-256.yaml \ --src_dir path/to/source/faces \ --dst_dir path/to/target/faces \ --checkpoint_dir path/to/checkpoint \ --model_id model_name ``` 其中,`path/to/source/faces` 和 `path/to/target/faces` 分别是提取后的源图像和目标图像中的人脸图像的存储路径,`path/to/checkpoint` 是训练后的模型存储路径,`model_name` 是模型的名称。 5. 进行换脸操作 使用 FOMM 提供的 `demo.py` 脚本来进行换脸操作: ``` python demo.py \ --config config/vox-adv-256.yaml \ --checkpoint path/to/checkpoint/model_name \ --source_image path/to/source/image \ --driving_video path/to/driving/video \ --result_video path/to/result/video ``` 其中,`path/to/checkpoint/model_name` 是训练后的模型存储路径和模型名称,`path/to/source/image` 是源图像的路径,`path/to/driving/video` 是驱动视频的路径,`path/to/result/video` 是输出的视频路径。 运行以上步骤,即可实现 AI 换脸。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值