TensorFlowのAPIメモ（Python）


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

##お試し方法
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と同じものが返ってくる。[公式リファレンス](https://www.tensorflow.org/versions/master/api_docs/python/array_ops.html#pack)には、
>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になる。