Использование реализации Коннекционистской временной классификации (CTC) Tensorflow

Я пытаюсь использовать реализацию CTC Tensorflow в пакете contrib (tf.ВНО.КТК.ctc_loss) без успеха.

  • прежде всего, кто-нибудь знает, где я могу прочитать хороший пошаговый учебник? Документация Tensorflow очень плоха по этой теме.
  • должен ли я предоставлять ctc_loss метки с чередованием пустой метки или нет?
  • Я не смог бы перенастроить свою сеть, даже используя набор данных поезда длиной 1 более 200 эпохи. :(
  • как я могу рассчитать частоту ошибок метки с помощью tf.edit_distance?

вот мой код:

with graph.as_default():

  max_length = X_train.shape[1]
  frame_size = X_train.shape[2]
  max_target_length = y_train.shape[1]

  # Batch size x time steps x data width
  data = tf.placeholder(tf.float32, [None, max_length, frame_size])
  data_length = tf.placeholder(tf.int32, [None])

  #  Batch size x max_target_length
  target_dense = tf.placeholder(tf.int32, [None, max_target_length])
  target_length = tf.placeholder(tf.int32, [None])

  #  Generating sparse tensor representation of target
  target = ctc_label_dense_to_sparse(target_dense, target_length)

  # Applying LSTM, returning output for each timestep (y_rnn1, 
  # [batch_size, max_time, cell.output_size]) and the final state of shape
  # [batch_size, cell.state_size]
  y_rnn1, h_rnn1 = tf.nn.dynamic_rnn(
    tf.nn.rnn_cell.LSTMCell(num_hidden, state_is_tuple=True, num_proj=num_classes), #  num_proj=num_classes
    data,
    dtype=tf.float32,
    sequence_length=data_length,
  )

  #  For sequence labelling, we want a prediction for each timestamp. 
  #  However, we share the weights for the softmax layer across all timesteps. 
  #  How do we do that? By flattening the first two dimensions of the output tensor. 
  #  This way time steps look the same as examples in the batch to the weight matrix. 
  #  Afterwards, we reshape back to the desired shape


  # Reshaping
  logits = tf.transpose(y_rnn1, perm=(1, 0, 2))

  #  Get the loss by calculating ctc_loss
  #  Also calculates
  #  the gradient.  This class performs the softmax operation for you, so    inputs
  #  should be e.g. linear projections of outputs by an LSTM.
  loss = tf.reduce_mean(tf.contrib.ctc.ctc_loss(logits, target, data_length))

  #  Define our optimizer with learning rate
  optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(loss)

  #  Decoding using beam search
  decoded, log_probabilities = tf.contrib.ctc.ctc_beam_search_decoder(logits, data_length, beam_width=10, top_paths=1)

спасибо!

обновление (29.06.2016)

спасибо, @jihyeon-seo! Итак, у нас есть на входе RNN что-то вроде [num_batch, max_time_step, num_features]. Мы используем dynamic_rnn для выполнения рекуррентных вычислений, заданных на входе, выводя тензор формы [num_batch, max_time_step, num_hidden]. После этого, нам нужно сделать аффинные проекции в каждой tilmestep с весом обмена, так что мы должны приспособиться к [num_batch*max_time_step, num_hidden], умножить на вес матричной формы [num_hidden, num_classes], сумма уклоном отменить, изменить форму, перенести (так мы будем иметь [max_time_steps, num_batch, num_classes] для КТК потери входной сигнал), и этот результат будет ввод ctc_loss функции. Я все сделал правильно?

этот код:

    cell = tf.nn.rnn_cell.MultiRNNCell([cell] * num_layers, state_is_tuple=True)

    h_rnn1, self.last_state = tf.nn.dynamic_rnn(cell, self.input_data, self.sequence_length, dtype=tf.float32)

    #  Reshaping to share weights accross timesteps
    x_fc1 = tf.reshape(h_rnn1, [-1, num_hidden])

    self._logits = tf.matmul(x_fc1, self._W_fc1) + self._b_fc1

    #  Reshaping
    self._logits = tf.reshape(self._logits, [max_length, -1, num_classes])

    #  Calculating loss
    loss = tf.contrib.ctc.ctc_loss(self._logits, self._targets, self.sequence_length)

    self.cost = tf.reduce_mean(loss)

обновление (07/11/2016)

спасибо @Xiv. Вот код после исправления ошибки:

    cell = tf.nn.rnn_cell.MultiRNNCell([cell] * num_layers, state_is_tuple=True)

    h_rnn1, self.last_state = tf.nn.dynamic_rnn(cell, self.input_data, self.sequence_length, dtype=tf.float32)

    #  Reshaping to share weights accross timesteps
    x_fc1 = tf.reshape(h_rnn1, [-1, num_hidden])

    self._logits = tf.matmul(x_fc1, self._W_fc1) + self._b_fc1

    #  Reshaping
    self._logits = tf.reshape(self._logits, [-1, max_length, num_classes])
    self._logits = tf.transpose(self._logits, (1,0,2))

    #  Calculating loss
    loss = tf.contrib.ctc.ctc_loss(self._logits, self._targets, self.sequence_length)

    self.cost = tf.reduce_mean(loss)

обновление (07/25/16)

Я опубликовано на GitHub часть моего кода, работа с одним высказыванием. Не стесняйтесь использовать! :)

2 ответов


Я пытаюсь сделать то же самое. вот то, что вас может заинтересовать.

было очень трудно найти учебник для ctc, но это example(https://github.com/tensorflow/tensorflow/blob/679f95e9d8d538c3c02c0da45606bab22a71420e/tensorflow/python/kernel_tests/ctc_loss_op_test.py) был полезен.

и для пустой метки слой ctc предполагает, что пустой индекс - num_classes-1. поэтому вам нужно предоставить дополнительный класс для blank этикетка. (https://github.com/tensorflow/tensorflow/blob/d42facc3cc9611f0c9722c81551a7404a0bd3f6b/tensorflow/core/kernels/ctc_loss_op.cc, строка 146)

также Сеть ctc выполняет слой softmax. в вашем коде слой rnn подключен к слою потерь ctc. выход слоя rnn внутренне активирован, поэтому вам нужно добавить еще один скрытый слой (это может быть выходной слой) без функции активации, а затем добавить слой потерь ctc.


посмотреть здесь для примера с двунаправленными реализациями LSTM, CTC и edit distance, обучение модели распознавания фонем на корпусе TIMIT. Если вы тренируетесь на тренировочном наборе этого корпуса, вы сможете снизить частоту ошибок фонемы до 20-25% после 120 эпох или около того.