![]() |
![]() |
![]() |
![]() |
これは、下記の手法を示す TensorFlow の入門チュートリアルです。
- 必要なパッケージのインポート
- テンソルの作成と使用
- GPUによる高速化の使用
tf.data.Dataset
のデモ
TensorFlowのインポート
始めるにはまず、tensorflow
モジュールをインポートします。TensorFlow 2 の時点では、Eager execution はデフォルトでオンになっています。Eager execution では、TensorFlow のフロントエンドがよりインタラクティブになります。これについては、後で詳しく説明します。
import tensorflow as tf
2022-08-08 21:14:05.143668: E tensorflow/stream_executor/cuda/cuda_blas.cc:2981] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered 2022-08-08 21:14:05.934391: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvrtc.so.11.1: cannot open shared object file: No such file or directory 2022-08-08 21:14:05.934646: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvrtc.so.11.1: cannot open shared object file: No such file or directory 2022-08-08 21:14:05.934659: 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.add、tf.matmul、tf.linalg.inv など)が多数含まれたライブラリが用意されています。これらの演算によって、組み込みの Python 型が自動的に変換されます。以下に例を示します。
print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))
# Operator overloading is also supported
print(tf.square(2) + tf.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.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.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 のどちらかを選択し、必要であればテンソルを GPU メモリと CPU メモリの間でコピーして実行します。演算で生成されたテンソルは通常演算を実行したデバイスのメモリに置かれます。例を見てみましょう。
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 は演算を実行するデバイスを自動的に決め、必要であればテンソルをそのデバイスにコピーします。しかし、tf.device
コンテキストマネジャーを使うことで、TensorFlow の演算を特定のデバイスに配置することができます。例を見てみましょう。
import time
def time_matmul(x):
start = time.time()
for loop in range(10):
tf.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: 48.71ms On GPU: 10 loops: 291.58ms
データセット
このセクションでは tf.data.Dataset
API を使って、モデルにデータを供給するためのパイプラインを構築します。tf.data.Dataset
APIは、単純で再利用可能な部品をもとに、モデルの訓練あるいは評価ループにデータを供給する高性能で複雑な入力パイプラインを構築するために使われます。
ソースDataset
の作成
Dataset.from_tensors やDataset.from_tensor_slices といったファクトリー関数または TextLineDataset あるいはTFRecordDataset のようなファイルを読み込むオブジェクトを使って、 元となるデータセットを作成しましょう。詳しくは、TensorFlow Dataset guide を参照してください。
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)
変換の適用
map, batch, shuffle などの変換関数を使って、データセットレコードに変換を適用します。
ds_tensors = ds_tensors.map(tf.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([4 9], shape=(2,), dtype=int32) tf.Tensor([ 1 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)