TensorFlow

【TensorFlow】Tensor(テンソル)の作成方法

【TensorFlow】Tensor(テンソル)の作成方法

Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensor(テンソル)を作成する各種方法を解説します。

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ぐらいまではイメージを持って扱えるようにしておくといいと思います。※各軸の意味はデータセットにより異なる場合があります。

Note

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.float1616ビット浮動小数点
tf.float3232ビット浮動小数点
tf.float6464ビット浮動小数点
tf.int88ビット整数
tf.int1616ビット整数
tf.int3232ビット整数
tf.int6464ビット整数
tf.uint8符号なし8ビット整数
tf.string文字列
tf.bool真偽値
Note

上記は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の要素の値を変更できることが分かるかと思います。

Note

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)
Note

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)
Note

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)
Note

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)
Note

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)
Note

tf.random.uniformの公式ドキュメントはこちらを参照してください。
tf.random.set_seedの公式ドキュメントはこちらを参照してください。

正規分布に従う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)
Note

tf.random.normalの公式ドキュメントはこちらを参照してください。
tf.random.set_seedの公式ドキュメントはこちらを参照してください。

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でプログラミングをしていくうえで基礎ともいえる内容のためしっかり使えるようにしてもらえるとよいかと思います。

Pythonによるディープラーニング」はTensorFlow/Kerasの中~上級者向けの本ですが非常におすすめできる書籍です。CNN, RNN, Transformer, GAN等高度なモデルも扱っており面白く、TensorFlow/Kerasの実装力をつけることができますので是非読んでみてもらえるといいと思います。