TensorFlow:执行此损失计算
Posted
技术标签:
【中文标题】TensorFlow:执行此损失计算【英文标题】:TensorFlow: Performing this loss computation 【发布时间】:2016-05-21 09:52:36 【问题描述】:我的问题和问题在两个代码块下方说明。
损失函数
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
都是张量,所以当我尝试访问单个元素时,我返回了一个形状为 [] 的张量。当我尝试使用 Int
作为其 k
参数时,这是一个问题。
另一个问题是我的label_lengths
是一个占位符,因为我的loss
值需要在optimizer.minimize(loss)
调用之前定义,我还收到一个错误,指出需要为占位符传递一个值。
我只是想知道如何尝试实现这个损失函数。或者如果我遗漏了一些明显的东西。
编辑: 在further reading 之后,我发现通常像我描述的损失一样用于验证和训练替代损失,该替代损失在与使用真实损失相同的地方最小化。有谁知道像我这样的基于编辑距离的场景使用什么替代损失?
【问题讨论】:
在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)
你的feed_dict
是什么? session.run 的 fetches 列表中不应包含占位符。
@TheMyth feed_dict 实际上存储了占位符值。这绝对是一种冗余,但我认为我这样做是为了让代码更简洁。
【参考方案1】:
我要做的第一件事是使用 tensorflow 而不是 numpy 来计算损失。这将允许 tensorflow 为您计算梯度,因此您将能够反向传播,这意味着您可以最大限度地减少损失。
核心库中有 tf.edit_distance(https://www.tensorflow.org/api_docs/python/tf/edit_distance) 函数。
很自然地要解决这个问题,我会尝试在 TensorFlow 中实现它。问题是,我的 logit_lengths 和 label_lengths 都是张量,所以当我尝试访问单个元素时,我返回了一个形状为 [] 的张量。当我尝试使用将 Int 作为其 k 参数的 tf.nn.top_k() 时,这是一个问题。
您能否提供更多详细信息,为什么这是一个问题?
【讨论】:
以上是关于TensorFlow:执行此损失计算的主要内容,如果未能解决你的问题,请参考以下文章