ホーム » TensorFlow 2.0 » TensorFlow 2.4 : ガイド : 基本 – 基本的な訓練ループ

TensorFlow 2.4 : ガイド : 基本 – 基本的な訓練ループ

TensorFlow 2.4 : ガイド : 基本 – 基本的な訓練ループ (翻訳/解説)

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

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

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

 

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

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

人工知能研究開発支援 人工知能研修サービス テレワーク & オンライン授業を支援
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。

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

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

 

 

ガイド : 基本 – 基本的な訓練ループ

前のガイドでは、tensor、変数、勾配テープそしてモジュールについて学習しました。このガイドでは、モデルを訓練するためにこれら総てを適合させます。

TensorFlow はまたボイラープレートを削減する有用な抽象を提供する高位ニューラルネットワーク API、tf.Keras API も含みます。けれども、このガイドでは、基本的なクラスを使います。

 

セットアップ

import tensorflow as tf

 

機械学習問題を解く

機械学習問題を解くことは通常は以下のステップから成ります :

  • 訓練データを得る。
  • モデルを定義する。
  • 損失関数を定義する。
  • 訓練データを通して実行し、理想的な値からの損失を計算する。
  • その損失のための勾配を計算してそしてデータに適合させるために変数を調整するために optimizer を利用する。
  • 結果を評価する。

例示目的で、このガイドでは単純な線形モデル $f(x) = x * W + b$ を開発します、これは 2 つの変数 : $W$ (重み) と $b$ (バイアス) を持ちます。

これは機械学習問題の最も基本です : $x$ と $y$ が与えられたとき、単純な線形回帰 を通して線 (= line) の傾きとオフセットを見つけようとします。

 

データ

教師あり学習は入力 (通常は x として記されます) と出力 (y として記され、しばしばラベルと呼ばれます) を使用します。目標は入力から出力の値を予測できるようにペアの入力と出力から学習することです。

データの各入力は、TensorFlow では、殆ど常に tensor で表されて、そしてそれはしばしばベクトルです。教師あり学習では、出力 (or 貴方が予測したい値) もまた tensor です。

ここに線に沿った点にガウス (正規) ノイズを追加することにより合成された幾つかのデータがあります。

# The actual line
TRUE_W = 3.0
TRUE_B = 2.0

NUM_EXAMPLES = 1000

# A vector of random x values
x = tf.random.normal(shape=[NUM_EXAMPLES])

# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])

# Calculate y
y = x * TRUE_W + TRUE_B + noise
# Plot all the data
import matplotlib.pyplot as plt

plt.scatter(x, y, c="b")
plt.show()

tensor は通常はバッチ、あるいは一緒にスタックされた入力と出力のグループにまとめて集められます。バッチ処理は幾つかの訓練の恩恵を与えてアクセラレータとベクトル化計算で上手く動作します。このデータセットがどれほど小さいと仮定しても、データセット全体を単一バッチとして扱うことができます。

 

モデルを定義する

モデルの総ての重みを表すために tf.Variable を使用します。tf.Variable は値をストアしてこれを必要に応じて tensor 形式で提供します。より詳細は 変数ガイド を見てください。

変数と計算をカプセル化するために tf.Module を使用します。任意の Python オブジェクトを使用できたでしょうけれども、このようにしてそれは容易にセーブされます。

ここでは、変数として wb を定義します。

class MyModel(tf.Module):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    # Initialize the weights to `5.0` and the bias to `0.0`
    # In practice, these should be randomly initialized
    self.w = tf.Variable(5.0)
    self.b = tf.Variable(0.0)

  def __call__(self, x):
    return self.w * x + self.b

model = MyModel()

# List the variables tf.modules's built-in variable aggregation.
print("Variables:", model.variables)

# Verify the model works
assert model(3.0).numpy() == 15.0
Variables: (<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>)

初期変数はここでは固定されたやり方で設定されますが、Keras の残りを伴ってもそうでなくても、Keras は利用可能な多くの initializer のどれかを装備します。

 

損失関数を定義する

損失関数は与えられた入力のためのモデルの出力がターゲット出力にどのくらい上手く一致しているかを測定します。目標は訓練の間にこの差を最小化することです。標準的な L2 損失を定義します、「平均二乗」誤差としても知られています :

# This computes a single loss value for an entire batch
def loss(target_y, predicted_y):
  return tf.reduce_mean(tf.square(target_y - predicted_y))

モデルを訓練する前に、モデルの予測を赤色でそして訓練データを青色でプロットすることにより損失値を可視化できます :

plt.scatter(x, y, c="b")
plt.scatter(x, model(x), c="r")
plt.show()

print("Current loss: %1.6f" % loss(model(x), y).numpy())

Current loss: 8.901840

 

訓練ループを定義する

訓練ループは 3 つのタスクを順番に反復して行なうことから成ります :

  • 出力を生成するために入力のバッチをモデルに送る
  • 出力を出力 (or ラベル) と比較することにより損失を計算します
  • 勾配を見つけるために勾配テープを使用します
  • それらの勾配で変数を最適化します

このサンプルについて、勾配降下 を使用してモデルを訓練できます。

tf.keras.optimizers で捕捉されている勾配降下スキームの多くの変種があります。しかし最初の原理から構築する精神で、ここでは基本的な数学を自動微分のための tf.GradientTape と値をデクリメントする tf.assign_sub (これは tf.assign と tf.sub を結合します) の手助けにより貴方自身で実装します :

# Given a callable model, inputs, outputs, and a learning rate...
def train(model, x, y, learning_rate):

  with tf.GradientTape() as t:
    # Trainable variables are automatically tracked by GradientTape
    current_loss = loss(y, model(x))

  # Use GradientTape to calculate the gradients with respect to W and b
  dw, db = t.gradient(current_loss, [model.w, model.b])

  # Subtract the gradient scaled by the learning rate
  model.w.assign_sub(learning_rate * dw)
  model.b.assign_sub(learning_rate * db)

訓練を見ている間に、訓練ループを通して xy の同じを送り、そして Wb がどのように進化するかを見ることができます。

model = MyModel()

# Collect the history of W-values and b-values to plot later
Ws, bs = [], []
epochs = range(10)

# Define a training loop
def training_loop(model, x, y):

  for epoch in epochs:
    # Update the model with the single giant batch
    train(model, x, y, learning_rate=0.1)

    # Track this before I update
    Ws.append(model.w.numpy())
    bs.append(model.b.numpy())
    current_loss = loss(y, model(x))

    print("Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f" %
          (epoch, Ws[-1], bs[-1], current_loss))
print("Starting: W=%1.2f b=%1.2f, loss=%2.5f" %
      (model.w, model.b, loss(y, model(x))))

# Do the training
training_loop(model, x, y)

# Plot it
plt.plot(epochs, Ws, "r",
         epochs, bs, "b")

plt.plot([TRUE_W] * len(epochs), "r--",
         [TRUE_B] * len(epochs), "b--")

plt.legend(["W", "b", "True W", "True b"])
plt.show()
Starting: W=5.00 b=0.00, loss=8.55563
Epoch  0: W=4.63 b=0.38, loss=5.97707
Epoch  1: W=4.33 b=0.69, loss=4.28069
Epoch  2: W=4.08 b=0.95, loss=3.16458
Epoch  3: W=3.88 b=1.15, loss=2.43017
Epoch  4: W=3.72 b=1.31, loss=1.94688
Epoch  5: W=3.59 b=1.44, loss=1.62882
Epoch  6: W=3.48 b=1.55, loss=1.41948
Epoch  7: W=3.39 b=1.64, loss=1.28169
Epoch  8: W=3.32 b=1.70, loss=1.19098
Epoch  9: W=3.26 b=1.76, loss=1.13127

# Visualize how the trained model performs
plt.scatter(x, y, c="b")
plt.scatter(x, model(x), c="r")
plt.show()

print("Current loss: %1.6f" % loss(model(x), y).numpy())

Current loss: 1.131265

 

同じ解法、しかし Keras で

上のコードを Keras の同値と対比することは有用です。

モデルを定義することは tf.keras.Model をサブクラス化する場合正確に同じに見えます。Keras モデルは究極的にはモジュールから継承することを覚えていてください。

class MyModelKeras(tf.keras.Model):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    # Initialize the weights to `5.0` and the bias to `0.0`
    # In practice, these should be randomly initialized
    self.w = tf.Variable(5.0)
    self.b = tf.Variable(0.0)

  def __call__(self, x, **kwargs):
    return self.w * x + self.b

keras_model = MyModelKeras()

# Reuse the training loop with a Keras model
training_loop(keras_model, x, y)

# You can also save a checkpoint using Keras's built-in support
keras_model.save_weights("my_checkpoint")
Epoch  0: W=4.63 b=0.38, loss=5.97707
Epoch  1: W=4.33 b=0.69, loss=4.28069
Epoch  2: W=4.08 b=0.95, loss=3.16458
Epoch  3: W=3.88 b=1.15, loss=2.43017
Epoch  4: W=3.72 b=1.31, loss=1.94688
Epoch  5: W=3.59 b=1.44, loss=1.62882
Epoch  6: W=3.48 b=1.55, loss=1.41948
Epoch  7: W=3.39 b=1.64, loss=1.28169
Epoch  8: W=3.32 b=1.70, loss=1.19098
Epoch  9: W=3.26 b=1.76, loss=1.13127

モデルを作成するたびに新しい訓練ループを書くのではなく、ショートカットとして Keras の組込み特徴を利用することができます。Python 訓練ループを書いたりデバッグすることを望まないときに有用であり得ます。

そうする場合、パラメータを設定するために model.compile() を、そして訓練するために model.fit() を使用する必要があります。再度ショートカットとして、L2 損失と勾配降下の Keras 実装を使用することはより少ないコードであり得ます。Keras 損失と optimizer はこれらの便利な関数の外でもまた利用できて、前のサンプルはそれらを利用できたでしょう。

keras_model = MyModelKeras()

# compile sets the training paramaeters
keras_model.compile(
    # By default, fit() uses tf.function().  You can
    # turn that off for debugging, but it is on now.
    run_eagerly=False,

    # Using a built-in optimizer, configuring as an object
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),

    # Keras comes with built-in MSE error
    # However, you could use the loss function
    # defined above
    loss=tf.keras.losses.mean_squared_error,
)

Keras fit はバッチ化データや完全なデータセットを NumPy 配列として想定します。NumPy 配列はバッチに切り刻まれて (= chop) 32 のバッチサイズがデフォルトとなります。

この場合、手書きループの動作に合わせるため、x をサイズ 1000 の単一バッチとして渡すべきです。

print(x.shape[0])
keras_model.fit(x, y, epochs=10, batch_size=1000)
1000
Epoch 1/10
1/1 [==============================] - 0s 248ms/step - loss: 8.5556
Epoch 2/10
1/1 [==============================] - 0s 2ms/step - loss: 5.9771
Epoch 3/10
1/1 [==============================] - 0s 4ms/step - loss: 4.2807
Epoch 4/10
1/1 [==============================] - 0s 4ms/step - loss: 3.1646
Epoch 5/10
1/1 [==============================] - 0s 3ms/step - loss: 2.4302
Epoch 6/10
1/1 [==============================] - 0s 3ms/step - loss: 1.9469
Epoch 7/10
1/1 [==============================] - 0s 3ms/step - loss: 1.6288
Epoch 8/10
1/1 [==============================] - 0s 3ms/step - loss: 1.4195
Epoch 9/10
1/1 [==============================] - 0s 3ms/step - loss: 1.2817
Epoch 10/10
1/1 [==============================] - 0s 3ms/step - loss: 1.1910
<tensorflow.python.keras.callbacks.History at 0x7f4756125710>

Keras は訓練の前ではなく、訓練後に損失をプリントアウトするので、最初の損失がより低く見えますが、そうでなければこれは本質的には同じ訓練パフォーマンスを示すことに注意してください。

 

以上





AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com