Image-to-Image Translation with Condition Adversarial Networks(基于条件性对抗网络的图片转义)

  在图片处理中涉及的一个问题就是将一个图片转化成一个对应的输出图片。这些问题经常使用特定应用的算法解决,即使设置通常是一样的:都是将像素映射到像素上(map pixels to pixels)。条件对抗网络是一个通用的解决方案,他似乎能在各种不同的问题中都能表现良好。

Abstract

  我们发现条件对抗网络是image-to-image转义问题的一个通用解决方案。这个网络不仅从输入图片到输出图片中学习映射, 而且学习了一个损失函数来训练这个映射。我们证明了这个方法可以有效的在标签映射(label maps)中合成(synthesizing)图片,从边缘映射(edge maps)中重构(reconstructing)物体,并且能够在其它任务中对图片着色。

Introduction

  将一个输入图片转化成对应的输出图片时,在图片处理、计算图和计算视觉上可以提出许多问题。比如一种观念可以通过英语或者法语表达,一个场景可以通过一个RGB图片,一个梯度领域,一个边缘映射,一个语义标签映射等表示出来。与自动的语言翻译类似,我们设计了图片到图片的转义,通过充足的训练数据,任务就是将一个场景翻译成另外一个可能表示的场景。传统意义上,他们的每一个任务都需要通过特定的机器分别进行处理,尽管他们的设置都是一样的:从一个像素预测另一个像素(predict pixels from pixels).本篇论文中我们的目标是开发一个共同的框架来解决上述问题。
  这里开始讲CNNs,CNNs在各种各样的图片预测问题上发挥了很重要的作用。CNNs学习最小化损失函数(一种计算结果质量的计分方式),尽管CNN的学习过程是自动的,但是仍然需要人工的努力来使得loss更高效。换句话说,我们仍然需要告诉CNN我们想最小化什么。如果我们采取一种天真的方式(naive approach)要求CNN最小化预测像素和ground truth像素之间的欧氏距离,他可能会趋向于产生模糊的结果(blurry results)。这是因为欧式距离是通过平均所有可能的输出来最小化的,而这就会造成blurring。提出一种能够迫使CNN做我们真正想要的(如输出真正的图片)损失函数,是一个公开的难题
  如果我们能够只设定一个高级目标,比如使输出和现实无法区分,然后自动地学习适合实现这一目标的损失函数,这是非常可取的。 幸运的是,最近提出的GAN已经做了这方面的工作。在GANs中学习的损失能够适应数据,他们可以被应用到多种不同的任务上,而如果使用传统的方法就需要各种不同的损失函数
  在这篇论文中,我们探讨了有条件设置的GANs。就像GANs学习数据的生成模型,cGANs学习有条件的生成模型(conditional generative model)。这就使得cGANs适用于图片到图片的转义任务,我们的条件就是一个输入的图片生成一个对应的输出图片。
  GANs在最近两年蓬勃发展,并且本文中探索的一些技术之前已经被提及过。尽管如此,早期的论文关注于特定的应用,如何有效地使条件图片的GANs成为图片到图片转义的通用方法仍然是个问题。 我们的主要贡献就是证明了在多种不同的问题中,条件GANs产生了合理的结果。我们的第二个贡献就是展现了一个简单的框架并且有效的实现了不错的结果,并且分析了几个重要的结构选择。 代码开源在github上面。

Related work

  图像模型的结构化损失 图片到图片的转化问题通长可以表表述为每个像素的分类或者回归。这些表达式将输出空间视为非结构化,在某种意义上说,就是每个输出像素都是有条件的独立于所有其它给的输入图片。有条件的GANs改为(instead)学习结构化损失。 结构化的损失惩罚输出的联合损失。大量的文献都考虑过这种损失,使用的方法包括。。。cGAN是不同的,它的损失在理论上可以惩罚输出和目标之间不同的任何可能结构。

  Conditional GANs 我们不是第一个将GANs应用到条件设置中(conditional setting)。。。每一种方法都被裁剪成一个特定的应用。我们的框架不同之处在于没有什么特定的应用场景。这使得我们的设置比其它的模型简单的多。
   在生成器和鉴别器的选择方面,我们的方法也不同于先前的工作。我们的生成器使用的是“U-Net”-based结构,我们的鉴别器使用的是一个卷积“PatchGAN”分类器,它只惩罚图像补丁规模上(image patch scale)的结构。在论文【38】中提到了一种和PatchGAN相似的结构,它用来捕捉局部特征的统计信息。==这里我们展示了这个方法在各种不同的问题上都是有效的,而且我们调查(investigate)了改变补丁大小的影响。

3 Method

GANs是一个生成网络,用来学习从随机噪声向量 z z z到输出图片 y y y的映射, G : z → y G:z \rightarrow y G:zy。对比之下,cGANs学习从获得的图片 x x x和随机噪声向量 z z z到输出图片 y y y的映射, G : { x , z } → y G:\{ x,z \} \rightarrow y G:{x,z}y. 训练流程如图2所示。
Figure 2 我感觉需要注意的一点就是,在cGANs网络中,生成器和分辨器都是可以获得输入的边缘映射的。

3.1Objective

  cGAN的目标函数可以表达如下:
L G A N ( G , D ) = E x , y [ l o g D ( x , y ) ] + E x , z [ l o g ( 1 − D ( x , G ( x , z ) ) ] L_{GAN}(G,D)=E_{x,y}[logD(x,y)]+E_{x,z}[log(1-D(x,G(x,z))] LGAN(G,D)=Ex,y[logD(x,y)]+Ex,z[log(1D(x,G(x,z))]
其中G的目标是最小化这个目标,而D的目标是最大化这个布标。 G ∗ = a r g m i n G m a x d L c G A N ( G , D ) G^* = argmin_Gmax_dL_{cGAN}(G,D) G=argminGmaxdLcGAN(G,D).
  为了测试分辨器D的条件重要性,我们也对比了非条件性的变种,这个的分辨器不观察x:
L G A N ( G , D ) = E y [ l o g D ( y ) ] + E x , z [ l o g ( 1 − D ( G ( x , z ) ) ] L_{GAN}(G,D)=E_{y}[logD(y)]+E_{x,z}[log(1-D(G(x,z))] LGAN(G,D)=Ey[logD(y)]+Ex,z[log(1D(G(x,z))]
之前的方法已经发现将GAN的目标和一个传统的loss结合(如L2距离)是有好处的。D的工作保持不变,但是G的工作不仅仅是欺骗D,而且在L2sense上接近ground truth 的输出。我们也探索了这个选择,使用L1距离而不是L2距离,因为L1能够减少模糊:
L L 1 ( G ) = E x , y , z [ ∣ ∣ y − G ( x , z ) ∣ ∣ 1 ] L_{L1}(G)=E_{x,y,z}[||y-G(x,z)||_1] LL1(G)=Ex,y,z[yG(x,z)1]
所以我们最后的目标是:
G ∗ = a r g m i n G m a x D L c G A N ( G , D ) + λ L L 1 ( G ) G^*=argmin_Gmax_DL_{cGAN}(G,D)+\lambda L_{L1}(G) G=argminGmaxDLcGAN(G,D)+λLL1(G)
  没有z,网络虽然能够继续学习从x到y的映射,到死会产生一些不可抗拒的结果,进而会导致不能和任何分布匹配,除了那个什么delta函数。 过去的cGANs 已经证明这一点,并且提供了一个高斯噪声z作为G的输入,除了x之外。在最开始的试验中,我们并没有发现有效的策略,G只是简单的学会了忽略噪声。进一步,对于我们最后的模型,我们只在dropout结构上提供了噪声,在训练和测试时运用在G的几个层上面。尽管存在dropout的噪声,在我们的网络输出中,我们只观察到了微弱的随机性(minor stochasticity).设计一个能够产生高度随机的cGANs,并且能够捕捉到这个模型状态分布(conditional distribution)的全熵值(full entropy),是当前工作遗留下来的重要问题

3.2. Network architectures

  G和D都是使用Conv-BatchNorm-ReLu的模型。

3.2.1 Generator with skips

  图像到图像转义问题的一个定义性的特征是它们要将一个高分辨率的输入网格映射到一个高分辨率的输出网格上。此外,我们考虑的问题是,输入和输出在表面显示上是不一样的,但是都呈现相同的底层结构。因此,输入结构和输出结构在大体上是对齐的。我们设计的G结构就是基于上述考虑
  之前的解决方案大都是使用编码解码网络。在该网络中,输入通过一系列的层逐步进行下采样,直到进入瓶颈层。这样的网络要求所有的信息(information)通过所有的层,包括瓶颈(bottleneck)。对于许多图片转换问题,在输入和输出中都存在大量的低层次(low-level)信息分享。 直接通过这个网络来传输信息是可取的。比如说,对于图片上色这个例子,输入和输出分享突出边缘的位置(location of prominent edges)。
  像这样,为了给G一个均值(means)来规避(circumvent)信息瓶颈,我们添加了skip连接,和U-net的大体结构类似。具体来说,我们在第 i i i层和第 n − i n-i ni层添加了一个skip连接,n是所有层的数量。每一个skip连接就是 i i i层和第 n − i n-i ni层所有通道的连接。

3.2.2 Markovian discriminator(PatchGAN)

  L2和L1损失众所周知,它们在图片生成问题中会产生模糊的问题。尽管这些losses不能很好的用在高清晰度图片中,但他们仍然能够正确的捕捉到低频(low frequencies)。在这种情况下的问题,我们不需要整个网络来保证低频的正确性,这就是L1在做的。
  这个动机约束GAN的鉴别器只模拟高频结构,而依靠L1项保证低频的正确性。 为了模拟高频,限制我们在局部图片补丁上的注意力是很有效的。因此,我们设计了一个分辨器结构,我们称之为PatchGAN ,它只惩罚Patch规模下的结构。这个鉴别器试着分辨每一个N×N的Patch是真的还是假的,然后平均所有的相应来得到最后的输出D。
  在4.4中,我们证明了N即使比整个图片的尺寸小很多依然能够产生高质量的效果。这是一个很大的优点,因为一个更小的PatchGAN意味着更少的参数,更快的速度,以及能够应用到任意图片中。
  这样一个鉴别器有效地将一个图片建模成一个马尔科夫随机场,假设每个像素之间相互独立,通过一个以上的Patch直径分开。这种连接在论文38中有过探索,在texture和风格模型中也是一种通用的假设。因此,我们的PatchGAN也可以被理解成texture/style 损失的一种。

3.3 Optimization and inference

  为了优化我们的网络,我们按照24的标准方法:我们选择G和D分开训练。在G的训练中,选择训练最大化 l o g D ( x , G ( x , z ) ) logD(x,G(x,z)) logD(x,G(x,z))而不是最小化 l o g ( 1 − D ( x , G ( x , z ) ) ) log(1-D(x,G(x,z))) log(1D(x,G(x,z)))。在优化D的时候我们要对目标除以2,这可以减缓D相对于G的学习率。使用minibatchSGD和Adam优化。
  在验证时,我们采用和训练时一样的方法运行生成网络。这不同于一般的protocol,我们在测试时使用了dropout。我们对测试的batch进行了BatchNorm,而不是对训练的Batch,这个方法中的BatchNorm,当Batch size=1时,被称之为“instance normalization”,并且被证实能在图片生成任务中有效的工作。 在我们的试验中,我们会根据我们的实验情况在1-10之间设置batch size。
后续内容不在翻译,可以参考此篇博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值