课程项目要求做image matting,于是找到了一篇这样的论文做image matting。刚好也对GAN比较感兴趣,GAN作为一种生成模型,至今已经在图像生成,图像风格转移等方面取得了很好的效果,那么使用GAN从trimap domain转换到alphamap domain应该是个自然的想法。
本项目是参考BMVC 2018的一篇论文 AlphaGAN: Generative adversarial networks for natural image matting的复现。目前还没有采用论文中的skip connection。效果也不是很好,或者说效果比较差吧╮( ̄▽ ̄)╭。
- Python 3
- Pytorch 0.4
- OpenCV
Follow the instruction to contact author for the dataset
你可能还需要按照Deep Image Matting中论文的方法在alpha mat的基础上生成trimap,这是一个别人实现的方法
import numpy as np
import cv2 as cv
def generate_trimap(alpha):
fg = np.array(np.equal(alpha, 255).astype(np.float32))
# fg = cv.erode(fg, kernel, iterations=np.random.randint(1, 3))
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))
unknown = np.array(np.not_equal(alpha, 0).astype(np.float32))
unknown = cv.dilate(unknown, kernel, iterations=np.random.randint(1, 20))
trimap = fg * 255 + (unknown - fg) * 128
return trimap.astype(np.uint8)
等我先重构下代码再说这部分的事情╮( ̄▽ ̄)╭
代码实现借鉴了
-
pytorch-book 中的GAN生成动漫头像
AlphaGAN matting 很大程度上借鉴了Deep Image matting。几乎可以理解为AlphaGAN matting 将Deep Image matting中的深度网络拿来作为了GAN的generator,只是把encoder中的VGG换成了ResNet50,并把少部分卷积层换成了空洞卷积,以达到不减小feature map也可以增大感受野的目的。
AlphaGAN matting 的discriminator采用PatchGAN。
文章借鉴了Rethinking Atrous Convolution for Semantic Image Segmentation中的Atrous Convolution和Atrous Spatial Pyramid Pooling(ASPP),当然这两个东西(方法?)都不是这篇论文首提的。空洞卷积的作用在于不改变feature map的大小进而增大下一层的感受野,使用空洞卷积结构的深度网络在小物体的目标识别上确实取得了不错的结果。用到这里,可能是作者想避免generator丢失那些毛发的细节信息吧,然而,我的复现并没有达到这种效果,理想很丰满,现实很骨感,生成的alphamat除了糊还是糊(ノ=Д=)ノ┻━┻。
更直观的理解卷积,空洞卷积戳这里。这可是pytorch官方推荐。pytorch说明文档懒得给你解释卷积,于是让你去看别人写好的╮( ̄▽ ̄)╭。
空洞卷积空间金字塔?
为此,我先去查了下空间金字塔究竟是个啥,看起来把Spatial pyramid pooling加在全连接层之前,可以让网络处理任意大小的图像输入,而不用将输入图片裁剪到一个固定的大小。
后来,我看了下相关论文中ASPP的结构,发现,这怎么好像和SPP不太一样???这怎么看起来像Inception结构。到网上找了个ASPP的实现,总感觉好像不太对。
后来,我打算按照下图的结构自己实现个ASPP,在ASPP的forward
过程中,将输入分别输入到各个空洞卷积中,再将结果torch.cat
到一起,结果还引发了另一个问题—— RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation。
关于这个RuntimeError的解决方法有几种
- 将
inplace=True
改成inplace=False
- 将
a += b
改成a = a + b
- 回退到pytorch0.3.0版本
GAN是一个很难训练的网络模型,很可能就会出现生成结果不理想的情况。我就觉得我现在训练出的这个模型很就没训练好,生成的结果可以说几乎没有细节信息,很是模糊_(:з」∠)_。尽管文章中采用了PatchGAN作为discriminator,而PatchGAN设计的初衷就是去模糊。
在复现过程中,参看了训练GAN的16个技巧以及Improved Techniques for Training GANs。
-
优化器采用Adam
-
不要通过loss statistics 去平衡G与D的训练过程
-
避免稀疏梯度:ReLU, MaxPool
复现中,我将原本ReLU都替换为了LeakyReLU, MaxPool都替换为了AveragePool
复现的时候,很大程度上参考了CycleGAN的实现,包括PatchGAN,读入数据的input_dataset等,都是借鉴CycleGAN中的代码实现。CycleGAN在图像风格转换等方面取得非常成功的效果,该项目的开源代码写的也十分棒。因此,复现中的一些超参数和CycleGAN中的超参数一致。
同时也有一篇关于GAN全景图的论文,The GAN Landscape论文中总结了近来效果比较好的GAN的超参数。
复现中的超参数
Parameter | value |
---|---|
learning rate α | 0.0002 |
negative slope | 0.2 |
(β1, β2) | (0.9, 0.999) |
AlphaGAN的损失函数由GAN的对抗损失与Deep Image Matting中提出的alpha-prediction loss和compositional loss构成,所以AlphaGAN的Loss如下:
$ L_{comp}
可以说生成结果边缘信息缺失,没有细节,非常模糊了。完全没有论文中的效果好╮( ̄▽ ̄)╭