TensorFlow.org で表示 | Google Colab で実行 | GitHub でソースを表示 | ノートブックをダウンロード |
これは、下記の手法を示す TensorFlow の入門チュートリアルです。
- 必要なパッケージのインポート
- テンソルの作成と使用
- GPU アクセラレーションの使用
tf.data.Dataset
を使用してデータパイプラインを構築する
TensorFlowのインポート
始めるにはまず、tensorflow
モジュールをインポートします。TensorFlow 2 の時点では、Eager execution はデフォルトでオンになっています。Eager execution では、TensorFlow のフロントエンドがよりインタラクティブになります。これについては、後で詳しく説明します。
import tensorflow as tf
2022-12-15 02:52:41.764436: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory 2022-12-15 02:52:41.764552: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory 2022-12-15 02:52:41.764564: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
テンソル
テンソルは多次元の配列です。NumPy の ndarray
オブジェクトと同様に、tf.Tensor
オブジェクトにはデータ型と形状があります。また、tf.Tensor
はアクセラレータのメモリ(GPU など)に留まることができます。TensorFlow には、tf.Tensor
を消費して生成する演算(tf.math.add
、tf.linalg.matmul
、tf.linalg.inv
など)が多数含まれたライブラリが用意されています。これらの演算によって、以下のように、組み込み Python 型が自動的に変換されます。
print(tf.math.add(1, 2))
print(tf.math.add([1, 2], [3, 4]))
print(tf.math.square(5))
print(tf.math.reduce_sum([1, 2, 3]))
# Operator overloading is also supported
print(tf.math.square(2) + tf.math.square(3))
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(13, shape=(), dtype=int32)
それぞれのtf.Tensor
には、形状とデータ型があります。
x = tf.linalg.matmul([[1]], [[2, 3]])
print(x)
print(x.shape)
print(x.dtype)
tf.Tensor([[2 3]], shape=(1, 2), dtype=int32) (1, 2) <dtype: 'int32'>
NumPy 配列と tf.Tensor
の間のもっとも明確な違いは
- テンソルは( GPU や TPU などの)アクセラレータメモリを使用できる
- テンソルは変更不可
NumPy との互換性
TensorFlow tf.Tensor
と NumPy ndarray
の変換は簡単です。
- TensorFlow の演算により NumPy の ndarray は自動的にテンソルに変換される
- NumPy の演算によりテンソルは自動的に NumPy の ndarray に変換される
テンソルは .numpy()
メソッドを使って明示的に NumPy の ndarray に変換されます。NumPy のndarray と tf.Tensor
はその下敷きとなるメモリ上の表現が、できるかぎり共通化されているので、通常この変換のコストは小さいです。しかし、NumPy 配列はホスト側のメモリに置かれる一方、tf.Tensor
はGPU のメモリに置かれる可能性もあるため、下層の表現をいつも共通化できるとは限りません。また、変換にはGPU からホスト側メモリへのコピーも関わってきます。
import numpy as np
ndarray = np.ones([3, 3])
print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.math.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())
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 メモリ間でテンソルをコピーします。演算によって生成されたテンソルは、通常、演算が実行されたデバイスのメモリによってバックアップされます。以下に例を示します。
x = tf.random.uniform([3, 3])
print("Is there a GPU available: "),
print(tf.config.list_physical_devices("GPU"))
print("Is the Tensor on GPU #0: "),
print(x.device.endswith('GPU:0'))
Is there a GPU available: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:2', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:3', device_type='GPU')] Is the Tensor on GPU #0: True
デバイス名
Tensor.device
プロパティにより、そのテンソルの内容を保持しているデバイスの完全な名前文字列を得ることができます。この名前には、プログラムを実行中のホストのネットワークアドレスや、ホスト上のデバイスについての詳細がエンコードされています。この情報は、TensorFlow プログラムの分散実行に必要なものです。テンソルがホスト上の N
番目のGPUにある場合、文字列の最後は GPU:<N>
となります。
明示的なデバイスの配置
TensorFlow における「配置」とは、個々の演算を実行するデバイスの割り当てを指します。前述のとおり、明示的に指定されていない場合、TensorFlow は演算を実行するデバイスを自動的に決定し、必要であれば、そのデバイスにテンソルをコピーします。
ただし、TensorFlow 演算は、tf.device
コンテキストマネージャーを使用して、特定のデバイスに明示的に配置することが可能です。以下に例を示します。
import time
def time_matmul(x):
start = time.time()
for loop in range(10):
tf.linalg.matmul(x, x)
result = time.time()-start
print("10 loops: {:0.2f}ms".format(1000*result))
# 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.config.list_physical_devices("GPU"):
print("On GPU:")
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 loops: 49.58ms On GPU: 10 loops: 343.95ms
データセット
このセクションでは、tf.data.Dataset
API を使用して、モデルにデータを提供するためのパイプラインを構築しています。tf.data.Dataset
は、パフォーマンスの高い複雑な入力パイプラインを、モデルのトレーニングまたは評価ループを提供する単純で再利用可能なピースから構築するために使用されます。(詳細については、tf.data: TensorFlow 入力パイプラインを構築するガイドをご覧ください。)
ソースDataset
の作成
ソース Dataset を作成するには、tf.data.Dataset.from_tensors
や tf.data.Dataset.from_tensor_slices
などのファクトリー関数を使用して、またはファイルから読み取る tf.data.TextLineDataset
や tf.data.TFRecordDataset
などのオブジェクトを使用します。詳細については、tf.data: 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)
変換の適用
tf.data.Dataset.map
、tf.data.Dataset.batch
、tf.data.Dataset.shuffle
などの変換関数を使用して、データセットのレコードに変換を適用します。
ds_tensors = ds_tensors.map(tf.math.square).shuffle(2).batch(2)
ds_file = ds_file.batch(2)
イテレート
tf.data.Dataset
オブジェクトは、中のレコードを繰り返し利用するためのイテレーションをサポートします。
print('Elements of ds_tensors:')
for x in ds_tensors:
print(x)
print('\nElements in ds_file:')
for x in ds_file:
print(x)
Elements of ds_tensors: tf.Tensor([1 9], shape=(2,), dtype=int32) tf.Tensor([ 4 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)