сумма по списку тензоров в tensorflow
у меня есть глубокая нейронная сеть, где веса между слоями хранятся в списке.
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 ?
2 ответов
стандартный способ суммировать список тензоров-использовать tf.add_n()
операция, которая принимает список тензоров (каждый из которых имеет одинаковый размер и форму) и производит один тензор, содержащий сумму.
для конкретной проблемы, которая у вас есть, я предполагаю, что каждый layers[j].weights
может иметь различный размер. Поэтому вам нужно будет уменьшить каждый элемент до скаляра перед суммированием, например, используя tf.nn.l2_loss()
на 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 (но неявно удвоит ваш β), и веса будут кубическими.