GAN Paint 水记 (GAN解剖+实时微调)
这个 GAN Paint 就是一个图像编辑模型
方案概述
先用重建任务训练一个自编码器(loss为:L1损失+VGG感知损失)
输入图片,用编码器编码为 z,然后用GAN Dissection 的方法编辑 z,然后用解码器产生图像。
为了保证未编辑的部分不变,在解码时会(通过对解码器网络权重加入扰动的方式)微调解码器。微调的优化目标是,令未编辑的部分与原图一致(loss为:带mask的L1损失+扰动的正则化项)。
注意,若要保证效果,每次编辑都需要微调扰动(单卡需要30秒)。
我认为这篇文章的关键是,他提到他用了一种技术,可以让未被编辑的部分与原图保持一致,而不是莫名其妙丢失很多信息。
一般的GAN(和自编码器)在重建的时候往往都不能重建原图的细节
重建损失
很平常的方案
他们用的重建损失包括一个 L1 损失,和一个 VGG 感知损失
L r ( x , G ( z ) ) = ∥ x − G ( z ) ∥ 1 + λ V G G ∑ i = 1 N 1 M i ∥ F ( i ) ( x ) − F ( i ) ( G ( z ) ) ∥ 1 \mathcal{L}_{r}(\mathrm{x}, G(\mathrm{z}))=\|\mathrm{x}-G(\mathrm{z})\|_{1}+\lambda_{\mathrm{VGG}} \sum_{i=1}^{N} \frac{1}{M_{i}}\left\|F^{(i)}(\mathrm{x})-F^{(i)}(G(\mathrm{z}))\right\|_{1} Lr(x,G(z))=∥x−G(z)∥1+λVGGi=1∑NMi1∥ ∥F(i)(x)−F(i)(G(z))∥ ∥1
这个 F ( i ) F^{(i)} F(i) 表示 VGG 的第 i i i 层,该层有 M i M_i Mi 个特征, λ V G G = 10 \lambda_{VGG}=10 λVGG=10
不过这些并不能保证重建原图中的细节
在生成器中保留原图的细节
为了保留原图的细节他们设计了这个生成器:
在细粒度的卷积层加入了扰动,希望生成结果能更接近原图
这个所谓扰动网络看起来就是给生成器加了一些可训练参数而已,
这些参数用于保证未编辑的部分与原图一致(尽量保证),
这些参数每次编辑后都需要训练一下,
好在训练起来够快,单块GPU只要30秒
这个扰动是乘到两层之间的,就是说:前一层的输出,乘上扰动,输入下一层
G F ′ ( z h ) ≡ g n ( ( 1 + δ n − 1 ) ⊙ g n − 1 ( ⋯ ( ( 1 + δ h + 1 ) ⊙ g h + 1 ( z h ) ⋯ ) ) ) G_{F}^{\prime}\left(\mathrm{z}_{h}\right) \equiv g_{n}\left( {\color{orange}\left(1+\delta_{n-1}\right)} \odot g_{n-1}\left(\cdots\left( {\color{orange}\left(1+\delta_{h+1}\right)} \odot g_{h+1}\left(\mathrm{z}_{h}\right) \cdots\right)\right)\right) GF′(zh)≡gn((1+δn−1)⊙gn−1(⋯((1+δh+1)⊙gh+1(zh)⋯)))
实际上不是非要用乘法,用加法也差不多
他们发现在最后 4 层加扰动比较有效(就是h=n-5)
他们对扰动加了 L2 正则化
扰动网络 R 的loss是:
L = L match + λ reg L reg \mathcal{L}=\mathcal{L}_{\text {match }}+\lambda_{\text {reg }} \mathcal{L}_{\text {reg }} L=Lmatch +λreg Lreg
注意,其中:
L match ≡ ∥ ( G ′ ( z e ) − x ) ⊙ ( 1 − mask e ) ∥ 1 \mathcal{L}_{\text {match }} \equiv\left\|\left(G^{\prime}\left(\mathrm{z}_{e}\right)-x\right) \odot\left(1-\operatorname{mask}_{e}\right)\right\|_{1} Lmatch ≡∥(G′(ze)−x)⊙(1−maske)∥1
mask e = { 1 where the stroke is present 0 outside the stroke \text { mask }_{e}=\left\{\begin{array}{ll} 1 & \text { where the stroke is present } \\ 0 & \text { outside the stroke } \end{array}\right. mask e={10 where the stroke is present outside the stroke
L r e g ≡ ∑ i = h + 1 n − 1 ∥ δ i ∥ 2 \mathcal{L}_{\mathrm{reg}} \equiv \sum_{i=h+1}^{n-1}\left\|\delta_{i}\right\|^{2} Lreg≡i=h+1∑n−1∥δi∥2
这个扰动网络 R 是随机初始化,而且本身是没有输入的,训练 R 的过程是:固定生成器,固定 z e z_e ze , 固定 x ⊙ m a s k e x\odot mask_e x⊙maske (这里可能有点歧义),然后用 adam 优化 1000 步。
他们的 λ r e g = 0.1 \lambda_{reg}=0.1 λreg=0.1
他们在单块 GPU 上训练只需要 30 秒
实时预览
由于每次编辑都是需要训练扰动网络的,他们做了一个预览器,用于实现实时交互
预览器只在图片上传时训练一次
使用ProGAN架构
注意,应该是利用了 ProGAN 的一个性质,就是靠前的层生成低像素低精度,靠后的层生成高像素高精度,所以编辑效果才会比较好吧?
他们的方法高度应用了 GAN Dissection的理论
只编辑 第四层与第五层之间的 特征图,特征图的尺寸是8x8x512