tf.SparseTensorとone hot表現
tensorflowのSparseTensorとone hot表現の関係についての備忘録
12/26 tf.one_hotについて追記
one hot表現
ある行列に対してこの
の
行目だけを抜き出してきたい場合について、前からone hotベクトル(
番目の要素だけ1でそれ以外は0のベクトル)をかけてやればいい。
具体例として、Wの2行目と1行目を順に抜き出す場合には *1
W = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) a = np.array([[0, 1, 0], [1, 0, 0]]) b = np.matmul(a, W) print(b) [[5 6 7 8] [1 2 3 4]]
また、行列積の転置の性質()を使うことにより、第一引数にWを使わなければ行けない場合には
W = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) a = np.array([[0, 1, 0], [1, 0, 0]]) Wt = np.transpose(W) at = np.transpose(a) b = np.matmul(Wt, at) bt = np.transpose(b) print(b) print(bt) [[5 1] [6 2] [7 3] [8 4]] [[5 6 7 8] [1 2 3 4]]
のようにすればよい。
tf.SparseTensor
ほとんどの要素が0でいくつかの要素のみが具体的な値を持つような行列をSparse Matrixとかよぶ。Sparse Matrixをtf.Variableのような形でメモリにおいておくのは非効率なので、そのような場合にはSparseMatrixとかを使う。
使い方は
x = tf.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4])
というような感じ。indicesは要素の位置、valuesはその値、dense_shapeは行列の形。上の例では(0, 0)の値が1、(1, 2)の値が2でその他の値が0の3行4列の行列になる。つまり、
[[1, 0, 0, 0] [0, 0, 2, 0] [0, 0, 0, 0]]
Sparse Matrixの掛け算
tf.sparse.matmulを使う
tf.sparse.matmul(sparse_matrix, dense_matrix)
sparse matrixとdense matrixの順番を逆にすることはできない。また、返り値はdense matrixになる。
Sparse Matrixとone hot表現
Sparse matrixの第行を抜き出して来たければ次のようにすればいいらしい。*2
import tensorflow as tf import numpy as np indices = [[i, j] for i in range(3) for j in range(4)] values = [i for i in range(1, 13)] W = tf.SparseTensor(indices=indices, values=values, dense_shape=[3, 4] # 上の例と同じ a = tf.Variable(np.array([[0, 1, 0], [1, 0, 0]]), dtype=tf.int32) Wt = tf.sparse.transpose(W) at = tf.transpose(a) b = tf.sparse.matmul(Wt, at) bt = tf.transpose(b) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print(sess.run(b)) print(sess.run(bt)) [[5 1] [6 2] [7 3] [8 4]] [[5 6 7 8] [1 2 3 4]]
上と同じ結果が得られた。
追記: tf.one_hot
tf.one_hotを使うとone hotベクトルを作ることができる。引数はindicesとdepth。indicesは何番目に1をたてるか、depthは行の長さ。
import tensorflow as tf import numpy as np indices = [[i, j] for i in range(3) for j in range(4)] values = [i for i in range(1, 13)] W = tf.SparseTensor(indices=indices, values=values, dense_shape=[3, 4]) one_hot_indices = tf.placeholder(tf.int32, shape=[None]) one_hot_depth = tf.placeholder(tf.int32) a = tf.one_hot(one_hot_indices, one_hot_depth, dtype=tf.int32) Wt = tf.sparse.transpose(W) at = tf.transpose(a) b = tf.sparse.matmul(Wt, at) bt = tf.transpose(b) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) feed_dict={one_hot_indices: [1, 0], one_hot_depth:3} print(sess.run(b, feed_dict=feed_dict)) print(sess.run(bt, feed_dict=feed_dict)) [[5 1] [6 2] [7 3] [8 4]] [[5 6 7 8] [1 2 3 4]]
結果は同じ。