pix2pix: Koşullu GAN ile görüntüden görüntüye çeviri

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Bu öğretici, Isola ve diğerleri tarafından koşullu rakip ağlarla Görüntüden görüntüye çeviri bölümünde açıklandığı gibi, giriş görüntülerinden çıktı görüntülerine bir eşleme öğrenen pix2pix adlı koşullu bir üretici hasım ağının (cGAN) nasıl oluşturulacağını ve eğitileceğini gösterir. (2017). pix2pix uygulamaya özel değildir; etiket haritalarından fotoğrafları sentezlemek, siyah beyaz görüntülerden renkli fotoğraflar oluşturmak, Google Haritalar fotoğraflarını havadan görüntülere dönüştürmek ve hatta eskizleri fotoğraflara dönüştürmek gibi çok çeşitli görevlere uygulanabilir.

Bu örnekte, ağınız Prag'daki Çek Teknik Üniversitesi'ndeki Makine Algılama Merkezi tarafından sağlanan CMP Cephe Veritabanını kullanarak bina cephelerinin görüntülerini oluşturacaktır. Kısa tutmak için, pix2pix yazarları tarafından oluşturulan bu veri kümesinin önceden işlenmiş bir kopyasını kullanacaksınız.

pix2pix cGAN'da giriş görüntülerini koşullandırır ve karşılık gelen çıktı görüntülerini oluşturursunuz. cGAN'lar ilk olarak Koşullu Üretken Düşman Ağlarında önerildi (Mirza ve Osindero, 2014)

Ağınızın mimarisi şunları içerecektir:

  • U-Net tabanlı mimariye sahip bir jeneratör.
  • Evrişimli PatchGAN sınıflandırıcısı tarafından temsil edilen bir ayırıcı ( pix2pix makalesinde önerilmiştir).

Tek bir V100 GPU'da her dönemin yaklaşık 15 saniye sürebileceğini unutmayın.

Aşağıda, cepheler veri kümesinde (80k adım) 200 dönemlik eğitimden sonra pix2pix cGAN tarafından üretilen çıktının bazı örnekleri verilmiştir.

örnek çıktı_1örnek çıktı_2

TensorFlow ve diğer kitaplıkları içe aktarın

import tensorflow as tf

import os
import pathlib
import time
import datetime

from matplotlib import pyplot as plt
from IPython import display

Veri kümesini yükleyin

CMP Cephe Veritabanı verilerini indirin (30MB). Ek veri kümeleri burada aynı biçimde mevcuttur. Colab'de açılır menüden diğer veri kümelerini seçebilirsiniz. Diğer veri kümelerinden bazılarının önemli ölçüde daha büyük olduğuna dikkat edin ( edges2handbags 8GB).

dataset_name = "facades"
_URL = f'http://efrosgans.eecs.berkeley.edu/pix2pix/datasets/{dataset_name}.tar.gz'

path_to_zip = tf.keras.utils.get_file(
    fname=f"{dataset_name}.tar.gz",
    origin=_URL,
    extract=True)

path_to_zip  = pathlib.Path(path_to_zip)

PATH = path_to_zip.parent/dataset_name
Downloading data from http://efrosgans.eecs.berkeley.edu/pix2pix/datasets/facades.tar.gz
30171136/30168306 [==============================] - 19s 1us/step
30179328/30168306 [==============================] - 19s 1us/step
list(PATH.parent.iterdir())
[PosixPath('/home/kbuilder/.keras/datasets/facades.tar.gz'),
 PosixPath('/home/kbuilder/.keras/datasets/YellowLabradorLooking_new.jpg'),
 PosixPath('/home/kbuilder/.keras/datasets/facades'),
 PosixPath('/home/kbuilder/.keras/datasets/mnist.npz')]

Her orijinal görüntü, iki adet 256 x 256 görüntü içeren 256 x 512 boyutundadır:

sample_image = tf.io.read_file(str(PATH / 'train/1.jpg'))
sample_image = tf.io.decode_jpeg(sample_image)
print(sample_image.shape)
(256, 512, 3)
yer tutucu8 l10n-yer
plt.figure()
plt.imshow(sample_image)
<matplotlib.image.AxesImage at 0x7f35a3653c90>

png

Gerçek bina cephe görüntülerini mimari etiket görüntülerinden ayırmanız gerekir; bunların tümü 256 x 256 boyutunda olacaktır.

Görüntü dosyalarını yükleyen ve iki görüntü tensörü çıkaran bir işlev tanımlayın:

def load(image_file):
  # Read and decode an image file to a uint8 tensor
  image = tf.io.read_file(image_file)
  image = tf.io.decode_jpeg(image)

  # Split each image tensor into two tensors:
  # - one with a real building facade image
  # - one with an architecture label image 
  w = tf.shape(image)[1]
  w = w // 2
  input_image = image[:, w:, :]
  real_image = image[:, :w, :]

  # Convert both images to float32 tensors
  input_image = tf.cast(input_image, tf.float32)
  real_image = tf.cast(real_image, tf.float32)

  return input_image, real_image

Girdi (mimari etiket görüntüsü) ve gerçek (bina cephe fotoğrafı) görüntülerin bir örneğini çizin:

inp, re = load(str(PATH / 'train/100.jpg'))
# Casting to int for matplotlib to display the images
plt.figure()
plt.imshow(inp / 255.0)
plt.figure()
plt.imshow(re / 255.0)
tutucu12 l10n-yer
<matplotlib.image.AxesImage at 0x7f35981a4910>

png

png

pix2pix makalesinde açıklandığı gibi, eğitim setini önceden işlemek için rastgele titreşim ve aynalama uygulamanız gerekir.

Aşağıdakileri sağlayan birkaç işlevi tanımlayın:

  1. Her 256 x 256 görüntüyü daha büyük bir yükseklik ve genişlikte yeniden boyutlandırın - 286 x 286 .
  2. Rastgele 256 x 256 kırpın.
  3. Görüntüyü rastgele yatay olarak, yani soldan sağa çevirin (rastgele yansıtma).
  4. Görüntüleri [-1, 1] aralığına normalleştirin.
# The facade training set consist of 400 images
BUFFER_SIZE = 400
# The batch size of 1 produced better results for the U-Net in the original pix2pix experiment
BATCH_SIZE = 1
# Each image is 256x256 in size
IMG_WIDTH = 256
IMG_HEIGHT = 256
def resize(input_image, real_image, height, width):
  input_image = tf.image.resize(input_image, [height, width],
                                method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
  real_image = tf.image.resize(real_image, [height, width],
                               method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)

  return input_image, real_image
def random_crop(input_image, real_image):
  stacked_image = tf.stack([input_image, real_image], axis=0)
  cropped_image = tf.image.random_crop(
      stacked_image, size=[2, IMG_HEIGHT, IMG_WIDTH, 3])

  return cropped_image[0], cropped_image[1]
# Normalizing the images to [-1, 1]
def normalize(input_image, real_image):
  input_image = (input_image / 127.5) - 1
  real_image = (real_image / 127.5) - 1

  return input_image, real_image
@tf.function()
def random_jitter(input_image, real_image):
  # Resizing to 286x286
  input_image, real_image = resize(input_image, real_image, 286, 286)

  # Random cropping back to 256x256
  input_image, real_image = random_crop(input_image, real_image)

  if tf.random.uniform(()) > 0.5:
    # Random mirroring
    input_image = tf.image.flip_left_right(input_image)
    real_image = tf.image.flip_left_right(real_image)

  return input_image, real_image

Önceden işlenmiş çıktılardan bazılarını inceleyebilirsiniz:

plt.figure(figsize=(6, 6))
for i in range(4):
  rj_inp, rj_re = random_jitter(inp, re)
  plt.subplot(2, 2, i + 1)
  plt.imshow(rj_inp / 255.0)
  plt.axis('off')
plt.show()

png

Yükleme ve ön işlemenin çalıştığını kontrol ettikten sonra, eğitim ve test setlerini yükleyen ve önişleyen birkaç yardımcı fonksiyon tanımlayalım:

def load_image_train(image_file):
  input_image, real_image = load(image_file)
  input_image, real_image = random_jitter(input_image, real_image)
  input_image, real_image = normalize(input_image, real_image)

  return input_image, real_image
tutucu20 l10n-yer
def load_image_test(image_file):
  input_image, real_image = load(image_file)
  input_image, real_image = resize(input_image, real_image,
                                   IMG_HEIGHT, IMG_WIDTH)
  input_image, real_image = normalize(input_image, real_image)

  return input_image, real_image

tf.data ile bir girdi ardışık düzeni oluşturun

train_dataset = tf.data.Dataset.list_files(str(PATH / 'train/*.jpg'))
train_dataset = train_dataset.map(load_image_train,
                                  num_parallel_calls=tf.data.AUTOTUNE)
train_dataset = train_dataset.shuffle(BUFFER_SIZE)
train_dataset = train_dataset.batch(BATCH_SIZE)
tutucu22 l10n-yer
try:
  test_dataset = tf.data.Dataset.list_files(str(PATH / 'test/*.jpg'))
except tf.errors.InvalidArgumentError:
  test_dataset = tf.data.Dataset.list_files(str(PATH / 'val/*.jpg'))
test_dataset = test_dataset.map(load_image_test)
test_dataset = test_dataset.batch(BATCH_SIZE)

Jeneratörü inşa et

pix2pix cGAN'ınızın oluşturucusu değiştirilmiş bir U- Net'tir. Bir U-Net, bir kodlayıcı (alt örnekleyici) ve kod çözücüden (yukarı örnekleyici) oluşur. (Bununla ilgili daha fazla bilgiyi Görüntü segmentasyonu eğitiminde ve U-Net proje web sitesinde bulabilirsiniz .)

  • Kodlayıcıdaki her blok: Evrişim -> Toplu normalleştirme -> Sızdıran ReLU
  • Kod çözücüdeki her blok: Aktarılan evrişim -> Toplu normalleştirme -> Bırakma (ilk 3 bloğa uygulanır) -> ReLU
  • Kodlayıcı ve kod çözücü arasında atlama bağlantıları vardır (U-Net'te olduğu gibi).

Altörnekleyiciyi (kodlayıcı) tanımlayın:

OUTPUT_CHANNELS = 3
def downsample(filters, size, apply_batchnorm=True):
  initializer = tf.random_normal_initializer(0., 0.02)

  result = tf.keras.Sequential()
  result.add(
      tf.keras.layers.Conv2D(filters, size, strides=2, padding='same',
                             kernel_initializer=initializer, use_bias=False))

  if apply_batchnorm:
    result.add(tf.keras.layers.BatchNormalization())

  result.add(tf.keras.layers.LeakyReLU())

  return result
yer tutucu25 l10n-yer
down_model = downsample(3, 4)
down_result = down_model(tf.expand_dims(inp, 0))
print (down_result.shape)
(1, 128, 128, 3)

Üst örnekleyiciyi (kod çözücü) tanımlayın:

def upsample(filters, size, apply_dropout=False):
  initializer = tf.random_normal_initializer(0., 0.02)

  result = tf.keras.Sequential()
  result.add(
    tf.keras.layers.Conv2DTranspose(filters, size, strides=2,
                                    padding='same',
                                    kernel_initializer=initializer,
                                    use_bias=False))

  result.add(tf.keras.layers.BatchNormalization())

  if apply_dropout:
      result.add(tf.keras.layers.Dropout(0.5))

  result.add(tf.keras.layers.ReLU())

  return result
up_model = upsample(3, 4)
up_result = up_model(down_result)
print (up_result.shape)
-yer tutucu29 l10n-yer
(1, 256, 256, 3)

Altörnekleyici ve üstörnekleyici ile jeneratörü tanımlayın:

def Generator():
  inputs = tf.keras.layers.Input(shape=[256, 256, 3])

  down_stack = [
    downsample(64, 4, apply_batchnorm=False),  # (batch_size, 128, 128, 64)
    downsample(128, 4),  # (batch_size, 64, 64, 128)
    downsample(256, 4),  # (batch_size, 32, 32, 256)
    downsample(512, 4),  # (batch_size, 16, 16, 512)
    downsample(512, 4),  # (batch_size, 8, 8, 512)
    downsample(512, 4),  # (batch_size, 4, 4, 512)
    downsample(512, 4),  # (batch_size, 2, 2, 512)
    downsample(512, 4),  # (batch_size, 1, 1, 512)
  ]

  up_stack = [
    upsample(512, 4, apply_dropout=True),  # (batch_size, 2, 2, 1024)
    upsample(512, 4, apply_dropout=True),  # (batch_size, 4, 4, 1024)
    upsample(512, 4, apply_dropout=True),  # (batch_size, 8, 8, 1024)
    upsample(512, 4),  # (batch_size, 16, 16, 1024)
    upsample(256, 4),  # (batch_size, 32, 32, 512)
    upsample(128, 4),  # (batch_size, 64, 64, 256)
    upsample(64, 4),  # (batch_size, 128, 128, 128)
  ]

  initializer = tf.random_normal_initializer(0., 0.02)
  last = tf.keras.layers.Conv2DTranspose(OUTPUT_CHANNELS, 4,
                                         strides=2,
                                         padding='same',
                                         kernel_initializer=initializer,
                                         activation='tanh')  # (batch_size, 256, 256, 3)

  x = inputs

  # Downsampling through the model
  skips = []
  for down in down_stack:
    x = down(x)
    skips.append(x)

  skips = reversed(skips[:-1])

  # Upsampling and establishing the skip connections
  for up, skip in zip(up_stack, skips):
    x = up(x)
    x = tf.keras.layers.Concatenate()([x, skip])

  x = last(x)

  return tf.keras.Model(inputs=inputs, outputs=x)

Jeneratör modeli mimarisini görselleştirin:

generator = Generator()
tf.keras.utils.plot_model(generator, show_shapes=True, dpi=64)

png

Jeneratörü test edin:

gen_output = generator(inp[tf.newaxis, ...], training=False)
plt.imshow(gen_output[0, ...])
tutucu33 l10n-yer
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
<matplotlib.image.AxesImage at 0x7f35cfd20610>

png

Jeneratör kaybını tanımlayın

GAN'lar verilere uyum sağlayan bir kayıp öğrenirken cGAN'lar, pix2pix belgesinde açıklandığı gibi ağ çıkışından ve hedef görüntüden farklı olası bir yapıyı cezalandıran yapılandırılmış bir kaybı öğrenir.

  • Jeneratör kaybı, oluşturulan görüntülerin ve bir dizi birin sigmoid çapraz entropi kaybıdır.
  • Pix2pix belgesi ayrıca, oluşturulan görüntü ile hedef görüntü arasında bir MAE (ortalama mutlak hata) olan L1 kaybından da bahseder.
  • Bu, oluşturulan görüntünün hedef görüntüye yapısal olarak benzer hale gelmesini sağlar.
  • Toplam jeneratör kaybını hesaplama formülü gan_loss + LAMBDA * l1_loss , burada LAMBDA = 100 . Bu değere makalenin yazarları karar vermiştir.
LAMBDA = 100
loss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True)
-yer tutucu36 l10n-yer
def generator_loss(disc_generated_output, gen_output, target):
  gan_loss = loss_object(tf.ones_like(disc_generated_output), disc_generated_output)

  # Mean absolute error
  l1_loss = tf.reduce_mean(tf.abs(target - gen_output))

  total_gen_loss = gan_loss + (LAMBDA * l1_loss)

  return total_gen_loss, gan_loss, l1_loss

Jeneratör için eğitim prosedürü aşağıdaki gibidir:

Jeneratör Güncelleme Resmi

Ayrımcıyı oluşturun

pix2pix cGAN'deki ayrımcı, evrişimli bir PatchGAN sınıflandırıcıdır; pix2pix belgesinde açıklandığı gibi her bir görüntü yamasının gerçek olup olmadığını sınıflandırmaya çalışır.

  • Ayırıcıdaki her blok: Evrişim -> Toplu normalleştirme -> Sızdıran ReLU.
  • Son katmandan sonraki çıktının şekli (batch_size, 30, 30, 1) .
  • Çıktının her 30 x 30 görüntü yaması, giriş görüntüsünün 70 x 70 bir bölümünü sınıflandırır.
  • Ayırıcı 2 girdi alır:
    • Gerçek olarak sınıflandırması gereken giriş görüntüsü ve hedef görüntü.
    • Sahte olarak sınıflandırması gereken giriş görüntüsü ve oluşturulan görüntü (jeneratörün çıkışı).
    • Bu 2 girişi birleştirmek için tf.concat([inp, tar], axis=-1) kullanın.

Ayırıcıyı tanımlayalım:

def Discriminator():
  initializer = tf.random_normal_initializer(0., 0.02)

  inp = tf.keras.layers.Input(shape=[256, 256, 3], name='input_image')
  tar = tf.keras.layers.Input(shape=[256, 256, 3], name='target_image')

  x = tf.keras.layers.concatenate([inp, tar])  # (batch_size, 256, 256, channels*2)

  down1 = downsample(64, 4, False)(x)  # (batch_size, 128, 128, 64)
  down2 = downsample(128, 4)(down1)  # (batch_size, 64, 64, 128)
  down3 = downsample(256, 4)(down2)  # (batch_size, 32, 32, 256)

  zero_pad1 = tf.keras.layers.ZeroPadding2D()(down3)  # (batch_size, 34, 34, 256)
  conv = tf.keras.layers.Conv2D(512, 4, strides=1,
                                kernel_initializer=initializer,
                                use_bias=False)(zero_pad1)  # (batch_size, 31, 31, 512)

  batchnorm1 = tf.keras.layers.BatchNormalization()(conv)

  leaky_relu = tf.keras.layers.LeakyReLU()(batchnorm1)

  zero_pad2 = tf.keras.layers.ZeroPadding2D()(leaky_relu)  # (batch_size, 33, 33, 512)

  last = tf.keras.layers.Conv2D(1, 4, strides=1,
                                kernel_initializer=initializer)(zero_pad2)  # (batch_size, 30, 30, 1)

  return tf.keras.Model(inputs=[inp, tar], outputs=last)

Ayrımcı model mimarisini görselleştirin:

discriminator = Discriminator()
tf.keras.utils.plot_model(discriminator, show_shapes=True, dpi=64)

png

Ayırt ediciyi test edin:

disc_out = discriminator([inp[tf.newaxis, ...], gen_output], training=False)
plt.imshow(disc_out[0, ..., -1], vmin=-20, vmax=20, cmap='RdBu_r')
plt.colorbar()
tutucu40 l10n-yer
<matplotlib.colorbar.Colorbar at 0x7f35cec82c50>

png

Diskriminatör kaybını tanımlayın

  • discriminator_loss işlevi 2 girdi alır: gerçek görüntüler ve oluşturulan görüntüler .
  • real_loss , gerçek görüntülerin ve bir dizi olanın sigmoid çapraz entropi kaybıdır (çünkü bunlar gerçek görüntülerdir) .
  • generated_loss , oluşturulan görüntülerin ve bir dizi sıfırın sigmoid çapraz entropi kaybıdır (çünkü bunlar sahte görüntülerdir) .
  • total_loss , real_loss generated_loss .
def discriminator_loss(disc_real_output, disc_generated_output):
  real_loss = loss_object(tf.ones_like(disc_real_output), disc_real_output)

  generated_loss = loss_object(tf.zeros_like(disc_generated_output), disc_generated_output)

  total_disc_loss = real_loss + generated_loss

  return total_disc_loss

Ayrımcı için eğitim prosedürü aşağıda gösterilmiştir.

Mimari ve hiperparametreler hakkında daha fazla bilgi edinmek için pix2pix belgesine başvurabilirsiniz.

Ayrımcı Güncelleme Resmi

Optimize edicileri ve bir kontrol noktası koruyucuyu tanımlayın

generator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)
discriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)
tutucu43 l10n-yer
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)

Görüntü oluştur

Eğitim sırasında bazı görüntüleri çizmek için bir fonksiyon yazın.

  • Test setinden görüntüleri jeneratöre iletin.
  • Jeneratör daha sonra giriş görüntüsünü çıkışa çevirecektir.
  • Son adım, tahminleri planlamak ve işte !
def generate_images(model, test_input, tar):
  prediction = model(test_input, training=True)
  plt.figure(figsize=(15, 15))

  display_list = [test_input[0], tar[0], prediction[0]]
  title = ['Input Image', 'Ground Truth', 'Predicted Image']

  for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.title(title[i])
    # Getting the pixel values in the [0, 1] range to plot.
    plt.imshow(display_list[i] * 0.5 + 0.5)
    plt.axis('off')
  plt.show()

İşlevi test edin:

for example_input, example_target in test_dataset.take(1):
  generate_images(generator, example_input, example_target)

png

Eğitim

  • Her örnek için girdi bir çıktı üretir.
  • Ayırıcı, input_image ve oluşturulan görüntüyü ilk girdi olarak alır. İkinci girdi input_image ve target_image .
  • Ardından, üreteci ve diskriminatör kaybını hesaplayın.
  • Ardından, hem oluşturucu hem de ayırıcı değişkenlere (girdiler) göre kayıp gradyanlarını hesaplayın ve bunları optimize ediciye uygulayın.
  • Son olarak, kayıpları TensorBoard'a kaydedin.
log_dir="logs/"

summary_writer = tf.summary.create_file_writer(
  log_dir + "fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
tutucu47 l10n-yer
@tf.function
def train_step(input_image, target, step):
  with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
    gen_output = generator(input_image, training=True)

    disc_real_output = discriminator([input_image, target], training=True)
    disc_generated_output = discriminator([input_image, gen_output], training=True)

    gen_total_loss, gen_gan_loss, gen_l1_loss = generator_loss(disc_generated_output, gen_output, target)
    disc_loss = discriminator_loss(disc_real_output, disc_generated_output)

  generator_gradients = gen_tape.gradient(gen_total_loss,
                                          generator.trainable_variables)
  discriminator_gradients = disc_tape.gradient(disc_loss,
                                               discriminator.trainable_variables)

  generator_optimizer.apply_gradients(zip(generator_gradients,
                                          generator.trainable_variables))
  discriminator_optimizer.apply_gradients(zip(discriminator_gradients,
                                              discriminator.trainable_variables))

  with summary_writer.as_default():
    tf.summary.scalar('gen_total_loss', gen_total_loss, step=step//1000)
    tf.summary.scalar('gen_gan_loss', gen_gan_loss, step=step//1000)
    tf.summary.scalar('gen_l1_loss', gen_l1_loss, step=step//1000)
    tf.summary.scalar('disc_loss', disc_loss, step=step//1000)

Gerçek eğitim döngüsü. Bu öğretici birden fazla veri kümesini çalıştırabileceğinden ve veri kümelerinin boyutu büyük ölçüde değişiklik gösterdiğinden, eğitim döngüsü dönemler yerine adım adım çalışacak şekilde ayarlanmıştır.

  • Adım sayısı üzerinden yinelenir.
  • Her 10 adımda bir nokta ( . ) yazdırın.
  • Her 1k adımda: ekranı temizleyin ve ilerlemeyi göstermek için generate_images komutunu çalıştırın.
  • Her 5 bin adımda bir: bir kontrol noktası kaydedin.
def fit(train_ds, test_ds, steps):
  example_input, example_target = next(iter(test_ds.take(1)))
  start = time.time()

  for step, (input_image, target) in train_ds.repeat().take(steps).enumerate():
    if (step) % 1000 == 0:
      display.clear_output(wait=True)

      if step != 0:
        print(f'Time taken for 1000 steps: {time.time()-start:.2f} sec\n')

      start = time.time()

      generate_images(generator, example_input, example_target)
      print(f"Step: {step//1000}k")

    train_step(input_image, target, step)

    # Training step
    if (step+1) % 10 == 0:
      print('.', end='', flush=True)


    # Save (checkpoint) the model every 5k steps
    if (step + 1) % 5000 == 0:
      checkpoint.save(file_prefix=checkpoint_prefix)

Bu eğitim döngüsü, eğitim ilerlemesini izlemek için TensorBoard'da görüntüleyebileceğiniz günlükleri kaydeder.

Yerel bir makinede çalışıyorsanız, ayrı bir TensorBoard işlemi başlatırsınız. Bir dizüstü bilgisayarda çalışırken, TensorBoard ile izleme eğitimine başlamadan önce görüntüleyiciyi başlatın.

Görüntüleyiciyi başlatmak için aşağıdakileri bir kod hücresine yapıştırın:

%load_ext tensorboard
%tensorboard --logdir {log_dir}

Son olarak, eğitim döngüsünü çalıştırın:

fit(train_dataset, test_dataset, steps=40000)
tutucu51 l10n-yer
Time taken for 1000 steps: 36.53 sec

png

Step: 39k
....................................................................................................

TensorBoard sonuçlarını herkese açık olarak paylaşmak istiyorsanız, aşağıdakileri bir kod hücresine kopyalayarak günlükleri TensorBoard.dev'e yükleyebilirsiniz.

tensorboard dev upload --logdir {log_dir}

Bu not defterinin önceki bir çalışmasının sonuçlarını TensorBoard.dev'de görüntüleyebilirsiniz .

TensorBoard.dev, makine öğrenimi deneylerini herkesle barındırmak, izlemek ve paylaşmak için yönetilen bir deneyimdir.

Ayrıca bir <iframe> kullanarak satır içi olarak da dahil edilebilir:

display.IFrame(
    src="https://tensorboard.dev/experiment/lZ0C6FONROaUMfjYkVyJqw",
    width="100%",
    height="1000px")

Günlükleri yorumlamak, basit bir sınıflandırma veya regresyon modeline kıyasla bir GAN'ı (veya pix2pix benzeri bir cGAN'ı) eğitirken daha inceliklidir. Aranacak şeyler:

  • Ne jeneratörün ne de ayrımcı modelin "kazanmadığını" kontrol edin. gen_gan_loss veya disc_loss çok düşerse, bu modelin diğerine hakim olduğunun ve birleşik modeli başarılı bir şekilde eğitemediğinizin bir göstergesidir.
  • log(2) = 0.69 değeri, bu kayıplar için iyi bir referans noktasıdır, çünkü 2'lik bir karışıklığı gösterir - ayırıcı, ortalama olarak, iki seçenek hakkında eşit derecede belirsizdir.
  • 0.69 için, disc_loss altındaki bir değer, ayırıcının gerçek ve oluşturulan görüntülerin birleştirilmiş kümesinde rastgeleden daha iyi performans gösterdiği anlamına gelir.
  • gen_gan_loss için gen_gan_loss altındaki bir değer, üretecin 0.69 kandırmada rastgele olmaktan daha iyi olduğu anlamına gelir.
  • Eğitim ilerledikçe, gen_l1_loss .

En son kontrol noktasını geri yükleyin ve ağı test edin

ls {checkpoint_dir}
checkpoint          ckpt-5.data-00000-of-00001
ckpt-1.data-00000-of-00001  ckpt-5.index
ckpt-1.index            ckpt-6.data-00000-of-00001
ckpt-2.data-00000-of-00001  ckpt-6.index
ckpt-2.index            ckpt-7.data-00000-of-00001
ckpt-3.data-00000-of-00001  ckpt-7.index
ckpt-3.index            ckpt-8.data-00000-of-00001
ckpt-4.data-00000-of-00001  ckpt-8.index
ckpt-4.index
yer tutucu57 l10n-yer
# Restoring the latest checkpoint in checkpoint_dir
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f35cfd6b8d0>

Test setini kullanarak bazı görüntüler oluşturun

# Run the trained model on a few examples from the test set
for inp, tar in test_dataset.take(5):
  generate_images(generator, inp, tar)

png

png

png

png

png