Как сделать взвешенную сумму как тензорную операцию в тензорном потоке? - PullRequest
0 голосов
/ 31 декабря 2018

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

У меня есть два тензора U с формой (B, F, M) и A с формой (C, B),Я хотел бы сделать взвешенную сумму и суммирование.

Взвешенная сумма

Для каждого индекса c из C у меня есть вектор весов a из A , с формой (B,).Я хочу использовать его для взвешенной суммы U , чтобы получить матрицу U_t с формой (F, M).Это почти то же самое с этим , где я нашел небольшую помощь.

Конкатенация

К сожалению, я хочу сделать это для каждого вектора a в A , чтобы получить матрицы C U _tcв списке U _tc имеют упомянутую форму (F, M).После этого я объединяю все матрицы в списке, чтобы получить суперматрицу с формой (C * F, M)

Мои значения: C = 2500, M = 500, F = 80, B = 300

* 1034.* В начале я попробовал очень наивный подход со множеством циклов и выбором элементов, которые генерируют очень много операций.Теперь с помощью this у меня есть следующее:
U = tf.Variable(tf.truncated_normal([B, F, M],stddev=1.0 ,dtype=tf.float32) #just for example
A = tf.Variable(tf.truncated_normal([C, B],stddev=1.0) ,dtype=tf.float32) #just for example

U_t = []

for ccc in xrange(C):
    a = A[ccc,:]
    a_broadcasted = tf.tile(tf.reshape(a,[B,1,1]), tf.stack([1,F,M]))
    T_p.append(tf.reduce_sum(tf.multiply(U,a_broadcasted), axis=0))


U_tcs = tf.concat(U_t,axis=0)

К сожалению, это не удается из-за ошибки памяти.Я не уверен, что сделал что-то не так, или это потому, что в вычислениях слишком много математической операции?Потому что я думаю ... переменные не слишком велики для памяти, верно?По крайней мере, у меня были большие переменные, и это было нормально.(У меня 16 ГБ памяти GPU)

Правильно ли я делаю эту взвешенную сумму?

Есть идеи, как сделать ее более эффективной?

Буду признателен за любую помощь.Спасибо.

1 Ответ

0 голосов
/ 01 января 2019

1.Взвешенная сумма и конкатенация

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

import tensorflow as tf

C,M,F,B=2500,500,80,300
U = tf.Variable(tf.truncated_normal([B, F, M],stddev=1.0 ,dtype=tf.float32)) #just for example
A = tf.Variable(tf.truncated_normal([C, B],stddev=1.0) ,dtype=tf.float32) #just for example

# shape=(C,B,1,1)
A_new = tf.expand_dims(tf.expand_dims(A,-1),-1)
# shape=(B,F,M)
U_t = tf.reduce_sum(tf.multiply(A_new , U),axis=1)

# shape=(C*F,M)
U_tcs = tf.reshape(U_t,(C*F,M))

2.Ошибка памяти

На самом деле, у меня также были ошибки памяти, когда я запустил приведенный выше код.

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[2500,300,80,500]...

С небольшой модификацией приведенного выше кода, он работает правильно на моих 8 ГБПамять графического процессора.

import tensorflow as tf

C,M,F,B=2500,500,80,300
U = tf.Variable(tf.truncated_normal([B, F, M],stddev=1.0 ,dtype=tf.float32)) #just for example
A = tf.Variable(tf.truncated_normal([C, B],stddev=1.0) ,dtype=tf.float32) #just for example

# shape=(C,B,1,1)
A_new = tf.expand_dims(tf.expand_dims(A,-1),-1)

U_t = []
for ccc in range(C):
    a = A_new[ccc,:]
    a_broadcasted = tf.reduce_sum(tf.multiply(a, U),axis=0)
    U_t.append(a_broadcasted)
U_tcs = tf.concat(U_t,axis=0)
...