11

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?

+0

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. –

+0

@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. –

risposta

1

La prima cosa che farei è calcolare la perdita usando tensorflow invece di numpy. Ciò consentirà a tensorflow di calcolare gradienti per te, così potrai back-propagare, il che significa che puoi minimizzare la perdita.

È presente la funzione tf.edit_distance (https://www.tensorflow.org/api_docs/python/tf/edit_distance) nella libreria principale.

So naturally to fix that I would try and implement this in TensorFlow. The issue is, my logit_lengths and label_lengths are both Tensors, so when I try and access a single element, I'm returned a Tensor of shape []. This is an issue when I'm trying to use tf.nn.top_k() which takes an Int for its k parameter.

Potrebbe fornire alcuni dettagli in più perché si tratta di un problema?