TensorFlow: Выполнение вычисления потерь

Мой вопрос и проблема указаны ниже двух блоков кода.


Функция потерь

def loss(labels, logits, sequence_lengths, label_lengths, logit_lengths):    
    scores = []
    for i in xrange(runner.batch_size):
        sequence_length = sequence_lengths[i]
        for j in xrange(length):
            label_length = label_lengths[i, j]
            logit_length = logit_lengths[i, j]

             # get top k indices <==> argmax_k(labels[i, j, 0, :], label_length)
            top_labels = np.argpartition(labels[i, j, 0, :], -label_length)[-label_length:]
            top_logits = np.argpartition(logits[i, j, 0, :], -logit_length)[-logit_length:]

            scores.append(edit_distance(top_labels, top_logits))

    return np.mean(scores)

# Levenshtein distance
def edit_distance(s, t):
    n = s.size
    m = t.size
    d = np.zeros((n+1, m+1))
    d[:, 0] = np.arrange(n+1)
    d[0, :] = np.arrange(n+1)

    for j in xrange(1, m+1):
        for i in xrange(1, n+1):
            if s[i] == t[j]:
                d[i, j] = d[i-1, j-1]
            else:
                d[i, j] = min(d[i-1, j] + 1,
                              d[i, j-1] + 1,
                              d[i-1, j-1] + 1)

    return d[m, n]

Используется в

Я пытался сгладить свой код, чтобы все происходило в одном месте. Сообщите мне, есть ли опечатки/точки путаницы.

sequence_lengths_placeholder = tf.placeholder(tf.int64, shape=(batch_size))
labels_placeholder = tf.placeholder(tf.float32, shape=(batch_size, max_feature_length, label_size))
label_lengths_placeholder = tf.placeholder(tf.int64, shape=(batch_size, max_feature_length))
loss_placeholder = tf.placeholder(tf.float32, shape=(1))

logit_W = tf.Variable(tf.zeros([lstm_units, label_size]))
logit_b = tf.Variable(tf.zeros([label_size]))

length_W = tf.Variable(tf.zeros([lstm_units, max_length]))
length_b = tf.Variable(tf.zeros([max_length]))

lstm = rnn_cell.BasicLSTMCell(lstm_units)
stacked_lstm = rnn_cell.MultiRNNCell([lstm] * layer_count)

rnn_out, state = rnn.rnn(stacked_lstm, features, dtype=tf.float32, sequence_length=sequence_lengths_placeholder)

logits = tf.concat(1, [tf.reshape(tf.matmul(t, logit_W) + logit_b, [batch_size, 1, 2, label_size]) for t in rnn_out])

logit_lengths = tf.concat(1, [tf.reshape(tf.matmul(t, length_W) + length_b, [batch_size, 1, max_length]) for t in rnn_out])

optimizer = tf.train.AdamOptimizer(learning_rate)
global_step = tf.Variable(0, name='global_step', trainable=False)
train_op = optimizer.minimize(loss_placeholder, global_step=global_step)

...
...
# Inside training loop

np_labels, np_logits, sequence_lengths, label_lengths, logit_lengths = sess.run([labels_placeholder, logits, sequence_lengths_placeholder, label_lengths_placeholder, logit_lengths], feed_dict=feed_dict)
loss = loss(np_labels, np_logits, sequence_lengths, label_lengths, logit_lengths)
_ = sess.run([train_op], feed_dict={loss_placeholder: loss})

Моя проблема

Проблема в том, что это возвращает ошибку:

  File "runner.py", line 63, in <module>
    train_op = optimizer.minimize(loss_placeholder, global_step=global_step)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py", line 188, in minimize
    name=name)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py", line 277, in apply_gradients
    (grads_and_vars,))

  ValueError: No gradients provided for any variable: <all my variables>

Поэтому я предполагаю, что это TensorFlow, жалующийся на то, что он не может вычислить градиенты моей потери, потому что потеря выполняется numpy, вне области TF.

Поэтому, естественно, исправить это, я бы попытался реализовать это в TensorFlow. Проблема в том, что мои logit_lengths и label_lengths - оба тензора, поэтому, когда я пытаюсь получить доступ к одному элементу, мне возвращается тензор формы []. Это проблема, когда я пытаюсь использовать tf.nn.top_k(), который принимает Int для своего параметра k.

Другой проблемой является мой label_lengths - это Заполнитель, и поскольку мое значение loss должно быть определено перед вызовом optimizer.minimize(loss), я также получаю сообщение об ошибке, которое говорит, что значение должно быть передано для заполнителя.

Мне просто интересно, как я могу попытаться реализовать эту функцию потерь. Или, если мне не хватает чего-то очевидного.


Изменить: После некоторого дальнейшего чтения я вижу, что обычно потери, подобные описанным, используются в валидации и в обучении суррогатной утрате, которая сводится к минимуму в том же месте, что и истинные потери. Кто-нибудь знает, какие суррогатные потери используются для сценария, основанного на изменении расстояния, например, моего?

Ответ 1

Первое, что я хотел бы сделать, - вычислить убытки, используя тензорный поток вместо numpy. Это позволит тензорному потоку вычислять градиенты для вас, так что вы сможете вернуться назад, то есть вы можете свести к минимуму потерю.

В основной библиотеке есть функция tf.edit_distance (https://www.tensorflow.org/api_docs/python/tf/edit_distance).

Поэтому, естественно, исправить это, я бы попытался реализовать это в TensorFlow. Проблема в том, что мои logit_lengths и label_lengths являются одновременно тензорами, поэтому, когда я пытаюсь получить доступ к одному элементу, мне возвращается тензор формы []. Это проблема, когда я пытаюсь использовать tf.nn.top_k(), которая берет Int для своего параметра k.

Не могли бы вы предоставить несколько подробностей, почему это проблема?