Ответ 1
Вы правы, что объединение градиентов может стать беспорядочным. Вместо этого просто вычислите градиенты каждого из потерь, а также окончательную потерю. Поскольку tensorflow оптимизирует ориентированный ациклический граф (DAG) перед компиляцией, это не приводит к дублированию работы.
Например:
import tensorflow as tf
with tf.name_scope('inputs'):
W = tf.Variable(dtype=tf.float32, initial_value=tf.random_normal((4, 1), dtype=tf.float32), name='W')
x = tf.random_uniform((6, 4), dtype=tf.float32, name='x')
with tf.name_scope('outputs'):
y = tf.matmul(x, W, name='y')
def my_loss_fn(output, targets, name):
return tf.reduce_mean(tf.abs(output - targets), name=name)
def my_other_loss_fn(output, targets, name):
return tf.sqrt(tf.reduce_mean((output - targets) ** 2), name=name)
def get_tensors(loss_fn):
loss = loss_fn(y, targets, 'loss')
grads = tf.gradients(loss, W, name='gradients')
norm = tf.norm(grads, name='norm')
return loss, grads, norm
targets = tf.random_uniform((6, 1))
with tf.name_scope('a'):
loss_a, grads_a, norm_a = get_tensors(my_loss_fn)
with tf.name_scope('b'):
loss_b, grads_b, norm_b = get_tensors(my_loss_fn)
with tf.name_scope('combined'):
loss = tf.add(loss_a, loss_b, name='loss')
grad = tf.gradients(loss, W, name='gradients')
with tf.Session() as sess:
tf.global_variables_initializer().run(session=sess)
writer = tf.summary.FileWriter('./tensorboard_results', sess.graph)
res = sess.run([norm_a, norm_b, grad])
print(*res, sep='\n')
Изменить. В ответ на ваш комментарий... Вы можете проверить DAG модели тензорного потока с помощью тензора. Я обновил код для хранения графика.
Запустите tensorboard --logdir $PWD/tensorboard_results
в терминале и перейдите к URL-адресу, напечатанному на командной строке (обычно http://localhost:6006/
). Затем перейдите на вкладку GRAPH, чтобы просмотреть DAG. Вы можете рекурсивно развернуть тензоры, ops, namespaces, чтобы увидеть подграфы, чтобы увидеть отдельные операции и их входы.