精华内容
下载资源
问答
  • 本地图片转换成网络链接图片
    千次阅读
    2020-11-19 13:51:14

    有时候我们需要将几张图片生成链接或者二维码,方便进行各种场景的展示和分享。因为链接是可以在各种设备和系统打开的。比如微信好友或朋友圈发一些类似H5页面的链接,类似于公众号一样自带缩略图和简介的小方格.如果自己去申请公众号来设置,会异常复杂.我们知道公众号虽然门槛低,但是从来没有接触过的人会在使用上有困难。但是有一些简单好用的方法也一样可以达到这个效果。

    qr.maitube.com 麦瓜图床

    首先我们打个腹稿,在心中想一想如何设置自己的微信分享小方块。比如:显示什么图片,什么标题,什么简介这三点。因为您上传的第一张图片将作为微信缩略图展示的小方格。

    我们进入图床制作器进行图片的上传和阅读次数的设置比如麦瓜图床。如果对展示顺序有要求的,可以将图片按字母或者数字的排列顺序进行图片的命名。然后我们就可以将图片进行上传了。

    上传之后,会提示是否上传成功。待上传成功之后,我们再进行下一步的设置,图片链接打开的次数和每次的阅读时间。如果想设置阅后即焚的效果,可以设置打开次数1,阅读时间60秒,这样别人在打开一次之后就无法打开第二次了。

    我们在生成链接之后就可以分享出去了!有两种方式可以展示图片,一种是滑动的轮播图片,还有一种是非常适合长图的自适应轮播图。
    而且我们还可以根据追踪链接来进行阅读记录的查看!

    有时候我们需要将pdf分享给他人,不是每一个app都兼容pdf的

    首先我们打开maipdf的网站,因为市场上做pdf安全分析的网站非常少,所以建议使用maipdf

    打开网站之后,选择您需要分享的pdf文件进行上传

    生成后的链接您可以打开看到您的pdf文件,并且在改页面下,pdf文件是不能复制,打印和下载的。100%安全的pdf文件分享网站。

    更多相关内容
  • GAN (生成对抗网络) 手写数字图片生成 文章目录GAN (生成对抗网络) 手写数字图片生成Discriminator NetworkGenerator Network简单版本的生成对抗网络判别器 Discriminator生成器 Generator超参数设置训练网络生成...

    GAN (生成对抗网络) 手写数字图片生成


    这种训练方式定义了一种全新的网络结构,就是生成对抗网络,也就是 GANs。这一部分,我们会形象地介绍生成对抗网络,以及用代码进行实现,而在书中会更加详细地介绍 GANs 的数学推导。

    根据这个名字就可以知道这个网络是由两部分组成的,第一部分是生成,第二部分是对抗。简单来说,就是有一个生成网络和一个判别网络,通过训练让两个网络相互竞争,生成网络来生成假的数据,对抗网络通过判别器去判别真伪,最后希望生成器生成的数据能够以假乱真。

    可以用这个图来简单的看一看这两个过程

    Discriminator Network

    首先我们来讲一下对抗过程,因为这个过程更加简单。

    对抗过程简单来说就是一个判断真假的判别器,相当于一个二分类问题,我们输入一张真的图片希望判别器输出的结果是1,输入一张假的图片希望判别器输出的结果是0。这其实已经和原图片的 label 没有关系了,不管原图片到底是一个多少类别的图片,他们都统一称为真的图片,label 是 1 表示真实的;而生成的假的图片的 label 是 0 表示假的。

    我们训练的过程就是希望这个判别器能够正确的判出真的图片和假的图片,这其实就是一个简单的二分类问题,对于这个问题可以用我们前面讲过的很多方法去处理,比如 logistic 回归,深层网络,卷积神经网络,循环神经网络都可以。

    Generator Network

    接着我们看看生成网络如何生成一张假的图片。首先给出一个简单的高维的正态分布的噪声向量,如上图所示的 D-dimensional noise vector,这个时候我们可以通过仿射变换,也就是 xw+b 将其映射到一个更高的维度,然后将他重新排列成一个矩形,这样看着更像一张图片,接着进行一些卷积、转置卷积、池化、激活函数等进行处理,最后得到了一个与我们输入图片大小一模一样的噪音矩阵,这就是我们所说的假的图片。

    这个时候我们如何去训练这个生成器呢?这就需要通过对抗学习,增大判别器判别这个结果为真的概率,通过这个步骤不断调整生成器的参数,希望生成的图片越来越像真的,而在这一步中我们不会更新判别器的参数,因为如果判别器不断被优化,可能生成器无论生成什么样的图片都无法骗过判别器。

    生成器的效果可以看看下面的图示

    关于生成对抗网络,出现了很多变形,比如 WGAN,LS-GAN 等等,这一节我们只使用 mnist 举一些简单的例子来说明,更复杂的网络结构可以再 github 上找到相应的实现

    简单版本的生成对抗网络

    通过前面我们知道生成对抗网络有两个部分构成,一个是生成网络,一个是对抗网络,我们首先写一个简单版本的网络结构,生成网络和对抗网络都是简单的多层神经网络

    所以,如果我们需要完成一个生成对抗网络,我们需要一个生成器判别器

    判别器 Discriminator

    判别网络的结构非常简单,就是一个二分类器,结构如下:

    • 全连接(784 -> 1024)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(1024 -> 512)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(512 -> 256)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(256 -> 1)
    • Sigmoid

    其中 leakyrelu 是指 f(x) = max( α \alpha α x, x)

    我们判别网络实际上就是一个二分类器,我们需要判断我们的图片是真还是假

    class discriminator(nn.Module):
        def __init__(self,input_size):
            super(discriminator,self).__init__()
            
            self.dis = nn.Sequential(
                nn.Linear(input_size, 1024),
                nn.LeakyReLU(0.2),
                nn.Dropout(0.3),
                nn.Linear(1024, 512),
                nn.LeakyReLU(0.2),
                nn.Dropout(0.3),
                nn.Linear(512, 256),
                nn.LeakyReLU(0.2),
                nn.Dropout(0.3),
                nn.Linear(256, 1),
                nn.Sigmoid()
            )
        def forward(self,x):
            out = self.dis(x)
            return out
    

    生成器 Generator

    接下来我们看看生成网络,生成网络的结构也很简单,就是根据一个随机噪声生成一个和数据维度一样的张量,结构如下:

    • 全连接(噪音维度 -> 256)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(256 -> 512)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(512 -> 1024)
    • leakyrelu, α \alpha α 是 0.2
    • 全连接(1024 -> 784)
    • tanh 将数据裁剪到 -1 ~ 1 之间
    class generator(nn.Module):
        def __init__(self, noise_dim):
            super(generator,self).__init__()
            
            self.gen = nn.Sequential(
                nn.Linear(noise_dim, 256),
                nn.LeakyReLU(0.2),
                nn.Linear(256, 512),
                nn.LeakyReLU(0.2),
                nn.Linear(512, 1024),
                nn.LeakyReLU(0.2),
                nn.Linear(1024, 784),
                nn.Tanh()
            )
            
        def forward(self, x):
            out = self.gen(x)
            return out
    

    超参数设置

    对于对抗网络,相当于二分类问题,将真的判别为真的,假的判别为假的,作为辅助,可以参考一下论文中公式

    ℓ D = E x ∼ p data [ log ⁡ D ( x ) ] + E z ∼ p ( z ) [ log ⁡ ( 1 − D ( G ( z ) ) ) ] \ell_D = \mathbb{E}_{x \sim p_\text{data}}\left[\log D(x)\right] + \mathbb{E}_{z \sim p(z)}\left[\log \left(1-D(G(z))\right)\right] D=Expdata[logD(x)]+Ezp(z)[log(1D(G(z)))]
    而对于生成网络,需要去骗过对抗网络,也就是将假的也判断为真的,作为辅助,可以参考一下论文中公式

    ℓ G = E z ∼ p ( z ) [ log ⁡ D ( G ( z ) ) ] \ell_G = \mathbb{E}_{z \sim p(z)}\left[\log D(G(z))\right] G=Ezp(z)[logD(G(z))]
    如果你还记得前面的二分类 loss,那么你就会发现上面这两个公式就是二分类 loss

    b c e ( s , y ) = y ∗ log ⁡ ( s ) + ( 1 − y ) ∗ log ⁡ ( 1 − s ) bce(s, y) = y * \log(s) + (1 - y) * \log(1 - s) bce(s,y)=ylog(s)+(1y)log(1s)
    如果我们把 D(x) 看成真实数据的分类得分,那么 D(G(z)) 就是假数据的分类得分,所以上面判别器的 loss 就是将真实数据的得分判断为 1,假的数据的得分判断为 0,而生成器的 loss 就是将假的数据判断为 1

    criterion = nn.BCELoss()
    d_optimizer = torch.optim.Adam(D.parameters(), lr=3e-4, betas=(0.5, 0.999))
    g_optimizer = torch.optim.Adam(G.parameters(), lr=3e-4, betas=(0.5, 0.999))
    

    训练网络生成图片

    d_losses = []
    g_losses = []
    iter_count = 0
    for i in range(nepochs):
        for img,_ in train_loader:
            num_img = img.shape[0] # 图片的数量
            real_img = img.view(num_img,-1) 
            real_img = real_img.to(device) # 真实图片
            real_label = Variable(torch.ones(num_img,1)).to(device) # 随机得到单位张量作为真实标签 1
            fake_label = Variable(torch.zeros(num_img,1)).to(device) # 随机得到零张量作为假标签 0
            
            real_out = D(real_img) # 判别真实图片
    #         print(real_out.shape)
            
            d_loss_real = criterion(real_out,real_label) # 真实图片的损失
            real_scores = real_out
            
            z = torch.randn(num_img, NOISE).to(device) # 随机生成z NOISE造成的数据
            fake_img = G(z) # 生成假图片
            fake_out = D(fake_img) # 得到D(G(z))
            d_loss_fake = criterion(fake_out,fake_label) # log(1-D(G(z)))
            fake_scores = fake_out
            
            d_loss = d_loss_real + d_loss_fake # 总的损失 x-logD(x) + z-log(1-D(G(z))) 
            d_optimizer.zero_grad() # 梯度归0
            d_loss.backward() # 反向传播
            d_optimizer.step() # 更新生成网络的参数
            
            z = torch.randn(num_img, NOISE).to(device) # 随机生成z NOISE造成的数据
            fake_img = G(z) # 生成图片
            output = D(fake_img) # 经过判别器得到结果
            g_loss = criterion(output, real_label) # 得到假的图片和真实图片的label的loss log(D(G(z)))
            
            g_optimizer.zero_grad() # 归0梯度
            g_loss.backward() # 反向传播
            g_optimizer.step() # 更新生成网络的参数
    
            if (iter_count % 250 == 0):
    #                 display.clear_output(True)
                    print('Iter: {}, D: {:.4}, G:{:.4}'.format(iter_count, d_loss.data, g_loss.data))
                    d_losses.append(d_loss),g_losses.append(g_loss)
                    imgs_numpy = deprocess_img(fake_img.data.cpu().numpy())
                    show_images(imgs_numpy[0:16])
                    plt.savefig("images/%d.png" % iter_count) # 每250次保存一次图片
                    plt.show()
                    print()
            iter_count += 1
    

    Iter: 0, D: 1.364, G:0.6648
    在这里插入图片描述

    Iter: 250, D: 1.362, G:0.8941
    在这里插入图片描述

    Iter: 93500, D: 1.331, G:0.8405
    在这里插入图片描述
    Iter: 93750, D: 1.303, G:0.7253
    在这里插入图片描述

    我们可以看到,到后面,我们基本可以看到了一个比较好的数字样本图片了,而这些图片都是假的图片,是靠我们的GAN生成出来的,从一开始全是噪声,慢慢的生成这样,还是很不错的,不够迭代了比较长的时间。

    我们已经完成了一个简单的生成对抗网络,是不是非常容易呢。但是可以看到效果并不是特别好,迭代的次数有点多,因为我们仅仅使用了简单的多层全连接网络。除了这种最基本的生成对抗网络之外,还有很多生成对抗网络的变式,有结构上的变式,也有 loss 上的变式,不过这些,就留到下次再说吧。

    展开全文
  • 如果是刚入深度学习的新手小白,可能有着只学习了一点深度学习的理论,也见识到了各种神经网络的强大而不能立马实现的烦恼,想学习TensorFlow,pytorch等出色强大的深度学习框架,又看到那代码晦涩难懂而有些想...

    1. 写在前面

    如果是刚入深度学习的新手小白,可能有着只学习了一点深度学习的理论,也见识到了各种神经网络的强大而不能立马实现的烦恼,想学习TensorFlow,pytorch等出色强大的深度学习框架,又看到那代码晦涩难懂而有些想知难而退,这时候,我觉得有必要掌握一下Keras了,这是个啥? Keras是高级神经网络API,因为Keras短小精悍,非常适合快速原型制作和神经网络的搭建。在很短的时间内,就能够建立一个模型,以实现出色的结果,让神经网络的搭建像积木一样简单,更重要的一点学习深度学习网络,能快速实现,有满满的成就感,不仅可以增加对知识的理解,更可以给自己提供源源不断的学习动力。

    基于这些,想把自己学习Keras的经历整理一下,因为我也是小白学起,正好边学边整理。 最近又正好看了《将夜》,发现昊天世界的修炼等级名称比较有趣(初识,感知,不惑,洞玄,知命),所以为了增加趣味性,把Keras学习系列的名字和修炼级别关联起来了,因为我们学习本身就是一场修行。

    深度学习框架经过更新很快,TensorFlow,Pytorch等传播盛行,但短小精悍的Keras在未来仍会占据一席之地,并长期占据下去

    如果学习了深度学习框架之Keras初识:像搭积木般的玩转神经网络,那么恭喜你进入了感知境, 感知境中我们要完成下面的任务:

    五篇文章,五个项目,就可以用Keras玩转DNN, CNN, RNN, GAN。 今天是感知的第二篇文章,用Keras搭建生成对抗网络生成自己想要的图片,在前面那篇文章中,我们用CNN进行了手写数字识别的分类,在这篇文章,我们会用Keras的Sequential方式建立DCGAN网络生成手写数字的数据集,然后再用Keras的Model方式建立DCGAN网络生成彩色的青蛙图片,这样也顺便复习一下初识境的知识。 但是在这之前,我们得需要学习一下GAN的工作原理,当然这里我也会再简单解释一遍,如果想知道GAN的详细细节,可以先看一下我们真的了解生成式对抗网络GAN的工作原理吗?(白话+数学公式推导)这篇文章,算是先修知识吧, 好了,话不多说,现在开始。

    知识框架

    • 简单说一下GAN的工作原理(还是以生成手写数字识别为例)和DCGAN
    • Keras搭建DCGAN网络生成手写数字图片(一维黑白)
    • Keras搭建DCGAN网络生成青蛙图片(彩色三维)

    OK, let’s go!

    2. GAN的工作原理

    GAN 的基本原理就在于两个网络:G(Generator)和D(Discriminator),分别是生成器和判别器。

    生成器网络以一个随机向量作为输入,并将其解码生成为一张图像,而判别器一张真实或者合成的图像作为输入,并预测该图像是来自于真实数据还是合成的图像。

    在训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量把G生成的图片和真实的图片分别开来。这样,G和D构成了一个动态的“博弈过程”。在理想状态下,博弈的结果就是G可以生成足以以假乱真的图片G(z),而此时的 D 难以判定生成的图像到底是真是假,最后得到D(G(z)) = 0.5的结果。这块的理解跟博弈论中零和博弈非常类似,可以说 GAN 借鉴了博弈论中相关的思想和方法。

    还是引用我上篇文章的手写数字识别的例子,这样下面编程实现的时候也更容易理解些,假设我想生成手写数字,我们应该怎么办呢?

    准备工作

    1. 首先, 我们要准备1000张真实的手写数字图片,也就是从手写数字数据集中选出1000张来。

      然后,我要搭建一个生成器(就理解成一个神经网络就可以),这个生成器的任务就是我输入一个向量,你输出给我一张图片即可。 再搭建一个判别器(也是一个神经网络),这个判别器的任务就是我给你一张我生成器的图片和一张真实的图片,你给我做一个二分类问题就可以了。

    2. 然后我们开始训练两个网络(这是重点,看看究竟怎么训练让它们变强的)

      首先,我先让生成器V1随机生成1000张图片(不管图片内容,随机生成即可)并给这些图片打上0标签,然后我把1000张真实的图片打上1标签和上面1000张混合组成一个训练集,去训练我的判别器V1,由于这两种图片相差很大,判别器V1很快就能够看出来哪些是真正的手写数字图片,哪些生成器V1伪造的假图片。

      然后,我们得训练生成器V1,让它提高一下伪造图片的技能(这样一下子就露馅了可不好),怎么做呢? 这时候我们冻结住判别器V1的参数不让他训练,只训练生成器V1的参数(先理解成生成器和判别器是可以搭建到一块的),训练的方式就是不断的调整生成器V1的参数,让判别器V1生成1(目前不是手写数字识别生成的是0),这样训练完了之后,就说明生成器V1生成的图片判别器V1已经判别成真实的手写数字图片了,这样生成器V1的伪造水平提高,我们赋予它一个新的名字生成器V2

      接下来,我们得提高判别器V1的判别水平了,因为它已经无法判别出生成器V2生成的图片和真实的图片的区别。这时候,我们冻结住生成器V2的参数不进行训练,只训练判别器V1的参数,方式就是生成器V2生成的图片为0, 真实图片为1,混合作为训练集让判别器V1做二分类的问题进行参数调整,这样,当准确率很高的时候,判别器V1的判别能力提高了,能够区分出生成器V2生成的图片和真实图片了。 我们把这个判别器赋予新的名字:判别器V2。

      这样我们就完成了一轮生成器和判别器的训练,两者都升级到了V2水平,接下来和上面的思想一样,冻结判别器V2的参数,以判别器V2输出1为目标去调生成器V2的参数,直到这个目标达成,就说明生成器V2的伪造水平进一步提高,判别器V2不行了,接下来,让生成器V3生成图片标0,真实图片标1再次训练判别器V2,这样就完成了两者的又一轮升级。

      重复上面的步骤,直到生成器能够达到以假乱真的地步。

    这样我们的目标就达成了,当缺少手写数字训练样本的时候,就可以利用这里锻炼的生成器进行图片生成供我们使用。当然换成别的图片一个道理。

    好了,下面就可以根据上面说的过程,我们看看用Keras怎么实现DCGAN模型,来完成这个任务,DCGAN的原始论文为 “UNSUPERVISED REPRESENTATION LEARNING WITH DEEP CONVOLUTIONAL GENERATIVE ADVERSARIAL NETWORKS”,所谓DCGAN,顾名思义就是生成器和判别器都是深度卷积神经网络的GAN。

    3. Keras搭建DCGAN网络生成手写数字图片

    搭建一个稳健的DCGAN主要在于:

    • 所有的pooling层使用步幅卷积(判别网络)和微步幅度卷积(生成网络)进行替换。
    • 在生成网络和判别网络上使用批处理规范化。
    • 对于更深的架构移除全连接隐藏层。
    • 在判别网络的所有层上使用LeakyReLU激活函数。
    • 在生成网络的所有层上使用ReLU激活函数

    好了,下面我们就搭建深度卷积生成对抗网络完成任务, 我们边搭建边回忆上面的过程哈:

    • 导入包

      # 导入包的时候先从必备包开始
      import numpy as np
      import pandas as pd
      import matplotlib.pyplot as plt
      
      # Keras的包, 搭建神经网络用的包
      from keras.models import Sequential
      from keras.layers import Dense, Activation, Flatten, Reshape
      from keras.layers import Conv2D, Conv2DTranspose, UpSampling2D
      from keras.layers import LeakyReLU, Dropout
      from keras.layers import BatchNormalization
      from keras.optimizers import RMSprop
      
      # 设置相关参数
      latent_dim = 100  # 这个是那个生成器接收的向量的维度,这个向量经过生成器后产生手写数字图片
      
      # 手写数字图片的大小和维度
      img_rows = 28
      img_cols = 28
      channel = 1
      
    • 下面我们用Keras建立生成器G(Sequential方法)

      dim = 7
      depth = 64 + 64 + 64 + 64
      dropout = 0.4
      
      # 搭积木生成生成器
      G = Sequential()
      # In: 100   out: dim x dim x depth
      G.add(Dense(dim*dim*depth, input_dim=100))
      G.add(BatchNormalization(momentum=0.9))
      G.add(Activation('relu'))
      G.add(Reshape((dim, dim, depth))
      G.add(Dropout(dropout))
      
      # In: dim x dim x depth    out: 2*dim x 2*dim x depth/2
      G.add(UpSampling2D())   # 上采样函数(2,2)  x表示放大倍数,这里取2代表原来的一行变成了两行(也就是每一行和每一列复制了一下,使得字迹加粗)
      G.add(Conv2DTranspose(int(depth/2), 5, padding='same'))   # 卷积的逆操作
      G.add(BatchNormalization(momentum=0.9)
      G.add(Activation('relu'))
      
      # In: 2*dim x 2*dim x depth/2   Out:4*dim * 4*dim * depth/4
      G.add(UpSampling2D())
      G.add(Conv2DTranspose(int(depth/4), 5, padding='same'))
      G.add(BatchNormalization(momentum=0.9))
      G.add(Activation('relu'))
      
      # In: 4*dim * 4*dim * depth/4   Out: 4*dim * 4*dim * depth/8
      G.add(Conv2DTranspose(int(depth/8), 5, padding='same'))
      G.add(BatchNormalization(momentum=0.9))
      G.add(Activation('relu'))
      
      # Out: 28 x 28 x 1 grayscale image [0.0,1.0] per pix
      G.add(Conv2DTranspose(1, 5, padding='same'))
      G.add(Activation('sigmoid'))
      #G.summary()
      
      

      通过这样的一个生成器,我们输入100维的向量,就会得到一个28 * 28 *1的矩阵,和我们的图片一样大, 这个地方一定要检查好输出维度,因为建立好判别器之后,要把这两个拼起来,所以这里的输出维度一定要和判别器的输入维度统一起来

    • 下面我们用Keras建立判别器D(Sequential方法)

      depth = 64
      dropout = 0.4
      
      D = Sequential()
      # In: 28 x 28 x 1, depth = 1   Out: 14 x 14 x 1, depth=64
      input_shape = (img_rows, img_cols, channel)
      D.add(Conv2D(depth*1, 5, strides=2, input_shape=input_shape, padding='same'))
      D.add(LeakyReLU(alpha=0.2))
      D.add(Dropout(dropout))
      
      # In: 14 * 14 * 1, depth=64, Out:7*7*1, depth=64*2
      D.add(Conv2D(depth*2, 5, strides=2, padding='same'))
      D.add(LeakyReLU(alpha=0.2))
      D.add(Dropout(dropout))
      
      # In: 7 * 7 * 1, depth=128, Out:4*4*1, depth=64*4
      D.add(Conv2D(depth*4, 5, strides=2, padding='same'))
      D.add(LeakyReLU(alpha=0.2))
      D.add(Dropout(dropout))
      
      # In: 4 * 4 * 1, depth=64*4, Out:4*4*1, depth=64*8
      D.add(Conv2D(depth*8, 5, strides=1, padding='same'))
      D.add(LeakyReLU(alpha=0.2))
      D.add(Dropout(dropout))
      
      # Out: 1-dim probability
      D.add(Flatten())
      D.add(Dense(1))
      D.add(Activation('sigmoid'))
      #D.summary()
      
      discriminator_optimizer = RMSprop(lr=0.0002, decay=1e-8)
      D.compile(optimizer=discriminator_optimizer,
                        loss='binary_crossentropy')
      
    • 下面把生成器和判别器接在一块,得到DCGAN模型
      注意,判别器的参数禁止训练

      # 将判别器参数设置为不可训练
      D.trainable = False
      
      # 搭建对抗网络, 接起来即可
      gan = Sequential()
      gan.add(G)
      gan.add(D)
      gan_optimizer = RMSprop(lr=0.0004, 
                                         clipvalue=1.0, 
                                         decay=1e-8)
      gan.compile(optimizer=gan_optimizer, loss='binary_crossentropy')
      
    • 下面是画图像的一个函数,这个不是重点,是为了看一下效果

      def plot_images(save2file=False, fake=True, samples=16, noise=None, step=0):
          filename = 'mnist.png'
          if fake:
              if noise is None:
                  noise = np.random.uniform(-1.0, 1.0, size=[samples, 100])
              else:
                  filename = "mnist_%d.png" % step
              images = G.predict(noise)
          else:
              i = np.random.randint(0, train_x.shape[0], samples)
              images = train_x[i, :, :, :]
      
          plt.figure(figsize=(10,10))
          for i in range(images.shape[0]):
              plt.subplot(4, 4, i+1)
              image = images[i, :, :, :]
              image = np.reshape(image, [img_rows, img_cols])
              plt.imshow(image, cmap='gray')
              plt.axis('off')
          plt.tight_layout()
          if save2file:
              plt.savefig(filename)
              plt.close('all')
          else:
              plt.show()
      
    • 导入数据集,然后进行训练

      # 导入数据集
      path = './dataset/mnist.npz'  # 提前下好
      f = np.load(path)
      
      # 重置形状,然后归一化一下
      train_x = f['x_train']
      train_x = train_x.reshape(train_x.shape[0], 28, 28, 1).astype('float32') / 255.
      
      # 下面是训练部分,和理论部分的过程基本一致
      epoches = 10000
      batch_size = 256
      
      for i in range(epoches):
      	# 我们从真实图片中得到256张图片
      	images_train = train_x[np.random.randint(0, train_x.shape[0], size=batch_size), :, :, :]
      
      	# 然后我们随机生成一些噪声向量,通过生成器生成256张图片
      	noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])
      	images_fake = G.predict(noise)
      
      	# 两者合并成一个训练集,并打上标签
      	x = np.concatenate((images_train, images_fake))
      	y = np.ones([2*batch_size, 1])
      	y[batch_size:, :]) = 0
      
      	# 下面就是让判别器进行训练分类
      	d_loss = D.train_on_batch(x, y)
      
      	# 下面就是训练生成器,还记得吗,以假乱真式训练
      	noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])
      	y = np.ones([batch_size, 1])   # 打上1标签
      	# 训练DSGAN
      	a_loss = gan.train_on_batch(noise, y)
      
      	# 下面是画图,看看训练的效果
      	noise_input = np.random.uniform(-1.0, 1.0, size=[16, 100])
      	# 每500次绘制一遍图像,并保存
      	if i % 500 == 0:
           	G.save_weights('./weights/Gmnist_weights.h5')
              print('discriminator loss:', d_loss)
              print('adversarial loss:', a_loss)
              plot_images(save2file=True, samples=noise_input.shape[0], noise=noise_input, step=i)
      

    这样,就大功告成了, 让它自己训练吧, 结果如下(训练到9500代时的结果和初始的结果对比):
    在这里插入图片描述
    脚下留心:

    上面保存模型这个地方,我用的是model.save_weight这个函数,这个的作用是只保留了最后训练的参数,释放了计算图,这样,如果想下一次导入模型用的时候,就不能单纯的使用load_model函数导入了。 这时候,得先把模型建立起来之后,然后用load_weights给模型赋予参数。


    详细情况可以看这篇博客keras保存模型中的save()和save_weights()

    4. Keras搭建DCGAN网络生成青蛙图片

    在这里,我们依然是搭建DCGAN网络,只不过我们换Model的方式进行搭建,这两种搭建方式要熟记于心才可以。 并且这里的网络也尝试换一下,毕竟都用一样的改改参数没啥意思, Don’t repeat yourself! 但是思想还是一样的思想。

    • 导入相关包

      import numpy as np
      
      from keras.layers import Conv2D, Dense, LeakyReLU, Dropout, Input
      from keras.layers import Reshape, Conv2DTranspose, Flatten
      from keras.layers import BatchNormalization
      from keras.models import Model
      from keras import optimizers
      import keras
      
      import warnings
      warning.filterwarnings('ignore')
      
      """设置相关参数"""
      # 潜变量维度
      latent_dim = 100
      # 输入像素维度
      height = 32
      width = 32
      channels = 3
      
    • 搭建生成器网络(Model方式)

      generator_input = Input(shape=(latent_dim,))
      x = Dense(128*16*16)(generator_input)
      x = LeakyReLU()(x)
      x = Reshape((16, 16, 128))(x)
      
      # IN: 16*16*128  OUT: 16*16*256
      x = Conv2D(256, 5, padding='same')(x)
      x = LeakyReLU()(x)
      
      # IN: 16*16*256  OUT: 32*32*256
      x = Conv2DTranspose(256, 4, strides=2, padding='same')(x)
      x = LeakyReLU()(x)
      
      # 通过反卷积操作,把维度变得和图片一样大了,就别用反卷积了
      x = Conv2D(256, 5, padding='same')(x)
      x = LeakyReLU()(x)
      x = Conv2D(256, 5, padding='same')(x)
      x = LeakyReLU()(x)
      
      # 把通道变回来
      x = Conv2D(channels, 7, activation='tanh', padding='same')(x)
      
      generator = Model(generator_input, x)
      #generator.summary()
      

      这里可以简单总结一下生成器大体上在做一个什么事情, 我们有一个一维的向量,通过生成器,可以获得一个和图片大小的一个矩阵, 所以我们生成器做的就是通过卷积这些操作进行一系列变换, 首先一般会先通过一个全连接层,然后通过Reshape层之后,把向量转成三维的形式,这时候一般前两维会比图片的维度小,但成倍数关系。 这样,后面我们就可以通过Conv2DTranspose这个卷积的逆操作设定步长进行前两维的维度提升,或者用UpSampling2D()也能实现这个效果,然后就是增加或者减少通道数,然后卷积的一些层,进行最终的变换,这个写多了,就慢慢会有感觉,但一定要保证输出和真实图片的维度要一样。这个层不用complie, 因为要后面和判别器连起来一块训练。

    • 搭建判别器,判别器就真的是一个卷积神经网络了

      discriminator_input = Input(shape=(height, width, channels))
      # IN:32*32*3   OUT: 30*30*128
      x = Conv2D(128, 3)(discriminator_input)
      x = LeakyReLU()(x)
      
      # IN: 30*30*128  OUT:14*14*128
      x = Conv2D(128, 4, strides=2)(x)
      x = LeakyReLU()(x)
      
      # IN:14*14*128   OUT:6*6*128
      x = Conv2D(128, 4, strides=2)(x)
      x = LeakyReLU()(x)
      
      # IN:6*6*128  OUT:2*2*128
      x = Conv2D(128, 4, strides=2)(x)
      x = LeakyReLU()(x)
      
      # 展开成512个神经元
      x = Flatten()(x)
      x = Dropout(0.4)(x)
      x = Dense(1, activation='sigmoid')(x)
      
      discriminator = Model(discriminator_input, x)
      #discriminator.summary()
      
      discriminator_optimizer = optimizers.RMSprop(lr=0.0008, 
                                                   clipvalue=1.0, 
                                                   decay=1e-8)
      
      discriminator.compile(optimizer=discriminator_optimizer,
                            loss='binary_crossentropy')
      

      搭建判别器,就类似搭建普通的卷积神经网络并且只需要做二分类, 这个就需要complie了。

    • 将上面两个连起来组成生成对抗网络

      # 将判别器参数设置为不可训练
      discriminator.trainable = False
      
      gan_input = Input(shape=(latent_dim,))
      gan_output = discriminator(generator(gan_input))
      # 搭建对抗网络
      gan = Model(gan_input, gan_output)
      gan_optimizer = optimizers.RMSprop(lr=0.0004, 
                                         clipvalue=1.0, 
                                         decay=1e-8)
      gan.compile(optimizer=gan_optimizer, loss='binary_crossentropy')
      
    • 下面导入数据集进行训练,数据集选用的是Keras自带的CIFAR-10数据集

      import os
      from keras.preprocessing import image
      
      # 加载数据集(手写数字的数据集也可以这样加载)
      (x_train, y_train), (_,_) = keras.datasets.cifar10.load_data()
      # 指定青蛙图像(编号为6)
      x_train = x_train[y_train.flatten() == 6]
      x_train = x_train.reshape((x_train.shape[0],) +(height, width, channels)).astype('float32') / 255.
      
      # 下面开始训练
      iterations = 10000
      batch_size = 64
      save_dir = './image'
      
      start = 0
      for step in range(iterations):
      	
      	# 先通过噪声生成64张伪造图片
      	noise = np.random.normal(size=(batch_size, latent_dim))
      	images_fake = generator.predict(noise)
      
      	# 从真实图片中抽64张
      	end = start+batch_size
      	images_train = x_train[start:end]
      
      	# 两者混合作为训练集,并打上标签
      	x = np.concatenate([images_fake, images_train])
      	y = np.concatenate([np.zeors((batch_size, 1)), np.ones((batch_size, 1))])
      
      	# 向标签中添加噪声
      	y += 0.05 * np.random.random(y.shape)
      
      	# 训练判别器
      	d_loss = discriminator.train_on_batch(x, y)
      
      	# 训练生成对抗网络
      	noise = np.random.normal(size=(batch_size, latent_dim))
      	labels = np.ones((batch_size, 1))
      
      	# 通过gan模型来训练生成器模型,冻结判别器模型权重
      	a_loss = gan.train_on_batch(noise, labels)
      	
      	start += batch_size
      	if start > len(x_train) - batch_size:
      		start = 0
      	
      	# 每500步绘图并保存
      	if step % 500 == 0:
              generator.save_weights('./weights/G_weights.h5')
              print('discriminator loss:', d_loss)
              print('adversarial loss:', a_loss)
              img = image.array_to_img(images_fake[0] * 255., scale=False)
              img.save(os.path.join(save_dir, 'generated_frog' + str(step) + '.png'))
              img = image.array_to_img(images_train[0] * 255., scale=False)
              img.save(os.path.join(save_dir, 'real_frog' + str(step) + '.png'))
      

    这样,我们就完成了一个生成3维图片的任务。训练结果:
    在这里插入图片描述
    受限于CIFAR-10数据本身的低像素性,DCGAN生成出来的图像虽然也很模糊,但基本上足以达到以假乱真的水平。上图图片中,每一列有两张是生成样本,有一张是真实样本,按列第2、1、3和2张图片是真实样本,其余都是DCGAN伪造出来的青蛙图片。

    脚下留心:

    关于训练,这个训练需要挺长时间的,并且我试图把优化方法RMSprop改成Adam,发现效果变差了,并且这两个项目里面的优化方法都是RMSprop,你也可以试试其他的优化方法或者学习率什么的, 但是目前我看到的这种GAN里面的优化方法,RMSprop的多。

    当然这个也可以用上面的那个手写数字的跑,只不过需要改一些参数,毕竟维度不同,那个效果可能还好些吧。

    5. 总结

    好了,搭建生成对抗网络的学习就到这里吧,通过这一节课,相信可以使用Keras搭建一个不错的GAN来生成自己想要的图像了吧。 简单梳理一下这次学习: 首先是介绍了生成对抗网络的工作原理,然后用Keras的Sequential方式搭建了DCGAN完成了个手写数字生成,并在这里面拓展了一点模型保存的知识, 然后用Keras的Model方式搭建了另一个网络生成了一些彩色图片,在这里汇总了一下搭建生成器和判别器的一些思想。

    这样两个项目下来,估计对GAN也不是那么陌生了吧,感知境的第二篇文章已经完成, 后面还有更加精彩的Keras搭建LSTM, Attention的一些知识, 还得继续修炼, Rush !

    参考

    展开全文
  • 生成对抗网络 图像生成Machines are generating perfect images these days and it’s becoming more and more difficult to distinguish the machine-generated images from the originals.如今,机器正在生成完美...

    生成对抗网络 图像生成

    Machines are generating perfect images these days and it’s becoming more and more difficult to distinguish the machine-generated images from the originals.

    如今,机器正在生成完美的图像,将机器生成的图像与原始图像区分开来变得越来越困难。

    If you are reading this article, I am sure that we share similar interests and are/will be in similar industries. So let’s connect via Linkedin! Please do not hesitate to send a contact request! Orhan G. Yalçın — Linkedin

    如果您正在阅读本文,我相信我们拥有相似的兴趣并且将会/将会从事相似的行业。 因此,让我们通过Linkedin连接 请不要犹豫,发送联系请求! Orhan G.Yalçın— Linkedin

    Image for post
    3] 3 ]

    After receiving more than 300k views for my article, Image Classification in 10 Minutes with MNIST Dataset, I decided to prepare another tutorial on deep learning. But this time, instead of classifying images, we will generate images using the same MNIST dataset, which stands for Modified National Institute of Standards and Technology database. It is a large database of handwritten digits that is commonly used for training various image processing systems[1].

    在我的文章“使用MNIST数据集在10分钟内进行图像分类”获得了超过30万的观看次数之后,我决定编写另一篇有关深度学习的教程。 但是这一次,我们将使用相同的MNIST数据集生成图像,而不是对图像进行分类,该数据集代表改良的美国国家标准技术研究院数据库。 它是一个庞大的手写数字数据库,通常用于训练各种图像处理系统[1]。

    生成对抗网络 (Generative Adversarial Networks)

    To generate -well basically- anything with machine learning, we have to use a generative algorithm and at least for now, one of the best performing generative algorithms for image generation is Generative Adversarial Networks (or GANs).

    为了通过机器学习基本生成任何东西,我们必须使用一种生成算法,并且至少到目前为止,用于生成图像的性能最好的生成算法之一是“生成对抗网络”(GAN)。

    生成对抗网络的发明 (The invention of Generative Adversarial Network)

    Image for post
    Ian Goodfellow on Wikipedia上的 Wikipedia [ Ian Goodfellow的照片[ 4] 4 ]

    The invention of GANs has occurred pretty unexpectedly. The famous AI researcher, then, a Ph.D. fellow at the University of Montreal, Ian Goodfellow, landed on the idea when he was discussing with his friends -at a friend’s going away party- about the flaws of the other generative algorithms. After the party, he came home with high hopes and implemented the concept he had in mind. Surprisingly, everything went as he hoped in the first trial [5] and he successfully created the Generative Adversarial Networks (shortly, GANs). According to Yann Lecun, the director of AI research at Facebook and a professor at New York University, GANs are “the most interesting idea in the last 10 years in machine learning” [6].

    GAN的发明已经出乎意料地发生了。 当时著名的AI研究人员是博士学位。 蒙特利尔大学的研究员伊恩·古德费洛( Ian Goodfellow )在与朋友(在一个朋友走开的聚会上)讨论其他生成算法的缺陷时,想到了这个想法。 晚会结束后,他满怀希望地回到了家,并实现了他所构想的构想。 出乎意料的是,一切都如他在第一次试验中所希望的那样[ 5 ],并且他成功创建了Generative Adversarial Networks(简称GAN)。 根据Facebook AI研究总监,纽约大学教授Yann Lecun的说法,GAN是“过去10年来机器学习中最有趣的想法” [ 6 ]。

    The rough structure of the GANs may be demonstrated as follows:

    GAN的粗略结构可以证明如下:

    Image for post
    Figure 4. Generative Adversarial Networks (GANs) utilizing CNNs | (Graph by author)
    图4.使用CNN的生成对抗网络(GAN)| (作者图表)

    In an ordinary GAN structure, there are two agents competing with each other: a Generator and a Discriminator. They may be designed using different networks (e.g. Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs), or just Regular Neural Networks (ANNs or RegularNets)). Since we will generate images, CNNs are better suited for the task. Therefore, we will build our agents with convolutional neural networks.

    在普通GAN结构中,有两个代理相互竞争:生成器鉴别器。 可以使用不同的网络(例如卷积神经网络( CNN ),递归神经网络( RNN )或仅常规神经网络( ANN或RegularNets))来设计它们。 由于我们将生成图像,因此CNN更适合该任务。 因此,我们将使用卷积神经网络构建代理。

    我们的GAN模型如何运作? (How does our GAN model operate?)

    Image for post
    Figure 5. Generator and Discriminator Relationship in a GAN Network | (Graph by author)
    图5. GAN网络中的生成器和鉴别器关系(作者图表)

    In a nutshell, we will ask the generator to generate handwritten digits without giving it any additional data. Simultaneously, we will fetch the existing handwritten digits to the discriminator and ask it to decide whether the images generated by the Generator are genuine or not. At first, the Generator will generate lousy images that will immediately be labeled as fake by the Discriminator. After getting enough feedback from the Discriminator, the Generator will learn to trick the Discriminator as a result of the decreased variation from the genuine images. Consequently, we will obtain a very good generative model which can give us very realistic outputs.

    简而言之,我们将要求生成器在不提供任何其他数据的情况下生成手写数字。 同时,我们将现有的手写数字提取给鉴别器,并要求鉴别器确定生成器生成的图像是否真实。 首先,生成器将生成糟糕的图像,这些图像将立即由鉴别器标记为伪造的。 从鉴别器获得足够的反馈后,生成器将学习欺骗鉴别器,因为与真实图像的差异减小了。 因此,我们将获得一个非常好的生成模型,该模型可以为我们提供非常实际的输出。

    建立GAN模型 (Building the GAN Model)

    GANs often use computationally complex calculations and therefore, GPU-enabled machines will make your life a lot easier. Therefore, I will use Google Colab to decrease the training time with GPU acceleration.

    GAN经常使用复杂的计算,因此,支持GPU的计算机将使您的生活更加轻松。 因此,我将使用Google Colab通过GPU加速来减少训练时间。

    Google Colab启用GPU的培训 (GPU-Enabled Training with Google Colab)

    For machine learning tasks, for a long time, I used to use -iPython- Jupyter Notebook via Anaconda distribution for model building, training, and testing almost exclusively. Lately, though, I have switched to Google Colab for several good reasons.

    对于机器学习任务,很长一段时间以来,我曾经通过Anaconda发行版使用-iPython- Jupyter Notebook几乎专门用于模型构建,训练和测试。 不过,最近,出于几个很好的原因,我改用了Google Colab。

    Google Colab offers several additional features on top of the Jupyter Notebook such as (i) collaboration with other developers, (ii) cloud-based hosting, and (iii) GPU & TPU accelerated training. You can do all these with the free version of Google Colab. The relationship between Python, Jupyter Notebook, and Google Colab can be visualized as follows:

    Google Colab在Jupyter Notebook之上提供了其他一些功能,例如(i)与其他开发人员的协作,(ii)基于云的托管以及(iii)GPU和TPU加速培训。 您可以使用免费版本的Google Colab来完成所有这些操作。 Python,Jupyter Notebook和Google Colab之间的关系可以如下所示:

    Image for post
    Figure 6. Relationship between iPython, Jupyter Notebook, Google Colab | (Graph by author)
    图6. iPython,Jupyter Notebook,Google Colab之间的关系| (作者图表)

    Anaconda provides free and open-source distribution of the Python and R programming languages for scientific computing with tools like Jupyter Notebook (iPython) or Jupyter Lab. On top of these tools, Google Colab lets its users use the iPython notebook and lab tools with the computing power of their servers.

    Anaconda使用Jupyter Notebook(iPython)或Jupyter Lab等工具为科学计算提供了免费和开源的Python和R编程语言分发。 除了这些工具之外,Google Colab还允许其用户使用iPython笔记本和实验室工具来发挥其服务器的计算能力。

    Now that we have a general understanding of generative adversarial networks as our neural network architecture and Google Collaboratory as our programming environment, we can start building our model. In this tutorial, we will do our own take from an official TensorFlow tutorial [7].

    现在我们已经对生成对抗网络(作为我们的神经网络体系结构)和Google协作实验室(作为我们的编程环境)有了一般的了解,我们可以开始构建模型。 在本教程中,我们将从TensorFlow官方教程[ 7 ]中自己动手做。

    初始进口 (Initial Imports)

    Colab already has most machine learning libraries pre-installed, and therefore, you can just import them as shared below:

    Colab已经预先安装了大多数机器学习库,因此,您可以按以下共享方式导入它们:

    import tensorflow as tf
    from tensorflow.keras.layers import (Dense, 
                                         BatchNormalization, 
                                         LeakyReLU, 
                                         Reshape, 
                                         Conv2DTranspose,
                                         Conv2D,
                                         Dropout,
                                         Flatten)
    import matplotlib.pyplot as plt

    For the sake of shorter code, I prefer to import layers individually, as shown above.

    为了简化代码,我更喜欢分别导入图层,如上所示。

    加载和处理MNIST数据集 (Load and Process the MNIST Dataset)

    For this tutorial, we can use the MNIST dataset. The MNIST dataset contains 60,000 training images and 10,000 testing images taken from American Census Bureau employees and American high school students [8].

    对于本教程,我们可以使用MNIST数据集。 MNIST数据集包含60,000张训练图像和10,000张测试图像,这些图像是从美国人口普查局员工和美国高中学生那里拍摄的[ 8 ]。

    Luckily we may directly retrieve the MNIST dataset from the TensorFlow library. We retrieve the dataset from Tensorflow because this way, we can have the already processed version of it. We still need to do a few preparation and processing works to fit our data into the GAN model. Therefore, in the second line, we separate these two groups as train and test and also separated the labels and the images.

    幸运的是,我们可以直接从TensorFlow库中检索MNIST数据集。 我们从Tensorflow检索数据集,因为通过这种方式,我们可以获得已经处理过的版本。 我们仍然需要做一些准备和处理工作,以使我们的数据适合GAN模型。 因此,在第二行中,我们将这两个组分开进行训练和测试,并且还将标签和图像分开。

    x_train and x_test parts contain greyscale RGB codes (from 0 to 255) while y_train and y_test parts contain labels from 0 to 9 which represents which number they actually are. Since we are doing an unsupervised learning task, we will not need label values and therefore, we use underscores (i.e., _) to ignore them. We also need to convert our dataset to 4-dimensions with the reshape function. Finally, we convert our NumPy array to a TensorFlow Dataset object for more efficient training. The lines below do all these tasks:

    x_trainx_test部分包含灰度RGB代码(从0到255),而y_trainy_test部分包含从0到9的标签,这些标签代表它们实际的编号。 由于我们正在执行无监督的学习任务,因此我们不需要标签值,因此,我们使用下划线(即_)来忽略它们。 我们还需要使用reshape函数将数据集转换为4维。 最后,我们将NumPy数组转换为TensorFlow Dataset对象,以进行更有效的训练。 下面的行完成所有这些任务:

    # underscore to omit the label arrays
    (train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data() 
    
    
    
    
    train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
    train_images = (train_images - 127.5) / 127.5 # Normalize the images to [-1, 1]
    
    
    BUFFER_SIZE = 60000
    BATCH_SIZE = 256
    
    
    # Batch and shuffle the data
    train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

    Our data is already processed and it is time to build our GAN model.

    我们的数据已经处理完毕,现在该建立GAN模型了。

    建立模型 (Build the Model)

    As mentioned above, every GAN must have at least one generator and one discriminator. Since we are dealing with image data, we need to benefit from Convolution and Transposed Convolution (Inverse Convolution) layers in these networks. Let's define our generator and discriminator networks below.

    如上所述,每个GAN必须至少具有一个生成器和一个鉴别器。 由于我们正在处理图像数据,因此需要从这些网络中的卷积和转置卷积(逆卷积)层中受益。 让我们在下面定义我们的生成器和鉴别器网络。

    发电机网络 (Generator Network)

    Our generator network is responsible for generating 28x28 pixels grayscale fake images from random noise. Therefore, it needs to accept 1-dimensional arrays and output 28x28 pixels images. For this task, we need Transposed Convolution layers after reshaping our 1-dimensional array to a 2-dimensional array. Transposed Convolution layers can increase the size of a smaller array. We also take advantage of BatchNormalization and LeakyReLU layers. The below lines create a function which would generate a generator network with Keras Sequential API:

    我们的生成器网络负责根据随机噪声生成28x28像素的灰度假图像。 因此,它需要接受一维数组并输出28x28像素的图像。 为此,在将一维数组重塑为二维数组后,需要转置卷积层。 转置的卷积层可以增加较小阵列的大小。 我们还利用了BatchNormalization和LeakyReLU层。 以下几行创建了一个函数,该函数将使用Keras Sequential API生成发电机网络:

    def make_generator_model():
        model = tf.keras.Sequential()
        model.add(Dense(7*7*256, use_bias=False, input_shape=(100,)))
        model.add(BatchNormalization())
        model.add(LeakyReLU())
    
    
        model.add(Reshape((7, 7, 256)))
        assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size
    
    
        model.add(Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
        assert model.output_shape == (None, 7, 7, 128)
        model.add(BatchNormalization())
        model.add(LeakyReLU())
    
    
        model.add(Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
        assert model.output_shape == (None, 14, 14, 64)
        model.add(BatchNormalization())
        model.add(LeakyReLU())
    
    
        model.add(Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
        assert model.output_shape == (None, 28, 28, 1)
    
    
        return model

    We can call our generator function with the following code:

    我们可以使用以下代码调用生成器函数:

    generator = make_generator_model()
    Image for post
    Figure 7. The Summary of Our Generator Network | (Graph by Author)
    图7.我们的发电机网络摘要| (作者图表)

    Now that we have our generator network, we can easily generate a sample image with the following code:

    现在我们有了生成器网络,我们可以使用以下代码轻松生成示例图像:

    # Create a random noise and generate a sample
    noise = tf.random.normal([1, 100])
    generated_image = generator(noise, training=False)
    # Visualize the generated sample
    plt.imshow(generated_image[0, :, :, 0], cmap='gray')

    which would look like this:

    看起来像这样:

    Image for post
    Figure 8. A Sample Image Generated by Non-Trained Generator Network | (Image by author)
    图8.非训练发电机网络生成的样本图像(图片由作者提供)

    It is just plain noise. But, the fact that it can create an image from a random noise array proves its potential.

    这只是普通的声音。 但是,它可以从随机噪声阵列生成图像的事实证明了它的潜力。

    鉴别网络 (Discriminator Network)

    For our discriminator network, we need to follow the inverse version of our generator network. It takes the 28x28 pixels image data and outputs a single value, representing the possibility of authenticity. So, our discriminator can review whether a sample image generated by the generator is fake.

    对于鉴别器网络,我们需要遵循生成器网络的逆版本。 它获取28x28像素的图像数据并输出一个单一值,表示真实性的可能性。 因此,我们的鉴别器可以检查由生成器生成的样本图像是否为伪造的。

    We follow the same method that we used to create a generator network, The following lines create a function that would create a discriminator model using Keras Sequential API:

    我们遵循与创建发电机网络相同的方法。以下几行创建了一个函数,该函数将使用Keras Sequential API创建鉴别器模型:

    def make_discriminator_model():
        model = tf.keras.Sequential()
        
        model.add(Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))
        model.add(LeakyReLU())
        model.add(Dropout(0.3))
    
    
        model.add(Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
        model.add(LeakyReLU())
        model.add(Dropout(0.3))
    
    
        model.add(Flatten())
        model.add(Dense(1))
    
    
        return model

    We can call the function to create our discriminator network with the following line:

    我们可以使用以下行调用该函数来创建我们的鉴别器网络:

    discriminator = make_discriminator_model()
    Image for post
    Figure 9. The Summary of Our Discriminator Network | (Graph by author)
    图9.鉴别器网络摘要| (作者图表)

    Finally, we can check what our non-trained discriminator says about the sample generated by the non-trained generator:

    最后,我们可以检查非训练鉴别器对非训练生成器生成的样本的评价:

    decision = discriminator(generated_image)
    print (decision)

    Output: tf.Tensor([[-0.00108097]], shape=(1, 1), dtype=float32)

    输出: tf.Tensor([[- 0.00108097 ]],shape =(1,1),dtype = float32)

    A negative value shows that our non-trained discriminator concludes that the image sample in Figure 8 is fake. At the moment, what's important is that it can examine images and provide results, and the results will be much more reliable after training.

    负值表示我们的未经训练的判别器得出的结论是,图8中的图像样本是伪造的。 目前,重要的是它可以检查图像并提供结果,训练后结果将更加可靠。

    配置模型 (Configure the Model)

    Since we are training two sub-networks inside a GAN network, we need to define two loss functions and two optimizers.

    由于我们正在训练GAN网络中的两个子网,因此我们需要定义两个损失函数和两个优化器。

    Loss Functions: We start by creating a Binary Crossentropy object from tf.keras.losses module. We also set the from_logits parameter to True. After creating the object, we fill them with custom discriminator and generator loss functions. Our discriminator loss is calculated as a combination of (i) the discriminator’s predictions on real images to an array of ones and (ii) its predictions on generated images to an array of zeros. Our generator loss is calculated by measuring how well it was able to trick the discriminator. Therefore, we need to compare the discriminator’s decisions on the generated images to an array of 1s.

    损失函数:我们首先从tf.keras.losses模块创建一个Binary Crossentropy对象。 我们还将from_logits参数设置为True 。 创建对象后,我们使用自定义鉴别符和生成器损失函数填充它们。 我们的鉴别器损失的计算方式是:(i)鉴别器对真实图像的预测为一的数组,以及(ii)对鉴别器对生成图像的预测为零的数组。 我们的发电机损耗是通过测量其欺骗鉴别器的能力来计算的。 因此,我们需要将鉴别器对生成图像的决策与1s数组进行比较。

    Optimizers: We also set two optimizers separately for generator and discriminator networks. We can use the Adam optimizer object from tf.keras.optimizers module.

    优化器:我们还分别为生成器和鉴别器网络设置了两个优化器。 我们可以使用tf.keras.optimizers模块中的Adam优化器对象。

    The following lines configure our loss functions and optimizers

    以下几行配置我们的损失函数和优化器

    # This method returns a helper function to compute cross entropy loss
    cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
    
    
    def discriminator_loss(real_output, fake_output):
        real_loss = cross_entropy(tf.ones_like(real_output), real_output)
        fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
        total_loss = real_loss + fake_loss
        return total_loss
    
    
    def generator_loss(fake_output):
        return cross_entropy(tf.ones_like(fake_output), fake_output)
    
    
    generator_optimizer = tf.keras.optimizers.Adam(1e-4)
    discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

    设置检查点(Set the Checkpoints)

    We would like to have access to previous training steps and TensorFlow has an option for this: checkpoints. By setting a checkpoint directory, we can save our progress at every epoch. This will be especially useful when we restore our model from the last epoch. The following lines configure the training checkpoints by using the os library to set a path to save all the training steps

    我们希望可以访问以前的培训步骤,并且TensorFlow为此提供了一个选项: checkpoints 。 通过设置检查点目录,我们可以在每个时期保存进度。 当我们从最后一个时期恢复模型时,这将特别有用。 以下各行通过使用os库来设置保存所有训练步骤的路径来配置训练检查点

    import os
    
    
    checkpoint_dir = './training_checkpoints'
    checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
    checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
                                     discriminator_optimizer=discriminator_optimizer,
                                     generator=generator,
                                     discriminator=discriminator)

    训练模型(Train the Model)

    Now our data ready, our model is created and configured. It is time to design our training loop. Note that at the moment, GANs require custom training loops and steps. I will try to make them as understandable as possible for you. Make sure that you read the code comments in the Github Gists.

    现在我们的数据准备就绪,我们的模型已创建并配置。 现在是时候设计我们的训练循环了。 请注意,目前,GAN需要自定义训练循环和步骤。 我将尽力使它们对您来说尽可能地易于理解。 确保您阅读了Github Gists中的代码注释。

    Let’s create some of the variables with the following lines:

    让我们用以下几行创建一些变量:

    EPOCHS = 60
    # We will reuse this seed overtime (so it's easier)
    # to visualize progress in the animated GIF)
    num_examples_to_generate = 16
    noise_dim = 100
    seed = tf.random.normal([num_examples_to_generate, noise_dim])

    Our seed is the noise that we use to generate images on top of. The code below generates a random array with normal distribution with the shape (16, 100).

    我们的种子是我们用来生成图像的噪声。 下面的代码生成一个形状为(16,100)且具有正态分布的随机数组。

    定义培训步骤 (Define the Training Step)

    This is the most unusual part of our tutorial: We are setting a custom training step. After defining the custom train_step() function by annotating the tf.function module, our model will be trained based on the custom train_step() function we defined.

    这是本教程中最不寻常的部分:我们正在设置自定义培训步骤。 通过注释的tf.function模块定义自定义train_step()函数后,我们的模型将基于自定义train_step进行培训()函数中,我们定义。

    The code below with excessive comments are for the training step. Please read the comments carefully:

    以下带有过多注释的代码用于培训步骤。 请仔细阅读评论:

    # tf.function annotation causes the function 
    # to be "compiled" as part of the training
    @tf.function
    def train_step(images):
      
        # 1 - Create a random noise to feed it into the model
        # for the image generation
        noise = tf.random.normal([BATCH_SIZE, noise_dim])
        
        # 2 - Generate images and calculate loss values
        # GradientTape method records operations for automatic differentiation.
        with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
          generated_images = generator(noise, training=True)
    
    
          real_output = discriminator(images, training=True)
          fake_output = discriminator(generated_images, training=True)
    
    
          gen_loss = generator_loss(fake_output)
          disc_loss = discriminator_loss(real_output, fake_output)
    
    
        # 3 - Calculate gradients using loss values and model variables
        # "gradient" method computes the gradient using 
        # operations recorded in context of this tape (gen_tape and disc_tape).
        
        # It accepts a target (e.g., gen_loss) variable and 
        # a source variable (e.g.,generator.trainable_variables)
        # target --> a list or nested structure of Tensors or Variables to be differentiated.
        # source --> a list or nested structure of Tensors or Variables.
        # target will be differentiated against elements in sources.
    
    
        # "gradient" method returns a list or nested structure of Tensors  
        # (or IndexedSlices, or None), one for each element in sources. 
        # Returned structure is the same as the structure of sources.
        gradients_of_generator = gen_tape.gradient(gen_loss, 
                                                   generator.trainable_variables)
        gradients_of_discriminator = disc_tape.gradient(disc_loss, 
                                                    discriminator.trainable_variables)
        
        # 4 - Process  Gradients and Run the Optimizer
        # "apply_gradients" method processes aggregated gradients. 
        # ex: optimizer.apply_gradients(zip(grads, vars))
        """
        Example use of apply_gradients:
        grads = tape.gradient(loss, vars)
        grads = tf.distribute.get_replica_context().all_reduce('sum', grads)
        # Processing aggregated gradients.
        optimizer.apply_gradients(zip(grads, vars), experimental_aggregate_gradients=False)
        """
        generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
        discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

    Now that we created our custom training step with tf.function annotation, we can define our train function for the training loop.

    现在,我们使用tf.function注释创建了自定义训练步骤,我们可以为训练循环定义训练功能。

    定义训练循环 (Define the Training Loop)

    We define a function, named train, for our training loop. Not only we run a for loop to iterate our custom training step over the MNIST, but also do the following with a single function:

    我们为训练循环定义了一个名为train的函数。 我们不仅运行for循环来遍历MNIST上的自定义训练步骤,而且还可以通过单个函数执行以下操作:

    During the Training:

    培训期间:

    • Start recording time spent at the beginning of each epoch;

      开始记录每个时期开始时所花费的时间;
    • Produce GIF images and display them,

      产生GIF图像并显示它们,
    • Save the model every five epochs as a checkpoint,

      每五个时期将模型保存为一个检查点,
    • Print out the completed epoch time; and

      打印出完整的纪元时间; 和
    • Generate a final image in the end after the training is completed.

      训练结束后最后生成最终图像。

    The following lines with detailed comments, do all these tasks:

    下面的行带有详细的注释,可以完成所有这些任务:

    import time
    from IPython import display # A command shell for interactive computing in Python.
    
    
    def train(dataset, epochs):
      # A. For each epoch, do the following:
      for epoch in range(epochs):
        start = time.time()
        # 1 - For each batch of the epoch, 
        for image_batch in dataset:
          # 1.a - run the custom "train_step" function
          # we just declared above
          train_step(image_batch)
    
    
        # 2 - Produce images for the GIF as we go
        display.clear_output(wait=True)
        generate_and_save_images(generator,
                                 epoch + 1,
                                 seed)
    
    
        # 3 - Save the model every 5 epochs as 
        # a checkpoint, which we will use later
        if (epoch + 1) % 5 == 0:
          checkpoint.save(file_prefix = checkpoint_prefix)
    
    
        # 4 - Print out the completed epoch no. and the time spent
        print ('Time for epoch {} is {} sec'.format(epoch + 1, time.time()-start))
    
    
      # B. Generate a final image after the training is completed
      display.clear_output(wait=True)
      generate_and_save_images(generator,
                               epochs,
                               seed)

    图像生成功能(Image Generation Function)

    In the train function, there is a custom image generation function that we haven’t defined yet. Our image generation function does the following tasks:

    在train函数中,有一个尚未定义的自定义图像生成函数。 我们的图像生成功能执行以下任务:

    • Generate images by using the model;

      使用模型生成图像;
    • Display the generated images in a 4x4 grid layout using matplotlib;

      使用matplotlib以4x4网格布局显示生成的图像;
    • Save the final figure in the end

      最后保存最终图形

    The following lines are in charge of these tasks:

    以下行负责这些任务:

    def generate_and_save_images(model, epoch, test_input):
      # Notice `training` is set to False.
      # This is so all layers run in inference mode (batchnorm).
      # 1 - Generate images
      predictions = model(test_input, training=False)
      # 2 - Plot the generated images
      fig = plt.figure(figsize=(4,4))
      for i in range(predictions.shape[0]):
          plt.subplot(4, 4, i+1)
          plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
          plt.axis('off')
      # 3 - Save the generated images
      plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
      plt.show()

    开始训练(Start the Training)

    After training three complex functions, starting the training is fairly easy. Just call the train function with the below arguments:

    在训练了三个复杂的功能之后,开始训练非常容易。 只需使用以下参数调用train函数即可:

    train(train_dataset, EPOCHS)

    If you use GPU enabled Google Colab notebook, the training will take around 10 minutes. If you are using CPU, it may take much more. Let's see our final product after 60 epochs.

    如果您使用支持GPU的Google Colab笔记本,则培训大约需要10分钟。 如果您使用的是CPU,则可能会花费更多。 让我们看看60个时代之后的最终产品。

    Image for post
    Figure 10. The Digits Generated by Our GAN after 60 Epochs. Note that we are seeing 16 samples because we configured our output this way. | (Image by author)
    图10.我们的GAN在60个纪元后生成的数字。 请注意,由于我们以这种方式配置了输出,因此我们看到了16个样本。 | (图片由作者提供)

    产生数字 (Generate Digits)

    Before generating new images, let's make sure we restore the values from the latest checkpoint with the following line:

    在生成新图像之前,请确保使用以下行从最新的检查点还原值:

    checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))

    We can also view the evolution of our generative GAN model by viewing the generated 4x4 grid with 16 sample digits for any epoch with the following code:

    我们还可以通过使用以下代码查看生成的4x4网格以及任意时期的16个样本数字,从而查看生成的GAN模型的演变情况:

    # PIL is a library which may open different image file formats
    import PIL 
    # Display a single image using the epoch number
    def display_image(epoch_no):
      return PIL.Image.open('image_at_epoch_{:04d}.png'.format(epoch_no))
    display_image(EPOCHS)

    or better yet, let's create a GIF image visualizing the evolution of the samples generated by our GAN with the following code:

    或更妙的是,让我们用以下代码创建一个GIF图像,以可视化由GAN生成的样本的演变:

    import glob # The glob module is used for Unix style pathname pattern expansion.
    import imageio # The library that provides an easy interface to read and write a wide range of image data
    
    
    anim_file = 'dcgan.gif'
    
    
    with imageio.get_writer(anim_file, mode='I') as writer:
      filenames = glob.glob('image*.png')
      filenames = sorted(filenames)
      for filename in filenames:
        image = imageio.imread(filename)
        writer.append_data(image)
      # image = imageio.imread(filename)
      # writer.append_data(image)
      
    display.Image(open('dcgan.gif','rb').read())

    Our output is as follows:

    我们的输出如下:

    Image for post
    Figure 11. The GIF Image Showing the Evolution of our GAN Generated Sample Digits over Time | (Image by author)
    图11. GIF图像显示了我们GAN生成的样本数字随时间的演变(图片由作者提供)

    As you can see in Figure 11, the outputs generated by our GAN becomes much more realistic over time.

    如您在图11中所看到的,随着时间的流逝,我们的GAN生成的输出变得更加现实。

    恭喜啦 (Congratulations)

    You have built and trained a generative adversarial network (GAN) model, which can successfully create handwritten digits. There are obviously some samples that are not very clear, but only for 60 epochs trained on only 60,000 samples, I would say that the results are very promising.

    您已经建立并训练了生成对抗网络(GAN)模型,该模型可以成功创建手写数字。 显然有一些样本不是很清楚,但是仅在60,000个样本上训练了60个纪元,我想说结果是非常有希望的。

    Once you can build and train this network, you can generate much more complex images,

    建立并训练该网络后,您可以生成更复杂的图像,

    • by working with a larger dataset with colored images in high definition;

      通过使用更大的数据集和高清彩色图像;
    • by creating a more sophisticated discriminator and generator network;

      通过创建更复杂的鉴别器和生成器网络;
    • by increasing the number of epochs;

      通过增加时期数;
    • by working on a GPU-enabled powerful hardware

      通过使用支持GPU的强大硬件

    In the end, you can create art pieces such as poems, paintings, text or realistic photos or videos.

    最后,您可以创建艺术品,例如诗歌,绘画,文字或逼真的照片或视频。

    订阅邮件列表以获取完整代码 (Subscribe to the Mailing List for the Full Code)

    If you would like to have access to full code on Google Colab and have access to my latest content, subscribe to the mailing list: ✉️

    如果您想访问Google Colab上的完整代码并访问我的最新内容,请订阅邮件列表:✉️

    Slide to Subscribe
    滑动以订阅

    资源资源(Resources)

    [1] Orhan G. Yalcin, Image Classification in 10 Minutes with MNIST Dataset, Towards Data Science, https://towardsdatascience.com/image-classification-in-10-minutes-with-mnist-dataset-54c35b77a38d

    [1] Orhan G. Yalcin,使用MNIST数据集在10分钟内进行图像分类,迈向数据科学, https: //towardsdatascience.com/image-classification-in-10-minutes-with-mnist-dataset-54c35b77a38d

    [2] Lehtinen, J. (n.d.). Analyzing and Improving the Image Quality of StyleGAN Tero Karras NVIDIA Samuli Laine NVIDIA Miika Aittala NVIDIA Janne Hellsten NVIDIA. Retrieved from https://github.com/NVlabs/stylegan2

    [2] Lehtinen,J.(nd)。 分析和改善Style的图像质量GAN Tero Karras NVIDIA Samuli Laine NVIDIA Miika Aittala NVIDIA Janne Hellsten NVIDIA 。 取自https://github.com/NVlabs/stylegan2

    [3] Or Sharir & Ronen Tamari & Nadav Cohen & Amnon Shashua, Tensorial Mixture Models, https://www.researchgate.net/profile/Or_Sharir/publication/309131743.

    [3]或Sharir和Ronen Tamari和Nadav Cohen和Amnon Shashua,张量混合模型, https: //www.researchgate.net/profile/Or_Sharir/publication/309131743。

    [4] Wikipedia, File:Ian Goodfellow.jpg, https://upload.wikimedia.org/wikipedia/commons/f/fe/Ian_Goodfellow.jpg

    [4]维基百科,文件:Ian Goodfellow.jpg, https ://upload.wikimedia.org/wikipedia/commons/f/fe/Ian_Goodfellow.jpg

    SYNCED, Father of GANs Ian Goodfellow Splits Google For Apple, https://medium.com/syncedreview/father-of-gans-ian-goodfellow-splits-google-for-apple-279fcc54b328

    SYNC的GAN父亲伊恩·古德费洛(Ian Goodfellow)拆分了Google for Apple, https: //medium.com/syncedreview/father-of-gans-ian-goodfellow-splits-google-for-apple-279fcc54b328

    [5] YOUTUBE, Heroes of Deep Learning: Andrew Ng interviews Ian Goodfellow, https://www.youtube.com/watch?v=pWAc9B2zJS4

    [5] YOUTUBE,《深度学习英雄》:吴安德(Andrew Ng)采访伊恩·古德费洛(Ian Goodfellow), https://www.youtube.com/watch?v = pWAc9B2zJS4

    [6] George Lawton, Generative adversarial networks could be most powerful algorithm in AI, https://searchenterpriseai.techtarget.com/feature/Generative-adversarial-networks-could-be-most-powerful-algorithm-in-AI

    [6]乔治·劳顿(George Lawton),生成对抗网络可能是AI中最强大的算法, https://searchenterpriseai.techtarget.com/feature/Generative-adversarial-networks-could-be-most-powerful-algorithm-in-AI

    [7] Deep Convolutional Generative Adversarial Network, TensorFlow, available at https://www.tensorflow.org/tutorials/generative/dcgan

    [7]深度卷积生成对抗网络,TensorFlow,网址https://www.tensorflow.org/tutorials/generative/dcgan

    [8] Wikipedia, MNIST database, https://en.wikipedia.org/wiki/MNIST_database

    [8]维基百科,MNIST数据库, https: //en.wikipedia.org/wiki/MNIST_database

    翻译自: https://towardsdatascience.com/image-generation-in-10-minutes-with-generative-adversarial-networks-c2afc56bfa3b

    生成对抗网络 图像生成

    展开全文
  • 一文读懂对抗生成网络的3种模型

    千次阅读 2019-01-07 08:01:07
      2018-12-17 14:53:28   ...基于对抗生成网络技术的在线...在GAN系列课程中分别讲解了对抗生成网络的三种模型,从Goodfellow最初提出的原始的对抗生成网络,到改进型的DC GAN,再到解决了原始GAN存在问题,...
  • 好像还挺好玩的GAN重制版2——Pytorch搭建DCGAN利用深度卷积神经网络实现图片生成学习前言什么是DCGAN生成网络的构建判断网络的构建训练思路判别器的训练实现全部代码 学习前言 我又死了我又死了我又死了! 什么是...
  • 抓取图片网络爬虫)

    热门讨论 2012-09-19 23:14:07
    能够大量的抓取图片,算法也比较容易理解,能很快的改成自己的。
  • GAN生成对抗网络入门篇

    万次阅读 多人点赞 2019-01-19 16:16:34
    全称:generative adversarial network 生成式对抗网络(不一定是深度学习) 论文:https://arxiv.org/abs/1406.2661 提出者:Ian Goodfellow(也是深度学习花园书的作者) 2 Gan能做什么? 2.1 生成图片 下图,第一...
  • GAN生成对抗网络

    千次阅读 2022-02-06 21:59:27
    GANs(Generativeadversarial networks,对抗式生成网络)可以这三个单词拆分理解。 Generative:生成式模型 Adversarial:采取对抗的策略 Networks:网络(不一定是深度学习) 模型通过框架中(至少)两个模块:...
  • 怎样将本地图片转换成网络链接图片

    万次阅读 多人点赞 2019-06-03 17:44:39
    第一步:打开浏览器在地址栏输入https://sm.ms/ 第二步,单击browse,选择需要装换的本地图片,然后单击“打开” 第三步:单击上传就ok了 我们就会看到生成的url链接图片 ...
  • 生成对抗网络

    千次阅读 2019-09-03 23:20:56
    生成对抗网络 说明: 本文中代码与dc_gan.py的运行结果一致,可直接运行(https://github.com/PaddlePaddle/book/blob/develop/09.gan/dc_gan.py)进行验证。 背景介绍 生成对抗网络(Generative Adversarial ...
  • 生成对抗网络GANs理解(附代码)

    万次阅读 多人点赞 2017-01-20 12:36:28
    生成模型和判别模型理解对抗网络,首先要了解生成模型和判别模型。判别模型比较好理解,就像分类一样,有一个判别界限,通过这个判别界限去区分样本。从概率角度分析就是获得样本x属于类别y的概率,是一个条件概率P...
  • 其实这也很好理解,判别器希望能够图片判别为fake_label,而生成器则希望能他判别为true_label,判别器和生成器互相对抗提升。 接下来就是一些可视化的代码。每次可视化使用的噪声都是固定的fix_noises,因为...
  • 前几日,学校期末作业要求我们使用机器学习的方法解决一个实际问题,思考了很久,尝试做了很多选题,最终决定做一个cDCGAN,即条件深度卷积...生成对抗网络这几年实在是火爆,图片上色,视频去马赛克,包括英伟达...
  • 作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的...2.1 GAN网络的目标达成器:生成网络G 2.2 GNN网络的助教:判决网络 第3章 GAN网络的模型训练:G网络和D网络如何协同学习,共同进步 3.1来自大自然的启示 3..
  • 深度学习生成对抗网络(GAN)

    千次阅读 2021-12-20 11:27:50
    生成对抗网络(Generative Adversarial Networks)是一种无监督深度学习模型,用来通过计算机生成数据,由Ian J. Goodfellow等人于2014年提出。模型通过框架中(至少)两个模块:生成模型(Generative Model)和判别模型...
  • 判别器则需要对接收的图片进行真假判别。 在整个过程中,生成器努力地让生成的图像更加真实,而判别器则努力地去识别出图像的真假,这个过程相当于一个二人博弈,随着时间的推移,生成器和判别器在不断地进行对抗
  • 本文综合整理常用的神经网络,包括生物神经网络、人工神经网络、卷积神经网络、循环神经网络生成对抗网络;参考了许多高校的课程、论文、博客和视频等。文章的结构是先进行概念了解,然后结合图片、结构图、一步...
  • 图解 生成对抗网络GAN 原理 超详解

    万次阅读 多人点赞 2020-03-29 14:00:30
    生成对抗网络 一.背景 一般而言,深度学习模型可以分为判别式模型与生成式模型。由于反向传播(Back propagation, BP)、Dropout等算法的发明,判别式模型得到了迅速发展。然而,由于生成式模型建模较为困难,因此...
  • 生成对抗网络(GAN)

    千次阅读 2020-07-20 22:38:40
    学习目标 目标 了解GAN的作用 说明GAN的训练过程 知道DCGAN的结构 ...生成对抗网络(Generative Adversarial Network,简称GAN),主要结构包括一个生成器G(Generator)和一个判别器D(Discri.
  • 在本文中,你将发现如何使用深度神经网络模型来自动生成图像描述。 完成这篇文章后,你将了解: 关于为图像生成文本描述所面临的挑战以及将计算机视觉和自然语言处理方面的突破相结合的需求。
  • (1)最主要的就是标签变成one-hot编码然后与输入进行拼接 (2)原作者还有些代码写法可以借鉴一下 定义数据类型的代码 保存图片的代码,用的from torchvision.utils import save_image 结果,跑了20轮 (DCGAN)...
  • 生成式对抗网络GAN(Generative Adversarial Networks)是一种深度学习模型,是近年来复杂分布上无监督学习最具前景的方法之一。它源于2014年发表的论文:《Generative Adversarial Nets》,论文地址:...
  • 通俗理解生成对抗网络GAN

    万次阅读 2020-12-30 14:54:53
    2.1 GAN的基本结构 GAN的主要结构包括一个生成器G(Generator)和一个判别器D(Discriminator)。...我们现在拥有大量的手写数字的数据集,我们希望通过GAN生成一些能够以假乱真的手写字图片。主要由如下两个部
  • 这篇文章主要记录如何使用PaddlePaddle Fluid搭建对抗神经网络生成手写数字图像集。
  • 生成对抗网络-GAN

    千次阅读 2017-09-01 15:59:41
    生成对抗网络-GAN 1. GAN基础 2. 深度 GAN 3. 条件 GAN 4. Info GAN 5. Wasserstein GAN
  • 免费将图片转换成网络链接

    千次阅读 2021-04-01 11:52:52
    一、引用网络图片 直接鼠标右键复制图片地址 二、本地图片图片上传到QQ空间或其他的公共网站,例如qq空间发布动态。
  • 原始GAN(生成对抗网络)详细解析

    千次阅读 2019-07-24 13:15:36
    伟大的GAN(生成对抗网络)前言:以下所有内容是学习过程中产生的,不一定具有Ture可信度,仅供初学者学习参考,如果有不对的地方,敬请指正再批评;所有参考资料均来源于互联网和论文,文末贴出链接。摘要:主要从...
  • 图片生成任务来说就是拟合训练集图片的像素概率分布。下面我们从原理的角度演示一下GAN的训练过程: 上图中: 黑色点线为训练集数据分布曲线 蓝色点线为判别器输出的分布曲线 绿色实线为生成器输出的分布曲线 z...
  • DCGAN深度卷积生成对抗网络&python自动绘图

    千次阅读 热门讨论 2019-01-16 16:12:23
    生成对抗网络 是一种深度学习模型,是近年来复杂分布上无监督学习最具前景的方法之一。模型通过框架中(至少)两个模块:生成模型(Generative Model)和判别模型(Discriminative Model)的互相博弈学习产生相当好...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 159,879
精华内容 63,951
关键字:

怎么把图片生成网络连接