ds证据理论python实现_WGANdiv模型理论以及Python实现

https://arxiv.org/pdf/1712.01026.pdf

WGAN-div很明显是基于WGAN的一个很重要的创新。

WGAN在理论上确实发现了一个GAN存在的收敛性上的问题。在WGAN中,WGAN作者通过提出JS测度(GAN),Wasserstein测度(WGAN)等多种测度的角度出发,去拟合平行线(0, Z)其中Z是[0,1]上的分布。这时候,选取生成器为g_theta(z) = (theta, z)。这时候,就会发现衡量生成器的分布和目标分布(0, Z)直接的测度关系,有:

0c74e2ddcd9420019b87cfd6d74bfa46.png

会发现,这里,只有W测度(EM距离),对应的是连续的,其他却不能保证连续。

换个角度看,这里的theta对应对于模型本身的分布的参数(也就是神经网络G的参数),在输入的z之后的输出分布和原来的真实部分之间是平行关系的时候,其他的测度比如(JS)对应的梯度(相对于模型参数theta)就消失了。

这也就解释了为什么GAN(对应于JS散度),很容易出现梯度消失的问题。

也就会导致模型输出的结果不一定和真实分布的图像很接近。

比如输出一个人,人分为头和脚(假设分布下两者被生成概率相同), 那么完全可以出现将头和脚的位置调换的情况。从测度上看是没有问题的,但是从输出的图像上看就不是我们需要的结果。(也一定程度上解释了GAN的效果不太行的原因)。

这就是为什么大家后来都吹WGAN的原因。毕竟从理论上解释了GAN的收敛不稳定问题。但是Wasserstein测度不好求,于是WGAN就提出处理对应问题的对偶问题,但是却引入了lipschitz约束

这个约束如何在模型的设计中表现出现,就是不同WGAN的设计问题了。

WGAN给出了weight clipping的操作但是不理想。

WGAN-gp给出了gradient penalty的操作。可以说是开了先河(后面的很多WGAN-family模型都是在这个gp上做文章)

但是这一堆WGAN-family的模型中,WGAN-div可以说是集大成者...吧?(其他的我还没实现,反正论文作者把其他都拿出来做对比(论文中显示效果确实更优),可能是理论上有优势吧,后续再看)

WGAN-div重要的地方就是把这个lipschitz约束给去掉了。

讲到这个改进,就需要设计到了一篇97年发的数学论文(55页)(太长, 之后有时间再看看)。emmm做ai都需要去考古以前的数学论文了,感觉宝藏还不少。

Evans, L.C.: Partial differential equations and monge-kantorovich mass transfer. Current developments in mathematics 1997(1) (1997) 65–126 

675e2af34ae56c829e96737ab5d2d00c.png

也就是上面的这个函数,当p这个指数趋于无穷的时候,这个f的对应就是wgan的Wasserstein测度的最优解的负数上。(那这样一样是完成了求解嘛)

而且这个函数是没有lipschitz约束在的,但是仍然存在p是需要趋于无穷的时候,才能保证趋于WGAN给定EM距离的最小的情况。

但是,根据极限的定义,学过数分的都写下面这段话,对任意常数C,存在某个常数G,s.t. 任意k大于G都有f(k) < C。

所以说,我们只需要找个有点大的p就可能够用了。

因此,作者需要做一堆关于p的测试。如下(第二行左图):

2b3cd82480ba869678d52afc97b35a9d.png

因为看到p取6的时候效果就还不错了,所以WGAN-div推荐的超参p取6,同理k取2。


恰饭


实验

做了几组实验测试:

  1. 线性模型+wgan-div

  2. 线性模型+wgan-div+sigmoid

  3. conv测试

  4. conv再测

首先,我是先用DCGAN的直接去改的wgan-div。因为之前的WGANWGAN-gp就是这么成功。

但是我试了很多次之后,发现wgan一直失败,我就在网上找到成功的代码。发现他们都是使用线性模型的,然后就有了实验1。

用他们的模型,成功之后,发现他们居然没给D最后一层放sigmoid。感觉很无语啊。因此就有了实验2。

但我很不服气,如果改成dcgan就不成功了,那么wgan-div感觉也没啥用吧?于是就再试着探索了下为什么加了卷积层不成功。这就有了实验3。

从实验的结果来看,是D中不应该使用BN层。反正加了BN层的之后,模型就崩溃了。(D超早就直接拒绝G(这???不是 梯度消失导致的嘛,wgan不是就是解决这个的嘛,怎么被这玩意搞定了。))

最后再验证是否是BN存在的问题,就把DCGAN中的D的BN删掉之后,再做测试。也就是实验4。

个人猜测(不一定准确):可能还是梯度的问题。本质上还是有没有log嘛。log虽然在接近1的时候, 会很缓。但是在接近0的时候就会相当陡。但是换成wgan这样之后,log被去掉了。那么这么来就导致一开始的时候(数值接近0的时候),梯度太小,训练结果不好。删掉BN之后,使得D进步的慢一点,就不那么容易一开始就拒绝G。(G的零启动问题)

效果提前展示,代码统一放在了最后。

实验一效果:

线性模型+wgan-div

ff8184a6b764d7ec119d0d67352ef7f0.png

935421c4d4b8d56a89334322080fd153.png

15bde24b5fc53c11e3897e67ee7be07f.png

ca38d9671c2cebc6c931015a8480e4ac.png

87263cb376dd0592fc189765004ad01f.png

实验二效果:

线性模型+wgan-div+sigmoid

6d3dc83d3238dd9312df265cfbfa5203.png

65bfee8366df51b1eb28fb8078a5b739.png

8a943383ea3c092583e43fe3baca75e5.png

143e743cb1c6c20c04756fdf31787f8a.png

fed825a315cc42bdcb103aff55180781.png

实验三效果:

conv测试

18e575e471f8dd3e63f98443a096db8b.png

63c2f87f5353d31f87a6b1341f6a4f99.png

a446e3ddb3dd9e89ced133c769d1bb45.png

829e1fc2e95eb0836302555a92f36e5e.png

bbeebe34c676dbe4a490c4ecfc26e7e1.png

实验4效果:

conv再测

9ae80aa8e8ffd0d4f549f46848c503b3.png

cfa11e0316a44293a0a74d4a6581609c.png

714a87543cd0ae539f534a1702429fcc.png

f269bd0d291bcfe890a35903f85adfe0.png

7b55730c5a3cafb0cf282d2240cd4ade.png

实验中线性的部分都是用epoch 50,卷积的部分使用的是epoch20。在这种情况下,实验4仍然是较好的结果。

实验1代码:

main.py

import osimport torchfrom torch.utils.data import Dataset, DataLoaderfrom model import Generator, Discriminator, div_lossimport torchvisionimport matplotlib.pyplot as pltif __name__ == '__main__':    LR = 0.0002    EPOCH = 50  # 50    BATCH_SIZE = 100    N_IDEAS = 100    nc = 2    TRAINED = False    k = 2    p = 6    DOWNLOAD_MNIST = False    mnist_root = '../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)    torch.cuda.empty_cache()    if TRAINED:        G = torch.load('G.pkl').cuda()        D = torch.load('D.pkl').cuda()    else:        G = Generator(N_IDEAS).cuda()        D = Discriminator().cuda()    optimizerG = torch.optim.Adam(G.parameters(), lr=LR)    optimizerD = torch.optim.Adam(D.parameters(), lr=LR)    for epoch in range(EPOCH):        tmpD, tmpG = 0, 0        for step, (x, y) in enumerate(train_loader):            x = x.cuda()            rand_noise = torch.randn((x.shape[0], N_IDEAS)).cuda()            G_imgs = G(rand_noise)            D_fake = torch.squeeze(D(G_imgs))            D_real = torch.squeeze(D(x))            D_real_loss = -torch.mean(D_real)            D_fake_loss = torch.mean(D_fake)            D_loss = D_real_loss + D_fake_loss + k * div_loss(D, x, G_imgs, p=p, cuda=True)            optimizerD.zero_grad()            D_loss.backward(retain_graph=True)            optimizerD.step()            if (step + 1) % nc == 0:                G_loss = -torch.mean(D_fake)                optimizerG.zero_grad()                G_loss.backward(retain_graph=True)                optimizerG.step()                tmpG_ = G_loss.cpu().detach().data                tmpG += tmpG_                tmpD_ = D_loss.cpu().detach().data                tmpD += tmpD_        tmpD /= (step + 1)        tmpG /= (step + 1)        print(            'epoch %d avg of loss: D: %.6f, G: %.6f' % (epoch, tmpD * nc, tmpG * nc)        )        if epoch % 2 == 0:            plt.imshow(torch.squeeze(G_imgs[0].cpu().detach()).numpy())            plt.show()    torch.save(G, 'G.pkl')    torch.save(D, 'D.pkl')

model.py

import osimport torchimport torch.nn as nnimport torch.utils.data as Dataimport torchvisionimport torch.autograd as autogradimport numpy as npclass Generator(nn.Module):    def __init__(self, latent_dim):        super(Generator, self).__init__()        self.img_shape = (1, 28, 28)        def block(in_feat, out_feat, normalize=True):            layers = [nn.Linear(in_feat, out_feat)]            if normalize:                layers.append(nn.BatchNorm1d(out_feat, 0.8))            layers.append(nn.LeakyReLU(0.2, inplace=True))            return layers        self.model = nn.Sequential(            *block(latent_dim, 128, normalize=False),            *block(128, 256),            *block(256, 512),            *block(512, 1024),            nn.Linear(1024, int(np.prod(self.img_shape))),            nn.Tanh()        )    def forward(self, z):        img = self.model(z)        img = img.view(img.shape[0], *self.img_shape)        return imgclass Discriminator(nn.Module):    def __init__(self):        super(Discriminator, self).__init__()        self.img_shape = (1, 28, 28)        self.model = nn.Sequential(            nn.Linear(int(np.prod(self.img_shape)), 512),            nn.LeakyReLU(0.2, inplace=True),            nn.Linear(512, 256),            nn.LeakyReLU(0.2, inplace=True),            nn.Linear(256, 1),        )    def forward(self, img):        img_flat = img.view(img.shape[0], -1)        validity = self.model(img_flat)        return validitydef div_loss(D, real_x, fake_x, p=6, cuda=False):    if cuda:        alpha = torch.rand((real_x.shape[0], 1, 1, 1)).cuda()    else:        alpha = torch.rand((real_x.shape[0], 1, 1, 1))    x_ = (alpha * real_x + (1-alpha) * fake_x).requires_grad_(True)    y_ = D(x_)    # cal f'(x)    grad = autograd.grad(        outputs=y_,        inputs=x_,        grad_outputs=torch.ones_like(y_),        create_graph=True,        retain_graph=True,        only_inputs=True,    )[0]    grad = grad.view(x_.shape[0], -1)    div = (grad.norm(2, dim=1) ** p).mean()    return divif __name__ == '__main__':    N_IDEAS = 100    G = Generator(N_IDEAS, )    # rand_noise = torch.randn((10, N_IDEAS, 1, 1))    # print(G(rand_noise).shape)    DOWNLOAD_MNIST = False    mnist_root = '../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    D = Discriminator()    print(len(train_data))    train_loader = Data.DataLoader(dataset=train_data, batch_size=2, shuffle=True)    for step, (x, y) in enumerate(train_loader):        print(x.shape)        print(D(x).shape)        rand_noise = torch.randn((x.shape[0], N_IDEAS))  # .cuda()        G_imgs = G(rand_noise)        print(div_loss(D, x, G_imgs))        break

judge.py

import numpy as npimport torchimport matplotlib.pyplot as pltfrom model import Generator, Discriminatorimport torchvision.utils as vutilsif __name__ == '__main__':    BATCH_SIZE = 100    N_IDEAS = 100    img_shape = (1, 28, 28)    TIME = 5    G = torch.load("G.pkl").cuda()    for t in range(TIME):        rand_noise = torch.randn((BATCH_SIZE, N_IDEAS)).cuda()        G_imgs = G(rand_noise).cpu().detach()        fig = plt.figure(figsize=(10, 10))        plt.axis("off")        plt.imshow(np.transpose(vutils.make_grid(G_imgs, nrow=10, padding=0, normalize=True, scale_each=True), (1, 2, 0)))        plt.savefig(str(t) + '.png')        plt.show()

实验2代码

相比于实验一只是改了下model.py

import osimport torchimport torch.nn as nnimport torch.utils.data as Dataimport torchvisionimport torch.autograd as autogradimport numpy as npclass Generator(nn.Module):    def __init__(self, latent_dim):        super(Generator, self).__init__()        self.img_shape = (1, 28, 28)        def block(in_feat, out_feat, normalize=True):            layers = [nn.Linear(in_feat, out_feat)]            if normalize:                layers.append(nn.BatchNorm1d(out_feat, 0.8))            layers.append(nn.LeakyReLU(0.2, inplace=True))            return layers        self.model = nn.Sequential(            *block(latent_dim, 128, normalize=False),            *block(128, 256),            *block(256, 512),            *block(512, 1024),            nn.Linear(1024, int(np.prod(self.img_shape))),            nn.Tanh()        )    def forward(self, z):        img = self.model(z)        img = img.view(img.shape[0], *self.img_shape)        return imgclass Discriminator(nn.Module):    def __init__(self):        super(Discriminator, self).__init__()        self.img_shape = (1, 28, 28)        self.model = nn.Sequential(            nn.Linear(int(np.prod(self.img_shape)), 512),            nn.LeakyReLU(0.2, inplace=True),            nn.Linear(512, 256),            nn.LeakyReLU(0.2, inplace=True),            nn.Linear(256, 1),            nn.Sigmoid()        )    def forward(self, img):        img_flat = img.view(img.shape[0], -1)        validity = self.model(img_flat)        return validitydef div_loss(D, real_x, fake_x, p=6, cuda=False):    if cuda:        alpha = torch.rand((real_x.shape[0], 1, 1, 1)).cuda()    else:        alpha = torch.rand((real_x.shape[0], 1, 1, 1))    x_ = (alpha * real_x + (1-alpha) * fake_x).requires_grad_(True)    y_ = D(x_)    # cal f'(x)    grad = autograd.grad(        outputs=y_,        inputs=x_,        grad_outputs=torch.ones_like(y_),        create_graph=True,        retain_graph=True,        only_inputs=True,    )[0]    grad = grad.view(x_.shape[0], -1)    div = (grad.norm(2, dim=1) ** p).mean()    return divif __name__ == '__main__':    N_IDEAS = 100    G = Generator(N_IDEAS, )    # rand_noise = torch.randn((10, N_IDEAS, 1, 1))    # print(G(rand_noise).shape)    DOWNLOAD_MNIST = False    mnist_root = '../../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    D = Discriminator()    print(len(train_data))    train_loader = Data.DataLoader(dataset=train_data, batch_size=2, shuffle=True)    for step, (x, y) in enumerate(train_loader):        print(x.shape)        print(D(x).shape)        rand_noise = torch.randn((x.shape[0], N_IDEAS))  # .cuda()        G_imgs = G(rand_noise)        print(div_loss(D, x, G_imgs))        break

实验3代码

因为G这时候前面是加了线性映射层的,所以就不用改其他代码,只需要修改model.py就好了。

import osimport torchimport torch.nn as nnimport torch.utils.data as Dataimport torchvisionimport torch.autograd as autogradimport numpy as npdef conv_T_block(in_feat, out_feat, normalize=True):    layers = [nn.ConvTranspose2d(in_feat, out_feat, kernel_size=4, stride=2, padding=1)]    if normalize:        layers.append(nn.BatchNorm2d(out_feat, 0.8))    layers.append(nn.LeakyReLU(0.2, inplace=True))    return layersdef conv_block(in_feat, out_feat, normalize=True):    layers = [nn.Conv2d(in_feat, out_feat, kernel_size=4, stride=2, padding=1)]    if normalize:        layers.append(nn.BatchNorm2d(out_feat, 0.8))    layers.append(nn.LeakyReLU(0.2, inplace=True))    return layersdef block(in_feat, out_feat, normalize=True):    layers = [nn.Linear(in_feat, out_feat)]    if normalize:        layers.append(nn.BatchNorm1d(out_feat, 0.8))    layers.append(nn.LeakyReLU(0.2, inplace=True))    return layersclass Generator(nn.Module):    def __init__(self, latent_dim):        super(Generator, self).__init__()        self.img_shape = (1, 28, 28)        self.init_img_shape = (64, 7, 7)        self.fc = nn.Sequential(            *block(latent_dim, np.prod(self.init_img_shape), normalize=False),        )        self.model = nn.Sequential(            *conv_T_block(self.init_img_shape[0], self.init_img_shape[0] // 2),            *conv_T_block(self.init_img_shape[0] // 2, 1),            nn.Tanh()        )    def forward(self, z):        img = self.fc(z).view(z.shape[0], *self.init_img_shape)        img = self.model(img)        return imgclass Discriminator(nn.Module):    def __init__(self):        super(Discriminator, self).__init__()        self.img_shape = (1, 28, 28)        self.final_img_shape = (64, 7, 7)        self.model = nn.Sequential(            *conv_block(self.img_shape[0], self.final_img_shape[0] // 2, normalize=False),            *conv_block(self.final_img_shape[0] // 2, self.final_img_shape[0], normalize=False)        )        self.fc = nn.Sequential(            nn.Linear(int(np.prod(self.final_img_shape)), 256),            nn.LeakyReLU(0.2, inplace=True),            nn.Linear(256, 1),            nn.Sigmoid()        )    def forward(self, img):        img_conv = self.model(img)        img_flat = img_conv.view(img.shape[0], -1)        validity = self.fc(img_flat)        return validitydef div_loss(D, real_x, fake_x, p=6, cuda=False):    if cuda:        alpha = torch.rand((real_x.shape[0], 1, 1, 1)).cuda()    else:        alpha = torch.rand((real_x.shape[0], 1, 1, 1))    x_ = (alpha * real_x + (1 - alpha) * fake_x).requires_grad_(True)    y_ = D(x_)    # cal f'(x)    grad = autograd.grad(        outputs=y_,        inputs=x_,        grad_outputs=torch.ones_like(y_),        create_graph=True,        retain_graph=True,        only_inputs=True,    )[0]    grad = grad.view(x_.shape[0], -1)    div = (grad.norm(2, dim=1) ** p).mean()    return divif __name__ == '__main__':    N_IDEAS = 100    G = Generator(N_IDEAS)    rand_noise = torch.randn((10, N_IDEAS))    print(G(rand_noise).shape)    DOWNLOAD_MNIST = False    mnist_root = '../../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    D = Discriminator()    print(len(train_data))    train_loader = Data.DataLoader(dataset=train_data, batch_size=2, shuffle=True)    for step, (x, y) in enumerate(train_loader):        print(x.shape)        print(D(x).shape)        rand_noise = torch.randn((x.shape[0], N_IDEAS))  # .cuda()        G_imgs = G(rand_noise)        print(div_loss(D, x, G_imgs))        break

实验4代码

相比起来,因为需要同时修改输入给G的z的规模并且最后的结果也是最优的,因此这里就放一下完整代码。

main.py

import osimport torchfrom torch.utils.data import Dataset, DataLoaderfrom model import Generator, Discriminator, div_lossimport torchvisionimport matplotlib.pyplot as pltif __name__ == '__main__':    LR = 0.0002    EPOCH = 20  # 50    BATCH_SIZE = 100    N_IDEAS = 100    nc = 2    TRAINED = False    k = 2    p = 6    DOWNLOAD_MNIST = False    mnist_root = '../../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)    torch.cuda.empty_cache()    if TRAINED:        G = torch.load('G.pkl').cuda()        D = torch.load('D.pkl').cuda()    else:        G = Generator(N_IDEAS).cuda()        D = Discriminator().cuda()    optimizerG = torch.optim.Adam(G.parameters(), lr=LR)    optimizerD = torch.optim.Adam(D.parameters(), lr=LR)    for epoch in range(EPOCH):        tmpD, tmpG = 0, 0        for step, (x, y) in enumerate(train_loader):            x = x.cuda()            rand_noise = torch.randn((x.shape[0], N_IDEAS, 1, 1)).cuda()            G_imgs = G(rand_noise)            D_fake = torch.squeeze(D(G_imgs))            D_real = torch.squeeze(D(x))            D_real_loss = -torch.mean(D_real)            D_fake_loss = torch.mean(D_fake)            D_loss = D_real_loss + D_fake_loss + k * div_loss(D, x, G_imgs, p=p, cuda=True)            optimizerD.zero_grad()            D_loss.backward(retain_graph=True)            optimizerD.step()            if (step + 1) % nc == 0:                G_loss = -torch.mean(D_fake)                optimizerG.zero_grad()                G_loss.backward(retain_graph=True)                optimizerG.step()                tmpG_ = G_loss.cpu().detach().data                tmpG += tmpG_                tmpD_ = D_loss.cpu().detach().data                tmpD += tmpD_        tmpD /= (step + 1)        tmpG /= (step + 1)        print(            'epoch %d avg of loss: D: %.6f, G: %.6f' % (epoch, tmpD * nc, tmpG * nc)        )        if epoch % 2 == 0:            plt.imshow(torch.squeeze(G_imgs[0].cpu().detach()).numpy())            plt.show()    torch.save(G, 'G.pkl')    torch.save(D, 'D.pkl')

model.py

import osimport torch.autograd as autogradimport torchimport torch.nn as nnimport torch.utils.data as Dataimport torchvisionfrom torch.utils.data import DataLoaderclass Generator(nn.Module):    def __init__(self, input_size):        super(Generator, self).__init__()        strides = [1, 2, 2, 2]        padding = [0, 1, 1, 1]        channels = [input_size,                    256, 128, 64, 1]  # 1表示一维        kernels = [4, 3, 4, 4]        model = []        for i, stride in enumerate(strides):            model.append(                nn.ConvTranspose2d(                    in_channels=channels[i],                    out_channels=channels[i + 1],                    stride=stride,                    kernel_size=kernels[i],                    padding=padding[i]                )            )            if i != len(strides) - 1:                model.append(                    nn.BatchNorm2d(channels[i + 1], 0.8)                )                model.append(                    nn.LeakyReLU(.2)                )            else:                model.append(                    nn.Tanh()                )        self.main = nn.Sequential(*model)    def forward(self, x):        x = self.main(x)        return xclass Discriminator(nn.Module):    def __init__(self, input_size=1):        super(Discriminator, self).__init__()        strides = [2, 2, 2, 1]        padding = [1, 1, 1, 0]        channels = [input_size,                    64, 128, 256, 1]  # 1表示一维        kernels = [4, 4, 4, 3]        model = []        for i, stride in enumerate(strides):            model.append(                nn.Conv2d(                    in_channels=channels[i],                    out_channels=channels[i + 1],                    stride=stride,                    kernel_size=kernels[i],                    padding=padding[i]                )            )            if i != len(strides) - 1:                model.append(                    nn.LeakyReLU(0.2)                )            else:                model.append(                    nn.Sigmoid()                )        self.main = nn.Sequential(*model)    def forward(self, x):        x = self.main(x)        return xdef div_loss(D, real_x, fake_x, p=6, cuda=False):    if cuda:        alpha = torch.rand((real_x.shape[0], 1, 1, 1)).cuda()    else:        alpha = torch.rand((real_x.shape[0], 1, 1, 1))    x_ = (alpha * real_x + (1 - alpha) * fake_x).requires_grad_(True)    y_ = D(x_)    # cal f'(x)    grad = autograd.grad(        outputs=y_,        inputs=x_,        grad_outputs=torch.ones_like(y_),        create_graph=True,        retain_graph=True,        only_inputs=True,    )[0]    grad = grad.view(x_.shape[0], -1)    div = (grad.norm(2, dim=1) ** p).mean()    return divif __name__ == '__main__':    N_IDEAS = 100    G = Generator(N_IDEAS, )    rand_noise = torch.randn((10, N_IDEAS, 1, 1))    print(G(rand_noise).shape)    DOWNLOAD_MNIST = False    mnist_root = '../../Conditional-GAN/mnist/'    if not (os.path.exists(mnist_root)) or not os.listdir(mnist_root):        # not mnist dir or mnist is empyt dir        DOWNLOAD_MNIST = True    train_data = torchvision.datasets.MNIST(        root=mnist_root,        train=True,  # this is training data        transform=torchvision.transforms.ToTensor(),  # Converts a PIL.Image or numpy.ndarray to        # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]        download=DOWNLOAD_MNIST,    )    D = Discriminator(1)    print(len(train_data))    train_loader = Data.DataLoader(dataset=train_data, batch_size=2, shuffle=True)    for step, (x, y) in enumerate(train_loader):        print(x.shape)        print(D(x).shape)        break

judge.py

import numpy as npimport torchimport matplotlib.pyplot as pltfrom model import Generator, Discriminatorimport torchvision.utils as vutilsif __name__ == '__main__':    BATCH_SIZE = 100    N_IDEAS = 100    img_shape = (1, 28, 28)    TIME = 5    G = torch.load("G.pkl").cuda()    for t in range(TIME):        rand_noise = torch.randn((BATCH_SIZE, N_IDEAS, 1, 1)).cuda()        G_imgs = G(rand_noise).cpu().detach()        fig = plt.figure(figsize=(10, 10))        plt.axis("off")        plt.imshow(np.transpose(vutils.make_grid(G_imgs, nrow=10, padding=0, normalize=True, scale_each=True), (1, 2, 0)))        plt.savefig(str(t) + '.png')        plt.show()

ff860dd6ed9e5cd5b32e517e06fdc88d.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值