Tensorflowでリストを使用する方法は?
-
16-10-2019 - |
解決
このようなnumpy配列を作成するとき:
x_data = np.array( [[1,2],[4,5,6],[1,2,3,4,5,6]])
内部numpy dtypeは「オブジェクト」です。
array([[1, 2], [4, 5, 6], [1, 2, 3, 4, 5, 6]], dtype=object)
そして、これはTensorflowのテンソルとして使用することはできません。いずれにせよ、テンソルは各次元で同じサイズを持っている必要があり、それらは「ぼろぼろ」することはできず、各ディメンションの単一の数字で定義された形状を持たなければなりません。 Tensorflowは基本的に、すべてのデータ型についてこれを想定しています。 Tensorflowの設計者は理論的にそれを書くことができますが、それは不規則な配列を受け入れ、変換関数を含めることができますが、入力コードの問題を隠す可能性があるため、その種の自動キャスティングは必ずしも良い考えではありません。
したがって、入力データをパッドして使用可能な形状にする必要があります。簡単な検索で、私は見つけました スタックオーバーフローでのこのアプローチ, 、コードの変更として複製:
import tensorflow as tf
import numpy as np
x = tf.placeholder( tf.int32, [3,None] )
y = x * 2
with tf.Session() as session:
x_data = np.array( [[1,2],[4,5,6],[1,2,3,4,5,6]] )
# Get lengths of each row of data
lens = np.array([len(x_data[i]) for i in range(len(x_data))])
# Mask of valid places in each row
mask = np.arange(lens.max()) < lens[:,None]
# Setup output array and put elements from data into masked positions
padded = np.zeros(mask.shape)
padded[mask] = np.hstack((x_data[:]))
# Call TensorFlow
result = session.run(y, feed_dict={x:padded})
# Remove the padding - the list function ensures we
# create same datatype as input. It is not necessary in the case
# where you are happy with a list of Numpy arrays instead
result_without_padding = np.array(
[list(result[i,0:lens[i]]) for i in range(lens.size)]
)
print( result_without_padding )
出力は次のとおりです。
[[2, 4] [8, 10, 12] [2, 4, 6, 8, 10, 12]]
最後にパディングを削除する必要はありません - 同じ不規則な配列形式で出力を表示する必要がある場合にのみこれを行います。また、結果を供給するときにも注意してください padded
より複雑なルーチンへのデータ、Zerosまたはその他のパディングデータを変更すると、実装したアルゴリズムがどのようなアルゴリズムでも使用される場合があります。
多くの短い配列があり、非常に長いアレイが1つか2つある場合は、 まばらなテンソル表現 メモリを保存し、計算をスピードアップします。
他のヒント
パッド付き配列を使用する代わりに、すべてのデータを1つの大きなスパゲッティストリングとしてフィードしてから、Tensorflowグラフ内で折り紙を実行できます。
例:
import tensorflow as tf
import numpy as np
sess = tf.InteractiveSession()
noodle = tf.placeholder(tf.float32, [None])
chop_indices = tf.placeholder(tf.int32, [None,2])
do_origami = lambda list_idx: tf.gather(noodle, tf.range(chop_indices[list_idx,0], chop_indices[list_idx,1]))
print( [do_origami(list_idx=i).eval({noodle:[1,2,3,2,3,6], chop_indices:[[0,2],[2,3],[3,6]]}).tolist() for i in range(3)] )
結果:
[[1.0, 2.0], [3.0], [2.0, 3.0, 6.0]]
ただし、さまざまな数の内側リストがある場合は、幸運を祈ります。 TF.While_loopからリストを返すことはできず、上記のようにリスト理解を使用することはできないため、各内部リストに対して個別に計算を行う必要があります。
import tensorflow as tf
sess = tf.InteractiveSession()
my_list = tf.Variable(initial_value=[1,2,3,4,5])
init = tf.global_variables_initializer()
sess.run(init)
sess.run(my_list)
結果:配列([1、2、3、4、5])