今回もテンソルを取り上げます。
Numpy の表示の『[ ]』と axis の関係は・・・
axis=0, 1, 2・・・n を例に考えます。
その内のaxis=i の括られているカッコの数を見てみましょう。
n - i となっていることが分かります。
下の図ではn=2を例に取り上げています。
するとaxis=0 は 2 - 0 で2つの[ ]で括られていることになります。
同じくaxis=1 は 2 - 1 で1つの[ ]で括られていることになります。
最後のaxis=2 は 2- 2 でカッコではなくコンマ『, 』で区切られていることになります。
また、newaxis は要素1つの割り込みのようなものだと考えられます。
axis=0 のところに持ってくると、元の axis=0 が 1 に押し上げられ、 1 は 2 に押し上げられます。
また、axis=0 と axis=1 の間に割り込ませると、axis=0 は変わらずにそのまま
axis=1 に要素1の軸が生じ、元の axis=1 が 2 に昇格するように見えます。
テンソルは切り口(軸の選び方)によって捉える形が変わります。
面としている行列の形や内容が軸の選び方によって変わってしまいます。
そして、層となっている部分もそれに伴って変わります。
ここから先は、あくまでも一つの切り口の例です。
最後に直観的にイメージしてみましょう。
まず、n -1 行 n 列の行列があるとします。
そして、それが n-2 の枚数の層をつくっていると捉えます。
更にそれは n-3 の層となり、更に更にそれが n-4 の層となる。
この層追加のループを n-n まで繰り返すと考えることができると思います。
(1, 3, 5) は3行5列の行列が1枚の層となっている。
また(3, 1, 5) は1行5列の行列が3枚の層になっている
と捉えるということです。
ただし、先にも述べた通りテンソルは軸の選び方で形を変えます。
言い換えると演算の対象とする軸の選び方によって形が変わります。
例えば、onesすなわちすべて1の(2, 3, 4)のテンソルと
同じくすべて1の(2, 3)のテンソルのテンソル積の場合
tf.einsum('ijk, ij ->k', ・・)
共に2行3列の形をとり
答えは
[6, 6, 6, 6]
となります。
チョット面倒ですが
a = np.arange(1, 25, dtype='float32')
b = np.reshape(a, (2, 3, 4))
c = tf.convert_to_tensor(b)
d = tf.ones([2, 3])
tf.einsum('ijk, ij ->k', c, d)
[66. 72. 78. 84.] その直観的捉え方を試みたのが右側の図です。

