tensorのshape/dimension
一般的には m行n列の行列は m×n行列 と表記すると思うけど
m = tf.Variable([2,3])
とかしたときは2行3列なのか??とかちゃんとわかってないので確認したい
constantで確認する
In [12]: c1 = tf.constant([[1,2,3], [2,3,4]]) In [13]: c2 = tf.constant([[2,2], [3,3], [4,4]]) In [14]: sess.run(tf.matmul(c1, c2)) Out[14]: array([[20, 20], [29, 29]], dtype=int32) In [15]: sess.run(tf.matmul(c2, c1)) Out[15]: array([[ 6, 10, 14], [ 9, 15, 21], [12, 20, 28]], dtype=int32) In [16]: c1.shape Out[16]: TensorShape([Dimension(2), Dimension(3)]) In [17]: c2.shape Out[17]: TensorShape([Dimension(3), Dimension(2)])
ということで、constantでは shape(2, 3) は 2行3列 の行列を表すっぽい
では、縦ベクトル、横ベクトルはどうか?
In [18]: v1 = tf.constant([1,2,3]) In [19]: v2 = tf.constant([[2],[2],[2]]) In [21]: sess.run(tf.matmul(v1, v2)) ...(略) ~/dev/tf-train/tf-env/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn) 689 missing_shape_fn = True 690 else: --> 691 raise ValueError(err.message) 692 693 if missing_shape_fn: ValueError: Shape must be rank 2 but is rank 1 for 'MatMul_2' (op: 'MatMul') with input shapes: [3], [3,1].
... rank が 2じゃなきゃいけないらしい
In [23]: v1.shape Out[23]: TensorShape([Dimension(3)]) In [24]: v2.shape Out[24]: TensorShape([Dimension(3), Dimension(1)])
https://www.tensorflow.org/programmers_guide/tensors
rank は 0がscalar, 1がvector, 2がmatrix らしい
逆に、縦ベクトルも横ベクトルも[1,2,3]みたいに書くべきなのか?
In [25]: v1 = tf.constant([1,2,3]) In [26]: v2 = tf.constant([2,2,2]) In [27]: sess.run(tf.matmul(v1, v2)) ...(略) ~/dev/tf-train/tf-env/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn) 689 missing_shape_fn = True 690 else: --> 691 raise ValueError(err.message) 692 693 if missing_shape_fn: ValueError: Shape must be rank 2 but is rank 1 for 'MatMul_6' (op: 'MatMul') with input shapes: [3], [3].
やっぱりだめ 内積を計算したければ、ベクトルであっても1×n と n×1 の行列で表さなければならないみたい
In [31]: v1 = tf.constant([[1,2,3]]) In [32]: v2 = tf.constant([[2],[2],[2]]) In [33]: sess.run(tf.matmul(v1, v2)) Out[33]: array([[12]], dtype=int32) In [34]: v1.shape Out[34]: TensorShape([Dimension(1), Dimension(3)]) In [35]: v2.shape Out[35]: TensorShape([Dimension(3), Dimension(1)])
shape part2
触りだしたらやっぱり理解があやふやだったので、再確認
shape [1,2,3] と shape [3,2,1] はどう違うのか?
左からi番目は外側からi番目の[]に入ってる要素の数、みたいに考えれば良さそう
In [12]: tf.constant([ [ [1,1,1], [2,2,2] ] ]) Out[12]: <tf.Tensor 'Const_4:0' shape=(1, 2, 3) dtype=int32>
shape [1, ...] なので 一番外側のに入っている要素は1つ
-> [ [...] ]
shape [1, 2, ...] なので 次のに入っている要素は2つ
-> [ [ [...], [...] ] ]
shape [1, 2, 3] なので 次の[]に入っている要素は3つ
-> [ [ [1,1,1], [2,2,2] ] ]
みたいな
逆に shape [3,2,1] なら
[ [...], [...], [...] ]
- > [ [ [...], [...] ], [ [...], [...] ], [ [...], [...] ] ]
- > [ [ [1], [2] ], [ [5], [6] ], [ [9], [0] ] ]
みたいな
あと c[1, :, 1] みたいな ':' をつかった操作もあんまり自信がないので確認
In [26]: c1 = tf.constant([[ [1,3,5], [2,4,6] ]]) In [27]: c2 = tf.constant([ [[1], [2]], [[5], [6]], [[9], [0]] ])
c1[0, :, 1] だと [ [3], [4] ]
c2[:, 1, :] だと [ [2], [6], [0] ]
c2[:, 1, 0] だと [2, 6, 0]
となるみたい
In [28]: sess.run(c1[0,:,1]) Out[28]: array([3, 4], dtype=int32) In [29]: sess.run(c2[:,1,:]) Out[29]: array([[2], [6], [0]], dtype=int32) In [30]: sess.run(c2[:,1,0]) Out[30]: array([2, 6, 0], dtype=int32)
scope
サンプルとか見ると
with tf.variable_scope("conv1"): ....
とかあるけどこれは何???
https://www.tensorflow.org/programmers_guide/variables
を読むと、同じ名前でget_variableを複数回呼ぶと変数を再利用するのか新規に作るのか判別できないけど、variable_scopeで区切っておけば別のvariable_scope内の変数は再利用しない、みたいなことらしい
In [37]: v1 = tf.get_variable('the_var', [2,3]) In [38]: v2 = tf.get_variable('the_var', [2,3]) ... 略 ValueError: Variable the_var already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at: File "<ipython-input-37-ce1950cb36a3>", line 1, in <module> v1 = tf.get_variable('the_var', [2,3]) File "/home/shuhei/dev/tf-train/tf-env/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "/home/shuhei/dev/tf-train/tf-env/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2850, in run_ast_nodes if self.run_code(code, result):
やはり同名の変数を get_value しようとすると "Variable the_var already exists,"のエラーが起こるらしい
(reuse=Trueとかすれば再利用できるらしい)
これを、variable_scopeで囲っておくと別のスコープで定義された変数は無視して新しく作ってくれるらしい
In [39]: with tf.variable_scope('scope1'): ...: v1 = tf.get_variable('scoped_var', [1,2]) ...: In [40]: with tf.variable_scope('scope2'): ...: v2 = tf.get_variable('scoped_var', [1,2]) ...: In [41]: v1.name Out[41]: 'scope1/scoped_var:0' In [42]: v2.name Out[42]: 'scope2/scoped_var:0'