Тензор потока: расчет градиента от входа к выходу
Я хотел бы рассчитать градиенты вывода нейронной сети по отношению к входу. У меня есть следующие тензоры:
Input: (num_timesteps, features)
Output: (num_timesteps, 1)
Для градиентов от входных данных ко всему выходному вектору я могу использовать следующее:
tf.gradients(Output, Input)
Поскольку я хотел бы вычислить градиенты для каждого временного отсчета, я хотел бы рассчитать
tf.gradients(Output[i], Input)
для каждого i
,
Каков наилучший способ сделать это?
1 ответ
Во-первых, я полагаю, вы имеете в виду градиент Output
по отношению к Input
,
Теперь результат обоих этих вызовов:
dO = tf.gradients(Output, Input)
dO_i = tf.gradients(Output[i], Input)
(для любого действительногоi
)
будет список с одним элементом - тензор с той же формой, что и Input
а именно [num_timesteps, features]
матрица. Также, если вы сложите все матрицы dO_i
(по всем действительным i
) это именно матрица dO
,
Имея это в виду, вернемся к вашему вопросу. Во многих случаях отдельные строки из Input
независимы, это означает, что Output[i]
рассчитывается только от Input[i]
и не знает других входных данных (типичный случай: пакетная обработка без пакетной обработки). Если это ваш случай, то dO
собирается дать вам все отдельные компоненты dO_i
однажды.
Это потому, что каждый dO_i
Матрица будет выглядеть так:
[[ 0. 0. 0.]
[ 0. 0. 0.]
...
[ 0. 0. 0.]
[ xxx xxx xxx] <- i-th row
[ 0. 0. 0.]
...
[ 0. 0. 0.]]
Все ряды будут 0
кроме i
один Так что просто вычисляя одну матрицу dO
, вы можете легко получить каждый dO_i
, Это очень эффективно.
Однако, если это не ваш случай и все Output[i]
зависит от всех входов, нет возможности извлечь индивидуальный dO_i
только от их суммы. У вас нет другого выбора, кроме как рассчитать каждый градиент отдельно: просто переберите i
и выполнить tf.gradients
,