Я вручную собираю статистику градиентов модели Multi-Tasking , график которой схематически выглядит следующим образом:
input -> [body_var1 ... body_varN] --> [task1_var1 ... task1_varM] <-- loss_1
\-> [task2_var1 ... task2_varM] <-- loss_2
I 'Определение отдельного оптимизатора для каждой потери следующим образом (фактический код значительно сложнее, для этого вопроса упрощено следующее):
# for simplicity, just demonstrate the case with the 1st task
task_index = 1
# here we define the optimizer (create an instance in graph)
loss = losses[task_index]
optimizer = tf.train.GradientDescentOptimizer()
grads_and_vars = optimizer.compute_gradients(loss)
# now let's see what it returns
for g, v in grads_and_vars:
print(' grad:', g, ', var:', v)
Итак, приведенный выше код явно создает отдельный оптимизатор только для ветвизадачи 1, затем мы создаем операции вычисления градиента с optimizer.compute_gradients(loss)
и печатаем переменные, к которым мы применяем градиенты.
Ожидаемые результаты :
grad: body_var1_grad, var: body_var1 # \
... # --> body vars and gradients
grad: body_varN_grad, var: body_varN # /
grad: task1_var1_grad, var: task1_var1 # \
... # --> task 1 vars and gradients
grad: task1_var1_grad, var: task1_var1 # /
Так что я ожидаю, что оптимизатор содержит только операции градиентного вычисления для ветви, к которой он был применен (т. Е. Ветви для 1-й задачи)
Фактические результаты
grad: body_var1_grad, var: body_var1 # \
... # --> body vars and gradients
grad: body_varN_grad, var: body_varN # /
grad: task1_var1_grad, var: task1_var1 # \
... # --> task 1 vars and gradients
grad: task1_var1_grad, var: task1_var1 # /
grad: None, var: task2_var1 # \
... # --> task 2 vars, with None gradients
grad: None, var: task2_var1 # /
Таким образом, похоже, что optimizer.compute_gradients(loss)
захватывает не только подграф, который выводит в loss
(который может быть извлечен с помощью tf.graph_util.extract_sub_graph
), но также и все обучаемые переменные, которые связаны с loss
без креатинаg переменная градиента для них (поэтому возвращаемые переменные градиента None
).
Вопрос: нормально ли такое поведение?