2015-12-09 2 views
9

Tensorflow имеет функцию, называемую batch_matmul, которая умножает тензоры большей размерности. Но мне трудно понять, как это работает, возможно, частично потому, что мне трудно его визуализировать.Как работает tensorflow batch_matmul?

enter image description here

То, что я хочу сделать, это умножить матрицу каждого кусочек 3D тензора, но я не совсем понимаю, что форма тензора а есть. Является ли внутреннее измерение? Что из следующего верно?

enter image description here

Я бы наиболее предпочитаю первый правильным - это наиболее интуитивно мне и легко увидеть на выходе .eval(). Но я подозреваю, что второй правильный.

Tensorflow говорит, что batch_matmul выполняет:

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

Что это значит? Что это значит в контексте моего примера? С чем что умножается? И почему я не получаю 3D-тензор так, как я ожидал?

+0

[tf.batch_matmul больше не доступен] (http://stackoverflow.com/a/ 43819275/1090562) –

ответ

18

Вы можете представить, как это делает матовую маску над каждым примером обучения в партии.

Например, если у вас есть два тензоры со следующими размерами:

a.shape = [100,2,5] 
b.shape = [100,5,2] 

и вы делаете batch.matmul (а, б), ваш выход будет иметь форму [100,2,2] ,

100 - ваш размер партии, другие два измерения - размеры ваших данных.

+0

Я чувствую, что вы только частично отвечаете на вопрос. В частности, почему первое измерение b в вашем примере должно быть 100? что, если у меня есть тензор a, который представляет собой пакет примеров, и я хочу применить операцию sampe для каждого из них, то есть я хочу умножить каждую из них на b, что является [5, 2]. Единственный способ сделать это с помощью tf.tile? А если нет, то как определяется выход batch_matmul? –

+1

@AlexLenail: У меня есть тот же вопрос - я хочу умножить трехмерный тензор на 2D-тензор без явной разбивки 2D-тензора. Вы нашли ответ? – ahmadh

+0

Использовать механизм вещания, поддерживаемый matmul –

-1

Это просто расщепление на первом измерении соответственно, умножение и конкатение назад. Если вы хотите сделать 3D 2D, вы можете изменить его, перемножить и изменить. То есть [100, 2, 5] -> [200, 5] -> [200, 2] -> [100, 2, 2]

3

Теперь вы можете сделать это с помощью tf.einsum, начиная с Tensorflow 0.11. 0rc0.

Например,

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 с каждым кадром (3 кадра) в каждой партии (2) партий в M1.

Выход:

[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)] 

Я проверил, арифметика правильно.

+0

Просто небольшое сомнение - это 'tf.einsum()' быстрый или медленный по сравнению с другими методами, такими как 'batch_matmul(), matmul()'? Я хочу реализовать продукт tensordot в тензорном потоке, но только метод 'einsum()', по-видимому, поддерживает его, а остальные методы нуждаются в некоторых изменениях и формировании обратных процедур, поэтому я хочу знать, эффективно ли использовать 'einsum() ' – pikachuchameleon

-1

Ответ на этот конкретный ответ заключается в использовании функции tf.scan.

Если а = [5,3,2] #dimension 5 партии, с 3x2 мата в каждой партии
и б = [2,3] # постоянная матрица, чтобы быть умножена на каждом образце

затем давайте def fn (a, x): return tf.matmul (x, b)

initializer = tf.Variable (tf.случайное_число (3,3))

ч = tf.scan (п, выходы, инициализатор)

это ч будет хранить все выходы.

11

Прежде всего tf.batch_matmul() был removed и больше не доступен. Теперь вы предполагаете использовать 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 из матриц nxm и batch_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)