Максимальная маржинальная потеря в TensorFlow
Я пытаюсь реализовать максимальную потерю маржи в TensorFlow. идея состоит в том, что у меня есть положительный пример, и я пробую некоторые отрицательные примеры и хочу вычислить что-то вроде
где B - размер моей партии, а N - количество отрицательных образцов, которые я хочу использовать.
Я новичок в tenorflow, и мне сложно реализовать его. Моя модель вычисляет вектор баллов измерения B * (N + 1)
где я чередую положительные образцы и отрицательные образцы. Например, для размера партии 2 и 2 отрицательных примера у меня есть вектор размера 6 с оценками для первого положительного примера с индексом 0 и для второго положительного примера в позиции 3 и оценками для отрицательных примеров в позиции 1, 2, 4 и 5. Идеально было бы получить такие значения, как [1, 0, 0, 1, 0, 0]
,
То, что я мог придумать, заключается в следующем, используя время и условия:
# Function for computing max margin inner loop
def max_margin_inner(i, batch_examples_t, j, scores, loss):
idx_pos = tf.mul(i, batch_examples_t)
score_pos = tf.gather(scores, idx_pos)
idx_neg = tf.add_n([tf.mul(i, batch_examples_t), j, 1])
score_neg = tf.gather(scores, idx_neg)
loss = tf.add(loss, tf.maximum(0.0, 1.0 - score_pos + score_neg))
tf.add(j, 1)
return [i, batch_examples_t, j, scores, loss]
# Function for computing max margin outer loop
def max_margin_outer(i, batch_examples_t, scores, loss):
j = tf.constant(0)
pos_idx = tf.mul(i, batch_examples_t)
length = tf.gather(tf.shape(scores), 0)
neg_smp_t = tf.constant(num_negative_samples)
cond = lambda i, b, j, bi, lo: tf.logical_and(
tf.less(j, neg_smp_t),
tf.less(pos_idx, length))
tf.while_loop(cond, max_margin_inner, [i, batch_examples_t, j, scores, loss])
tf.add(i, 1)
return [i, batch_examples_t, scores, loss]
# compute the loss
with tf.name_scope('max_margin'):
loss = tf.Variable(0.0, name="loss")
i = tf.constant(0)
batch_examples_t = tf.constant(batch_examples)
condition = lambda i, b, bi, lo: tf.less(i, b)
max_margin = tf.while_loop(
condition,
max_margin_outer,
[i, batch_examples_t, scores, loss])
В коде есть два цикла: один для внешней суммы, а другой для внутренней. Проблема, с которой я сталкиваюсь, заключается в том, что переменная потерь продолжает накапливать ошибки на каждой итерации без сброса после каждой итерации. Так что на самом деле это не работает вообще.
Более того, кажется, что он действительно не соответствует принципу реализации вещей. Я думаю, что могут быть лучшие способы, более векторизованные способы его реализации, надеюсь, кто-то предложит варианты или укажет на примеры.
1 ответ
Сначала нам нужно очистить ввод:
- мы хотим, чтобы множество положительных оценок, формы
[B, 1]
- мы хотим матрицу отрицательных оценок, формы
[B, N]
import tensorflow as tf
B = 2
N = 2
scores = tf.constant([0.5, 0.2, -0.1, 1., -0.5, 0.3]) # shape B * (N+1)
scores = tf.reshape(scores, [B, N+1])
scores_pos = tf.slice(scores, [0, 0], [B, 1])
scores_neg = tf.slice(scores, [0, 1], [B, N])
Теперь нам нужно только вычислить матрицу потерь, то есть все индивидуальные потери для каждой пары (положительные, отрицательные), и вычислить ее сумму.
loss_matrix = tf.maximum(0., 1. - scores_pos + scores_neg) # we could also use tf.nn.relu here
loss = tf.reduce_sum(loss_matrix)