Как Tensorflow `tf.train.Optimizer` вычисляет градиенты?

10

Я следую учебнику по Mensist Tensorflow ( https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_softmax.py ).

Учебник использует tf.train.Optimizer.minimize(конкретно tf.train.GradientDescentOptimizer). Я не вижу каких-либо аргументов, передаваемых где-либо для определения градиентов.

Тензорный поток использует числовое дифференцирование по умолчанию?

Есть ли способ передать градиенты, как вы можете с scipy.optimize.minimize?

limscoder
источник

Ответы:

16

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

Если по какой-то причине вы хотите переопределить это по кусочкам, это возможно с gradient_override_map.

Дугал
источник
Разве автоматическое дифференцирование не использует числовое дифференцирование?
Аэрин
@BYOR Нет; проверьте ссылку Wikipedia выше. То, что делает тензорный поток, на самом деле находится где-то между «реальным» автодифференцированием в обратном режиме и символическим дифференцированием.
Дугал
@ Думаю, я использую активный режим без графа, без декоратора tf.function, как автоматическое дифференцирование узнает связь между тензорами?
19
1
@datdinhquoc Это тот же фундаментальный алгоритм, чуть более сложный в реализации.
Дугал
9

Он использует автоматическое дифференцирование. Где он использует правило цепочки и обратное слово в графе, назначая градиенты.

Допустим, у нас есть тензор C Этот тензор C был создан после ряда операций. Допустим, путем сложения, умножения, прохождения некоторой нелинейности и т. Д.

Так что, если этот C зависит от некоторого набора тензоров, называемых Xk, нам нужно получить градиенты

Тензор потока всегда отслеживает путь операций. Я имею в виду последовательное поведение узлов и как поток данных между ними. Что сделано графом введите описание изображения здесь

Если нам нужно получить производные стоимости от X входных данных, то, что сначала будет сделано, это загрузить путь от x-input к стоимости путем расширения графика.

Тогда это начнется в порядке рек. Затем распределите градиенты с помощью цепного правила. (То же, что и обратное распространение)

В любом случае, если вы читаете исходные коды, принадлежащие tf.gradients (), вы можете обнаружить, что тензор потока хорошо выполнил эту часть распределения градиента.

В то время как обратное отслеживание tf взаимодействует с графом, в проходе обратного слова TF встретит разные узлы. Внутри этих узлов есть операции, которые мы называем (ops) matmal, softmax, relu, batch_normalization и т. Д. Итак, что мы tf делаем, это автоматически загружает эти ops в график

Этот новый узел составляет частную производную операций. get_gradient ()

Давайте немного поговорим об этих недавно добавленных узлах

Внутри этих узлов мы добавляем 2 вещи: 1. Производная, которую мы вычислили раньше) 2. Также входы для сопоставления OPP в прямом проходе

Таким образом, по правилу цепи мы можем рассчитать

Так что это так же, как бэк-слово API

Так что тензор потока всегда думает о порядке графа, чтобы сделать автоматическое дифференцирование

Так как мы знаем, что нам нужны переменные прямого прохода для вычисления градиентов, то нам нужно хранить промежуточные значения также в тензорах, это может уменьшить память. Для многих операций tf знают, как вычислять градиенты и распределять их.

Шамане Сиривардхана
источник
1
Я использую нетерпеливый режим без графа, без декоратора tf.function, как автоматическое дифференцирование узнает связь между тензорами?
19