[GAN03]详解WGAN-GP的pytorch实现中的一些难点

参考代码

DCGAN-GP

G的网络搭建

DIM=64
class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()

        preprocess = nn.Sequential(
            nn.Linear(128, 4*4*4*DIM),
            nn.ReLU(True),
        )
        block1 = nn.Sequential(
            nn.ConvTranspose2d(4*DIM, 2*DIM, 5),
            nn.ReLU(True),
        )
        block2 = nn.Sequential(
            nn.ConvTranspose2d(2*DIM, DIM, 5),
            nn.ReLU(True),
        )
        deconv_out = nn.ConvTranspose2d(DIM, 1, 8, stride=2)

        self.block1 = block1
        self.block2 = block2
        self.deconv_out = deconv_out
        self.preprocess = preprocess
        self.sigmoid = nn.Sigmoid()

    def forward(self, input):
        output = self.preprocess(input)
        output = output.view(-1, 4*DIM, 4, 4)
        #print output.size()
        output = self.block1(output)
        #print output.size()
        output = output[:, :, :7, :7]
        #print output.size()
        output = self.block2(output)
        #print output.size()
        output = self.deconv_out(output)
        output = self.sigmoid(output)
        #print output.size()
        return output.view(-1, OUTPUT_DIM)


我们传一个128维的噪音进去,观察28*28图像的生成过程
在这里插入图片描述

在这里插入图片描述
要想理解这个生成过程,必须知道普通的Conv2D网络output_size和input_size的计算方法:
在这里插入图片描述
Conv2DTranspose是Conv2D的逆转,如果我们想要由Conv2DTranspose完成a*a->b*b的上采样,所需要的参数是b*b->a*a通过Conv2D进行上采样中所用的。

一开始我们传入一个长度为128的一维tensor,这个tensor在经过一层全连接层后,得到4*4*4*64个特征,这些特征是这样分布的:4*64作为深度,4*4作为size,这一步通过一次reshape(即view)实现。
通过输出,我们知道生成的是(2*64,8*8)的feature map,深度的变化是由Conv2DTranspose的深度决定的,而size是由kernal_size,padding和stride决定的,我们知道,这里第一层Conv2DTranspose采用的是kernal_size=5,padding=0(by default),stride=1(by default),如果这是个Conv2D层,他会将inputsize=8转化为(8-5+0)/1+1=4=outputsize,而这是个Conv2DT层,完成相反的工作,得到outputsize=8。
用类似的思路,我们可以计算所有的size变化。

W-GP-Loss的实现

在这里插入图片描述
1.
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

首先,我们只需要知道real_data_v和inputv是一个由real生成的[batchsize,(28,28)]的tensor,将其放入辨别器D,得到[batchsize]个[0,1]之间的得分。
然后,我们对其取均值(目的是将一个batch中的socre相加),作为loss做一次BP。
这里做BP的方法用到了backward的参数(grad_tensor),我们传入一个scalar tensor[-1],这个参数的意思是每一次梯度下降都乘上这个tensor,就形成了paper中的线性Loss,这里real传入-1,fake传入1,实际上倒过来(real传入1,fake传入-1)也是可以的,只要在下面训练G时对应。

在这里插入图片描述

GP函数

原paper
在这里插入图片描述传设入一个[50,28*28]real_tensor。一个[50,28,28]的fake_tensor。
1.融合得到[50,28,28]的alpha。
2.将alpha传入D得到[50,1]的score。
3.score对alpha求导得[50,28*28]的导数gradient,这里是只对传入的alpha求导。注意grad()的返回值加了[0],这是因为原返回值是一个len=1的tuple。
4.gradient.norm(2,dim=1)会对dim=1(即vector)求一次2-范数,这里实际上是对50个长为28*28的gradient_vector分别求了2范数,然后将其减1平方再求平均,得到一个scalar。
注意norm这个函数这里如果不传dim=1,会对这个[50,28*28]的矩阵求矩阵的二范数,而传dim=1之后是对50个vector求向量的二范数。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值