2016-10-10 9 views
4

Представьте крошечную сеть определяется следующим образом, где линейный является типичным помощником функции, определяющая TensorFlow переменных для матрицы веса и активации функции:Как напрямую установить градиент слоя перед обратным распространением?

final_layer = linear(linear(_input,10,tf.nn.tanh),20)

Как правило, это будет оптимизировано с помощью градиентного спуска на потерях:

loss = tf.reduce_sum(tf.square(final_layer - _target)) train_step = tf.train.AdamOptimizer().minimmize(loss)

Но предположим, что я получаю производные от потери по final_layer из внешнего источника (например, tf.placeholder с именем _deriv). Как я могу использовать эту информацию о градиенте с одним из встроенных оптимизаторов для backpropagate и обновления сетевых параметров?

Обходной путь, который я использую в настоящее время, заключается в создании искусственной потери, состоящей из внутреннего продукта между _deriv и final_layer (так как производные этой потери w.r.t. final_layer будут равны _deriv).

loss = tf.reduce_sum(final_layer*_deriv) train_step = tf.train.AdamOptimizer().minimmize(loss)

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

Для тех, кто считает это странным делом, необходимо реализовать synthetic gradients.

+0

Интересный вопрос. Возможно, копайте в stop_gradients, как в [этом вопросе] (http://stackoverflow.com/questions/36456436/how-can-i-define-only-the-gradient-for-a-tensorflow-subgraph)? – jean

ответ

2

tf.gradients предоставляет эту функциональность с помощью аргумента grad_ys, см. here. В вашем случае tf.gradients([final_layer], list_of_variables, grad_ys=[_deriv]) вычислит требуемые градиенты.

К сожалению, похоже, что встроенные оптимизаторы не передают аргумент grad_ys в tf.gradients. Возможно, вам придется взломать что-то в методе compute_gradients класса оптимизатора.