web-dev-qa-db-ja.com

tensorflow batch_matmulはどのように機能しますか?

Tensorflowには、高次元のテンソルを乗算する batch_matmul という関数があります。しかし、それがどのように機能するのかを理解するのに苦労しています。おそらくそれを視覚化するのに苦労しているためかもしれません。

enter image description here

私がやりたいことは、行列に3Dテンソルの各スライスを掛けることですが、テンソルaの形状が何なのかよくわかりません。 zは最も内側の次元ですか?次のうち正しいものはどれですか。

enter image description here

私は最初のものが正しいことを最も望みます-それは私にとって最も直感的で、.eval()の出力で簡単に確認できます。しかし、私は2番目が正しいと思います。

Tensorflowは、batch_matmulが次のことを実行すると述べています。

out[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :])

どういう意味ですか?私の例の文脈ではそれはどういう意味ですか?何と何を掛け合わせているのですか?そして、なぜ私が期待した方法で3Dテンソルを取得しないのですか?

11
Alex Lenail

バッチ内の各トレーニング例をまとめて実行していると想像できます。

たとえば、次のディメンションを持つ2つのテンソルがあるとします。

_a.shape = [100, 2, 5]
b.shape = [100, 5, 2]
_

バッチtf.matmul(a, b)を実行すると、出力は_[100, 2, 2]_という形になります。

100はバッチサイズで、他の2つのディメンションはデータのディメンションです。

21
Daniela

まず、tf.batch_matmul()削除 であり、使用できなくなりました。 tf.matmul() を使用するとします。

入力は、行列(または行列のバッチを表すランク> 2のテンソル)である必要があり、おそらく転置後の内部次元が一致している必要があります。

したがって、次のコードがあるとします。

import tensorflow as tf
batch_size, n, m, k = 10, 3, 5, 2
A = tf.Variable(tf.random_normal(shape=(batch_size, n, m)))
B = tf.Variable(tf.random_normal(shape=(batch_size, m, k)))
tf.matmul(A, B)

これで、形状(batch_size, n, k)のテンソルを受け取ります。ここで何が起こっているかです。 batch_sizeの行列nxmbatch_sizeの行列mxkがあるとします。次に、それらの各ペアについて、nxm X mxkを計算します。これにより、nxkマトリックスが得られます。そのうちbatch_size枚あります。

次のようなものも有効であることに注意してください。

A = tf.Variable(tf.random_normal(shape=(a, b, n, m)))
B = tf.Variable(tf.random_normal(shape=(a, b, m, k)))
tf.matmul(A, B)

そしてあなたに形を与えます(a, b, n, k)

16
Salvador Dali

Tensorflow .11.0rcから始めて、tf.einsumを使用してこれを実行できます。

例えば、

M1 = tf.Variable(tf.random_normal([2,3,4]))
M2 = tf.Variable(tf.random_normal([5,4]))  
N = tf.einsum('ijk,lk->ijl',M1,M2)       

マトリックスM2に、M1のすべてのバッチ(2バッチ)のすべてのフレーム(3フレーム)を乗算します。

出力は次のとおりです。

[array([[[ 0.80474716, -1.38590837, -0.3379252 , -1.24965811],
        [ 2.57852983,  0.05492432,  0.23039417, -0.74263287],
        [-2.42627382,  1.70774114,  1.19503212,  0.43006262]],

       [[-1.04652011, -0.32753903, -1.26430523,  0.8810069 ],
        [-0.48935518,  0.12831448, -1.30816901, -0.01271309],
        [ 2.33260512, -1.22395933, -0.92082584,  0.48991606]]], dtype=float32),
array([[ 1.71076882, 0.79229093, -0.58058828, -0.23246667],
       [ 0.20446332,  1.30742455, -0.07969904,  0.9247328 ],
       [-0.32047141,  0.66072595, -1.12330854,  0.80426538],
       [-0.02781649, -0.29672042,  2.17819595, -0.73862702],
       [-0.99663496,  1.3840003 , -1.39621222,  0.77119476]], dtype=float32), 
array([[[ 0.76539308, 2.77609682, -1.79906654,  0.57580602, -3.21205115],
        [ 4.49365759, -0.10607499, -1.64613271,  0.96234947, -3.38823152],
        [-3.59156275,  2.03910899,  0.90939498,  1.84612727,  3.44476724]],

       [[-1.52062428,  0.27325237,  2.24773455, -3.27834225,  3.03435063],
        [ 0.02695178,  0.16020992,  1.70085776, -2.8645196 ,  2.48197317],
        [ 3.44154787, -0.59687197, -0.12784094, -2.06931567, -2.35522676]]], dtype=float32)]

私は検証しました、計算は正しいです。

4
xuancong84

tf.tensordotはこの問題を解決するはずです。たとえば、2Dテンソルと3Dテンソルを縮小したい場合、後者はバッチディメンションを持ちます。

Aが形状[n、m] bが形状[?、m、l]の場合、

y = tf.tensordot(b、a、axes = [1、1])は、形状[?、n、l]のテンソルを生成します

https://www.tensorflow.org/api_docs/python/tf/tensordot

2
aph