U-GAT-IT: 人脸转动漫网络(非配对图像翻译)精华总结

ugatit也是基于cyclegan,需要使用gan loss, cycle loss和idt loss。除此之外,论文还提出了在G和D中使用一个分类器,训练分类器也需要一个loss,叫做cam loss,受类激活映射启发。

论文的两个创新点:

  • adaptive Layer Instance normalization(adaLIN)
  • 类似于SENet的通道注意力。只不过exciting权重是来自CAM分类器。

方法

G_A代表从A域往B域转换,D_A代表判别真实的B域和假的B域样本G_A(X)。另外的一个方向BtoA就不多重复说明。
Note: 实际上tensorflow的源代码,指明作者用了两个不同感受野的D(一个方向有两个D,一共4个D),但用法一样。这里我统一用D表示。

将生成器G分解为4部分:E,M,A,U。
E包含:

  • 前两层是stride为2的下采样。
  • 后x层是stride为1的resblock。使用Instance norm

M: 一个MLP,有几层全连接层组成。(light 版本的区别就在于此)
A: 论文创新其一,注意力模块,后续接了x层adaLIn的resblock。
U是上采样模块: 两层两倍上采样(upsample, conv , LN, relu),以及一个conv+tanh作为head。这里使用的LN而不是IN,有原因,见下文

生成器的部分着重在M和A的作用上。

判别器D就是patch-base的D,只不过作者在一个方向上使用了local和global两个尺度的D。同时D中也是用了CAM。使用方式了G中的CAM一致,但作用不一样。

details

A的部分

样本经过G中的E之后,得到一个tensor,其shape为 c × h × w c \times h\times w c×h×w(省略batchsize),这个tensor用T表示
然后经过GAP和GMP(均值池化和最大池化,全局的),得到两个向量,记作 t m ∈ R c , t a ∈ R c t_m \in R^{c}, t_a \in R^c tmRc,taRc。然后使用一个全连接层得到对应的标量:
s c a l a r i = m a t m u l ( W , t i ) ; i ∈ { a , m } scalar_i = matmul(W, t_i); i \in \{a,m\} scalari=matmul(W,ti);i{a,m}
这个标量会用于计算cam loss。同时这个W(全连接层的权重),会作为weight重新激活T(类似senet的通道重激活,一个值重新加权整个通道)。
这两个特征经过cat以及1x1的conv降维之后,会送入M中。

M的部分

M是一个MLP。其作用是预测gamm和beta,用于后面需要的adalin的norm之后的denorm 部分。gamm和beta都是c维的向量。

X层使用AdaLIN的resblock

def adaptive_ins_layer_resblock(x_init, channels, gamma, beta, use_bias=True, smoothing=True, scope='adaptive_resblock') :
    with tf.variable_scope(scope):
        with tf.variable_scope('res1'):
            x = conv(x_init, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias)
            x = adaptive_instance_layer_norm(x, gamma, beta, smoothing)
            x = relu(x)

        with tf.variable_scope('res2'):
            x = conv(x, channels, kernel=3, stride=1, pad=1, pad_type='reflect', use_bias=use_bias)
            x = adaptive_instance_layer_norm(x, gamma, beta, smoothing)

        return x + x_init

进入adaptive_instance_layer_norm中看一下:

def adaptive_instance_layer_norm(x, gamma, beta, smoothing=True, scope='instance_layer_norm') :
    with tf.variable_scope(scope):
        ch = x.shape[-1]
        eps = 1e-5

        ins_mean, ins_sigma = tf.nn.moments(x, axes=[1, 2], keep_dims=True)
        x_ins = (x - ins_mean) / (tf.sqrt(ins_sigma + eps))

        ln_mean, ln_sigma = tf.nn.moments(x, axes=[1, 2, 3], keep_dims=True)
        x_ln = (x - ln_mean) / (tf.sqrt(ln_sigma + eps))

        rho = tf.get_variable("rho", [ch], initializer=tf.constant_initializer(1.0), constraint=lambda x: tf.clip_by_value(x, clip_value_min=0.0, clip_value_max=1.0))

        if smoothing :
            rho = tf.clip_by_value(rho - tf.constant(0.1), 0.0, 1.0)

        x_hat = rho * x_ins + (1 - rho) * x_ln


        x_hat = x_hat * gamma + beta

        return x_hat

AdaLIN的操作和论文描述一致,代码也很直观。rho是一个trainable parameter,限制在0到1,用来融合LN和IN。最后使用MLP预测的beta和gamma重新denorm。

两个创新点的作用

  • CAM机制的引入:在G和D中都用了CAM,但其作用不一样。G中的CAM的作用是让生成器感知到什么区域是两个域(A,B)差别很大的。D中的CAM的目的是让D了解真假样本哪个位置是差别很大的,以此grident能让G生成更好的样本。
  • AdaLIN:作者认为IN和LN在翻译任务上各有好处。IN有注意更好保留源域的细节,这是由于IN是channel-wise的norm,但风格特性就不够。而LN因为是layer-wise的norm,更好的学到风格的统计量。因此在特征表征上,更希望使用IN保留源域的细节,在解码(decoder)上,更希望利用这些源域的细节特征,转换到风格上,这就是为啥上采样的部分使用的是LN。在上采样前,使用adaLIN,将两种norm的优点吸收,根据两个域的数据分布自己决定偏向IN还是LN,更适合unpair的图像翻译任务。
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值