1. Eager 実行(デフォルト)
概要
-
即時実行モード。Python の命令をそのまま実行し、
その場で結果(tf.Tensor
オブジェクト)を返します。 - デバッグや開発がしやすく、NumPy ライクな感覚で手軽に試せます。
特徴
- 各演算は呼び出し順にすぐ実行される
-
.numpy()
を使って簡単に NumPy 配列に変換可能 - Python の標準デバッガ(
print
、pdb
)が有効
コード例
import tensorflow as tf
# Eager 実行では即座に結果が返る
a = tf.constant([[1.0, 2.0], [3.0, 4.0]])
b = tf.constant([[5.0, 6.0], [7.0, 8.0]])
c = a + b
print("c =", c) # tf.Tensor([...], shape=(2,2), dtype=float32)
print("NumPy array:", c.numpy())
2. グラフ実行(Graph Execution)
概要
-
計算グラフ(
tf.Graph
)を事前に組み立て、そのグラフをまとめて実行する方式。 - TensorFlow 1.x の標準モードで、TensorFlow 2.x でも
@tf.function
を付けることで擬似的に利用できます。
特徴
- 実行前にグラフを最適化(定数折り畳み、融合など)
- GPU/TPU などハードウェアへの最適化が強力
- 大規模モデルや本番環境でのスループット向上に有利
コード例
import tensorflow as tf
@tf.function # このデコレータで関数内の演算が「グラフ」として構築される
def my_matmul(x, y):
# ここはグラフ化され、最適化・再利用される
return tf.matmul(x, y)
# 関数を呼び出すと、初回はグラフ構築 → 実行、
# 2 回目以降はキャッシュされたグラフを即実行
x = tf.random.uniform([2, 3])
y = tf.random.uniform([3, 4])
z1 = my_matmul(x, y) # グラフをビルドして実行
z2 = my_matmul(x, y) # キャッシュ済みグラフを実行(高速)
-
my_matmul.get_concrete_function(x, y)
を呼ぶと、入力シェイプ・型に合わせたグラフが具体化(Concrete Function)されます。
3. 両モードの使い分け
特徴 | Eager 実行 | グラフ実行 (tf.function ) |
---|---|---|
開発・デバッグ | ◎(直感的、デバッギング容易) | △(中間グラフが見えにくい) |
パフォーマンス | ◯(小規模実験向き) | ◎(大規模・本番環境向き) |
最適化 | なし | 定数折り畳み、演算融合など自動 |
ハードウェア対応 | 普通 | GPU/TPU 最適化 |
-
開発段階 ではまず Eager 実行で動作確認し、安定したら
@tf.function
を付けてグラフ実行に切り替えてパフォーマンスを上げる、という流れが一般的です。
4. まとめ
- Eager 実行:即時実行。Python ライクに動かせてデバッグしやすい。
- グラフ実行:計算グラフを最適化/キャッシュしてまとめて実行。大規模学習や本番向き。
-
実践的流れ:
- 最初は Eager で試し、
- コアとなるトレーニングループや推論関数に
@tf.function
を付けてグラフ化すると、性能向上が得られる。
まずは Eager モードで手を動かし、慣れてきたら tf.function
でグラフ実行を試してみましょう。