ちょっと話題の記事

[TensorFlow] APIドキュメントを眺める -Tensor編-

2015.12.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

TensorFlow研究会に先立ち、予習をしておこうと思い、まずはGithubリポジトリのREADME.mdを試してみたあと、APIドキュメントを眺めてみました。

まずはぱっと目についた Tensor クラス を一通り通読したのでまとめてみます。

Tensor について

Tensor (Tensor クラスのインスタンス)は TensorFlow の名前の由来でもあり、数学で言うところのテンソルですが、スカラー、ベクトル、行列の概念をより一般化したものと捉えられます。こちらでは厳密な説明は避けますが、テンソルについての詳しい定義等は線形代数学(佐武一郎)の五章にかかれています。

ここでは TensorFlow の Tensor クラスについて詳しく見ていきます。

Tensor は Operation(演算) (TensorFlowで Hello Worldを動かしてみた&その解説に詳細あり)で施される操作の対象です。TensorFlow の性質上、実際の演算操作は Session を通じて行われます。Operation は実際に計算を行うことなく、計算の計画を Graph(グラフ) (先ほど言及した記事に詳細あり)に入力した上で新しく Tensor を生成していきます。

Tensor は次のように生成することができます。(以下 iPython で挙動を確認)

In [1]: import tensorflow as tf
In [2]: a = tf.constant([[2, 1], [1, 2]])
In [3]: a
Out[3]: <tensorflow.python.framework.ops.Tensor at 0x1137d4a90>

この Tensor の数学的実体は 2x2 行列ですが、これは2階のテンソルを表します。

Tensor に対しては要素の数値型を #dtype で取得できます

In [1]: import tensorflow as tf
In [2]: a = tf.constant([[2, 1], [1, 2]])
In [3]: a.dtype
Out[3]: tf.int32

整数リテラルを使って生成した Tensor については int32 が要素の数値型として適用される模様です。

また、#name では名前, #graph では Tensor の属するグラフ, #op では Tensor を生成した Operation を取得できます

In [1]: import tensorflow as tf
In [2]: a = tf.constant([[2, 1], [1, 2]])
In [3]: a.name
Out[3]: u'Const:0'
In [4]: a.graph
Out[4]: <tensorflow.python.framework.ops.Graph at 0x108c7f550>
In [5]: a.op
Out[5]: <tensorflow.python.framework.ops.Operation at 0x108c7f990>

TensorShape

先ほど上げた例の直後に2階のテンソルと言いましたが、標準的な線形代数上の概念とテンソルに関しては大雑把に言って次のような対応が成り立ちます

  • スカラー : 0階のテンソル
  • ベクトル : 1階のテンソル
  • 行列 : 2階のテンソル

TensorFlowで用いられる3階以上のテンソルについては複雑になりますが、おおよその私の理解としては次のようなものです:

TensorFlowで用いられる3階のテンソルは、二次元の紙面上の行と列をもった値のテーブルである行列に高さ方向の成分が加わり、三次元上での値のテーブルになったものである

図示すると次のようになります。

以下は2階テンソル、つまり行列の値の配置のされかたです。

tensor1

一方3階テンソルでは末尾の添字に高さの成分が加わり、次のように配置されます。

tensor2

三次元より先のものは次元数がさらに増え、認知しやすい3次元ユークリッド空間上での認知は困難を極めますが、イメージとしては新たな方向の成分が加わって成分の位置を表す添字が一つづつ増えていくような感じです。

このようにn階のテンソルを定義することができ、各階のサイズ(≒ベクトルの長さ、行列の行数、列数)を含めて TensorFlow では TensorShape と呼んでおり、各 Tensor に対しては #get_shape() 関数で取得できます。

値の定まっている TensorShape に対しては階数を #ndims で取得でき、各階のサイズは #dims で取得可能です。尚、値の定まらない TensorShape についての説明はこの記事では割愛します。

例えば先ほどのコード例の Tensor a について TensorShape 等を取得してみると次のようになります。

In [1]: import tensorflow as tf
In [2]: a = tf.constant([[2, 1], [1, 2]])
In [3]: s = a.get_shape()
In [4]: s.ndims
Out[4]: 2
In [5]: s.dims
Out[5]: [Dimension(2), Dimension(2)]

2x2行列については2階のテンソル、各階のサイズは [2, 2] で表せることが分かります。

In [1]: import tensorflow as tf
In [2]: a = tf.constant([[[2, 1], [1, 2]], [[1, 2], [2, 1]]])
In [4]: s = a.get_shape()
In [5]: s.ndims
Out[5]: 3
In [6]: s.dims
Out[6]: [Dimension(2), Dimension(2), Dimension(2)]

2x2x2テンソルについては3階のテンソル、各階のサイズは [2, 2, 2] で表せることが分かります。

最後に

TensorFlowのAPI解説第二弾としてMath編を現在鋭意作成中です。近日中にお届けする予定です!

参考