La domanda e il problema sono indicati sotto i due blocchi di codice.TensorFlow: esecuzione del calcolo delle perdite
funzione di perdita
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]
utilizzato in
Ho cercato di appiattire il mio codice in modo che tutto ciò che sta accadendo in un unico luogo. Fammi sapere se ci sono errori di battitura/punti di confusione.
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})
Il mio problema
Il problema è che questo sta tornando l'errore:
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>
quindi immagino che questo sia tensorflow dice che non è in grado di calcolare i gradienti di la mia perdita perché la perdita viene eseguita da Numpy, al di fuori della portata di TF.
Quindi, naturalmente, per risolvere il problema, vorrei provare a implementarlo in TensorFlow. Il problema è che il mio logit_lengths
e label_lengths
sono entrambi Tensor, quindi quando provo ad accedere a un singolo elemento, mi viene restituito un Tensore di forma []. Questo è un problema quando sto cercando di utilizzare tf.nn.top_k()
che accetta uno Int
per il suo parametro .
Un altro problema con questo è il mio label_lengths
è un segnaposto e dal momento che il mio valore loss
devono essere definiti prima della chiamata optimizer.minimize(loss)
, ho anche ottenere un errore che dice un valore deve essere passato per il segnaposto.
Mi chiedo come potrei provare a implementare questa funzione di perdita. O se mi manca qualcosa di ovvio.
Edit: Dopo qualche further reading vedo che di solito le perdite come quella che descrivo sono utilizzati in validazione e nella formazione di un perdita surrogata che minimizza nello stesso luogo, come viene utilizzata la vera perdita. Qualcuno sa cosa viene usata la perdita surrogata per uno scenario basato sulla modifica di modifica come il mio?
in 'np_labels, np_logits, sequence_lengths, label_lengths, logit_lengths = sess.run ([labels_placeholder, logit, sequence_lengths_placeholder, label_lengths_placeholder, logit_lengths], feed_dict = feed_dict) ' Qual è il tuo 'feed_dict'? Non dovresti avere segnaposti nella lista dei prelievi per session.run. –
@TheMyth feed_dict memorizza effettivamente i valori segnaposto. Questa è sicuramente una ridondanza, ma penso di averlo fatto per rendere il codice più sintetico per SO. –