2016-07-06 6 views
3

У меня есть два тензора в тензорном потоке, первый тензор 3-D, а второй - 2D. И я хочу их размножить следующим образом:Эффективный способ тензорного потока для умножения тензоров

x = tf.placeholder(tf.float32, shape=[sequence_length, batch_size, hidden_num]) 
w = tf.get_variable("w", [hidden_num, 50]) 
b = tf.get_variable("b", [50]) 

output_list = [] 
for step_index in range(sequence_length): 
    output = tf.matmul(x[step_index, :, :], w) + b 
    output_list.append(output) 
output = tf.pack(outputs_list) 

Я использую цикл для многократной работы, но я думаю, что это слишком медленно. Какой был бы лучший способ сделать этот процесс максимально простым и чистым?

ответ

2

Вы можете использовать batch_matmul. К сожалению, не похоже, что batch_matmul поддерживает широковещательную рассылку по размеру партии, поэтому вы должны плировать свою матрицу w. Это будет использовать больше памяти, но все операции будут оставаться в TensorFlow

a = tf.ones((5, 2, 3)) 
b = tf.ones((3, 1)) 
b = tf.reshape(b, (1, 3, 1)) 
b = tf.tile(b, [5, 1, 1]) 
c = tf.batch_matmul(a, b) # use tf.matmul in TF 1.0 
sess = tf.InteractiveSession() 
sess.run(tf.shape(c)) 

Это дает

array([5, 2, 1], dtype=int32) 
+0

Благодарим вас за ответ, но у меня есть вопрос, после использования tf.tile размер переменной b изменяется, потому что в нем есть бесполезные данные. Поэтому трудно вычислить tf.nn.l2_loss (b) –

+0

Ввод черепицы может быть тензором, поэтому вы можете динамически строить форму arg из tf.shape (w) –

+1

В tensorflow 1.0 используйте 'tf.matmul' вместо 'tf.batch_matmul'. – holdenlee

1

Вы можете использовать map_fn, который сканирует функцию вдоль первого измерения.

x = tf.placeholder(tf.float32, shape=[sequence_length, batch_size, hidden_num]) 
w = tf.get_variable("w", [hidden_num, 50]) 
b = tf.get_variable("b", [50]) 

def mul_fn(current_input): 
    return tf.matmul(current_input, w) + b 

output = tf.map_fn(mul_fn, x) 

I used this at one point осуществить SoftMax сканирование вдоль последовательности.