Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensor(テンソル)を作成する各種方法を解説します。
Contents
Tensorの作成方法
TensorFlowで扱うn次元の多次元配列をTensor(テンソル)と言います。ディープラーニングでの各種計算はTensorを通して実行されます。以降では、Tensorの作成方法について解説していきます。
定数Tensorの作成 tf.constant
定数の作成方法
TensorFlowで定数のTensorを作成するには、以下の例のようにtf.constantを使用します。
import tensorflow as tf # ===== 定数を作成する tf.constant # 階数0のTensor (scalar) scalar = tf.constant(10) print(scalar) print(scalar.ndim, "\n") # 階数1のTensor (vector) vector = tf.constant([1, 2, 3, 4, 5]) print(vector) print(vector.ndim, "\n") # 階数2のTensor (matrix) matrix_2d = tf.constant([[1, 2], [3, 4]]) print(matrix_2d) print(matrix_2d.ndim, "\n") # 階数3のTensor (matrix) matrix_3d = tf.constant([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]) print(matrix_3d) print(matrix_3d.ndim, "\n") # 階数4のTensor (matrix) matrix_4d = tf.constant( [ [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]], [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]], ] ) print(matrix_4d) print(matrix_4d.ndim)
【実行結果】 tf.Tensor(10, shape=(), dtype=int32) 0 tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32) 1 tf.Tensor( [[1 2] [3 4]], shape=(2, 2), dtype=int32) 2 tf.Tensor( [[[ 1 2] [ 3 4]] [[ 5 6] [ 7 8]] [[ 9 10] [11 12]]], shape=(3, 2, 2), dtype=int32) 3 tf.Tensor( [[[[ 1 2] [ 3 4]] [[ 5 6] [ 7 8]] [[ 9 10] [11 12]]] [[[ 1 2] [ 3 4]] [[ 5 6] [ 7 8]] [[ 9 10] [11 12]]]], shape=(2, 3, 2, 2), dtype=int32) 4
Tensorの添え字の組の数のことをTensorの階数と言います。例えば、スカラー(scalar)は階数0のTensor、ベクトル(vector)は階数1のTensor、2次元配列(matrix)は階数2のTensor、n次元配列(matrix)は階数nのTensorというように表現します。
上記例では階数4のTensorまでサンプルを作っています。ディープラーニングで扱う画像データは階数4のTensorを使って(データ数, チャンネル数, 縦, 横)※のような軸で扱う場合が多いので、階数4ぐらいまではイメージを持って扱えるようにしておくといいと思います。※各軸の意味はデータセットにより異なる場合があります。
tf.constantの公式ドキュメントはこちらを参照してください。
型を指定して作成する
以下の例のようにdtype引数で指定することで特定の型でTensorを作成することができます。
import tensorflow as tf # dtypeで型を指定して定数を作成する tf.constant matrix = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) print(matrix)
【実行結果】 tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float16)
上記の例では、16ビットの浮動小数点を指定してTensorを作成しています。Tensorのデータ型としては、例えば以下のようなものがあります。
型 | 概要 |
---|---|
tf.float16 | 16ビット浮動小数点 |
tf.float32 | 32ビット浮動小数点 |
tf.float64 | 64ビット浮動小数点 |
tf.int8 | 8ビット整数 |
tf.int16 | 16ビット整数 |
tf.int32 | 32ビット整数 |
tf.int64 | 64ビット整数 |
tf.uint8 | 符号なし8ビット整数 |
tf.string | 文字列 |
tf.bool | 真偽値 |
上記はTensorのデータ型の一部です。他のデータ型を確認したい方は、tf.dtypesの公式ドキュメントのこちらを参照してください。
定数の要素の値は変更できない
tf.constantで作成した定数テンソルの要素は後で変更できません。以下のようにTypeErrorとなります。
import tensorflow as tf tensor = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) # 定数は変更できない tensor[0, 0] = 5 print(tensor)
【実行結果】 TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment
要素を後で変更する必要があるようなケースでは後述するtf.Variableの変数を使用するようにしてください。
変数Tensorの作成 tf.Variable
変数の作成方法
TensorFlowで変数のTensorを作成するには、以下の例のようにtf.Variableを使用します。
import tensorflow as tf # ===== 変数を作成する tf.Variable # 階数0のTensor (scalar) scalar = tf.Variable(10) print(scalar, "\n") # 階数1のTensor (vector) vector = tf.Variable([1, 2, 3, 4, 5]) print(vector, "\n") # 階数2のTensor (matrix) matrix_2d = tf.Variable([[1, 2], [3, 4]]) print(matrix_2d, "\n") # 階数3のTensor (matrix) matrix_3d = tf.Variable([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]) print(matrix_3d, "\n") # 階数4のTensor (matrix) matrix_4d = tf.Variable( [ [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]], [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]], ] ) print(matrix_4d)
【実行結果】 <tf.Variable 'Variable:0' shape=() dtype=int32, numpy=10> <tf.Variable 'Variable:0' shape=(5,) dtype=int32, numpy=array([1, 2, 3, 4, 5])> <tf.Variable 'Variable:0' shape=(2, 2) dtype=int32, numpy= array([[1, 2], [3, 4]])> <tf.Variable 'Variable:0' shape=(3, 2, 2) dtype=int32, numpy= array([[[ 1, 2], [ 3, 4]], [[ 5, 6], [ 7, 8]], [[ 9, 10], [11, 12]]])> <tf.Variable 'Variable:0' shape=(2, 3, 2, 2) dtype=int32, numpy= array([[[[ 1, 2], [ 3, 4]], [[ 5, 6], [ 7, 8]], [[ 9, 10], [11, 12]]], [[[ 1, 2], [ 3, 4]], [[ 5, 6], [ 7, 8]], [[ 9, 10], [11, 12]]]])>
上記のように結果としては、tf.constantと同じような結果となります。tf.constantとの違いとしては、変数なので後述するように値を変更することができる点があります。
変数の値を変更する方法 assign
tf.Variableで作成されたTensorは変数なので値を変更することができます。ただし、以下のように直接変数を変更しようとするとエラーとなります。
import tensorflow as tf tensor = tf.Variable([[1, 2], [3, 4]], dtype=tf.float16) # 変数は直接は変更できない (TypeError) tensor[0, 0] = 5
【実行結果】 TypeError: 'ResourceVariable' object does not support item assignment
そこで、tf.Variableでは以下のようにassignメソッドを使って値を変更します。
import tensorflow as tf tensor = tf.Variable([[1, 2], [3, 4]], dtype=tf.float16) # Tensorの値を更新する assign tensor[0, 0].assign(5) print(tensor)
【実行結果】 <tf.Variable 'Variable:0' shape=(2, 2) dtype=float16, numpy= array([[5., 2.], [3., 4.]], dtype=float16)>
上記のように、Tensorの要素の値を変更できることが分かるかと思います。
tf.Variableの公式ドキュメントはこちらを参照してください。
【補足】assignはtf.constantには存在しない
tf.Variableは、上記で説明したようにassignで変更することができました。tf.constantでも同じようにassignで変更できるのかなと思われる方もいるかもしれませんが、tf.constantにはassignは定義されていないため以下のようにAttributeErrorとなります。
import tensorflow as tf tensor = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) # tf.constantにはtf.Variableにあるassignは存在しない (AttributeError) tensor[0, 0].assign(5) print(tensor)
【実行結果】 AttributeError: 'tensorflow.python.framework.ops.EagerTensor' object has no attribute 'assign'
0埋めのTensorを作成する方法
形状を指定して作成する方法 tf.zeros
0埋めのTensorを作成するには、tf.zerosを使用します。引数としてshapeにより形状を指定することで指定した形状で0埋めのTensorを作成することが可能です。
import tensorflow as tf # 0埋めのTensorを作成する tf.zeros zeros_tensor = tf.zeros(shape=(3, 5)) print(zeros_tensor)
【実行結果】 tf.Tensor( [[0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.]], shape=(3, 5), dtype=float32)
tf.zerosの公式ドキュメントはこちらを参照してください。
既存のTensorと同じ形状で作成する方法 tf.zeros_like
既存のTensorと同じ形状で全て0のTensorを作成するには、以下のようにtf.zeros_likeが使用できます。既存のTensorに対する0のラベルを作成する際などにとても便利です。
import tensorflow as tf # ===== 既存のTensorと同じ形状の0埋めTensorを作成する # 階数1のTensor (vector) vector = tf.constant([1, 2, 3, 4, 5], dtype=tf.float16) zeros_vector = tf.zeros_like(vector) print(zeros_vector, "\n") # 階数2のTensor (matrix) matrix = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) zeros_matrix = tf.zeros_like(matrix) print(zeros_matrix)
【実行結果】 tf.Tensor([0. 0. 0. 0. 0.], shape=(5,), dtype=float16) tf.Tensor( [[0. 0.] [0. 0.]], shape=(2, 2), dtype=float16)
tf.zeros_likeの公式ドキュメントはこちらを参照してください。
1埋めのTensorを作成する方法
形状を指定して作成する方法 tf.ones
1埋めのTensorを作成するには、tf.onesを使用します。引数としてshapeにより形状を指定することで指定した形状で1埋めのTensorを作成することが可能です。
import tensorflow as tf # 1埋めのTensorを作成する tf.ones ones_tensor = tf.ones(shape=(3, 5)) print(ones_tensor)
【実行結果】 tf.Tensor( [[1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.] [1. 1. 1. 1. 1.]], shape=(3, 5), dtype=float32)
tf.onesの公式ドキュメントはこちらを参照してください。
既存のTensorと同じ形状で作成する方法 tf.ones_like
既存のTensorと同じ形状で全て1のTensorを作成するには、以下のようにtf.ones_likeが使用できます。既存のTensorに対する1のラベルを作成する際などにとても便利です。
import tensorflow as tf # ===== 既存のTensorと同じ形状の1埋めTensorを作成する # 階数1のTensor (vector) vector = tf.constant([1, 2, 3, 4, 5], dtype=tf.float16) ones_vector = tf.ones_like(vector) print(ones_vector, "\n") # 階数2のTensor (matrix) matrix = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) ones_matrix = tf.ones_like(matrix) print(ones_matrix)
【実行結果】 tf.Tensor([1. 1. 1. 1. 1.], shape=(5,), dtype=float16) tf.Tensor( [[1. 1.] [1. 1.]], shape=(2, 2), dtype=float16)
tf.ones_likeの公式ドキュメントはこちらを参照してください。
ランダムな数値でTensorを作成する方法 tf.random
以降ではランダムな数値でTensorを作成する方法の例を紹介します。ディープラーニングでは初期値などに乱数を使用するため、使い方をしっかり覚えておきましょう。
0~1のランダムなTensorを作成する場合 tf.random.uniform
0~1のランダムなTensorを作成する場合には、tf.random.uniformを使用します。
tf.random.set_seedにより乱数のシードを指定できるので結果を固定したい場合はset_seedを使用しましょう。set_seedを指定しない場合は、実行毎に結果が変わります。
import tensorflow as tf # 乱数を固定したい場合は、set_seedで設定する tf.random.set_seed(1) # 0~1の乱数でTensorを作成する uniform_tensor = tf.random.uniform(shape=(3, 5)) print(uniform_tensor)
【実行結果】 tf.Tensor( [[0.16513085 0.9014813 0.6309742 0.4345461 0.29193902] [0.64250207 0.9757855 0.43509948 0.6601019 0.60489583] [0.6366315 0.6144488 0.8893349 0.6277617 0.53197503]], shape=(3, 5), dtype=float32)
正規分布に従うTensorを作成する場合 tf.random.normal
標準正規分布に従うランダムなTensorを作成する場合には、tf.random.normalを使用します。
tf.random.set_seedにより乱数のシードを指定できるので結果を固定したい場合はset_seedを使用しましょう。set_seedを指定しない場合は、実行毎に結果が変わります。
import tensorflow as tf # 乱数を固定したい場合は、set_seedで設定する tf.random.set_seed(1) # 標準正規分布からランダムなTensorを作成する normal_tensor = tf.random.normal(shape=(3, 5)) print(normal_tensor)
【実行結果】 tf.Tensor( [[-1.1012203 1.5457517 0.383644 -0.87965786 -1.2246722 ] [-0.9811211 0.08780783 -0.20326038 -0.5581562 -0.7205441 ] [-0.6259924 -0.71502596 -0.34835446 -0.33646983 0.18257578]], shape=(3, 5), dtype=float32)
NumPy配列(ndarray)とTensorの相互変換
Pythonのデータ分析でよく使われるライブラリとしてNumPyがあります。NumPyの配列はndarrayという型ですが、NumPy配列(ndarray)とTensorは相互に変換が可能です。以下で方法を見ていきましょう。
NumPy配列(ndarray)からTensorを作成する方法
NumPy配列(ndarray)からTensorを作成するのは簡単です。NumPyで作成した配列をtf.constantやtf.Variableに渡すことでTensorを作成できます。
import numpy as np import tensorflow as tf numpy_array = np.arange(1, 11) print(numpy_array, "\n") # ===== ndarrayからTensorを作成する # ndarrayの形状でTensorに変換する same_shape_tensor = tf.constant(numpy_array) print(same_shape_tensor, "\n") # 形状(shape)を指定して変換してTensorを作成する changed_tensor = tf.constant(numpy_array, shape=(2, 5)) print(changed_tensor)
【実行結果】 [ 1 2 3 4 5 6 7 8 9 10] tf.Tensor([ 1 2 3 4 5 6 7 8 9 10], shape=(10,), dtype=int32) tf.Tensor( [[ 1 2 3 4 5] [ 6 7 8 9 10]], shape=(2, 5), dtype=int32)
上記の例のようにNumPy配列の形状そのままでTensorに変換することもできますし、shapeを指定することで形状を変換しつつTensorを作成することができます。なお、要素数が合うようにshapeを指定する必要がありますので注意しましょう。
また、上記例はtf.constantで説明していますが、tf.Variableでも同じです。
TensorをNumPy配列(ndarray)に変換する方法
Tensorのnumpyメソッドを使用する場合
作成したTensorをNumPy配列(ndarray)に変換するのも簡単です。以下のようにnumpyメソッドを使用することでNumPy配列にすることができます。
import tensorflow as tf tensor = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) print(tensor, "\n") # NumPy配列(ndarray)に変換する numpyメソッド numpy_array = tensor.numpy() print(numpy_array) print(type(numpy_array))
【実行結果】 tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float16) [[1. 2.] [3. 4.]] <class 'numpy.ndarray'>
NumPyのnp.array関数を使用する場合
もう一つの方法として、NumPyのnp.array関数にTensorFlowのTensorを渡して以下のようにしても、NumPy配列(ndarray)に変換することが可能です(TensorFlowのnumpyメソッド実行時と結果は同じ)。
import numpy as np import tensorflow as tf tensor = tf.constant([[1, 2], [3, 4]], dtype=tf.float16) print(tensor, "\n") # NumPy配列(ndarray)に変換する np.arrayを使用 numpy_array = np.array(tensor) print(numpy_array) print(type(numpy_array))
【実行結果】 tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float16) [[1. 2.] [3. 4.]] <class 'numpy.ndarray'>
NumPyの配列(ndarray)とTensorFlowのTensorの違い
TensorFlowのTensorがNumPy配列(ndarray)より有利な点として、GPUやTPUの利用ができるという点が挙げられます。
ディープラーニングでは、大規模なデータセット、モデルになってくるほどGPUやTPUを使用して処理を高速化することが必須になってきます。TensorFlowのTensorに変換することで適切にTensorFlowがGPUやTPUを使用して高速に処理をしてくれます。
まとめ
Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensor(テンソル)を作成する以下のような各種方法を解説してきました。
- tf.constant:定数のTensorを作成する
- tf.Variable:変数のTensorを作成する
- tf.zeros:0埋めのTensorを作成する
- tf.zeros_like:既存のTensorと同じ形状の0埋めTensorを作成する
- tf.ones:1埋めのTensorを作成する
- tf.ones_like:既存のTensorと同じ形状の1埋めTensorを作成する
- tf.random.uniform:0~1のランダムなTensorを作成する
- tf.random.normal:標準正規分布に従うランダムなTensorを作成する
- NumPy配列(ndarray)とTensorの相互変換
Tensorの作成方法は、TensorFlowでプログラミングをしていくうえで基礎ともいえる内容のためしっかり使えるようにしてもらえるとよいかと思います。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。