《Image-to-Image Translation with Conditional Adversarial NetWorks》

Image-to-Image Translation with Conditional Adversarial NetWorks

  这是加里福利亚大学在CVPR 2017上发表的一篇论文,讲的是如何用条件生成对抗网络实现图像到图像的转换任务。
  > 原文链接:https://arxiv.org/abs/1611.07004
  > 论文主页:https://phillipi.github.io/pix2pix/,其中包含了PyTorch、Tensorflow等主流框架的代码实现

  
  图像、视觉中很多问题都涉及到将一副图像转换为另一幅图像(Image-to-Image Translation Problem),这些问题通常都使用特定的方法来解决,不存在一个通用的方法。但图像转换问题本质上其实就是像素到像素的映射问题,这篇论文提出“条件生成对抗网络(CGAN)”能够解决这一问题。如上图所示,使用CGAN可以实现语义/标签到真实图片、灰度图到彩色图、航空图到地图、白天到黑夜、线稿图到实物图的转换。使用完全一样的网络结构和目标函数,仅更换不同的训练数据集就能分别实现以上的任务。

摘要

  我们研究将条件生成对抗网络作为图像转换问题的通用解决方案。该网络不仅可以学习输入图像到输出图像的映射关系,还能够学习用于训练映射关系的loss函数。这使得我们可以使用同一种方法来解决那些传统上需要各种形式loss函数的问题。我们证明了该方法可以有效实现下列任务:从标签图合成相片,从线稿图重构对象,给图片上色等。所以我们不再需要人工设计映射函数,而且这项工作表明,我们即使不手动设计loss函数,也能达到合理的结果。(听起来十分诱人)

前言

  在图像处理、计算机图形学和计算机视觉领域,很多问题都可以认为是将一张输入图片“转换”成相对应的输出图片。一个场景可以被渲染为RGB图像,梯度域,边缘图或语义图等。类比自动语言翻译,我们将图像到图像的转换问题定义为,在给定足够训练数据的情况下,将场景的一个可能表示转换成另一个。语言翻译之所以困难的一个原因是,语言之间的映射很少是一对一的,一种语言中的概念总是比用其他语言表达来的容易。相似的,绝大多数图像转换问题也是多对一的(计算机视觉)或者一对多的(计算机图形学)。传统上,每个任务都使用一种单独的,专用的机制来解决。但是实际上这些任务本质上都是一样的:从像素点预测新的像素点。本文的目标就是为这些问题设计一种通用的框架。
  同行已经在这个方向取得了重大的进步,CNNs逐渐成为解决各种图像预测问题的主力。CNNs通过学习使loss函数最小化(评估结果质量的目标),尽管学习过程是自动化的,但仍需要投入大量人力来设计有效的loss函数。换句话说,我们仍然需要告诉CNN我们希望将什么最小化。但是我们必须得和Midas一样小心我们期望的东西!如果我们采用了不成熟的方法,要求CNN最小化预测图像和真值图像之间的欧氏距离,那么这将会产生模糊的结果。这是因为欧式距离是通过将所有输出平均来最小化的,这将会产生模糊的结果。为了得到能够使CNN输出锐利,真实的图像,如何设计loss函数是一个开放性的且需要专业知识的问题。
  相对的,如果我们只需要指定一个高级的目标,比如“产生难以和真实图片分辨的输出”,然后自动学习一个适合目标的loss函数,这就非常令人满意了。幸运的是,这正是最近提出的生成对抗网络GANs所做的事。GANs学习的是一个区分真实和伪造图像的loss函数,同时训练一个生成模型来最小化这个loss。模糊的图像将无法被容忍,因为它们看起来像伪造的图像。由于GANs学习的是适应于数据的loss,因此可以将GANs应用到大量的任务中去,而传统方法可能针对不同任务需要不同类型的loss函数。
  本文中,我们研究有条件的GANs。和GANs从数据中学习一个生成模型一样,条件GANs学习一个条件生成模型。这使cGANs适用于图像转换问题,我们在输入图片上设置条件,得到相应的输出图像。
  GANs在最近两年得到了广泛的研究,本文研究的许多技术在之前就已经提出了。尽管如此,之前的论文都是关注特定的应用,而cGANs作为图像转换问题的通用方法的有效性却仍然是不清楚的。我们主要的贡献是阐释了cGANs在很多问题上都能产生合理的结果。第二个贡献是提出了一个简单有效的框架,并分析了几种重要结构选择的效果。·

相关工作

  1. 图像建模的结构loss
  图像转换问题通常表述为各像素的分类或回归问题,将输出空间视为“非结构化的”,输出的每个像素酌情视为独立于输入图像的其他所有像素。相反的,条件GANs学习结构化的loss。结构化loss会对输出的节点构造进行惩罚。大多数文献都考虑这种类型的loss,比如条件随机场、SSIM度量、特征匹配、非参数loss、convolutional pseudo-prior以及基于匹配协方差统计的loss。我们条件GAN不同于这些学习到的loss,理论上可以对不同于输出和目标的任何可能结构进行惩罚。
  2. 条件GANs
  我们并不是第一个将GANs应用到条件设置下。已经有先前工作用离散标签、文本及图像来约束GANs。以图片为条件的GANs已经解决了图像修复、从法线图预测图像、根据用户约束来编辑图像、视频预测、状态预测、从相片中产生商品和风格迁移等。这些方法都根据特殊的应用进行了改变,我们的方法比他们大多数都要简单。
  我们的方法在生成器和判别器几个结构上的选择也不同于之前的工作。不同于之前,我们生成器使用了“U-Net”结构,而判别器使用了卷积“PatchGAN”分类器(只在patch的规模下惩罚结构)(我就是为了这个才看看这篇论文的!)。前人提出过相似的PatchGAN结构,用于捕捉局部风格统计信息。我们的方法在广泛的问题上都有效,并且还讨论了改变patch size带来的影响。

方法

  GANs是一个学习随机噪声向量zz尽可能检测出生成器的“伪造”图像。

  
  1. 目标函数
  条件GAN的目标函数可以表示为

LcGAN(G,D)=Ex,ypdata(x,y)[logD(x,y)]+Expdata(x),zpz(z)[log1D(x,G(x,z))]LcGAN(G,D)=Ex,y∼pdata(x,y)[log⁡D(x,y)]+Ex∼pdata(x),z∼pz(z)[log⁡1−D(x,G(x,z))]输入的变体形式:
LGAN(G,D)=Eypdata(y)[logD(y)]+Expdata(x),zpz(z)[log1D(G(x,z))]LGAN(G,D)=Ey∼pdata(y)[log⁡D(y)]+Ex∼pdata(x),z∼pz(z)[log⁡1−D(G(x,z))]相片的任务(上表所示)。基于GAN的loss函数得到了更高的分数,这表明合成出来的图像包含更多可识别的结构。我们也测试了移除判别器上条件(标记为GAN)的影响。这种情况下。loss没有惩罚输入和输出中不匹配的地方,它只关心生成的图片是否真实,所以结果非常差。而且不论输入图片,生成器生成几乎一样的图片,在这项任务中这是非常不好的现象,明显cGAN表现比GAN优秀。然后L1 loss项也鼓励输出尊重输入,因为L1会对预测输出和真值输出之间的距离进行惩罚,所以L1加上GAN之后同样可以产生真实且尊重输入的结果,L1+cGAN得分和L1+GAN的情况差不多。
Fig 7
   色度:条件GAN一个显著的优点是甚至能够合成在标签输入中不存在空间结构,并且产生清晰的图像。我们猜想cGANs在光谱域内也有相似的效果,即使图像色彩更丰富。就像当无法确定边界的时候,L1 loss会造成模糊的结果,当像素点无法确定颜色的时候,L1 loss会促使生成平均、灰色调的颜色。特别的,L1将会通过选择各种可能颜色的条件概率中位数来使loss最小。另一方面,对抗loss大体上能够判断灰色的输出是不符合真实情况的,会鼓励生成符合真实颜色分布的色彩。在上图中我们研究了cGANs在Cityscapes数据集中达到的实际效果。曲线描述了在Lab空间中输出色彩的边缘分布。真实分布用点线表示。显然L1导致比真实情况更窄的分布,证明了L1鼓励平均,灰度化的颜色。另一方面,使用cGAN使输出的分布更加贴合真实分布。

  
  3.3 生成器结构分析
  U-Net结构允许低级信息直接在网络中传递。这会导致更好的结果吗?上图比较了有无U-Net结构的效果。单纯的encoder-decoder在我们的实验中无法学会生成真实的图像,对于每个输入标签,生成了几乎一样的图像(朦朦胧胧一片)。U-Net结构并没有依赖于条件GAN结构:加和不加U-Net结构的网络分别在L1和L1+cGAN条件下进行了训练,两种情况下U-Net结构都达到了更好的效果。
这里写图片描述

  3.4 从PixelGANs到PatchGANs到ImageGANs
  我们测试了判别器接收域使用不同patch size N的效果:从1x1的“PixelGANs”到整张图像256x256的“ImageGANs”。上图图呈现了定性结果,上表呈现了FCN分数的定量结果。请注意本文其他地方,如果没有特别指明,均使用的是70x70的“PatchGANs”,本节所有实验都使用L1+cGAN的loss。
  PixelGAN对于空间清晰度没有帮助,但是提升了结果的色彩效果。比如图中的巴士,在L1 loss下是灰色的,在PixelGAn下变成了橘红色。颜色直方图匹配在图像处理中一个很常见的问题,PixelGANs或许能成为一个解决方法。
  使用16x16的PathGAN进一步提升了输出的清晰度,但是出现了一些不自然的纹理。70x70则减轻了这种效果。如果进一步提高N,使用256x256并没有提升效果,实际上FCN得分还下降了。这也许是因为ImageGAN相比70x70的patch拥有更多的参数和更深的深度,导致难以训练。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
image-to-Image Translation with Conditional Adversarial Networks(条件对抗网络的图像到图像转换)是一种用于图像转换的深度学习方法。它通过训练一个生成器网络和一个判别器网络来实现图像的转换。生成器网络将输入图像转换为目标图像,而判别器网络则试图区分生成的图像和真实的目标图像。 这种方法的关键是使用对抗性训练。生成器网络和判别器网络相互竞争,以提高生成器网络生成逼真图像的能力。生成器网络通过最小化判别器网络对生成的图像的判别误差来学习生成逼真的图像。判别器网络则通过最大化对生成的图像和真实图像的判别能力来学习区分真实图像和生成图像。 在条件对抗网络中,生成器网络和判别器网络都接收额外的条件输入,以指导图像转换的过程。这个条件输入可以是任何与图像转换任务相关的信息,例如标签、语义分割图或其他图像。 通过训练生成器网络和判别器网络,条件对抗网络可以实现各种图像转换任务,例如将黑白图像转换为彩色图像、将马的图像转换为斑马的图像等。 这是一个使用条件对抗网络进行图像到图像转换的示例代码: ```python import tensorflow as tf from tensorflow.keras import layers # 定义生成器网络 def build_generator(): # 定义生成器网络结构 generator = tf.keras.Sequential() generator.add(layers.Conv2DTranspose(64, (4, 4), strides=(2, 2), padding='same', input_shape=(256, 256, 3))) generator.add(layers.BatchNormalization()) generator.add(layers.ReLU()) generator.add(layers.Conv2DTranspose(32, (4, 4), strides=(2, 2), padding='same')) generator.add(layers.BatchNormalization()) generator.add(layers.ReLU()) generator.add(layers.Conv2DTranspose(3, (4, 4), strides=(2, 2), padding='same', activation='tanh')) return generator # 定义判别器网络 def build_discriminator(): # 定义判别器网络结构 discriminator = tf.keras.Sequential() discriminator.add(layers.Conv2D(64, (4, 4), strides=(2, 2), padding='same', input_shape=(256, 256, 3))) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(128, (4, 4), strides=(2, 2), padding='same')) discriminator.add(layers.BatchNormalization()) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(256, (4, 4), strides=(2, 2), padding='same')) discriminator.add(layers.BatchNormalization()) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(1, (4, 4), strides=(1, 1), padding='same')) return discriminator # 定义条件对抗网络 class cGAN(tf.keras.Model): def __init__(self, generator, discriminator): super(cGAN, self).__init__() self.generator = generator self.discriminator = discriminator def compile(self, g_optimizer, d_optimizer, loss_fn): super(cGAN, self).compile() self.g_optimizer = g_optimizer self.d_optimizer = d_optimizer self.loss_fn = loss_fn def train_step(self, real_images, labels): # 生成器网络生成假图像 with tf.GradientTape() as tape: fake_images = self.generator([real_images, labels], training=True) # 判别器网络判别真实图像和假图像 real_output = self.discriminator([real_images, labels], training=True) fake_output = self.discriminator([fake_images, labels], training=True) # 计算生成器和判别器的损失 g_loss = self.loss_fn(fake_output, tf.ones_like(fake_output)) d_loss_real = self.loss_fn(real_output, tf.ones_like(real_output)) d_loss_fake = self.loss_fn(fake_output, tf.zeros_like(fake_output)) d_loss = d_loss_real + d_loss_fake # 更新生成器和判别器的参数 g_gradients = tape.gradient(g_loss, self.generator.trainable_variables) d_gradients = tape.gradient(d_loss, self.discriminator.trainable_variables) self.g_optimizer.apply_gradients(zip(g_gradients, self.generator.trainable_variables)) self.d_optimizer.apply_gradients(zip(d_gradients, self.discriminator.trainable_variables)) return {"g_loss": g_loss, "d_loss": d_loss} # 创建生成器和判别器 generator = build_generator() discriminator = build_discriminator() # 创建条件对抗网络 cgan = cGAN(generator, discriminator) # 编译条件对抗网络 cgan.compile( g_optimizer=tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5), d_optimizer=tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5), loss_fn=tf.keras.losses.BinaryCrossentropy(from_logits=True) ) # 训练条件对抗网络 cgan.fit(dataset, epochs=100) # 使用生成器网络进行图像转换 input_image = ... label = ... output_image = generator([input_image, label]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值