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

TensorFlow 2.0 : ガイド : Keras :- Keras で層とモデルを書く

Posted on 12/04/2019 by Sales Information

TensorFlow 2.0 : ガイド : Keras :- Keras で層とモデルを書く (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/04/2019

* 本ページは、TensorFlow org サイトの Guide – Keras の以下のページを翻訳した上で
適宜、補足説明したものです:

  • Writing custom layers and models with Keras

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

 

★ 無料セミナー開催中 ★ クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

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

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

 

ガイド : Keras :- Keras で層とモデルを書く

セットアップ

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

tf.keras.backend.clear_session()  # For easy reset of notebook state.

 

Layer クラス

層は状態 (重み) と幾つかの計算をカプセル化します

貴方が作業する主要なデータ構造は Layer です。層は状態 (層の「重み」) と入力から出力への変換 (“call”、層の forward パス) をカプセル化します。

ここに密結合の層があります。それは状態: 変数 w と b を持ちます。

from tensorflow.keras import layers


class Linear(layers.Layer):

  def __init__(self, units=32, input_dim=32):
    super(Linear, self).__init__()
    w_init = tf.random_normal_initializer()
    self.w = tf.Variable(initial_value=w_init(shape=(input_dim, units),
                                              dtype='float32'),
                         trainable=True)
    b_init = tf.zeros_initializer()
    self.b = tf.Variable(initial_value=b_init(shape=(units,),
                                              dtype='float32'),
                         trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.w) + self.b

x = tf.ones((2, 2))
linear_layer = Linear(4, 2)
y = linear_layer(x)
print(y)
tf.Tensor(
[[-0.03533589 -0.02663077 -0.0507721  -0.02178559]
 [-0.03533589 -0.02663077 -0.0507721  -0.02178559]], shape=(2, 4), dtype=float32)

重み w と b は (その上で) 層の属性として設定された層により自動的に追跡されることに注意してください :

assert linear_layer.weights == [linear_layer.w, linear_layer.b]

重みを層に追加するためのより素早いショートカットへのアクセスも持つことに注意してください : add_weight メソッドです :

class Linear(layers.Layer):

  def __init__(self, units=32, input_dim=32):
    super(Linear, self).__init__()
    self.w = self.add_weight(shape=(input_dim, units),
                             initializer='random_normal',
                             trainable=True)
    self.b = self.add_weight(shape=(units,),
                             initializer='zeros',
                             trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.w) + self.b

x = tf.ones((2, 2))
linear_layer = Linear(4, 2)
y = linear_layer(x)
print(y)
tf.Tensor(
[[-0.03276853 -0.02655794  0.10825785  0.00806852]
 [-0.03276853 -0.02655794  0.10825785  0.00806852]], shape=(2, 4), dtype=float32)

 

層は非訓練可能な重みを持つことができます

訓練可能な重みの他に、層に非訓練可能な重みを追加することもできます。そのような重みは、層を訓練しているとき、逆伝播の間は考慮されません。

ここに非訓練可能な重みをどのように追加して使用するかがあります :

class ComputeSum(layers.Layer):

  def __init__(self, input_dim):
    super(ComputeSum, self).__init__()
    self.total = tf.Variable(initial_value=tf.zeros((input_dim,)),
                             trainable=False)

  def call(self, inputs):
    self.total.assign_add(tf.reduce_sum(inputs, axis=0))
    return self.total

x = tf.ones((2, 2))
my_sum = ComputeSum(2)
y = my_sum(x)
print(y.numpy())
y = my_sum(x)
print(y.numpy())
[2. 2.]
[4. 4.]

それは layer.weights の一部ですが、それは非訓練可能な重みとして分類されます :

print('weights:', len(my_sum.weights))
print('non-trainable weights:', len(my_sum.non_trainable_weights))

# It's not included in the trainable weights:
print('trainable_weights:', my_sum.trainable_weights)
weights: 1
non-trainable weights: 1
trainable_weights: []

 

ベストプラクティス: 入力の shape が知れるまで重み作成を遅延する

上のロジスティック回帰のサンプルでは、私達の Linear 層は __init__ で重み w と b の shape を計算するために使用された input_dim 引数を取りました :

class Linear(layers.Layer):

  def __init__(self, units=32, input_dim=32):
      super(Linear, self).__init__()
      self.w = self.add_weight(shape=(input_dim, units),
                               initializer='random_normal',
                               trainable=True)
      self.b = self.add_weight(shape=(units,),
                               initializer='zeros',
                               trainable=True)

多くの場合、貴方は入力のサイズを前もって知らないかもしれません、そしてその値が知れたときに重みを遅れて作成したいでしょう、時に層をインスタンス化した後に。

Keras API では、層重みを層の build(inputs_shape) メソッドで作成することを推奨します。このようにです :

class Linear(layers.Layer):

  def __init__(self, units=32):
    super(Linear, self).__init__()
    self.units = units

  def build(self, input_shape):
    self.w = self.add_weight(shape=(input_shape[-1], self.units),
                             initializer='random_normal',
                             trainable=True)
    self.b = self.add_weight(shape=(self.units,),
                             initializer='random_normal',
                             trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.w) + self.b

貴方の層の __call__ メソッドは最初にそれが呼び出されたときに build を自動的に実行します。今貴方は lazy で容易に利用できる層を持ちます :

linear_layer = Linear(32)  # At instantiation, we don't know on what inputs this is going to get called
y = linear_layer(x)  # The layer's weights are created dynamically the first time the layer is called

 

層は再帰的に構成可能です

Layer インスタンスを他の層の属性として割り当てる場合、外側の層は内側の層の重みを追跡し始めるでしょう。

そのような副層 (= sublayer) は __init__ メソッドで作成することを勧めます (何故ならば副層は典型的には build メソッドを持つので、それらは外側の層が構築されるときに構築されるからです)。

# Let's assume we are reusing the Linear class
# with a `build` method that we defined above.

class MLPBlock(layers.Layer):

  def __init__(self):
    super(MLPBlock, self).__init__()
    self.linear_1 = Linear(32)
    self.linear_2 = Linear(32)
    self.linear_3 = Linear(1)

  def call(self, inputs):
    x = self.linear_1(inputs)
    x = tf.nn.relu(x)
    x = self.linear_2(x)
    x = tf.nn.relu(x)
    return self.linear_3(x)


mlp = MLPBlock()
y = mlp(tf.ones(shape=(3, 64)))  # The first call to the `mlp` will create the weights
print('weights:', len(mlp.weights))
print('trainable weights:', len(mlp.trainable_weights))
weights: 6
trainable weights: 6

 

層は forward パスの間に作成された損失を再帰的に集めます

層の call メソッドを書くとき、貴方の訓練ループを書くときに、後で使用することを望む損失 tensor を作成できます。これは self.add_loss(value) を呼び出すことで行なうことができます :

# A layer that creates an activity regularization loss
class ActivityRegularizationLayer(layers.Layer):

  def __init__(self, rate=1e-2):
    super(ActivityRegularizationLayer, self).__init__()
    self.rate = rate

  def call(self, inputs):
    self.add_loss(self.rate * tf.reduce_sum(inputs))
    return inputs

(任意の内側の層で作成されたものを含む) これらの損失は layer.losses を通して取得できます。このプロパティは top-level 層への総ての __call__ の開始でリセットされますので、layer.losses は最後の forward パスの間に作成された損失値を常に含みます。

class OuterLayer(layers.Layer):

  def __init__(self):
    super(OuterLayer, self).__init__()
    self.activity_reg = ActivityRegularizationLayer(1e-2)

  def call(self, inputs):
    return self.activity_reg(inputs)


layer = OuterLayer()
assert len(layer.losses) == 0  # No losses yet since the layer has never been called
_ = layer(tf.zeros(1, 1))
assert len(layer.losses) == 1  # We created one loss value

# `layer.losses` gets reset at the start of each __call__
_ = layer(tf.zeros(1, 1))
assert len(layer.losses) == 1  # This is the loss created during the call above

加えて、loss プロパティはまた任意の内側の層の重みのために作成された正則化損失を含みます :

class OuterLayer(layers.Layer):

  def __init__(self):
    super(OuterLayer, self).__init__()
    self.dense = layers.Dense(32, kernel_regularizer=tf.keras.regularizers.l2(1e-3))

  def call(self, inputs):
    return self.dense(inputs)


layer = OuterLayer()
_ = layer(tf.zeros((1, 1)))

# This is `1e-3 * sum(layer.dense.kernel ** 2)`,
# created by the `kernel_regularizer` above.
print(layer.losses)
[<tf.Tensor: id=247, shape=(), dtype=float32, numpy=0.0015638918>]

これらの損失は訓練ループを書くときに考慮されます、このようにです :

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

# Iterate over the batches of a dataset.
for x_batch_train, y_batch_train in train_dataset:
  with tf.GradientTape() as tape:
    logits = layer(x_batch_train)  # Logits for this minibatch
    # Loss value for this minibatch
    loss_value = loss_fn(y_batch_train, logits)
    # Add extra losses created during this forward pass:
    loss_value += sum(model.losses)

  grads = tape.gradient(loss_value, model.trainable_weights)
  optimizer.apply_gradients(zip(grads, model.trainable_weights))

訓練ループを書くための詳細なガイドについては、訓練 & 評価 へのガイド の 2nd セクションを見てください。

 

オプションで貴方の層上でシリアライゼーションを有効にできます

貴方のカスタム層が Functional モデル の一部としてシリアライズ可能であることが必要ならば、オプションで get_config メソッドを実装できます :

class Linear(layers.Layer):

  def __init__(self, units=32):
    super(Linear, self).__init__()
    self.units = units

  def build(self, input_shape):
    self.w = self.add_weight(shape=(input_shape[-1], self.units),
                             initializer='random_normal',
                             trainable=True)
    self.b = self.add_weight(shape=(self.units,),
                             initializer='random_normal',
                             trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.w) + self.b

  def get_config(self):
    return {'units': self.units}


# Now you can recreate the layer from its config:
layer = Linear(64)
config = layer.get_config()
print(config)
new_layer = Linear.from_config(config)
{'units': 64}

基底 Layer クラスの __init__ メソッドは幾つかのキーワード引数、特に nameと dtype を取ることに注意してください。これらの引数を __init__ で親クラスに渡してそれらを層 config に含めることは良い実践です :

class Linear(layers.Layer):

  def __init__(self, units=32, **kwargs):
    super(Linear, self).__init__(**kwargs)
    self.units = units

  def build(self, input_shape):
    self.w = self.add_weight(shape=(input_shape[-1], self.units),
                             initializer='random_normal',
                             trainable=True)
    self.b = self.add_weight(shape=(self.units,),
                             initializer='random_normal',
                             trainable=True)

  def call(self, inputs):
    return tf.matmul(inputs, self.w) + self.b

  def get_config(self):
    config = super(Linear, self).get_config()
    config.update({'units': self.units})
    return config


layer = Linear(64)
config = layer.get_config()
print(config)
new_layer = Linear.from_config(config)
{'name': 'linear_8', 'trainable': True, 'dtype': 'float32', 'units': 64}

層をその config からデシリアライズするときにより柔軟性を必要とする場合には、from_config クラス・メソッドをオーバーライドすることもできます。これは from_config の基底実装です :

def from_config(cls, config):
  return cls(**config)

シリアライゼーションとセービングについて更に学習するためには、完全な Guide to Saving and Serializing Models を見てください。

 

call メソッドの特権 training 引数

幾つかの層、特に BatchNormalization 層と Dropout 層は訓練と推論の間で異なる挙動を持ちます。そのような層のために、call メソッドで training (ブーリアン) 引数を公開することは標準的な実践です。

call でこの引数を公開することで、組み込み訓練と評価ループ (e.g. fit) に訓練と推論で層を正しく使用することを可能にします。

class CustomDropout(layers.Layer):

  def __init__(self, rate, **kwargs):
    super(CustomDropout, self).__init__(**kwargs)
    self.rate = rate

  def call(self, inputs, training=None):
    if training:
        return tf.nn.dropout(inputs, rate=self.rate)
    return inputs

 

モデルを構築する

Model クラス

一般に、内側の計算ブロックを定義するために Layer クラスを使用し、そして外側のモデル — 貴方が訓練するオブジェクト — を定義するために Model クラスを使用します。

例えば、ResNet 50 モデルでは、Layer をサブクラス化した幾つかの ResNet ブロックと、ResNet 50 ネットワーク全体を取り囲む単一のモデルを持つでしょう。

Model クラスは Layer と同じ API を持ちますが、次の違いがあります :

  • それは組み込み訓練、評価と予測ループを公開します (model.fit(), model.evaluate(), model.predict())。
  • それはその内側の層のリストを model.layers プロパティを通して公開します。
  • それはセービングとシリアライゼーション API を公開します。

実際上、”Layer” クラスは著述では (「畳込み層」や「リカレント層」内の) 「層 (= layer)」や (「ResNet ブロック」や「Inception ブロック」内の) 「ブロック”」として言及するものに対応しています。

一方で、”Model” クラスは著述で (「深層学習モデル」内の)「モデル」や (「深層ニューラルネットワーク」内の)「ネットワーク」として言及されるものに対応しています。

例えば、上の mini-resnet サンプルを取り、それを (fit() で訓練可能で save_weights でセーブできるような) Model を構築するために使用できるでしょう :

class ResNet(tf.keras.Model):

    def __init__(self):
        super(ResNet, self).__init__()
        self.block_1 = ResNetBlock()
        self.block_2 = ResNetBlock()
        self.global_pool = layers.GlobalAveragePooling2D()
        self.classifier = Dense(num_classes)

    def call(self, inputs):
        x = self.block_1(inputs)
        x = self.block_2(x)
        x = self.global_pool(x)
        return self.classifier(x)


resnet = ResNet()
dataset = ...
resnet.fit(dataset, epochs=10)
resnet.save_weights(filepath)

 

総てを一つにまとめる : end-to-end サンプル

ここに貴方がここまでに学習したものがあります :

  • 層は (__init__ か build で作成された) 状態と (call 内の) ある計算をカプセル化します。
  • 層は新しい、より大きな計算ブロックを作成するために再帰的にネストできます。
  • 層は損失を作成して追跡できます (典型的には正則化損失)。
  • 外側のコンテナ、貴方が訓練したいものはモデルです。モデルはちょうど層のようなものですが、追加の訓練とシリアライゼーション・ユティリティを持ちます。

これら総てのものを end-to-end サンプルにまとめましょう : 変分オートエンコーダ (VAE) を実装していきます。それを MNIST 数字の上で訓練します。

私達の VAE は Model のサブクラスで、 Layer をサブクラス化した層のネストされた構成として構築されます。それは正則化損失 (KL ダイバージェンス) をフィーチャーします。

class Sampling(layers.Layer):
  """Uses (z_mean, z_log_var) to sample z, the vector encoding a digit."""

  def call(self, inputs):
    z_mean, z_log_var = inputs
    batch = tf.shape(z_mean)[0]
    dim = tf.shape(z_mean)[1]
    epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
    return z_mean + tf.exp(0.5 * z_log_var) * epsilon


class Encoder(layers.Layer):
  """Maps MNIST digits to a triplet (z_mean, z_log_var, z)."""

  def __init__(self,
               latent_dim=32,
               intermediate_dim=64,
               name='encoder',
               **kwargs):
    super(Encoder, self).__init__(name=name, **kwargs)
    self.dense_proj = layers.Dense(intermediate_dim, activation='relu')
    self.dense_mean = layers.Dense(latent_dim)
    self.dense_log_var = layers.Dense(latent_dim)
    self.sampling = Sampling()

  def call(self, inputs):
    x = self.dense_proj(inputs)
    z_mean = self.dense_mean(x)
    z_log_var = self.dense_log_var(x)
    z = self.sampling((z_mean, z_log_var))
    return z_mean, z_log_var, z


class Decoder(layers.Layer):
  """Converts z, the encoded digit vector, back into a readable digit."""

  def __init__(self,
               original_dim,
               intermediate_dim=64,
               name='decoder',
               **kwargs):
    super(Decoder, self).__init__(name=name, **kwargs)
    self.dense_proj = layers.Dense(intermediate_dim, activation='relu')
    self.dense_output = layers.Dense(original_dim, activation='sigmoid')

  def call(self, inputs):
    x = self.dense_proj(inputs)
    return self.dense_output(x)


class VariationalAutoEncoder(tf.keras.Model):
  """Combines the encoder and decoder into an end-to-end model for training."""

  def __init__(self,
               original_dim,
               intermediate_dim=64,
               latent_dim=32,
               name='autoencoder',
               **kwargs):
    super(VariationalAutoEncoder, self).__init__(name=name, **kwargs)
    self.original_dim = original_dim
    self.encoder = Encoder(latent_dim=latent_dim,
                           intermediate_dim=intermediate_dim)
    self.decoder = Decoder(original_dim, intermediate_dim=intermediate_dim)

  def call(self, inputs):
    z_mean, z_log_var, z = self.encoder(inputs)
    reconstructed = self.decoder(z)
    # Add KL divergence regularization loss.
    kl_loss = - 0.5 * tf.reduce_mean(
        z_log_var - tf.square(z_mean) - tf.exp(z_log_var) + 1)
    self.add_loss(kl_loss)
    return reconstructed
original_dim = 784
vae = VariationalAutoEncoder(original_dim, 64, 32)

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
mse_loss_fn = tf.keras.losses.MeanSquaredError()

loss_metric = tf.keras.metrics.Mean()

(x_train, _), _ = tf.keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') / 255

train_dataset = tf.data.Dataset.from_tensor_slices(x_train)
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

epochs = 3

# Iterate over epochs.
for epoch in range(epochs):
  print('Start of epoch %d' % (epoch,))

  # Iterate over the batches of the dataset.
  for step, x_batch_train in enumerate(train_dataset):
    with tf.GradientTape() as tape:
      reconstructed = vae(x_batch_train)
      # Compute reconstruction loss
      loss = mse_loss_fn(x_batch_train, reconstructed)
      loss += sum(vae.losses)  # Add KLD regularization loss

    grads = tape.gradient(loss, vae.trainable_weights)
    optimizer.apply_gradients(zip(grads, vae.trainable_weights))

    loss_metric(loss)

    if step % 100 == 0:
      print('step %s: mean loss = %s' % (step, loss_metric.result()))
Start of epoch 0
step 0: mean loss = tf.Tensor(0.36229628, shape=(), dtype=float32)
step 100: mean loss = tf.Tensor(0.12543045, shape=(), dtype=float32)
step 200: mean loss = tf.Tensor(0.09899337, shape=(), dtype=float32)
step 300: mean loss = tf.Tensor(0.08906902, shape=(), dtype=float32)
step 400: mean loss = tf.Tensor(0.084127985, shape=(), dtype=float32)
step 500: mean loss = tf.Tensor(0.080847934, shape=(), dtype=float32)
step 600: mean loss = tf.Tensor(0.07870408, shape=(), dtype=float32)
step 700: mean loss = tf.Tensor(0.0770879, shape=(), dtype=float32)
step 800: mean loss = tf.Tensor(0.07593905, shape=(), dtype=float32)
step 900: mean loss = tf.Tensor(0.07492779, shape=(), dtype=float32)
Start of epoch 1
step 0: mean loss = tf.Tensor(0.07462462, shape=(), dtype=float32)
step 100: mean loss = tf.Tensor(0.073986255, shape=(), dtype=float32)
step 200: mean loss = tf.Tensor(0.073490135, shape=(), dtype=float32)
step 300: mean loss = tf.Tensor(0.07300871, shape=(), dtype=float32)
step 400: mean loss = tf.Tensor(0.072677866, shape=(), dtype=float32)
step 500: mean loss = tf.Tensor(0.07227722, shape=(), dtype=float32)
step 600: mean loss = tf.Tensor(0.07198606, shape=(), dtype=float32)
step 700: mean loss = tf.Tensor(0.07169241, shape=(), dtype=float32)
step 800: mean loss = tf.Tensor(0.071460575, shape=(), dtype=float32)
step 900: mean loss = tf.Tensor(0.07119254, shape=(), dtype=float32)
Start of epoch 2
step 0: mean loss = tf.Tensor(0.07112255, shape=(), dtype=float32)
step 100: mean loss = tf.Tensor(0.07095015, shape=(), dtype=float32)
step 200: mean loss = tf.Tensor(0.07082167, shape=(), dtype=float32)
step 300: mean loss = tf.Tensor(0.070664145, shape=(), dtype=float32)
step 400: mean loss = tf.Tensor(0.0705633, shape=(), dtype=float32)
step 500: mean loss = tf.Tensor(0.070415, shape=(), dtype=float32)
step 600: mean loss = tf.Tensor(0.07030472, shape=(), dtype=float32)
step 700: mean loss = tf.Tensor(0.07018032, shape=(), dtype=float32)
step 800: mean loss = tf.Tensor(0.07008379, shape=(), dtype=float32)
step 900: mean loss = tf.Tensor(0.06995715, shape=(), dtype=float32)

VAE は Model をサブクラス化していますから、それは組み込み訓練ループをフィーチャーすることに注意してください。従ってそれをこのように訓練することもできるでしょう :

vae = VariationalAutoEncoder(784, 64, 32)

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)

vae.compile(optimizer, loss=tf.keras.losses.MeanSquaredError())
vae.fit(x_train, x_train, epochs=3, batch_size=64)
Train on 60000 samples
Epoch 1/3
60000/60000 [==============================] - 3s 56us/sample - loss: 0.0745
Epoch 2/3
60000/60000 [==============================] - 3s 44us/sample - loss: 0.0676
Epoch 3/3
60000/60000 [==============================] - 3s 44us/sample - loss: 0.0676

<tensorflow.python.keras.callbacks.History at 0x7fa0d8645ba8>

 

オブジェクト指向開発を越えて : Functional API

このサンプルは貴方にとってオブジェクト指向開発に過ぎたでしょうか?貴方はまた Functional API を使用してモデルを構築することもできます。重要なことは、一つのスタイルか別のものの選択は他のスタイルで書かれたコンポーネントを活用することを妨げないことです : 貴方は常に上手く組み合わせることができます。

例えば、下の Functional API サンプルは上の例で定義した同じ Sampling 層を再利用しています。

original_dim = 784
intermediate_dim = 64
latent_dim = 32

# Define encoder model.
original_inputs = tf.keras.Input(shape=(original_dim,), name='encoder_input')
x = layers.Dense(intermediate_dim, activation='relu')(original_inputs)
z_mean = layers.Dense(latent_dim, name='z_mean')(x)
z_log_var = layers.Dense(latent_dim, name='z_log_var')(x)
z = Sampling()((z_mean, z_log_var))
encoder = tf.keras.Model(inputs=original_inputs, outputs=z, name='encoder')

# Define decoder model.
latent_inputs = tf.keras.Input(shape=(latent_dim,), name='z_sampling')
x = layers.Dense(intermediate_dim, activation='relu')(latent_inputs)
outputs = layers.Dense(original_dim, activation='sigmoid')(x)
decoder = tf.keras.Model(inputs=latent_inputs, outputs=outputs, name='decoder')

# Define VAE model.
outputs = decoder(z)
vae = tf.keras.Model(inputs=original_inputs, outputs=outputs, name='vae')

# Add KL divergence regularization loss.
kl_loss = - 0.5 * tf.reduce_mean(
    z_log_var - tf.square(z_mean) - tf.exp(z_log_var) + 1)
vae.add_loss(kl_loss)

# Train.
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
vae.compile(optimizer, loss=tf.keras.losses.MeanSquaredError())
vae.fit(x_train, x_train, epochs=3, batch_size=64)
Train on 60000 samples
Epoch 1/3
60000/60000 [==============================] - 3s 56us/sample - loss: 0.0745
Epoch 2/3
60000/60000 [==============================] - 3s 47us/sample - loss: 0.0676
Epoch 3/3
60000/60000 [==============================] - 3s 47us/sample - loss: 0.0675

<tensorflow.python.keras.callbacks.History at 0x7fa0d0323198>
 

以上



クラスキャット

最近の投稿

  • LangGraph Platform : Get started : クイックスタート
  • LangGraph Platform : 概要
  • LangGraph : Prebuilt エージェント : ユーザインターフェイス
  • LangGraph : Prebuilt エージェント : 配備
  • LangGraph : Prebuilt エージェント : マルチエージェント

タグ

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 (20) 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 Graphics (7) TensorFlow Probability (9) TensorFlow Programmer's Guide (22) TensorFlow Release Note (18) TensorFlow Tutorials (33) TF-Agents 0.4 (11)
2019年12月
月 火 水 木 金 土 日
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
« 11月   1月 »
© 2025 ClasCat® AI Research | Powered by Minimalist Blog WordPress Theme