在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PyTorch教程-20.2. 深度卷積生成對(duì)抗網(wǎng)絡(luò)

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

20.1 節(jié)中,我們介紹了 GAN 工作原理背后的基本思想。我們展示了他們可以從一些簡單的、易于采樣的分布中抽取樣本,比如均勻分布或正態(tài)分布,并將它們轉(zhuǎn)換成看起來與某些數(shù)據(jù)集的分布相匹配的樣本。雖然我們匹配 2D 高斯分布的示例說明了要點(diǎn),但它并不是特別令人興奮。

在本節(jié)中,我們將演示如何使用 GAN 生成逼真的圖像。我們的模型將基于 Radford等人介紹的深度卷積 GAN (DCGAN)。2015 年我們將借用已經(jīng)證明在判別計(jì)算機(jī)視覺問題上非常成功的卷積架構(gòu),并展示如何通過 GAN 來利用它們來生成逼真的圖像。

import warnings
import torch
import torchvision
from torch import nn
from d2l import torch as d2l
from mxnet import gluon, init, np, npx
from mxnet.gluon import nn
from d2l import mxnet as d2l

npx.set_np()
import tensorflow as tf
from d2l import tensorflow as d2l

20.2.1。口袋妖怪?jǐn)?shù)據(jù)集

我們將使用的數(shù)據(jù)集是從pokemondb獲得的 Pokemon 精靈的集合 首先下載、提取和加載此數(shù)據(jù)集。

#@save
d2l.DATA_HUB['pokemon'] = (d2l.DATA_URL + 'pokemon.zip',
              'c065c0e2593b8b161a2d7873e42418bf6a21106c')

data_dir = d2l.download_extract('pokemon')
pokemon = torchvision.datasets.ImageFolder(data_dir)
Downloading ../data/pokemon.zip from http://d2l-data.s3-accelerate.amazonaws.com/pokemon.zip...
#@save
d2l.DATA_HUB['pokemon'] = (d2l.DATA_URL + 'pokemon.zip',
              'c065c0e2593b8b161a2d7873e42418bf6a21106c')

data_dir = d2l.download_extract('pokemon')
pokemon = gluon.data.vision.datasets.ImageFolderDataset(data_dir)
Downloading ../data/pokemon.zip from http://d2l-data.s3-accelerate.amazonaws.com/pokemon.zip...
#@save
d2l.DATA_HUB['pokemon'] = (d2l.DATA_URL + 'pokemon.zip',
              'c065c0e2593b8b161a2d7873e42418bf6a21106c')

data_dir = d2l.download_extract('pokemon')
batch_size = 256
pokemon = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir, batch_size=batch_size, image_size=(64, 64))
Downloading ../data/pokemon.zip from http://d2l-data.s3-accelerate.amazonaws.com/pokemon.zip...
Found 40597 files belonging to 721 classes.

我們將每個(gè)圖像調(diào)整為64×64. 變換ToTensor 會(huì)將像素值投影到[0,1],而我們的生成器將使用 tanh 函數(shù)獲取輸出 [?1,1]. 因此我們用0.5意味著和0.5標(biāo)準(zhǔn)偏差以匹配值范圍。

batch_size = 256
transformer = torchvision.transforms.Compose([
  torchvision.transforms.Resize((64, 64)),
  torchvision.transforms.ToTensor(),
  torchvision.transforms.Normalize(0.5, 0.5)
])
pokemon.transform = transformer
data_iter = torch.utils.data.DataLoader(
  pokemon, batch_size=batch_size,
  shuffle=True, num_workers=d2l.get_dataloader_workers())
batch_size = 256
transformer = gluon.data.vision.transforms.Compose([
  gluon.data.vision.transforms.Resize(64),
  gluon.data.vision.transforms.ToTensor(),
  gluon.data.vision.transforms.Normalize(0.5, 0.5)
])
data_iter = gluon.data.DataLoader(
  pokemon.transform_first(transformer), batch_size=batch_size,
  shuffle=True, num_workers=d2l.get_dataloader_workers())
def transform_func(X):
  X = X / 255.
  X = (X - 0.5) / (0.5)
  return X

# For TF>=2.4 use `num_parallel_calls = tf.data.AUTOTUNE`
data_iter = pokemon.map(lambda x, y: (transform_func(x), y),
            num_parallel_calls=tf.data.experimental.AUTOTUNE)
data_iter = data_iter.cache().shuffle(buffer_size=1000).prefetch(
  buffer_size=tf.data.experimental.AUTOTUNE)
WARNING:tensorflow:From /home/d2l-worker/miniconda3/envs/d2l-en-release-1/lib/python3.9/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py:83: Analyzer.lamba_check (from tensorflow.python.autograph.pyct.static_analysis.liveness) is deprecated and will be removed after 2023-09-23.
Instructions for updating:
Lambda fuctions will be no more assumed to be used in the statement where they are used, or at least in the same block. https://github.com/tensorflow/tensorflow/issues/56089

讓我們想象一下前 20 張圖像。

warnings.filterwarnings('ignore')
d2l.set_figsize((4, 4))
for X, y in data_iter:
  imgs = X[:20,:,:,:].permute(0, 2, 3, 1)/2+0.5
  d2l.show_images(imgs, num_rows=4, num_cols=5)
  break
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9PgeAcQuvAAUFYoaPyj0359.svg
d2l.set_figsize((4, 4))
for X, y in data_iter:
  imgs = X[:20,:,:,:].transpose(0, 2, 3, 1)/2+0.5
  d2l.show_images(imgs, num_rows=4, num_cols=5)
  break
https://file.elecfans.com/web2/M00/AA/49/pYYBAGR9PgqAFv1VAAWC4qBkgJs206.svg
d2l.set_figsize(figsize=(4, 4))
for X, y in data_iter.take(1):
  imgs = X[:20, :, :, :] / 2 + 0.5
  d2l.show_images(imgs, num_rows=4, num_cols=5)
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9Pg6AP2sgAAWKkkbhRrg987.svg

20.2.2。發(fā)電機(jī)

生成器需要映射噪聲變量 z∈Rd, 長度-d向量,到具有寬度和高度的 RGB 圖像64×64. 14.11 節(jié)中我們介紹了全卷積網(wǎng)絡(luò),它使用轉(zhuǎn)置卷積層(參考 14.10 節(jié))來擴(kuò)大輸入尺寸。生成器的基本塊包含一個(gè)轉(zhuǎn)置卷積層,然后是批量歸一化和 ReLU 激活。

class G_block(nn.Module):
  def __init__(self, out_channels, in_channels=3, kernel_size=4, strides=2,
         padding=1, **kwargs):
    super(G_block, self).__init__(**kwargs)
    self.conv2d_trans = nn.ConvTranspose2d(in_channels, out_channels,
                kernel_size, strides, padding, bias=False)
    self.batch_norm = nn.BatchNorm2d(out_channels)
    self.activation = nn.ReLU()

  def forward(self, X):
    return self.activation(self.batch_norm(self.conv2d_trans(X)))
class G_block(nn.Block):
  def __init__(self, channels, kernel_size=4,
         strides=2, padding=1, **kwargs):
    super(G_block, self).__init__(**kwargs)
    self.conv2d_trans = nn.Conv2DTranspose(
      channels, kernel_size, strides, padding, use_bias=False)
    self.batch_norm = nn.BatchNorm()
    self.activation = nn.Activation('relu')

  def forward(self, X):
    return self.activation(self.batch_norm(self.conv2d_trans(X)))
class G_block(tf.keras.layers.Layer):
  def __init__(self, out_channels, kernel_size=4, strides=2, padding="same",
         **kwargs):
    super().__init__(**kwargs)
    self.conv2d_trans = tf.keras.layers.Conv2DTranspose(
      out_channels, kernel_size, strides, padding, use_bias=False)
    self.batch_norm = tf.keras.layers.BatchNormalization()
    self.activation = tf.keras.layers.ReLU()

  def call(self, X):
    return self.activation(self.batch_norm(self.conv2d_trans(X)))

默認(rèn)情況下,轉(zhuǎn)置卷積層使用 kh=kw=4內(nèi)核,一個(gè)sh=sw=2大步前進(jìn),一個(gè) ph=pw=1填充。輸入形狀為 nh′×nw′=16×16,生成器塊將使輸入的寬度和高度加倍。

(20.2.1)nh′×nw′=[(nhkh?(nh?1)(kh?sh)?2ph]×[(nwkw?(nw?1)(kw?sw)?2pw]=[(kh+sh(nh?1)?2ph]×[(kw+sw(nw?1)?2pw]=[(4+2×(16?1)?2×1]×[(4+2×(16?1)?2×1]=32×32.
x = torch.zeros((2, 3, 16, 16))
g_blk = G_block(20)
g_blk(x).shape
torch.Size([2, 20, 32, 32])
x = np.zeros((2, 3, 16, 16))
g_blk = G_block(20)
g_blk.initialize()
g_blk(x).shape
(2, 20, 32, 32)
x = tf.zeros((2, 16, 16, 3)) # Channel last convention
g_blk = G_block(20)
g_blk(x).shape
TensorShape([2, 32, 32, 20])

如果將轉(zhuǎn)置卷積層更改為4×4 核心,1×1步幅和零填充。輸入大小為 1×1,輸出的寬度和高度將分別增加 3。

x = torch.zeros((2, 3, 1, 1))
g_blk = G_block(20, strides=1, padding=0)
g_blk(x).shape
torch.Size([2, 20, 4, 4])
x = np.zeros((2, 3, 1, 1))
g_blk = G_block(20, strides=1, padding=0)
g_blk.initialize()
g_blk(x).shape
(2, 20, 4, 4)
x = tf.zeros((2, 1, 1, 3))
# `padding="valid"` corresponds to no padding
g_blk = G_block(20, strides=1, padding="valid")
g_blk(x).shape
TensorShape([2, 4, 4, 20])

生成器由四個(gè)基本塊組成,將輸入的寬度和高度從 1 增加到 32。同時(shí),它首先將潛在變量投影到64×8通道,然后每次將通道減半。最后,使用轉(zhuǎn)置卷積層生成輸出。它進(jìn)一步加倍寬度和高度以匹配所需的64×64形狀,并將通道尺寸減小到 3. tanh 激活函數(shù)用于將輸出值投影到(?1,1)范圍。

n_G = 64
net_G = nn.Sequential(
  G_block(in_channels=100, out_channels=n_G*8,
      strides=1, padding=0),         # Output: (64 * 8, 4, 4)
  G_block(in_channels=n_G*8, out_channels=n_G*4), # Output: (64 * 4, 8, 8)
  G_block(in_channels=n_G*4, out_channels=n_G*2), # Output: (64 * 2, 16, 16)
  G_block(in_channels=n_G*2, out_channels=n_G),  # Output: (64, 32, 32)
  nn.ConvTranspose2d(in_channels=n_G, out_channels=3,
            kernel_size=4, stride=2, padding=1, bias=False),
  nn.Tanh()) # Output: (3, 64, 64)
n_G = 64
net_G = nn.Sequential()
net_G.add(G_block(n_G*8, strides=1, padding=0), # Output: (64 * 8, 4, 4)
     G_block(n_G*4), # Output: (64 * 4, 8, 8)
     G_block(n_G*2), # Output: (64 * 2, 16, 16)
     G_block(n_G),  # Output: (64, 32, 32)
     nn.Conv2DTranspose(
       3, kernel_size=4, strides=2, padding=1, use_bias=False,
       activation='tanh')) # Output: (3, 64, 64)
n_G = 64
net_G = tf.keras.Sequential([
  # Output: (4, 4, 64 * 8)
  G_block(out_channels=n_G*8, strides=1, padding="valid"),
  G_block(out_channels=n_G*4), # Output: (8, 8, 64 * 4)
  G_block(out_channels=n_G*2), # Output: (16, 16, 64 * 2)
  G_block(out_channels=n_G), # Output: (32, 32, 64)
  # Output: (64, 64, 3)
  tf.keras.layers.Conv2DTranspose(
    3, kernel_size=4, strides=2, padding="same", use_bias=False,
    activation="tanh")
])

生成一個(gè) 100 維的潛在變量來驗(yàn)證生成器的輸出形狀。

x = torch.zeros((1, 100, 1, 1))
net_G(x).shape
torch.Size([1, 3, 64, 64])
x = np.zeros((1, 100, 1, 1))
net_G.initialize()
net_G(x).shape
(1, 3, 64, 64)
x = tf.zeros((1, 1, 1, 100))
net_G(x).shape
TensorShape([1, 64, 64, 3])

20.2.3。判別器

判別器是一個(gè)普通的卷積網(wǎng)絡(luò),除了它使用一個(gè) leaky ReLU 作為它的激活函數(shù)。鑒于 α∈[0,1], 它的定義是

(20.2.2)leaky ReLU(x)={xifx>0αxotherwise.

可以看出,如果α=0,以及一個(gè)身份函數(shù),如果α=1. 為了α∈(0,1),leaky ReLU 是一個(gè)非線性函數(shù),它為負(fù)輸入提供非零輸出。它旨在解決“垂死的 ReLU”問題,即神經(jīng)元可能始終輸出負(fù)值,因此無法取得任何進(jìn)展,因?yàn)?ReLU 的梯度為 0。

alphas = [0, .2, .4, .6, .8, 1]
x = torch.arange(-2, 1, 0.1)
Y = [nn.LeakyReLU(alpha)(x).detach().numpy() for alpha in alphas]
d2l.plot(x.detach().numpy(), Y, 'x', 'y', alphas)
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9PhKAAphBAACN8Sd5kmw122.svg
alphas = [0, .2, .4, .6, .8, 1]
x = np.arange(-2, 1, 0.1)
Y = [nn.LeakyReLU(alpha)(x).asnumpy() for alpha in alphas]
d2l.plot(x.asnumpy(), Y, 'x', 'y', alphas)
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9PhSAVJfHAACN_mMaeFE528.svg
alphas = [0, .2, .4, .6, .8, 1]
x = tf.range(-2, 1, 0.1)
Y = [tf.keras.layers.LeakyReLU(alpha)(x).numpy() for alpha in alphas]
d2l.plot(x.numpy(), Y, 'x', 'y', alphas)
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9PhaAZDDrAACPk58eqYI298.svg

判別器的基本塊是一個(gè)卷積層,然后是一個(gè)批量歸一化層和一個(gè) leaky ReLU 激活。卷積層的超參數(shù)類似于生成器塊中的轉(zhuǎn)置卷積層。

class D_block(nn.Module):
  def __init__(self, out_channels, in_channels=3, kernel_size=4, strides=2,
        padding=1, alpha=0.2, **kwargs):
    super(D_block, self).__init__(**kwargs)
    self.conv2d = nn.Conv2d(in_channels, out_channels, kernel_size,
                strides, padding, bias=False)
    self.batch_norm = nn.BatchNorm2d(out_channels)
    self.activation = nn.LeakyReLU(alpha, inplace=True)

  def forward(self, X):
    return self.activation(self.batch_norm(self.conv2d(X)))
class D_block(nn.Block):
  def __init__(self, channels, kernel_size=4, strides=2,
         padding=1, alpha=0.2, **kwargs):
    super(D_block, self).__init__(**kwargs)
    self.conv2d = nn.Conv2D(
      channels, kernel_size, strides, padding, use_bias=False)
    self.batch_norm = nn.BatchNorm()
    self.activation = nn.LeakyReLU(alpha)

  def forward(self, X):
    return self.activation(self.batch_norm(self.conv2d(X)))
class D_block(tf.keras.layers.Layer):
  def __init__(self, out_channels, kernel_size=4, strides=2, padding="same",
         alpha=0.2, **kwargs):
    super().__init__(**kwargs)
    self.conv2d = tf.keras.layers.Conv2D(out_channels, kernel_size,
                       strides, padding, use_bias=False)
    self.batch_norm = tf.keras.layers.BatchNormalization()
    self.activation = tf.keras.layers.LeakyReLU(alpha)

  def call(self, X):
    return self.activation(self.batch_norm(self.conv2d(X)))

正如我們?cè)诘?7.3 節(jié)中演示的那樣,具有默認(rèn)設(shè)置的基本塊會(huì)將輸入的寬度和高度減半例如,給定一個(gè)輸入形狀nh=nw=16, 具有內(nèi)核形狀 kh=kw=4, 步幅sh=sw=2和填充形狀ph=pw=1,輸出形狀將是:

(20.2.3)nh′×nw′=?(nh?kh+2ph+sh)/sh?×?(nw?kw+2pw+sw)/sw?=?(16?4+2×1+2)/2?×?(16?4+2×1+2)/2?=8×8.
x = torch.zeros((2, 3, 16, 16))
d_blk = D_block(20)
d_blk(x).shape
torch.Size([2, 20, 8, 8])
x = np.zeros((2, 3, 16, 16))
d_blk = D_block(20)
d_blk.initialize()
d_blk(x).shape
(2, 20, 8, 8)
x = tf.zeros((2, 16, 16, 3))
d_blk = D_block(20)
d_blk(x).shape
TensorShape([2, 8, 8, 20])

鑒別器是生成器的鏡像。

n_D = 64
net_D = nn.Sequential(
  D_block(n_D), # Output: (64, 32, 32)
  D_block(in_channels=n_D, out_channels=n_D*2), # Output: (64 * 2, 16, 16)
  D_block(in_channels=n_D*2, out_channels=n_D*4), # Output: (64 * 4, 8, 8)
  D_block(in_channels=n_D*4, out_channels=n_D*8), # Output: (64 * 8, 4, 4)
  nn.Conv2d(in_channels=n_D*8, out_channels=1,
       kernel_size=4, bias=False)) # Output: (1, 1, 1)
n_D = 64
net_D = nn.Sequential()
net_D.add(D_block(n_D),  # Output: (64, 32, 32)
     D_block(n_D*2), # Output: (64 * 2, 16, 16)
     D_block(n_D*4), # Output: (64 * 4, 8, 8)
     D_block(n_D*8), # Output: (64 * 8, 4, 4)
     nn.Conv2D(1, kernel_size=4, use_bias=False)) # Output: (1, 1, 1)
n_D = 64
net_D = tf.keras.Sequential([
  D_block(n_D), # Output: (32, 32, 64)
  D_block(out_channels=n_D*2), # Output: (16, 16, 64 * 2)
  D_block(out_channels=n_D*4), # Output: (8, 8, 64 * 4)
  D_block(out_channels=n_D*8), # Outupt: (4, 4, 64 * 64)
  # Output: (1, 1, 1)
  tf.keras.layers.Conv2D(1, kernel_size=4, use_bias=False)
])

它使用帶有輸出通道的卷積層1作為獲得單個(gè)預(yù)測(cè)值的最后一層。

x = torch.zeros((1, 3, 64, 64))
net_D(x).shape
torch.Size([1, 1, 1, 1])
x = np.zeros((1, 3, 64, 64))
net_D.initialize()
net_D(x).shape
(1, 1, 1, 1)
x = tf.zeros((1, 64, 64, 3))
net_D(x).shape
TensorShape([1, 1, 1, 1])

20.2.4。訓(xùn)練

第 20.1 節(jié)中的基本 GAN 相比,我們對(duì)生成器和鑒別器使用相同的學(xué)習(xí)率,因?yàn)樗鼈儽舜讼嗨啤?/font>此外,我們改變β1在 Adam 中(第 12.10 節(jié))來自0.90.5. 它降低了動(dòng)量的平滑度,即過去梯度的指數(shù)加權(quán)移動(dòng)平均值,以處理快速變化的梯度,因?yàn)樯善骱丸b別器相互爭斗。此外,隨機(jī)生成的噪聲Z是一個(gè) 4-D 張量,我們正在使用 GPU加速計(jì)算。

def train(net_D, net_G, data_iter, num_epochs, lr, latent_dim,
     device=d2l.try_gpu()):
  loss = nn.BCEWithLogitsLoss(reduction='sum')
  for w in net_D.parameters():
    nn.init.normal_(w, 0, 0.02)
  for w in net_G.parameters():
    nn.init.normal_(w, 0, 0.02)
  net_D, net_G = net_D.to(device), net_G.to(device)
  trainer_hp = {'lr': lr, 'betas': [0.5,0.999]}
  trainer_D = torch.optim.Adam(net_D.parameters(), **trainer_hp)
  trainer_G = torch.optim.Adam(net_G.parameters(), **trainer_hp)
  animator = d2l.Animator(xlabel='epoch', ylabel='loss',
              xlim=[1, num_epochs], nrows=2, figsize=(5, 5),
              legend=['discriminator', 'generator'])
  animator.fig.subplots_adjust(hspace=0.3)
  for epoch in range(1, num_epochs + 1):
    # Train one epoch
    timer = d2l.Timer()
    metric = d2l.Accumulator(3) # loss_D, loss_G, num_examples
    for X, _ in data_iter:
      batch_size = X.shape[0]
      Z = torch.normal(0, 1, size=(batch_size, latent_dim, 1, 1))
      X, Z = X.to(device), Z.to(device)
      metric.add(d2l.update_D(X, Z, net_D, net_G, loss, trainer_D),
            d2l.update_G(Z, net_D, net_G, loss, trainer_G),
            batch_size)
    # Show generated examples
    Z = torch.normal(0, 1, size=(21, latent_dim, 1, 1), device=device)
    # Normalize the synthetic data to N(0, 1)
    fake_x = net_G(Z).permute(0, 2, 3, 1) / 2 + 0.5
    imgs = torch.cat(
      [torch.cat([
        fake_x[i * 7 + j].cpu().detach() for j in range(7)], dim=1)
       for i in range(len(fake_x)//7)], dim=0)
    animator.axes[1].cla()
    animator.axes[1].imshow(imgs)
    # Show the losses
    loss_D, loss_G = metric[0] / metric[2], metric[1] / metric[2]
    animator.add(epoch, (loss_D, loss_G))
  print(f'loss_D {loss_D:.3f}, loss_G {loss_G:.3f}, '
     f'{metric[2] / timer.stop():.1f} examples/sec on {str(device)}')
def train(net_D, net_G, data_iter, num_epochs, lr, latent_dim,
     device=d2l.try_gpu()):
  loss = gluon.loss.SigmoidBCELoss()
  net_D.initialize(init=init.Normal(0.02), force_reinit=True, ctx=device)
  net_G.initialize(init=init.Normal(0.02), force_reinit=True, ctx=device)
  trainer_hp = {'learning_rate': lr, 'beta1': 0.5}
  trainer_D = gluon.Trainer(net_D.collect_params(), 'adam', trainer_hp)
  trainer_G = gluon.Trainer(net_G.collect_params(), 'adam', trainer_hp)
  animator = d2l.Animator(xlabel='epoch', ylabel='loss',
              xlim=[1, num_epochs], nrows=2, figsize=(5, 5),
              legend=['discriminator', 'generator'])
  animator.fig.subplots_adjust(hspace=0.3)
  for epoch in range(1, num_epochs + 1):
    # Train one epoch
    timer = d2l.Timer()
    metric = d2l.Accumulator(3) # loss_D, loss_G, num_examples
    for X, _ in data_iter:
      batch_size = X.shape[0]
      Z = np.random.normal(0, 1, size=(batch_size, latent_dim, 1, 1))
      X, Z = X.as_in_ctx(device), Z.as_in_ctx(device),
      metric.add(d2l.update_D(X, Z, net_D, net_G, loss, trainer_D),
            d2l.update_G(Z, net_D, net_G, loss, trainer_G),
            batch_size)
    # Show generated examples
    Z = np.random.normal(0, 1, size=(21, latent_dim, 1, 1), ctx=device)
    # Normalize the synthetic data to N(0, 1)
    fake_x = net_G(Z).transpose(0, 2, 3, 1) / 2 + 0.5
    imgs = np.concatenate(
      [np.concatenate([fake_x[i * 7 + j] for j in range(7)], axis=1)
       for i in range(len(fake_x)//7)], axis=0)
    animator.axes[1].cla()
    animator.axes[1].imshow(imgs.asnumpy())
    # Show the losses
    loss_D, loss_G = metric[0] / metric[2], metric[1] / metric[2]
    animator.add(epoch, (loss_D, loss_G))
  print(f'loss_D {loss_D:.3f}, loss_G {loss_G:.3f}, '
     f'{metric[2] / timer.stop():.1f} examples/sec on {str(device)}')
def train(net_D, net_G, data_iter, num_epochs, lr, latent_dim,
     device=d2l.try_gpu()):
  loss = tf.keras.losses.BinaryCrossentropy(
    from_logits=True, reduction=tf.keras.losses.Reduction.SUM)

  for w in net_D.trainable_variables:
    w.assign(tf.random.normal(mean=0, stddev=0.02, shape=w.shape))
  for w in net_G.trainable_variables:
    w.assign(tf.random.normal(mean=0, stddev=0.02, shape=w.shape))

  optimizer_hp = {"lr": lr, "beta_1": 0.5, "beta_2": 0.999}
  optimizer_D = tf.keras.optimizers.Adam(**optimizer_hp)
  optimizer_G = tf.keras.optimizers.Adam(**optimizer_hp)

  animator = d2l.Animator(xlabel='epoch', ylabel='loss',
              xlim=[1, num_epochs], nrows=2, figsize=(5, 5),
              legend=['discriminator', 'generator'])
  animator.fig.subplots_adjust(hspace=0.3)

  for epoch in range(1, num_epochs + 1):
    # Train one epoch
    timer = d2l.Timer()
    metric = d2l.Accumulator(3) # loss_D, loss_G, num_examples
    for X, _ in data_iter:
      batch_size = X.shape[0]
      Z = tf.random.normal(mean=0, stddev=1,
                 shape=(batch_size, 1, 1, latent_dim))
      metric.add(d2l.update_D(X, Z, net_D, net_G, loss, optimizer_D),
            d2l.update_G(Z, net_D, net_G, loss, optimizer_G),
            batch_size)

    # Show generated examples
    Z = tf.random.normal(mean=0, stddev=1, shape=(21, 1, 1, latent_dim))
    # Normalize the synthetic data to N(0, 1)
    fake_x = net_G(Z) / 2 + 0.5
    imgs = tf.concat([tf.concat([fake_x[i * 7 + j] for j in range(7)],
                  axis=1)
             for i in range(len(fake_x) // 7)], axis=0)
    animator.axes[1].cla()
    animator.axes[1].imshow(imgs)
    # Show the losses
    loss_D, loss_G = metric[0] / metric[2], metric[1] / metric[2]
    animator.add(epoch, (loss_D, loss_G))
  print(f'loss_D {loss_D:.3f}, loss_G {loss_G:.3f}, '
     f'{metric[2] / timer.stop():.1f} examples/sec on {str(device._device_name)}')

我們用少量的 epochs 訓(xùn)練模型只是為了演示。為了獲得更好的性能,可以將變量num_epochs設(shè)置為更大的數(shù)字。

latent_dim, lr, num_epochs = 100, 0.005, 20
train(net_D, net_G, data_iter, num_epochs, lr, latent_dim)
loss_D 0.030, loss_G 7.203, 1026.4 examples/sec on cuda:0
https://file.elecfans.com/web2/M00/AA/49/pYYBAGR9PhmAKNvvAAQ_akulsoA525.svg
latent_dim, lr, num_epochs = 100, 0.005, 20
train(net_D, net_G, data_iter, num_epochs, lr, latent_dim)
loss_D 0.224, loss_G 6.386, 2260.7 examples/sec on gpu(0)
https://file.elecfans.com/web2/M00/A9/CE/poYBAGR9PhyANJTuAAQWXCMFF5g049.svg
latent_dim, lr, num_epochs = 100, 0.0005, 40
train(net_D, net_G, data_iter, num_epochs, lr, latent_dim)
loss_D 0.112, loss_G 4.952, 1968.2 examples/sec on /GPU:0
https://file.elecfans.com/web2/M00/AA/49/pYYBAGR9Ph6ANe_HAAP3DIt7UTs347.svg

20.2.5。概括

  • DCGAN 架構(gòu)有四個(gè)用于鑒別器的卷積層和四個(gè)用于生成器的“分?jǐn)?shù)步”卷積層。

  • 鑒別器是一個(gè) 4 層跨步卷積,具有批量歸一化(除了它的輸入層)和 leaky ReLU 激活。

  • Leaky ReLU 是一種非線性函數(shù),可為負(fù)輸入提供非零輸出。它旨在解決“垂死的 ReLU”問題,并幫助梯度更容易地通過架構(gòu)。

20.2.6. 練習(xí)

  1. 如果我們使用標(biāo)準(zhǔn) ReLU 激活而不是 leaky ReLU 會(huì)發(fā)生什么?

  2. 在 Fashion-MNIST 上應(yīng)用 DCGAN,看看哪個(gè)類別效果好,哪個(gè)效果不好。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    809

    瀏覽量

    13876
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    圖像生成對(duì)抗生成網(wǎng)絡(luò)gan_GAN生成汽車圖像 精選資料推薦

    圖像生成對(duì)抗生成網(wǎng)絡(luò)ganHello there! This is my story of making a GAN that would generate images of cars
    發(fā)表于 08-31 06:48

    圖像生成對(duì)抗生成網(wǎng)絡(luò)

    圖像生成對(duì)抗生成網(wǎng)絡(luò)ganby Thalles Silva 由Thalles Silva暖身 (Warm up)Let’s say there’s a very cool party going
    發(fā)表于 09-15 09:29

    生成對(duì)抗網(wǎng)絡(luò)模型綜述

    ,開創(chuàng)性地提出了生成對(duì)抗網(wǎng)絡(luò)( GAN)。生成對(duì)抗網(wǎng)絡(luò)包含一個(gè)生成模型和一個(gè)判別模型。其中,生成
    發(fā)表于 04-03 10:48 ?1次下載
    <b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>模型綜述

    生成對(duì)抗網(wǎng)絡(luò)GAN,正在成為新的“深度學(xué)習(xí)”

    生成對(duì)抗網(wǎng)絡(luò)由一個(gè)生成網(wǎng)絡(luò)(Generator)與一個(gè)判別網(wǎng)絡(luò)(Discriminator)組成。生成
    的頭像 發(fā)表于 06-11 16:04 ?5105次閱讀
    <b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>GAN,正在成為新的“<b class='flag-5'>深度</b>學(xué)習(xí)”

    如何使用生成對(duì)抗網(wǎng)絡(luò)進(jìn)行信息隱藏方案資料說明

    針對(duì)信息隱藏中含密栽體會(huì)留有修改痕跡,從根本上難以抵抗基于統(tǒng)計(jì)的隱寫分析算法檢測(cè)的問題,提出一種基于生成對(duì)抗網(wǎng)絡(luò)( GAN)的信息隱藏方案。該方案首先利用生成對(duì)抗網(wǎng)絡(luò)中的
    發(fā)表于 12-12 16:57 ?6次下載
    如何使用<b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>進(jìn)行信息隱藏方案資料說明

    如何使用深度殘差生成對(duì)抗網(wǎng)絡(luò)設(shè)計(jì)醫(yī)學(xué)影像超分辨率算法

    針對(duì)醫(yī)學(xué)影像超分辨率重建過程中細(xì)節(jié)丟失導(dǎo)致的模糊問題,提出了一種基于深度殘差生成對(duì)抗網(wǎng)絡(luò)( GAN)的醫(yī)學(xué)影像超分辨率算法。首先,算法包括生成網(wǎng)絡(luò)
    發(fā)表于 01-02 16:59 ?5次下載
    如何使用<b class='flag-5'>深度</b>殘差<b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>設(shè)計(jì)醫(yī)學(xué)影像超分辨率算法

    基于譜歸一化條件生成對(duì)抗網(wǎng)絡(luò)的圖像修復(fù)算法

    基于生成對(duì)抗網(wǎng)絡(luò)的圖像修復(fù)算法在修復(fù)大尺寸缺失圖像時(shí),存在圖像失真較多與判別網(wǎng)絡(luò)性能不可控等問題,基于譜歸一化條件生成對(duì)抗網(wǎng)絡(luò),提出一種新的
    發(fā)表于 03-12 10:22 ?14次下載
    基于譜歸一化條件<b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>的圖像修復(fù)算法

    基于生成對(duì)抗網(wǎng)絡(luò)深度偽造視頻綜述

    深度偽造的濫用,給囯家、社會(huì)和個(gè)人帶來了潛在威脅。首先,介紹了深度偽造的概念和當(dāng)前發(fā)展趨勢(shì),分析了基于生成對(duì)抗網(wǎng)絡(luò)深度偽造視頻的
    發(fā)表于 05-10 15:39 ?11次下載

    基于密集卷積生成對(duì)抗網(wǎng)絡(luò)的圖像修復(fù)方法

    差等問題。針對(duì)上述問題,文中提出了一種基于密集卷積生成對(duì)抗網(wǎng)絡(luò)的圖像修復(fù)算法。該算法采用生成對(duì)抗網(wǎng)絡(luò)作為圖像修復(fù)的基本框架。首先,利用密集
    發(fā)表于 05-13 14:39 ?15次下載

    注塑瓶檢測(cè)的半監(jiān)督深度卷積生成對(duì)抗網(wǎng)絡(luò)模型

    ( Semi-supervised)深度卷積生成對(duì)抗網(wǎng)絡(luò)( Deep Convolutional Generative Adversarial Network, DCGAN)模型。該模
    發(fā)表于 05-18 14:24 ?2次下載

    基于深度卷積生成對(duì)抗網(wǎng)絡(luò)的花朵圖像識(shí)別分類

    為了提高花朵圖像識(shí)別與分類的準(zhǔn)確率,采用基于深度卷積生成對(duì)抗網(wǎng)絡(luò)的算法來完成花朵圖像的識(shí)別與分類。為了保證花朵圖像在卷積過程中的特征完整性,
    發(fā)表于 05-28 16:51 ?5次下載

    基于像素級(jí)生成對(duì)抗網(wǎng)絡(luò)的圖像彩色化模型

    基于像素級(jí)生成對(duì)抗網(wǎng)絡(luò)的圖像彩色化模型
    發(fā)表于 06-27 11:02 ?4次下載

    PyTorch教程8.1之深度卷積神經(jīng)網(wǎng)絡(luò)(AlexNet)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程8.1之深度卷積神經(jīng)網(wǎng)絡(luò)(AlexNet).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 10:09 ?0次下載
    <b class='flag-5'>PyTorch</b>教程8.1之<b class='flag-5'>深度</b><b class='flag-5'>卷積</b>神經(jīng)<b class='flag-5'>網(wǎng)絡(luò)</b>(AlexNet)

    PyTorch教程20.2深度卷積生成對(duì)抗網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程20.2深度卷積生成對(duì)抗網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 10:21 ?2次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>20.2</b>之<b class='flag-5'>深度</b><b class='flag-5'>卷積</b><b class='flag-5'>生成對(duì)抗</b><b class='flag-5'>網(wǎng)絡(luò)</b>

    生成對(duì)抗網(wǎng)絡(luò)(GANs)的原理與應(yīng)用案例

    生成對(duì)抗網(wǎng)絡(luò)(Generative Adversarial Networks,GANs)是一種由蒙特利爾大學(xué)的Ian Goodfellow等人在2014年提出的深度學(xué)習(xí)算法。GANs通過構(gòu)建兩個(gè)
    的頭像 發(fā)表于 07-09 11:34 ?2301次閱讀
    主站蜘蛛池模板: 色www免费视频 | 五月天婷婷电影 | 97综合久久| 亚洲视频在线一区二区 | 久久久久久久久久久观看 | 免费国产成高清人在线视频 | 美女又黄又免费 | 99草精品视频 | 播放欧亚一级特黄录像 | 天天摸夜夜摸爽爽狠狠婷婷97 | 天天爱天天操天天干 | 性色欧美xo影院 | 日本大黄在线观看 | 日本一视频一区视频二区 | 天天干天天操天天玩 | 大尺度视频在线观看 | 天天综合亚洲国产色 | 久久黄色一级片 | 毛片站 | 人人爱干 | 天天做天天爱天天爽 | 二区久久国产乱子伦免费精品 | 五月婷婷亚洲综合 | 亚洲免费色 | 欧美在线精品一区二区三区 | 欧美三级黄色 | 99视频网址| 欧美性色xo影院在线观看 | 国产在线麻豆自在拍91精品 | 一区一精品 | 美女免费毛片 | 久久老色鬼天天综合网观看 | 李老汉和小花的性生生活 | 日本一区二区高清免费不卡 | 狠狠天天 | 中文字幕久久精品波多野结 | 国产va | 九九99久久精品影视 | 日本亚洲天堂网 | 国产成人精品免费视频大全可播放的 | 免费被黄网站在观看 |