精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

PyTorch教程-20.2. 深度卷積生成對抗網絡

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀

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

在本節中,我們將演示如何使用 GAN 生成逼真的圖像。我們的模型將基于 Radford等人介紹的深度卷積 GAN (DCGAN)。2015 年我們將借用已經證明在判別計算機視覺問題上非常成功的卷積架構,并展示如何通過 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。口袋妖怪數據集

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

#@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.

我們將每個圖像調整為64×64. 變換ToTensor 會將像素值投影到[0,1],而我們的生成器將使用 tanh 函數獲取輸出 [?1,1]. 因此我們用0.5意味著和0.5標準偏差以匹配值范圍。

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。發電機

生成器需要映射噪聲變量 z∈Rd, 長度-d向量,到具有寬度和高度的 RGB 圖像64×64. 14.11 節中我們介紹了全卷積網絡,它使用轉置卷積層(參考 14.10 節)來擴大輸入尺寸。生成器的基本塊包含一個轉置卷積層,然后是批量歸一化和 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)))

默認情況下,轉置卷積層使用 kh=kw=4內核,一個sh=sw=2大步前進,一個 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])

如果將轉置卷積層更改為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])

生成器由四個基本塊組成,將輸入的寬度和高度從 1 增加到 32。同時,它首先將潛在變量投影到64×8通道,然后每次將通道減半。最后,使用轉置卷積層生成輸出。它進一步加倍寬度和高度以匹配所需的64×64形狀,并將通道尺寸減小到 3. tanh 激活函數用于將輸出值投影到(?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")
])

生成一個 100 維的潛在變量來驗證生成器的輸出形狀。

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。判別器

判別器是一個普通的卷積網絡,除了它使用一個 leaky ReLU 作為它的激活函數。鑒于 α∈[0,1], 它的定義是

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

可以看出,如果α=0,以及一個身份函數,如果α=1. 為了α∈(0,1),leaky ReLU 是一個非線性函數,它為負輸入提供非零輸出。它旨在解決“垂死的 ReLU”問題,即神經元可能始終輸出負值,因此無法取得任何進展,因為 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

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

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)))

正如我們在第 7.3 節中演示的那樣,具有默認設置的基本塊會將輸入的寬度和高度減半例如,給定一個輸入形狀nh=nw=16, 具有內核形狀 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作為獲得單個預測值的最后一層。

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。訓練

第 20.1 節中的基本 GAN 相比,我們對生成器和鑒別器使用相同的學習率,因為它們彼此相似。此外,我們改變β1在 Adam 中(第 12.10 節)來自0.90.5. 它降低了動量的平滑度,即過去梯度的指數加權移動平均值,以處理快速變化的梯度,因為生成器和鑒別器相互爭斗。此外,隨機生成的噪聲Z是一個 4-D 張量,我們正在使用 GPU加速計算。

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 訓練模型只是為了演示。為了獲得更好的性能,可以將變量num_epochs設置為更大的數字。

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 架構有四個用于鑒別器的卷積層和四個用于生成器的“分數步”卷積層。

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

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

20.2.6. 練習

  1. 如果我們使用標準 ReLU 激活而不是 leaky ReLU 會發生什么?

  2. 在 Fashion-MNIST 上應用 DCGAN,看看哪個類別效果好,哪個效果不好。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • pytorch
    +關注

    關注

    2

    文章

    803

    瀏覽量

    13152
收藏 人收藏

    評論

    相關推薦

    圖像生成對抗生成網絡gan_GAN生成汽車圖像 精選資料推薦

    圖像生成對抗生成網絡ganHello there! This is my story of making a GAN that would generate images of cars
    發表于 08-31 06:48

    圖像生成對抗生成網絡

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

    生成對抗網絡模型綜述

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

    生成對抗網絡GAN,正在成為新的“深度學習”

    生成對抗網絡由一個生成網絡(Generator)與一個判別網絡(Discriminator)組成。生成
    的頭像 發表于 06-11 16:04 ?4766次閱讀
    <b class='flag-5'>生成對抗</b><b class='flag-5'>網絡</b>GAN,正在成為新的“<b class='flag-5'>深度</b>學習”

    如何使用生成對抗網絡進行信息隱藏方案資料說明

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

    如何使用深度殘差生成對抗網絡設計醫學影像超分辨率算法

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

    基于譜歸一化條件生成對抗網絡的圖像修復算法

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

    基于生成對抗網絡深度偽造視頻綜述

    深度偽造的濫用,給囯家、社會和個人帶來了潛在威脅。首先,介紹了深度偽造的概念和當前發展趨勢,分析了基于生成對抗網絡深度偽造視頻的
    發表于 05-10 15:39 ?11次下載

    基于密集卷積生成對抗網絡的圖像修復方法

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

    注塑瓶檢測的半監督深度卷積生成對抗網絡模型

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

    基于深度卷積生成對抗網絡的花朵圖像識別分類

    為了提高花朵圖像識別與分類的準確率,采用基于深度卷積生成對抗網絡的算法來完成花朵圖像的識別與分類。為了保證花朵圖像在卷積過程中的特征完整性,
    發表于 05-28 16:51 ?5次下載

    基于像素級生成對抗網絡的圖像彩色化模型

    基于像素級生成對抗網絡的圖像彩色化模型
    發表于 06-27 11:02 ?4次下載

    PyTorch教程8.1之深度卷積神經網絡(AlexNet)

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

    PyTorch教程20.2深度卷積生成對抗網絡

    電子發燒友網站提供《PyTorch教程20.2深度卷積生成對抗網絡.pdf》資料免費下載
    發表于 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'>生成對抗</b><b class='flag-5'>網絡</b>

    生成對抗網絡(GANs)的原理與應用案例

    生成對抗網絡(Generative Adversarial Networks,GANs)是一種由蒙特利爾大學的Ian Goodfellow等人在2014年提出的深度學習算法。GANs通過構建兩個
    的頭像 發表于 07-09 11:34 ?821次閱讀