Help us understand the problem. What is going on with this article?

TensorFlowのAPIメモ(Python)

More than 3 years have passed since last update.

行列計算も統計もよく分からん、numpyなんて使ったこと無い。なのでTensorFlowのAPIが理解できない。
・・・というわけで、よく分からないAPIを一つずつ動かしてみて、どんな動きをするのかを確認するメモ。
専門知識は全くありませんので、ツッコミ・コメントお待ちしています。
参考:公式のAPIリファレンス

お試し方法

Pythonの対話モードで下記を一つずつ試してみる。

>>> import tensorflow as tf
>>> sess = tf.Session()
>>> sess.run(<実行するAPI>)

API

tf.size(input, name=None)

>>> sess.run(tf.size([0,1,2]))
3
>>> sess.run(tf.size([[0,1,2]]))
3
>>> sess.run(tf.size([[0,1,2],[4,5,6]]))
6

要素の個数を返すらしい。

tf.expand_dims(input, dim, name=None)

>>> sess.run(tf.expand_dims([0,1,2,3], 1))
array([[0],
       [1],
       [2],
       [3]], dtype=int32)
>>> sess.run(tf.expand_dims([[0,1,2,3],[4,5,6,7]], 1))
array([[[0, 1, 2, 3]],

       [[4, 5, 6, 7]]], dtype=int32)
>>> sess.run(tf.expand_dims([[0,1,2,3],[4,5,6,7]], 2))
array([[[0],
        [1],
        [2],
        [3]],

       [[4],
        [5],
        [6],
        [7]]], dtype=int32)

dimで指定された次元(Rank)分をinputに追加するらしい。
inputのRankが1で、dimに1が指定されてたら、戻り値はRank2になる。

tf.range(start, limit=None, delta=1, name='range')

>>> sess.run(tf.range(5))
array([0, 1, 2, 3, 4], dtype=int32)
>>> sess.run(tf.range(1,5))
array([1, 2, 3, 4], dtype=int32)

指定された分の1次元配列(厳密にはTensor)を返す。

tf.concat(concat_dim, values, name='concat')

>>> sess.run(tf.concat(0, [[1,2,3], [10,20,30]]))
array([ 1,  2,  3, 10, 20, 30], dtype=int32)
>>> sess.run(tf.concat(1, [[[1,2,3],[4,5,6]], [[10,20,30],[40,50,60]]]))
array([[ 1,  2,  3, 10, 20, 30],
       [ 4,  5,  6, 40, 50, 60]], dtype=int32)

valuesで与えたTensor同士を繋げるらしい。
繋げる元となるTensor同士は[<Tensor1>,<Tensor2>]みたいな形で与える。

tf.pack(values, name='pack')

>>> sess.run(tf.pack([1,2]))
array([1, 2], dtype=int32)
>>> sess.run(tf.pack([1,5]))
array([1, 5], dtype=int32)
>>> sess.run(tf.pack([1,5,10]))
array([ 1,  5, 10], dtype=int32)

イマイチよく分からないけど、valuesで与えたTensorと同じものが返ってくる。公式リファレンスには、

tf.pack([x, y, z]) = np.asarray([x, y, z])

と書いてあり、np.asarray()は引数で与えた配列の参照を作る関数らしいが・・・

>>> a = [0,1,2]
>>> b = sess.run(tf.pack(a))
>>> b
array([0, 1, 2], dtype=int32)
>>> b[0] = 5
>>> b
array([5, 1, 2], dtype=int32)
>>> a
[0, 1, 2]

参照にはなっていないようだが・・・??

tf.sparse_to_dense(sparse_indices, output_shape, sparse_values, default_value=0, validate_indices=True, name=None)

>>> sess.run(tf.sparse_to_dense([0,1],[5], 1.0, 0.0))
array([ 1.,  1.,  0.,  0.,  0.], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,1],[3], 1.0, 0.0))
array([ 1.,  1.,  0.], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,2],[5], 1.0, 0.0))
array([ 1.,  0.,  1.,  0.,  0.], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,2],[5], 2.0, 0.0))
array([ 2.,  0.,  2.,  0.,  0.], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,2],[5], 2.0, 5.0))
array([ 2.,  5.,  2.,  5.,  5.], dtype=float32)

下記は公式リファレンスの説明。

# If sparse_indices is scalar
dense[i] = (i == sparse_indices ? sparse_values : >default_value)

# If sparse_indices is a vector, then for each i
dense[sparse_indices[i]] = sparse_values[i]

# If sparse_indices is an n by d matrix, then for each i in [0, n)
dense[sparse_indices[i][0], ..., sparse_indices[i][d-1]] = sparse_values[i]

>>> sess.run(tf.sparse_to_dense([3],[5], 0.1, 0.0))
array([ 0. ,  0. ,  0. ,  0.1,  0. ], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0],[5], 0.1, 0.0))
array([ 0.1,  0. ,  0. ,  0. ,  0. ], dtype=float32)

sparse_indicesがスカラー(Rank0)の場合は、sparse_indicesで与えた数値のインデックスの箇所がsparse_valuesの値になる。

>>> sess.run(tf.sparse_to_dense([0,1],[5], [0.1,0.2], 0.0))
array([ 0.1,  0.2,  0. ,  0. ,  0. ], dtype=float32)
>>> sess.run(tf.sparse_to_dense([1,2],[5], [0.1,0.2], 0.0))
array([ 0. ,  0.1,  0.2,  0. ,  0. ], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,2],[5], [0.1,0.2], 0.0))
array([ 0.1,  0. ,  0.2,  0. ,  0. ], dtype=float32)
>>> sess.run(tf.sparse_to_dense([0,2],[5],0.1, 0.0))
array([ 0.1,  0. ,  0.1,  0. ,  0. ], dtype=float32)

sparse_indices=[0,2]で、sparse_valuesが[0.1,0.2]だった場合、output[0]=0.1、output[2]=0.2となる。わかりにくい。sparse_valuesがスカラー値だった場合は入る値は同じ。
sparse_indicesが昇順じゃなかったり([1,0]とか)、同じ値が入っている([1,1]とか)とエラーになるらしい。

>>> sess.run(tf.sparse_to_dense([[0,1],[0,2]],[5,5],0.1, 0.0))
array([[ 0. ,  0.1,  0.1,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ]], dtype=float32)

・・・まぁそういうことです。
このAPIの意味は理解出来ず。。。

tf.nn.softmax(logits, name=None)

>>> sess.run(tf.nn.softmax([[0.0,1.0]]))
array([[ 0.26894143,  0.7310586 ]], dtype=float32)
>>> sess.run(tf.nn.softmax([[0.0,1.0],[0.0,1.0]]))
array([[ 0.26894143,  0.7310586 ],
       [ 0.26894143,  0.7310586 ]], dtype=float32)
>>> sess.run(tf.nn.softmax([[1.0],[1.0]]))
array([[ 1.],
       [ 1.]], dtype=float32)
>>> sess.run(tf.nn.softmax([[0.0,1.0,2.0]]))
array([[ 0.09003057,  0.24472848,  0.66524094]], dtype=float32)
>>> sess.run(tf.nn.softmax([[0.0,1.0,2.0,10.0]]))
array([[  4.53770481e-05,   1.23347607e-04,   3.35293560e-04,
          9.99495983e-01]], dtype=float32)
>>> sess.run(tf.nn.softmax([[0.0,1.0,2.0],[1.0,1.0,1.0]]))
array([[ 0.09003057,  0.24472848,  0.66524094],
       [ 0.33333334,  0.33333334,  0.33333334]], dtype=float32)

logitsはRank2で、かつfloatである必要がある。
1つの次元内で足し合わせて全部1になるようなものを返す。

tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0]],[[1.0]]))
array([ 0.], dtype=float32)
>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0,0.0]],[[1.0,1.0]]))
array([ 1.62652326], dtype=float32)
>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0]],[[2.0]]))
array([ 0.], dtype=float32)
>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0,0.0],[0.0,2.0]],[[1.0,1.0],[0.0,1.0]]))
array([ 1.62652326,  0.12692805], dtype=float32)
>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0,2.0]],[[3.0,4.0]]))
array([ 5.19283152], dtype=float32)
>>> sess.run(tf.nn.softmax_cross_entropy_with_logits([[1.0,2.0]],[[4.0,3.0]]))
array([ 6.19283152], dtype=float32)

logitsとlabelsはfloatかつRank2である必要がある。
交差エントロピーを返すらしい。・・・が交差エントロピーが何であるかはイマイチよく理解できていない。多分「logitsとlabelsをSoftmaxした後、その2つがどれだけ近いか」を返しているんじゃないか・・・なぁ?

tf.nn.in_top_k(predictions, targets, k, name=None)

>>> sess.run(tf.nn.in_top_k([[0,2,1]],[1],1))
array([ True], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1]],[1],1))
array([False], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1]],[0],1))
array([ True], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1]],[0],2))
array([ True], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1]],[1],2))
array([ True], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1]],[2],2))
array([False], dtype=bool)
>>> sess.run(tf.nn.in_top_k([[3,2,1],[1,3,5]],[1,0],2))
array([ True, False], dtype=bool)

要は「一番大きい数字はどれか?」という話。
predictionsが[[3,2,1]]で、targetsが[0]だった場合、一番大きいのは0番目の「3」なので、正解となり、戻り値はTrueとなる。targetsが[1]や[2]だとFalseになる。
kは「大きさが~番目までならOK」という指定。kが2なら数字が2番目に大きい数字であってもTrueを返す。例えばpredictionsが[[3,2,1]]で、kが2であれば、targetsが[0](0番目の数字「3」)または[1](1番目の数字「2」)でTrueになる。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away