TensorFlow

【TensorFlow】Tensorの要素を参照する方法

【TensorFlow】Tensorの要素を参照する方法

Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensorの要素を参照する方法を解説します。

Tensorの要素の参照方法

TensorFlowにおけるTensorの要素へのアクセスは、PythonのリストやNumPyの配列(ndarray)にアクセスする方法と同じで角括弧([])でアクセスができます。

以降でTensorの各要素にアクセス方法について例を用いて説明します。

単一の要素を参照する方法

Tensorの中の単一の要素を参照する場合には、以下の例のように角括弧([])で要素位置を指定することで参照することができます。

import tensorflow as tf

tensor = tf.range(10)
print(tensor, "\n")

# 単一の要素にアクセスする(インデックスは0から開始)
print(f"tensor[0] = {tensor[0]}")
print(f"tensor[5] = {tensor[5]}")
print(f"tensor[9] = {tensor[9]}")
【実行結果】
tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32) 

tensor[0] = 0
tensor[5] = 5
tensor[9] = 9

上記例では、tf.range関数でサイズ10のTensorを作成した上で各要素を参照しています。インデックスの数字は0から開始することに注意しましょう。

スライスでTensorの一部を取り出す方法

Tensorの一部を取り出したい場合にはスライスを使用することで抽出することができます。

Tensorの階数がいくつでも考え方は同じですが、階数1のTensor(ベクトル)と階数2のTensor(配列)のそれぞれで例を見てみましょう。

階数1のTensorの場合

1階のTensorにおいてスライスで一部を取り出したい場合は、以下のように使用します。

import tensorflow as tf

tensor = tf.range(10)
print(tensor, "\n")

# スライスで要素の一部を取り出す
print("スライスで要素の一部を取り出す")
print(f"tensor[2:8] = {tensor[2:8]}")
print(f"tensor[5:] = {tensor[5:]}")
print(f"tensor[:5] = {tensor[:5]}", "\n")

# stepを指定して値を取り出す
print("stepを指定して一定間隔で値を取り出す")
print(f"tensor[0:5:2] = {tensor[0:5:2]}")
print(f"tensor[::2] = {tensor[::2]}", "\n")

# 逆順で値を取り出す
print("逆順で値を取り出す")
print(f"tensor[::-1] = {tensor[::-1]}")
【実行結果】
tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32) 

スライスで要素の一部を取り出す
tensor[2:8] = [2 3 4 5 6 7]
tensor[5:] = [5 6 7 8 9]
tensor[:5] = [0 1 2 3 4] 

stepを指定して一定間隔で値を取り出す
tensor[0:5:2] = [0 2 4]
tensor[::2] = [0 2 4 6 8] 

逆順で値を取り出す
tensor[::-1] = [9 8 7 6 5 4 3 2 1 0]

角括弧の中で[start:stop:step]というような記載方法を用います。start番目からstop-1番目までをstep刻みで取り出すという意味です。最後はstop-1番目のインデックスまでとなるため注意してください。なお、start, stop, stepの各項目は省略が可能です。

例えば上記例で、tensor[2:8]というようにすると2番目の要素から7番目の要素までということになります。また、マイナスのstep数を指定することもでき、tensor[::-1]のようにすると逆順の配列を取得することができます。

階数2のTensorの場合

2階のTensorにおいてスライスで一部を取り出したい場合は、以下のように使用します。

import tensorflow as tf

tensor = tf.reshape(tf.range(25), shape=(5, 5))
print(tensor, "\n")

# スライスで要素の一部を取り出す
print("スライスで要素の一部を取り出す")
print(f"tensor[:2, :2] = \n{tensor[:2, :2]}")
print(f"tensor[3:, 3:] = \n{tensor[3:, 3:]}", "\n")

# stepを指定して値を取り出す
print("stepを指定して一定間隔で値を取り出す")
print(f"tensor[::2, ::2] = \n{tensor[::2, ::2]}", "\n")

# 逆順で値を取り出す
print("逆順で値を取り出す")
print(f"tensor[::-1, ::-1] = \n{tensor[::-1, ::-1]}")
【実行結果】
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]], shape=(5, 5), dtype=int32) 

スライスで要素の一部を取り出す
tensor[:2, :2] = 
[[0 1]
 [5 6]]
tensor[3:, 3:] = 
[[18 19]
 [23 24]] 

stepを指定して一定間隔で値を取り出す
tensor[::2, ::2] = 
[[ 0  2  4]
 [10 12 14]
 [20 22 24]] 

逆順で値を取り出す
tensor[::-1, ::-1] = 
[[24 23 22 21 20]
 [19 18 17 16 15]
 [14 13 12 11 10]
 [ 9  8  7  6  5]
 [ 4  3  2  1  0]]

上記の例では5×5のTensorを作成し、その中で一部の部分Tensorを取り出しています。行、列それぞれでスライス記法を使用することで実行できます。

階数nのTensorの場合

階数3以上の階数nのTensorについても、書き出すときりがないので省略しますが、スライスの考え方は同じです。

TensorFlowを用いたプログラミングでは、例えば、画像のデータ表現に階数3や階数4のTensorをよく使います。Tensorの形状としては(データ数, 縦, 横)や(データ数, チャンネル数, 縦, 横)のような形がよくあるかと思います。ここでチャンネル数と言っているのは、例えばRGBA等になります。

例えば一部のデータだけ取り出して使いたいのであれば「データ数」の次元の部分でスライス表現を使えばいいですし、画像の一部分のみ取り出したいのであれば「縦」「横」の次元のスライス表現を工夫すれば画像の一部を取り出すこともできます。

このように、データの一部を取り出す際にスライスをよく使用しますので、使い方をよく覚えておくとよいでしょう。

まとめ

Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensorの要素を参照する方法を解説しました。

TensorFlowを用いたプログラミングでは、データをTensorで表現し、一部要素を参照するといったことを頻繁に行います。適切にデータを参照して操作できるようにしっかりと使い方を覚えておきましょう。

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