2016-04-06 2 views
9

Во-первых: Я всего несколько дней в Tensorflow, поэтому, пожалуйста, несите меня.Как определить только градиент для подграфа Tensorflow?

Я начал с кода учебника cifar10, и теперь я использую комбинацию сверток и разложения по собственным значениям, которые нарушают символическое дифференцирование. То есть график строится, затем при вызове train() сценарий останавливается с «Без градиента, определенного для операции [...] (тип операции: SelfAdjointEig)». Не удивительно.

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

Из того, что я вижу в документах, я могу зарегистрировать метод градиента для пользовательских операций с RegisterGradient или переопределить их с помощью экспериментального gradient_override_map. Обе из них должны дать мне доступ к тем вещам, которые мне нужны. Например, searching on Github Я нахожу множество примеров, которые обращаются к входам op как op.input[0] или тому подобное.

Проблема у меня в том, что я хочу по существу «сократить» целый подграф, а не один операнд, поэтому у меня нет единого ор, чтобы украсить. Так как это происходит в одном из сверточных слоев примера cifar, я попытался использовать объект области видимости для этого слоя. Концептуально, что входит и выходит, что граф области видимости - это именно то, что я хочу, если бы я мог каким-то образом переопределить градиенты всей области, которые «уже» это сделают.

Я видел tf.Graph.create_op, который (я думаю) мог бы использовать для регистрации нового типа операции, и тогда я мог бы переопределить вычисление градиента типа операции с вышеупомянутыми методами. Но я не вижу способа определить, что op пересылает, не записывая его в C++ ...

Может быть, я совсем не подхожу к этому? Так как все мои операции вперед или назад могут быть реализованы с помощью интерфейса python, я, очевидно, хочу избежать реализации чего-либо на C++.

+0

Может быть, вы можете изменить градиент для одного цита на верхней части undifferentiable графа, а затем использовать 'tf.stop_gradient()', чтобы не допустить строительство градиента для этого подграфа? http://stackoverflow.com/questions/33727935/how-to-use-stop-gradient-in-tensorflow –

+0

Я могу представить локально определение градиентной функции, а затем использовать в ней все еще входящие в нее входы. Но как бы сказать, какие градиенты узлов я беру в качестве вклада в вычисление градиента? Мне кажется, что я принципиально неправильно использую структуру: P –

ответ

20

Вот трик Сергея Иоффе:

Предположим, вы хотите группу опс, которые ведут себя, как F (X) в прямом режиме, но, как г (х) в режиме обратного. Вы реализуете его как

t = g(x) 
y = t + tf.stop_gradient(f(x) - t) 

Так что в вашем случае ваш г (х) может быть тождеством оп, с настраиваемой градиентом, используя gradient_override_map

+1

Для понимания: вызов 'stop_gradient' заботится о бит автоматического градиента, переопределение градиента для' g' дает мне возможность вставлять мои собственные и 't + f (x) - t' будет исключен? –

+2

Значение «t ​​+ f (x) - t" равно «f (x)». Он в вычислительной мере эквивалентен в текущей версии, но в будущей версии он может быть оптимизирован –

+1

Наконец, он смог применить это, хотя и не для той же функции. Но это не очень хорошо обобщает «сложные операции» с несколькими входами, потому что «add-subtract» не работает, не так ли? Лучшее, что я мог придумать (но не нужно было пытаться), как-то использовать кортежи вместо идентификатора. Но я немного не понимаю, как будет выглядеть график после этого. В любом случае, огромное спасибо :) –

-1

Как насчет умножения и деления, вместо сложения и вычитания т?

t = g(x) 
y = tf.stop_gradient(f(x)/t) * t 
+0

dy/dt здесь (f (x)/t) * dy - не то, что мы хотели. остановка градиента через левую сторону не препятствует производной умножения с использованием прямого результата. – lahwran

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