ホームページ >バックエンド開発 >Python チュートリアル >Python での GAN アルゴリズムの例

Python での GAN アルゴリズムの例

王林
王林オリジナル
2023-06-10 09:53:501230ブラウズ

Generative Adversarial Networks (GAN、Generative Adversarial Networks) は、互いに競合する 2 つのニューラル ネットワークを通じて新しいデータを生成する深層学習アルゴリズムです。 GAN は、画像、音声、テキスト、その他の分野の生成タスクに広く使用されています。この記事では、Python を使用して手書き数字の画像を生成する GAN アルゴリズムの例を作成します。

  1. データセットの準備

MNIST データ セットをトレーニング データ セットとして使用します。 MNIST データセットには 60,000 のトレーニング画像と 10,000 のテスト画像が含まれており、各画像は 28x28 のグレースケール画像です。 TensorFlow ライブラリを使用してデータセットをロードして処理します。データセットをロードする前に、TensorFlow ライブラリと NumPy ライブラリをインストールする必要があります。

import tensorflow as tf
import numpy as np

(train_images, train_labels), (test_images, test_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 # 正規化ピクセル値を [-1, 1] の範囲に設定します。

  1. GAN アーキテクチャの設計とトレーニング

私たちの GAN には、ジェネレーター ネットワークと弁別ネットワーク。生成ネットワークはノイズ ベクトルを入力として受け取り、28x28 の画像を出力します。弁別ネットワークは 28x28 画像を入力として受け取り、その画像が実画像である確率を出力します。

ジェネレーター ネットワークとディスクリミネーター ネットワークの両方のアーキテクチャでは、畳み込みニューラル ネットワーク (CNN) が使用されます。ジェネレーター ネットワークでは、デコンボリューション レイヤーを使用して、ノイズ ベクトルを 28x28 の画像にデコードします。弁別ネットワークでは、畳み込み層を使用して入力画像を分類します。

ジェネレーター ネットワークへの入力は、長さ 100 のノイズ ベクトルです。 tf.keras.Sequential 関数を使用してネットワーク層をスタックします。

def make_generator_model():

model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.LeakyReLU())

model.add(tf.keras.layers.Reshape((7, 7, 256)))
assert model.output_shape == (None, 7, 7, 256) # 注意:batch size没有限制

model.add(tf.keras.layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.LeakyReLU())

model.add(tf.keras.layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.LeakyReLU())

model.add(tf.keras.layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)

return model

識別ネットワークの入力は 28x28 の画像です。 tf.keras.Sequential 関数を使用してネットワーク層をスタックします。

def make_discriminator_model():

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
                                 input_shape=[28, 28, 1]))
model.add(tf.keras.layers.LeakyReLU())
model.add(tf.keras.layers.Dropout(0.3))

model.add(tf.keras.layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
model.add(tf.keras.layers.LeakyReLU())
model.add(tf.keras.layers.Dropout(0.3))

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1))

return model

次に、トレーニング コードを記述します。各バッチでジェネレーター ネットワークとディスクリミネーター ネットワークを交互にトレーニングします。トレーニング プロセス中に、 tf.GradientTape() 関数を使用して勾配を記録し、その後 tf.keras.optimizers.Adam() 関数を使用してネットワークを最適化します。

generator = make_generator_model()
discriminator = make_discriminator_model()

損失関数

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

ジェネレータ損失関数

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

トレーニング関数の定義

@tf.function
def train_step(images):

noise = tf.random.normal([BATCH_SIZE, 100])

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)

gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

BATCH_SIZE = 256
EPOCHS = 100

範囲内のエポック(EPOCHS):

for i in range(train_images.shape[0] // BATCH_SIZE):
    batch_images = train_images[i*BATCH_SIZE:(i+1)*BATCH_SIZE]
    train_step(batch_images)
  1. 新しい画像の生成
##トレーニングが完了したら、ジェネレーター ネットワークを使用して新しい画像を生成します。 100 個のノイズ ベクトルをランダムに生成し、それらを生成ネットワークに入力して、手書き数字の新しい画像を生成します。

import matplotlib.pyplot as plt

defgenerate_and_save_images(model, epoch, test_input):

# 注意 training` 设定为 False
# 因此,所有层都在推理模式下运行(batchnorm)。
predictions = model(test_input, training=False)

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

plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
plt.show()

ランダムにノイズ ベクトルを生成

noise = tf.random .normal([16, 100])

generate_and_save_images(generator, 0, Noise)

結果は、ジェネレーターが新しい手書き数字イメージを正常に生成したことを示しています。トレーニング エポックの数を徐々に増やすことで、モデルのパフォーマンスを向上させることができます。さらに、他のハイパーパラメータの組み合わせやネットワーク アーキテクチャを試すことで、GAN のパフォーマンスをさらに向上させることができます。

つまり、GAN アルゴリズムは、さまざまな種類のデータの生成に使用できる非常に便利な深層学習アルゴリズムです。この記事では、Python を使用して手書き数字の画像を生成する GAN アルゴリズムの例を作成し、ジェネレーター ネットワークをトレーニングして使用して新しい画像を生成する方法を示しました。

以上がPython での GAN アルゴリズムの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。