別に難しいことではないのですが、プログラム作成中に躓いたところをメモしておきます。
Kerasを使用して深層学習を行っている中で、各層を通った後の出力テンソルの数値を確認したい場面がありました。
Tensorは出力してもサイズや変数の種類などの情報しか与えてくれず、このままでは中身を見ることができなそうでしたので、numpyのndarrayに変換することを考えました。
Kerasとnumpy
Kerasの紹介はまた別の機会にしようと思うので簡単に説明します。
Kerasは深層学習用のフレームワークで、標準バックエンドにTensorFlowを使用しています。
TensorはKerasフレームワークで使用する行列のようなものです。(厳密には”テンソル”は行列ではないらしいです。)
一方のnumpyはpythonで数値計算を行うならばなくてはならない、行列等の数値計算が簡単にできるライブラリです。
ndarrayはnumpyで行列計算を扱うための行列クラスです。
TensorFlowのチュートリアルを基に変換
TensorFlowのチュートリアルを見たところ、基本的なnumpyとの互換は以下のような手法で行われると書いてありました。
ndarray ⇒ Tensor の変換
- tensorflowに含まれる演算を使用することで自動的にTensorに変換
例えば
import tensorflow as tf
import numpy as np
a = np.array([2,2,3,6]) #numpyのndarrayを作成
b = tf.add(a,0) #tensorflowを使用した加算演算
上記のbはTensorFlowのTensorに自動的に変換されています。
Tensor ⇒ ndarray の変換
ここからが私が少し躓いた部分です。
- numpyに含まれる演算を使用することで自動的にndarrayに変換
結果:できませんでした。
方法としては前述の例と同じく、
import tensorflow as tf
import numpy as np
a #kerasで計算した後のTensor。初期化等は略
b = np.add(a,0) #numpyを使用した加算演算
このbがなぜかTensorのままで、中身を見ることができません。
- Tensor.numpy()を使用して明示的に変換
結果:できませんでした。
チュートリアルに載っている方法としては
import tensorflow as tf
import numpy as np
a #kerasで計算した後のTensor。初期化等は略
b = a.numpy() #numpy()による変換
これでbはndarrayに変換されるはずなのですが、エラーメッセージは「そもそもTensorにはnumpy()なんてものはありませんよ。」とのこと。
原因ははっきりとは分かりませんが、TensorFlowのチュートリアルがTensorFlow2.0を対象としているからかもしれません。
TensorFlowのアップデートはなぜか上手くいかないし、環境を入れなおしてみると普通にインストールされるのはTensorFlow1.4でした。
もしくはKerasのTensorとTensorFlowのTensorが別物として扱われているのかもしれません。
原因がはっきりとわかっていないので、実際はこんな方法は必要ないのかもしれませんが、私が行きついた方法について書いておきます。
Tensor ⇒ ndarray の変換 (実行できた方法)
Kerasはバックエンドとして種フレームワークを使用することができるため、それらの演算機能についても抽象化されています。
この中にテンソルの中身を評価するための関数( eval( ) )があります。
from keras import backend as K
import numpy as np
a #kerasで計算した後のTensor。初期化等は略
b = K.eval(a) #backendのeval()による変換(評価)
これでbはndarrayに変換され、普通の行列としてb[1]のような形で添え字をつけることで中身の数値を確認することができます。
その他の方法
その後さらに調べたところでは以下の方法もあるようです。
ndarray ⇒ Tensor の変換
- tensorflow.convert_to_tensor()を使用する。
tf.convert_to_tensor(value, dtype=None, dtype_hint=None, name=None)
という関数があるようです。
Tensor ⇒ ndarray の変換
- Tensorのeval()を使用する。
バックグラウンドを使用するまでもなくTensorFlowのTensorクラスはeval()メソッドを持っているようですので、
import numpy as np
a #kerasで計算した後のTensor。初期化等は略
b = a.eval() #Tensorのeval()による変換(評価)
でも大丈夫そうです。ただしKerasのバックエンドがTensorFlowでない場合は実行できない場合があるかもしれません。(あくまでTensorFlowのドキュメントに載っているメソッドなので。)
ついでにTensorFlowドキュメント見てみると、確かにTensorクラスにはnumpy()メソッドなんて載っていませんでした・・・