2015-12-29 3 views
7

У меня есть глубокая нейронная сеть, где веса между слоями хранятся в списке.сумма по списку тензоров в тензорном потоке

layers[j].weights Я хочу включить штраф в гребень в свою стоимость. Мне нужно тогда использовать что-то вроде tf.nn.l2_loss(layers[j].weights**2 for j in range(self.n_layers)) т. Е. Квадрат суммы всех весов.

В частности, весовые коэффициенты определяются как:

>>> avs.layers 
[<neural_network.Layer object at 0x10a4b2a90>, <neural_network.Layer object at 0x10ac85080>, <neural_network.Layer object at 0x10b0f3278>, <neural_network.Layer object at 0x10b0eacf8>, <neural_network.Layer object at 0x10b145588>, <neural_network.Layer object at 0x10b165048>, <neural_network.Layer object at 0x10b155ba8>] 
>>> 
>>> avs.layers[0].weights 
<tensorflow.python.ops.variables.Variable object at 0x10b026748> 
>>> 

Как я могу сделать это в tensorflow?

+0

Я думаю, вам нужно создать новый тензор из этих весов и использовать его в уравнении стоимости. – fabrizioM

ответ

16

Стандартный способ суммирования списка тензоров состоит в использовании операции tf.add_n(), которая принимает список тензоров (каждый из которых имеет одинаковый размер и форму) и создает один тензор, содержащий сумму.

Для конкретной проблемы, которая у вас есть, я предполагаю, что каждый layers[j].weights может иметь разный размер. Поэтому вам необходимо уменьшить каждый элемент до скаляра перед суммированием, например. используя самое tf.nn.l2_loss() функции:

weights = [layers[j].weights for j in range(self.n_layers)] 
losses = [tf.nn.l2_loss(w) for w in weights] 
total_loss = tf.add_n(losses) 

(Обратите внимание на то, что, когда значения должны быть добавлены большие, вы можете найти его более эффективным, чтобы вычислить последовательность tf.add() операций, поскольку TensorFlow хранит значения каждого из add_n аргументы в памяти до все из них были вычислены. цепочка add ОПС позволяет некоторым из расчета произойдет раньше.)

0

tf.nn.l2_loss() функция возвращает тензор с 0 размерами.

Но приятно не применять вручную к каждому весовому тензору, поэтому сохранение весовых тензоров в списке является одним из способов решения проблемы (как отмечал @mrry).

Но вместо необходимости писать, что каждый раз, когда то, что вы могли бы сделать, это использовать следующую функцию

def l2_loss_sum(list_o_tensors): 
    return tf.add_n([tf.nn.l2_loss(t) for t in list_o_tensors]) 

В вашем случае это будет выглядеть так:

total_loss = l2_loss_sum([layers[j].weights for j in range(self.n_layers)]) 

Кроме того, tf.nn.l2_loss() неявно применяет квадратичную операцию к значениям, а также умножает все квадратные значения на 1/2, так что вы использовали что-то вроде tf.nn.l2_loss(layers[j].weights**2 for j in range(self.n_layers)), которое вы бы подняли весом до 4-й степени. В результате ваша производная от этого термина потери была бы странной: она не отменила бы 1/2 к 1 (но неявно удвоила бы ваш β), и веса были бы кубированы.

Смежные вопросы