在生成真实图像方面,常用的都是无监督模型,如GAN,VAE等。
然而ICCV2017的这篇文章,同样是从图像(图像分割结果的语义标注图)到原始的街景图像的转换,它并没有依靠生成对抗网络(GAN)以训练generator与discriminator network的方式来做image-to-image,而是采用了一种级联精练网络Cascaded Refinement Network (CRN)来实现逼真街景图的生成。
该模型的目标是:针对每个语义分割图,w(宽),h(长),c(语义的类别个数,如行人、车、树木、建筑等),其目标是要生成一张w(宽),h(长), RGB(三个通道)的彩色逼真图像。
然而,要达到图像逼真的效果,论文中指出有模型要具备三点:(摘自:https://www.leiphone.com/news/201708/Jy2RophpB7M9WIhf.html)
全局的协调性: 照片中物体的结构要正确,许多物体的结构都不是在局部独立存在的,它们可能有对称性。比如如果一辆车左侧的刹车灯亮了,那右侧的刹车灯也要亮。
高分辨率:为了达到足够高的分辨率,模型需要具有专门的分辨率倍增模块。
记忆力 (Memory):网络需要有足够大的容量才能复现出图像中物体足够多的细节。一个好的模型不仅在训练集中要有好的表现,也要有足够的泛化能力,都需要网络容量足够大。
那么作者提出上面的模型,为了具备这三点,设计的模型如下图所示。
从图上可以看到,在M0, M1, M2这几个阶段,一个缩小版的语义分割图(w0, h0, c),论文中为:(8, 4, c),然后经过卷积,输出特征F0,把F0经过升采样后,与下一个分辨率(上一个的翻倍)的语义分割图,一起传到下一个模块M1。
作者的实现主要代码如下:
with tf.variable_scope(tf.get_variable_scope()):
label=tf.placeholder(tf.float32,[None,None,None,20])
real_image=tf.placeholder(tf.float32,[None,None,None,3])
fake_image=tf.placeholder(tf.float32,[None,None,None,3])
generator=recursive_generator(label,sp)
weight=tf.placeholder(tf.float32)
# Vgg 19网络
vgg_real=build_vgg19(real_image)
vgg_fake=build_vgg19(generator,reuse=True)
p0=compute_error(vgg_real['input'],vgg_fake['input'],label)
p1=compute_error(vgg_real['conv1_2'],vgg_fake['conv1_2'],label)/2.6
p2=compute_error(vgg_real['conv2_2'],vgg_fake['conv2_2'],tf.image.resize_area(label,(sp//2,sp)))/4.8
p3=compute_error(vgg_real['conv3_2'],vgg_fake['conv3_2'],tf.image.resize_area(label,(sp//4,sp//2)))/3.7
p4=compute_error(vgg_real['conv4_2'],vgg_fake['conv4_2'],tf.image.resize_area(label,(sp//8,sp//4)))/5.6
p5=compute_error(vgg_real['conv5_2'],vgg_fake['conv5_2'],tf.image.resize_area(label,(sp//16,sp//8)))*10/1.5
G_loss=p0+p1+p2+p3+p4+p5
即提取了借助一个 VGG-19 图像感知模型,提取它识别的图像特征中高低不同的某几层作为计算训练损失的依据,从而同时涵盖了图像特征中边缘、颜色等低级细粒度特征和物体、类别等高级总体布局特征,从而构建了全面、强力的损失函数。
# 降采样
def recursive_generator(label,sp):
dim=512 if sp>=128 else 1024
if sp==512:
dim=128
if sp==4:
input=label
else:
downsampled=tf.image.resize_area(label,(sp//2,sp),align_corners=False)
input=tf.concat([tf.image.resize_bilinear(recursive_generator(downsampled,sp//2),(sp,sp*2),align_corners=True),label],3)
net=slim.conv2d(input,dim,[3,3],rate=1,normalizer_fn=slim.layer_norm,activation_fn=lrelu,scope='g_'+str(sp)+'_conv1')
net=slim.conv2d(net,dim,[3,3],rate=1,normalizer_fn=slim.layer_norm,activation_fn=lrelu,scope='g_'+str(sp)+'_conv2')
if sp==512:
net=slim.conv2d(net,3,[1,1],rate=1,activation_fn=None,scope='g_'+str(sp)+'_conv100')
net=(net+1.0)/2.0*255.0
return net
在具体的实现过程中,借助https://github.com/CQFIO/PhotographicImageSynthesis源码进行了实验,效果还是不错的。
如语义图:
其生成的逼真街景如下:
虽然人和车看起来还是有些模糊,但至少画面很流畅。