TensorFlow : Tutorials : Eager : Eager execution 基本 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 04/11/2019
作成日時 : 07/16/2018
* TensorFlow 1.9 でドキュメント構成が変わり新規にチュートリアル・ページも追加されました。
* 本ページは、TensorFlow 本家サイトの Tutorials – Research and Experimentation – Eager execution basics を
翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、適宜、追加改変している場合もあります。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
これは TensorFlow を (eager execution を有効にして) 使用するための初歩的なチュートリアルです。以下をカバーします :
- 必要なパッケージをインポートする。
- Tensor を作成して使用する。
- GPU アクセラレーション。
- データセット。
Import TensorFlow
始めるためには、tensorflow モジュールをインポートして Eager execution を有効にします。Eager execution は TensorFlow により対話的なフロントエンドを可能にします。
import tensorflow as tf tf.enable_eager_execution()
Tensor
Tensor は多次元配列です。NumPy ndarray オブジェクトと同様に、Tensor オブジェクトはデータ型と shape を持ちます。更に、Tensor は (GPU のような) アクセラレータ・メモリ内に常駐できます。TensorFlow は Tensor を消費して生成する演算 (tf.add, tf.matmul, tf.linalg.inv etc.) のリッチなライブラリを提供します。これらの演算は native Python 型を自動的に変換します。例えば :
print(tf.add(1, 2)) print(tf.add([1, 2], [3, 4])) print(tf.square(5)) print(tf.reduce_sum([1, 2, 3])) print(tf.encode_base64("hello world")) # Operator overloading is also supported print(tf.square(2) + tf.square(3))
Out:
tf.Tensor(3, shape=(), dtype=int32) tf.Tensor([4 6], shape=(2,), dtype=int32) tf.Tensor(25, shape=(), dtype=int32) tf.Tensor(6, shape=(), dtype=int32) tf.Tensor(b'aGVsbG8gd29ybGQ', shape=(), dtype=string) tf.Tensor(13, shape=(), dtype=int32)
各 Tensor は shape とデータ型を持ちます。
x = tf.matmul([[1]], [[2, 3]]) print(x.shape) print(x.dtype)
Out:
(1, 2) <dtype: 'int32'>
NumPy 配列と TensorFlow Tensor の間の最も明白な違いは :
- Tensor は (GPU, TPU のような) アクセラレータ・メモリで支援可能です。
- Tensors はイミュータブルです。
NumPy 互換性
TensorFlow Tensor と NumPy ndarray の間の変換は次のように非常に単純です :
- TensorFlow 演算は NumPy ndarray を Tensor に自動的に変換します。
- NumPy 演算は Tensor を NumPy ndarray に自動的に変換します。
Tensor はそれらの上で .numpy() メソッドを呼び出すことで NumPy ndarray に明示的に変換できます。これらの変換は典型的には安上がりです、何故ならば array と Tensor は可能であれば基礎的なメモリ表現を共有するからです。けれども、基礎的な表現は常に可能であるとは限りません、何故ならば Tensor は GPU メモリ内にホストされるかもしれず、その一方で NumPy 配列は常にホストメモリで支援されるからで、そのため変換は GPU からホストメモリへのコピーを呼び起こします。
import numpy as np ndarray = np.ones([3, 3]) print("TensorFlow operations convert numpy arrays to Tensors automatically") tensor = tf.multiply(ndarray, 42) print(tensor) print("And NumPy operations convert Tensors to numpy arrays automatically") print(np.add(tensor, 1)) print("The .numpy() method explicitly converts a Tensor to a numpy array") print(tensor.numpy())
Out:
TensorFlow operations convert numpy arrays to Tensors automatically tf.Tensor( [[ 42. 42. 42.] [ 42. 42. 42.] [ 42. 42. 42.]], shape=(3, 3), dtype=float64) And NumPy operations convert Tensors to numpy arrays automatically [[ 43. 43. 43.] [ 43. 43. 43.] [ 43. 43. 43.]] The .numpy() method explicitly converts a Tensor to a numpy array [[ 42. 42. 42.] [ 42. 42. 42.] [ 42. 42. 42.]]
GPU アクセラレーション
多くの TensorFlow 演算は計算のために GPU を使用することによりアクセラレートできます。どのようなアノテーションもなければ、TensorFlow は演算のために GPU か CPU を使用するかを自動的に決定します (そして必要であれば CPU と GPU メモリ間で tensor をコピーします)。演算により生成される tensor は典型的には (その上で演算が実行される) デバイスのメモリにより支援されます。例えば :
x = tf.random_uniform([3, 3]) print("Is there a GPU available: "), print(tf.test.is_gpu_available()) print("Is the Tensor on GPU #0: "), print(x.device.endswith('GPU:0'))
Out: (CPU 環境の場合)
Is there a GPU available: False Is the Tensor on GPU #0: False
デバイス名
Tensor.device プロパティは Tensor のコンテンツをホスティングするデバイスの完全修飾文字列名を提供します。この名前は (その上でプログラムが動作する) ホストのネットワーク・アドレスの識別子とホスト内のデバイスのような多くの詳細をエンコードします。これは TensorFlow プログラムの分散実行のために必要ですが、当面はそれをスキップします。tensor がホスト上の N-th GPU 上に置かれる場合には文字列は GPU:<N> で終わります。
明示的なデバイスへの配置
TensorFlow での用語「配置 (= placement)」は個々の演算が実行のためにどのようにデバイス上割り当てられるか (置かれるか) を指し示します。上で言及したように、提供される明示的なガイダンスがないときには、TensorFlow は演算を実行するためのデバイスを自動的に決定して必要であれば Tensor をそのデバイスにコピーします。けれども、TensorFlow 演算はtf.device コンテキスト・マネージャを使用して特定のデバイスに明示的に置かれることができます。例えば :
def time_matmul(x): %timeit tf.matmul(x, x) # Force execution on CPU print("On CPU:") with tf.device("CPU:0"): x = tf.random_uniform([1000, 1000]) assert x.device.endswith("CPU:0") time_matmul(x) # Force execution on GPU #0 if available if tf.test.is_gpu_available(): with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc. x = tf.random_uniform([1000, 1000]) assert x.device.endswith("GPU:0") time_matmul(x)
On CPU: 10.5 ms ± 38.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
データセット
このセクションはモデルにデータを供給するためのパイプラインを構築するために tf.data.Dataset API の使用方法を示します。それは次をカバーします :
- データセットを作成する。
- eager execution が有効である際にデータセットに渡り iterate する。
モデルの訓練と評価ループに供給する単純で、再利用可能なピースから高性能で、複雑な入力パイプラインを構築するために Dataset API を使用することを推奨します。
TensorFlow グラフに精通しているのであれば、eager execution が有効であるとき Dataset オブジェクトを構築するための API は正確に同じままですが、データセットの要素に渡り iterate するプロセスは少しだけ単純です。tf.data.Dataset オブジェクトに渡り Python iteration を使用できて tf.data.Iterator オブジェクトを明示的に作成する必要がありません。結果的に、TensorFlow ガイド の iterator の議論は eager execution が有効であるときには関係ありません。
ソース Dataset を作成する
ソース dataset は、(Dataset.from_tensors, Dataset.from_tensor_slices のような) factory 関数の一つを使用するか、(TextLineDataset や TFRecordDataset のような) ファイルから読むオブジェクトを使用して作成します。更なる情報のためには TensorFlow ガイド の “入力データを読む” を見てください。
ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6]) # Create a CSV file import tempfile _, filename = tempfile.mkstemp() with open(filename, 'w') as f: f.write("""Line 1 Line 2 Line 3 """) ds_file = tf.data.TextLineDataset(filename)
変換を適用する
dataset のレコードに変換を適用するために map, batch, shuffle etc. のような変換関数を使用します。詳細については tf.data.Dataset のための API ドキュメント を見てください。
ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2) ds_file = ds_file.batch(2)
Iterate
eager execution が有効であるとき Dataset オブジェクトは iteration をサポートします。TensorFlow グラフの Dataset の使用に精通している場合、Dataset.make_one_shot_iterator() または get_next() コールへの呼び出しの必要はないことに注意してください。
print('Elements of ds_tensors:') for x in ds_tensors: print(x) print('\nElements in ds_file:') for x in ds_file: print(x)
Out:
Elements of ds_tensors: tf.Tensor([1 4], shape=(2,), dtype=int32) tf.Tensor([ 9 16], shape=(2,), dtype=int32) tf.Tensor([25 36], shape=(2,), dtype=int32) Elements in ds_file: tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string) tf.Tensor([b'Line 3' b' '], shape=(2,), dtype=string)
以上