Подтвердить что ты не робот

Как использовать stop_gradient в Tensorflow

Мне интересно, как использовать stop_gradient в tensorflow, и документация мне не понятна.

В настоящее время я использую stop_gradient для создания градиента функции потерь w.r.t. слово вложения в модели CBOW word2vec. Я хочу просто получить значение, а не делать backpropagation (поскольку я создаю состязательные примеры).

В настоящее время я использую код:

lossGrad = gradients.gradients(loss, embed)[0]
real_grad = lossGrad.eval(feed_dict)

Но когда я запускаю это, он делает backpropogation в любом случае! Что я делаю неправильно, и так же важно, как я могу это исправить?

ПОДТВЕРЖДЕНИЕ: Чтобы уточнить "backpropagation", я имею в виду "вычисление значений и обновление параметров модели".

UPDATE

Если я запустил две строки выше после первого этапа обучения, я получаю другую потерю после 100 шагов обучения, чем когда я не запускаю эти две строки. Я мог бы принципиально не понимать что-то о Tensorflow.

Я попытался установить с помощью set_random_seed как в начале объявления графика, так и перед каждым шагом обучения. Полная потеря согласована между несколькими прогонами, но не между включением/исключением этих двух строк. Итак, если это не RNG, вызывающий диспропорцию, и это не непредвиденное обновление параметров модели между этапами обучения, знаете ли вы, что могло бы вызвать это поведение?

РЕШЕНИЕ

Welp, это немного поздно, но вот, как я это решил. Я только хотел оптимизировать некоторые, но не все, переменные. Я думал, что способ предотвратить оптимизацию некоторых переменных будет заключаться в использовании stop_grad - но я никогда не нашел способ сделать эту работу. Возможно, есть способ, но для меня работала настройка optimizer только для оптимизации списка переменных. Поэтому вместо:

opt = tf.train.GradientDescentOptimizer(learning_rate=eta)
train_op = opt.minimize(loss)

Я использовал:

opt = tf.train.GradientDescentOptimizer(learning_rate=eta)
train_op = opt.minimize(loss, var_list=[variables to optimize over])

Это предотвратило opt от обновления переменных не в var_list. Надеюсь, это сработает и для вас!

4b9b3361

Ответ 1

tf.gradients(loss, embed) вычисляет частную производную тензора loss относительно тензора embed. TensorFlow вычисляет эту частную производную путем backpropagation, поэтому ожидается, что поведение, которое оценивает результат tf.gradients(...), выполняет обратное распространение. Однако, оценивая, что тензор не выполняет никаких переменных обновлений, потому что выражение не включает в себя операции назначения.

tf.stop_gradient() - это операция, которая действует как функция идентификации в прямом направлении, но останавливает накопленный градиент от прохождения через этот оператор в обратном направлении. Это не предотвращает обратное распространение вообще, но вместо этого предотвращает внесение отдельного тензора в градиенты, которые вычисляются для выражения. документация для операции содержит более подробную информацию об операции и когда ее использовать.

Ответ 2

tf.stop_gradient предоставляет возможность не вычислять градиент по отношению к некоторым переменным во время обратного распространения.

Например, в приведенном ниже коде мы имеем три переменные: w1, w2, w3 и вход x. Потеря квадрата ((x1.dot(w1) - x.dot(w2 * w3))). Мы хотим минимизировать эту потерю по w1, но хотим сохранить w2 и w3 фиксированными. Для этого мы можем просто положить tf.stop_gradient (tf.matmul(x, w2 * w3)).

На рисунке ниже я описал, как w1, w2 и w3 от их начальных значений как функция тренировочных итераций. Видно, что w2 и w3 остаются фиксированными, а w1 изменяется до тех пор, пока не станет равным w2 * w3.

Изображение, показывающее, что w1 только узнает, но не w2 и w3

import tensorflow as tf
import numpy as np

w1 = tf.get_variable("w1", shape=[5, 1], initializer=tf.truncated_normal_initializer())
w2 = tf.get_variable("w2", shape=[5, 1], initializer=tf.truncated_normal_initializer())
w3 = tf.get_variable("w3", shape=[5, 1], initializer=tf.truncated_normal_initializer())
x = tf.placeholder(tf.float32, shape=[None, 5], name="x")


a1 = tf.matmul(x, w1)
a2 = tf.matmul(x, w2*w3)
a2 = tf.stop_gradient(a2)
loss = tf.reduce_mean(tf.square(a1 - a2))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
gradients = optimizer.compute_gradients(loss)
train_op = optimizer.apply_gradients(gradients)