Skip to content

ClasCat® AI Research

クラスキャット – 生成 AI, AI エージェント, MCP

Menu
  • ホーム
    • ClassCat® AI Research ホーム
    • クラスキャット・ホーム
  • OpenAI API
    • OpenAI Python ライブラリ 1.x : 概要
    • OpenAI ブログ
      • GPT の紹介
      • GPT ストアの紹介
      • ChatGPT Team の紹介
    • OpenAI platform 1.x
      • Get Started : イントロダクション
      • Get Started : クイックスタート (Python)
      • Get Started : クイックスタート (Node.js)
      • Get Started : モデル
      • 機能 : 埋め込み
      • 機能 : 埋め込み (ユースケース)
      • ChatGPT : アクション – イントロダクション
      • ChatGPT : アクション – Getting started
      • ChatGPT : アクション – アクション認証
    • OpenAI ヘルプ : ChatGPT
      • ChatGPTとは何ですか?
      • ChatGPT は真実を語っていますか?
      • GPT の作成
      • GPT FAQ
      • GPT vs アシスタント
      • GPT ビルダー
    • OpenAI ヘルプ : ChatGPT > メモリ
      • FAQ
    • OpenAI ヘルプ : GPT ストア
      • 貴方の GPT をフィーチャーする
    • OpenAI Python ライブラリ 0.27 : 概要
    • OpenAI platform
      • Get Started : イントロダクション
      • Get Started : クイックスタート
      • Get Started : モデル
      • ガイド : GPT モデル
      • ガイド : 画像生成 (DALL·E)
      • ガイド : GPT-3.5 Turbo 対応 微調整
      • ガイド : 微調整 1.イントロダクション
      • ガイド : 微調整 2. データセットの準備 / ケーススタディ
      • ガイド : 埋め込み
      • ガイド : 音声テキスト変換
      • ガイド : モデレーション
      • ChatGPT プラグイン : イントロダクション
    • OpenAI Cookbook
      • 概要
      • API 使用方法 : レート制限の操作
      • API 使用方法 : tiktoken でトークンを数える方法
      • GPT : ChatGPT モデルへの入力をフォーマットする方法
      • GPT : 補完をストリームする方法
      • GPT : 大規模言語モデルを扱う方法
      • 埋め込み : 埋め込みの取得
      • GPT-3 の微調整 : 分類サンプルの微調整
      • DALL-E : DALL·E で 画像を生成して編集する方法
      • DALL·E と Segment Anything で動的マスクを作成する方法
      • Whisper プロンプティング・ガイド
  • Gemini API
    • Tutorials : クイックスタート with Python (1) テキスト-to-テキスト生成
    • (2) マルチモーダル入力 / 日本語チャット
    • (3) 埋め込みの使用
    • (4) 高度なユースケース
    • クイックスタート with Node.js
    • クイックスタート with Dart or Flutter (1) 日本語動作確認
    • Gemma
      • 概要 (README)
      • Tutorials : サンプリング
      • Tutorials : KerasNLP による Getting Started
  • Keras 3
    • 新しいマルチバックエンド Keras
    • Keras 3 について
    • Getting Started : エンジニアのための Keras 入門
    • Google Colab 上のインストールと Stable Diffusion デモ
    • コンピュータビジョン – ゼロからの画像分類
    • コンピュータビジョン – 単純な MNIST convnet
    • コンピュータビジョン – EfficientNet を使用した微調整による画像分類
    • コンピュータビジョン – Vision Transformer による画像分類
    • コンピュータビジョン – 最新の MLPモデルによる画像分類
    • コンピュータビジョン – コンパクトな畳込み Transformer
    • Keras Core
      • Keras Core 0.1
        • 新しいマルチバックエンド Keras (README)
        • Keras for TensorFlow, JAX, & PyTorch
        • 開発者ガイド : Getting started with Keras Core
        • 開発者ガイド : 関数型 API
        • 開発者ガイド : シーケンシャル・モデル
        • 開発者ガイド : サブクラス化で新しい層とモデルを作成する
        • 開発者ガイド : 独自のコールバックを書く
      • Keras Core 0.1.1 & 0.1.2 : リリースノート
      • 開発者ガイド
      • Code examples
      • Keras Stable Diffusion
        • 概要
        • 基本的な使い方 (テキスト-to-画像 / 画像-to-画像変換)
        • 混合精度のパフォーマンス
        • インペインティングの簡易アプリケーション
        • (参考) KerasCV – Stable Diffusion を使用した高性能画像生成
  • TensorFlow
    • TF 2 : 初級チュートリアル
    • TF 2 : 上級チュートリアル
    • TF 2 : ガイド
    • TF 1 : チュートリアル
    • TF 1 : ガイド
  • その他
    • 🦜️🔗 LangChain ドキュメント / ユースケース
    • Stable Diffusion WebUI
      • Google Colab で Stable Diffusion WebUI 入門
      • HuggingFace モデル / VAE の導入
      • LoRA の利用
    • Diffusion Models / 拡散モデル
  • クラスキャット
    • 会社案内
    • お問合せ
    • Facebook
    • ClassCat® Blog
Menu

Keras 2 : ガイド : 訓練ループをスクラッチから書く

Posted on 10/25/202110/25/2021 by Sales Information

Keras 2 : ガイド : 訓練ループをスクラッチから書く (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/25/2021 (keras 2.6.0)

* 本ページは、Keras の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

  • Writing a training loop from scratch (Author: fchollet)

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス ★ 無料 Web セミナー開催中 ★

◆ クラスキャットは人工知能・テレワークに関する各種サービスを提供しております。お気軽にご相談ください :

  • 人工知能研究開発支援
    1. 人工知能研修サービス(経営者層向けオンサイト研修)
    2. テクニカルコンサルティングサービス
    3. 実証実験(プロトタイプ構築)
    4. アプリケーションへの実装

  • 人工知能研修サービス

  • PoC(概念実証)を失敗させないための支援

  • テレワーク & オンライン授業を支援
◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • ウェビナー運用には弊社製品「ClassCat® Webinar」を利用しています。

◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com  ;  WebSite: https://www.classcat.com/  ;  Facebook

 

Keras 2 : ガイド : 訓練ループをスクラッチから書く

セットアップ

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np

 

イントロダクション

Keras はデフォルトの訓練と評価ループ、fit() と evaluate() を提供します、それらの使用方法はガイド 組込みメソッドで訓練と評価 でカバーされます。

(例えば、fit() を使用して GAN を訓練するために) fit() の便利さを依然として活用しながら貴方のモデルの学習アルゴリズムをカスタマイズすることを望む場合、Model クラスをサブクラス化して独自の train_step() メソッドを実装できます、これは fit() の間に繰り返し呼び出されます。これはガイド Model.fit で起きることをカスタマイズする でカバーされます。

今は、訓練 & 評価に渡り非常に低位な制御を望む場合、独自の訓練 & 評価ループをスクラッチから書くべきです。このガイドはこれについてです。

 

GradientTape を使用する : 最初の end-to-end サンプル

GradientTape スコープ内でのモデルの呼び出しは損失値に関する層の訓練可能な重みの勾配を取得することを可能にします。optimizer インスタンスを使用して、これらの変数 (これらは model.trainable_weights を使用して取得できます) を更新するためにこれらの勾配を使用できます。

単純な MNIST モデルを考えましょう :

inputs = keras.Input(shape=(784,), name="digits")
x1 = layers.Dense(64, activation="relu")(inputs)
x2 = layers.Dense(64, activation="relu")(x1)
outputs = layers.Dense(10, name="predictions")(x2)
model = keras.Model(inputs=inputs, outputs=outputs)

カスタム訓練ループでミニバッチ勾配を使用してそれを訓練しましょう。

最初に、optimizer、損失関数、そしてデータセットを必要とします :

# Instantiate an optimizer.
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# Instantiate a loss function.
loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)

# Prepare the training dataset.
batch_size = 64
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = np.reshape(x_train, (-1, 784))
x_test = np.reshape(x_test, (-1, 784))
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)

ここに私達の訓練ループがあります :

  • エポックに渡り反復する for ループを開始します。
  • 各エポックについて、データセットに渡り、バッチで反復する for ループを開始します。
  • 各バッチについて、GradientTape() スコープを開始します。
  • このスコープ内で、modelを呼び出して (forward パス) 損失を計算します。
  • スコープの外で、損失に関するモデルの重みの勾配を取得します。
  • 最後に、勾配に基づいてモデルの重みを更新するために optimizer を使用します。
epochs = 2
for epoch in range(epochs):
    print("\nStart of epoch %d" % (epoch,))

    # Iterate over the batches of the dataset.
    for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):

        # Open a GradientTape to record the operations run
        # during the forward pass, which enables auto-differentiation.
        with tf.GradientTape() as tape:

            # Run the forward pass of the layer.
            # The operations that the layer applies
            # to its inputs are going to be recorded
            # on the GradientTape.
            logits = model(x_batch_train, training=True)  # Logits for this minibatch

            # Compute the loss value for this minibatch.
            loss_value = loss_fn(y_batch_train, logits)

        # Use the gradient tape to automatically retrieve
        # the gradients of the trainable variables with respect to the loss.
        grads = tape.gradient(loss_value, model.trainable_weights)

        # Run one step of gradient descent by updating
        # the value of the variables to minimize the loss.
        optimizer.apply_gradients(zip(grads, model.trainable_weights))

        # Log every 200 batches.
        if step % 200 == 0:
            print(
                "Training loss (for one batch) at step %d: %.4f"
                % (step, float(loss_value))
            )
            print("Seen so far: %s samples" % ((step + 1) * 64))
Start of epoch 0
Training loss (for one batch) at step 0: 76.3562
Seen so far: 64 samples
Training loss (for one batch) at step 200: 1.3921
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 1.0018
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 0.8904
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.8393
Seen so far: 51264 samples

Start of epoch 1
Training loss (for one batch) at step 0: 0.8572
Seen so far: 64 samples
Training loss (for one batch) at step 200: 0.7616
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 0.8453
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 0.4959
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.9363
Seen so far: 51264 samples

 

メトリクスの低位処理

この基本的なループにメトリクス監視を追加しましょう。

スクラッチから書かれたそのような訓練ループで組込みメトリクス (or 貴方が書いたカスタムメトリクス) を容易に再利用できます。ここにフローがあります :

  • ループの開始でメトリックをインスタンス化します。
  • 各バッチ後に metric.update_state() を呼び出します。
  • メトリックの現在値を表示する必要があるとき metric.result() を呼び出します。
  • メトリックの状態をクリアする必要があるとき (典型的にはエポックの最後) metric.reset_states() を呼び出します。

各エポックの最後に検証データ上 SparseCategoricalAccuracy を計算するためにこの知識を利用しましょう :

# Get model
inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)
model = keras.Model(inputs=inputs, outputs=outputs)

# Instantiate an optimizer to train the model.
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# Instantiate a loss function.
loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)

# Prepare the metrics.
train_acc_metric = keras.metrics.SparseCategoricalAccuracy()
val_acc_metric = keras.metrics.SparseCategoricalAccuracy()

# Prepare the training dataset.
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)

# Prepare the validation dataset.
# Reserve 10,000 samples for validation.
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

ここに私達の訓練 & 評価ループがあります :

import time

epochs = 2
for epoch in range(epochs):
    print("\nStart of epoch %d" % (epoch,))
    start_time = time.time()

    # Iterate over the batches of the dataset.
    for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
        with tf.GradientTape() as tape:
            logits = model(x_batch_train, training=True)
            loss_value = loss_fn(y_batch_train, logits)
        grads = tape.gradient(loss_value, model.trainable_weights)
        optimizer.apply_gradients(zip(grads, model.trainable_weights))

        # Update training metric.
        train_acc_metric.update_state(y_batch_train, logits)

        # Log every 200 batches.
        if step % 200 == 0:
            print(
                "Training loss (for one batch) at step %d: %.4f"
                % (step, float(loss_value))
            )
            print("Seen so far: %d samples" % ((step + 1) * 64))

    # Display metrics at the end of each epoch.
    train_acc = train_acc_metric.result()
    print("Training acc over epoch: %.4f" % (float(train_acc),))

    # Reset training metrics at the end of each epoch
    train_acc_metric.reset_states()

    # Run a validation loop at the end of each epoch.
    for x_batch_val, y_batch_val in val_dataset:
        val_logits = model(x_batch_val, training=False)
        # Update val metrics
        val_acc_metric.update_state(y_batch_val, val_logits)
    val_acc = val_acc_metric.result()
    val_acc_metric.reset_states()
    print("Validation acc: %.4f" % (float(val_acc),))
Start of epoch 0
Training loss (for one batch) at step 0: 134.3001
Seen so far: 64 samples
Training loss (for one batch) at step 200: 1.3430
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 1.3557
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 0.8682
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.5862
Seen so far: 51264 samples
Training acc over epoch: 0.7176
Validation acc: 0.8403
Time taken: 4.65s

Start of epoch 1
Training loss (for one batch) at step 0: 0.4264
Seen so far: 64 samples
Training loss (for one batch) at step 200: 0.4168
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 0.6106
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 0.4762
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.4031
Seen so far: 51264 samples
Training acc over epoch: 0.8429
Validation acc: 0.8774
Time taken: 5.07s

 

貴方の訓練ステップを tf.function でスピードアップする

TensorFlow 2.0 のデフォルトのランタイムは eager 実行 です。そのようなものとして、上の訓練ループは逐次的に実行されます。

これはデバッグのためには素晴らしいですが、グラフコンパイルは明らかなパフォーマンス優位を持ちます。貴方の計算を静的グラフとして記述することはフレームワークがグローバルなパフォーマンス最適化を適用することを可能にします。これはフレームワークが (次に何が来るかの知識なしに) 1 つの演算を他の 1 つの後に貪欲に実行するように制約されているときには不可能です。

入力としてテンソルを取る任意の関数を静的グラフにコンパイルできます。その上に @tf.function デコレータを単に追加します、このようにです :

@tf.function
def train_step(x, y):
    with tf.GradientTape() as tape:
        logits = model(x, training=True)
        loss_value = loss_fn(y, logits)
    grads = tape.gradient(loss_value, model.trainable_weights)
    optimizer.apply_gradients(zip(grads, model.trainable_weights))
    train_acc_metric.update_state(y, logits)
    return loss_value

評価ステップでも同じことを行ないましょう :

@tf.function
def test_step(x, y):
    val_logits = model(x, training=False)
    val_acc_metric.update_state(y, val_logits)

今は、訓練ループをこのコンパイルされた訓練ステップで再実行しましょう :

import time

epochs = 2
for epoch in range(epochs):
    print("\nStart of epoch %d" % (epoch,))
    start_time = time.time()

    # Iterate over the batches of the dataset.
    for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
        loss_value = train_step(x_batch_train, y_batch_train)

        # Log every 200 batches.
        if step % 200 == 0:
            print(
                "Training loss (for one batch) at step %d: %.4f"
                % (step, float(loss_value))
            )
            print("Seen so far: %d samples" % ((step + 1) * 64))

    # Display metrics at the end of each epoch.
    train_acc = train_acc_metric.result()
    print("Training acc over epoch: %.4f" % (float(train_acc),))

    # Reset training metrics at the end of each epoch
    train_acc_metric.reset_states()

    # Run a validation loop at the end of each epoch.
    for x_batch_val, y_batch_val in val_dataset:
        test_step(x_batch_val, y_batch_val)

    val_acc = val_acc_metric.result()
    val_acc_metric.reset_states()
    print("Validation acc: %.4f" % (float(val_acc),))
    print("Time taken: %.2fs" % (time.time() - start_time))
Start of epoch 0
Training loss (for one batch) at step 0: 0.6483
Seen so far: 64 samples
Training loss (for one batch) at step 200: 0.5966
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 0.5951
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 1.3830
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.2758
Seen so far: 51264 samples
Training acc over epoch: 0.8756
Validation acc: 0.8955
Time taken: 1.18s

Start of epoch 1
Training loss (for one batch) at step 0: 0.4447
Seen so far: 64 samples
Training loss (for one batch) at step 200: 0.3794
Seen so far: 12864 samples
Training loss (for one batch) at step 400: 0.4636
Seen so far: 25664 samples
Training loss (for one batch) at step 600: 0.3694
Seen so far: 38464 samples
Training loss (for one batch) at step 800: 0.2763
Seen so far: 51264 samples
Training acc over epoch: 0.8926
Validation acc: 0.9078
Time taken: 0.71s

Much faster, isn’t it?

 

モデルにより追跡される損失の低位処理

層 & モデルは self.add_loss(value) を呼び出す層により forward パスの間に作成された任意の損失を再帰的に追跡します。スカラー損失値の結果としてのリストは forward パスの最後にプロパティ model.losses を通して利用可能です。

これらの損失成分を使用することを望む場合、訓練ステップ内でそれらを合計してそれらを主要損失に追加するべきです。

この層を考えます、これは activity 正則化損失を作成します :

class ActivityRegularizationLayer(layers.Layer):
    def call(self, inputs):
        self.add_loss(1e-2 * tf.reduce_sum(inputs))
        return inputs

それを使用する実際に単純なモデルを構築しましょう :

inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu")(inputs)
# Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)
x = layers.Dense(64, activation="relu")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)

ここに今は訓練ステップがどのように見えるべきかがあります :

@tf.function
def train_step(x, y):
    with tf.GradientTape() as tape:
        logits = model(x, training=True)
        loss_value = loss_fn(y, logits)
        # Add any extra losses created during the forward pass.
        loss_value += sum(model.losses)
    grads = tape.gradient(loss_value, model.trainable_weights)
    optimizer.apply_gradients(zip(grads, model.trainable_weights))
    train_acc_metric.update_state(y, logits)
    return loss_value

 

まとめ

今では組込み訓練ループを使用することと独自のものをスクラッチから書くことについて知るべき (存在する) 総てのことを貴方は知っています。

結論として、ここに単純な end-to-end サンプルがあります、これはこのガイドで学習した総てを一緒に結び付けています : MNIST 数字上で訓練された DCGAN です。

 

End-to-end サンプル : スクラッチからの GAN 訓練ループ

貴方は敵対的生成ネットワーク (GAN, Generative Adversarial Networks) に馴染みがあるかもしれません。GAN は画像の訓練データセットの潜在的分布を学習することにより (画像の「潜在的空間 (= latent space)」)、殆どリアルに見える新しい画像を生成できます。

GAN は 2 つのパートから成ります : “generator” モデル、これは潜在的空間のポイントを画像空間のポイントにマップし、そして “discrimintor” モデル、分類器は (訓練データセットからの) リアル画像と (generator ネットワークの出力) フェイク画像の間の違いを識別できます。

GAN 訓練はこのようなものです :

1) discriminator を訓練する。- 潜在的空間のランダムポイントのバッチをサンプリングします。- ポイントを “generator” モデルを通してフェイク画像に変えます。- リアル画像のバッチを得てそれらを生成された画像と連結します。- 生成された (画像) vs. リアル画像を分類するために “discriminator” モデルを訓練します。

2) generator を訓練する。- 潜在的空間のランダムポイントをサンプリングします。- ポイントを “generator” ネットワークを通してフェイク画像に変えます。- リアル画像のバッチを得てそれらを生成された画像と連結します。- discriminator を「騙して (= fool)」そしてフェイク画像をリアルとして分類するように “generator” モデルを訓練します。

GAN がどのように動作するかの遥かに詳細な概要については、Deep Learning with Python を見てください。

この訓練ループを実装しましょう。最初に、フェイク vs リアル数字を分類することを意図した discriminator を作成します :

discriminator = keras.Sequential(
    [
        keras.Input(shape=(28, 28, 1)),
        layers.Conv2D(64, (3, 3), strides=(2, 2), padding="same"),
        layers.LeakyReLU(alpha=0.2),
        layers.Conv2D(128, (3, 3), strides=(2, 2), padding="same"),
        layers.LeakyReLU(alpha=0.2),
        layers.GlobalMaxPooling2D(),
        layers.Dense(1),
    ],
    name="discriminator",
)
discriminator.summary()
Model: "discriminator"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 14, 14, 64)        640       
_________________________________________________________________
leaky_re_lu (LeakyReLU)      (None, 14, 14, 64)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 7, 7, 128)         73856     
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU)    (None, 7, 7, 128)         0         
_________________________________________________________________
global_max_pooling2d (Global (None, 128)               0         
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 129       
=================================================================
Total params: 74,625
Trainable params: 74,625
Non-trainable params: 0
_________________________________________________________________

そして generator ネットワークを作成しましょう、それは潜在ベクトルを (MNIST 数字を表す) shape (28, 28, 1) の出力に変えます :

latent_dim = 128

generator = keras.Sequential(
    [
        keras.Input(shape=(latent_dim,)),
        # We want to generate 128 coefficients to reshape into a 7x7x128 map
        layers.Dense(7 * 7 * 128),
        layers.LeakyReLU(alpha=0.2),
        layers.Reshape((7, 7, 128)),
        layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding="same"),
        layers.LeakyReLU(alpha=0.2),
        layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding="same"),
        layers.LeakyReLU(alpha=0.2),
        layers.Conv2D(1, (7, 7), padding="same", activation="sigmoid"),
    ],
    name="generator",
)

ここにキービット (= key bit) があります : 訓練ループです。ご覧のようにそれは非常に簡単です。訓練ステップ関数は 17 行だけを取ります。

# Instantiate one optimizer for the discriminator and another for the generator.
d_optimizer = keras.optimizers.Adam(learning_rate=0.0003)
g_optimizer = keras.optimizers.Adam(learning_rate=0.0004)

# Instantiate a loss function.
loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)


@tf.function
def train_step(real_images):
    # Sample random points in the latent space
    random_latent_vectors = tf.random.normal(shape=(batch_size, latent_dim))
    # Decode them to fake images
    generated_images = generator(random_latent_vectors)
    # Combine them with real images
    combined_images = tf.concat([generated_images, real_images], axis=0)

    # Assemble labels discriminating real from fake images
    labels = tf.concat(
        [tf.ones((batch_size, 1)), tf.zeros((real_images.shape[0], 1))], axis=0
    )
    # Add random noise to the labels - important trick!
    labels += 0.05 * tf.random.uniform(labels.shape)

    # Train the discriminator
    with tf.GradientTape() as tape:
        predictions = discriminator(combined_images)
        d_loss = loss_fn(labels, predictions)
    grads = tape.gradient(d_loss, discriminator.trainable_weights)
    d_optimizer.apply_gradients(zip(grads, discriminator.trainable_weights))

    # Sample random points in the latent space
    random_latent_vectors = tf.random.normal(shape=(batch_size, latent_dim))
    # Assemble labels that say "all real images"
    misleading_labels = tf.zeros((batch_size, 1))

    # Train the generator (note that we should *not* update the weights
    # of the discriminator)!
    with tf.GradientTape() as tape:
        predictions = discriminator(generator(random_latent_vectors))
        g_loss = loss_fn(misleading_labels, predictions)
    grads = tape.gradient(g_loss, generator.trainable_weights)
    g_optimizer.apply_gradients(zip(grads, generator.trainable_weights))
    return d_loss, g_loss, generated_images

画像のバッチ上で train_step を繰り返し呼び出すことにより、私達の GAN を訓練しましょう。

discriminator と generator は convnet (畳込みネットワーク) ですので、このコードを GPU 上で実行することを望むはずです。

import os

# Prepare the dataset. We use both the training & test MNIST digits.
batch_size = 64
(x_train, _), (x_test, _) = keras.datasets.mnist.load_data()
all_digits = np.concatenate([x_train, x_test])
all_digits = all_digits.astype("float32") / 255.0
all_digits = np.reshape(all_digits, (-1, 28, 28, 1))
dataset = tf.data.Dataset.from_tensor_slices(all_digits)
dataset = dataset.shuffle(buffer_size=1024).batch(batch_size)

epochs = 1  # In practice you need at least 20 epochs to generate nice digits.
save_dir = "./"

for epoch in range(epochs):
    print("\nStart epoch", epoch)

    for step, real_images in enumerate(dataset):
        # Train the discriminator & generator on one batch of real images.
        d_loss, g_loss, generated_images = train_step(real_images)

        # Logging.
        if step % 200 == 0:
            # Print metrics
            print("discriminator loss at step %d: %.2f" % (step, d_loss))
            print("adversarial loss at step %d: %.2f" % (step, g_loss))

            # Save one generated image
            img = tf.keras.preprocessing.image.array_to_img(
                generated_images[0] * 255.0, scale=False
            )
            img.save(os.path.join(save_dir, "generated_img" + str(step) + ".png"))

        # To limit execution time we stop after 10 steps.
        # Remove the lines below to actually train the model!
        if step > 10:
            break
Start epoch 0
discriminator loss at step 0: 0.70
adversarial loss at step 0: 0.68

That’s it! Colab GPU 上で単なる ~30s の訓練後に見栄えの良いフェイク MNIST 数字を得るでしょう。

 

以上



クラスキャット

最近の投稿

  • LangGraph 0.5 : エージェント開発 : ワークフローとエージェント
  • LangGraph 0.5 : エージェント開発 : エージェントの実行
  • LangGraph 0.5 : エージェント開発 : prebuilt コンポーネントを使用したエージェント開発
  • LangGraph 0.5 : Get started : ローカルサーバの実行
  • LangGraph 0.5 on Colab : Get started : human-in-the-loop 制御の追加

タグ

AutoGen (13) ClassCat Press Release (20) ClassCat TF/ONNX Hub (11) DGL 0.5 (14) Eager Execution (7) Edward (17) FLUX.1 (16) Gemini (20) HuggingFace Transformers 4.5 (10) HuggingFace Transformers 4.6 (7) HuggingFace Transformers 4.29 (9) Keras 2 Examples (98) Keras 2 Guide (16) Keras 3 (10) Keras Release Note (17) Kubeflow 1.0 (10) LangChain (45) LangGraph (24) LangGraph 0.5 (8) MediaPipe 0.8 (11) Model Context Protocol (16) NNI 1.5 (16) OpenAI Agents SDK (8) OpenAI Cookbook (13) OpenAI platform (10) OpenAI platform 1.x (10) OpenAI ヘルプ (8) TensorFlow 2.0 Advanced Tutorials (33) TensorFlow 2.0 Advanced Tutorials (Alpha) (15) TensorFlow 2.0 Advanced Tutorials (Beta) (16) TensorFlow 2.0 Guide (10) TensorFlow 2.0 Guide (Alpha) (16) TensorFlow 2.0 Guide (Beta) (9) TensorFlow 2.0 Release Note (12) TensorFlow 2.0 Tutorials (20) TensorFlow 2.0 Tutorials (Alpha) (14) TensorFlow 2.0 Tutorials (Beta) (12) TensorFlow 2.4 Guide (24) TensorFlow Deploy (8) TensorFlow Get Started (7) TensorFlow Probability (9) TensorFlow Programmer's Guide (22) TensorFlow Release Note (18) TensorFlow Tutorials (33) TF-Agents 0.4 (11)
2021年10月
月 火 水 木 金 土 日
 123
45678910
11121314151617
18192021222324
25262728293031
« 8月   11月 »
© 2025 ClasCat® AI Research | Powered by Minimalist Blog WordPress Theme