Как обучают матрице встраивания в этом фрагменте кода?

Я следую коду задания Coursera, которое реализует тег NER с помощью двунаправленного LSTM.

Но я не могу понять, как обновляется матрица встраивания. В следующем коде build_layers имеет переменную embedding_matrix_variable который действует на входе в LSTM. Однако это нигде не обновляется.

Можете ли вы помочь мне понять, как встраиваются?

def build_layers(self, vocabulary_size, embedding_dim, n_hidden_rnn, n_tags):
    initial_embedding_matrix = np.random.randn(vocabulary_size, embedding_dim) / np.sqrt(embedding_dim)
    embedding_matrix_variable = tf.Variable(initial_embedding_matrix, name='embedding_matrix', dtype=tf.float32)

    forward_cell =  tf.nn.rnn_cell.DropoutWrapper(
        tf.nn.rnn_cell.BasicLSTMCell(num_units=n_hidden_rnn, forget_bias=3.0),
        input_keep_prob=self.dropout_ph,
        output_keep_prob=self.dropout_ph,
        state_keep_prob=self.dropout_ph
    )

    backward_cell =  tf.nn.rnn_cell.DropoutWrapper(
        tf.nn.rnn_cell.BasicLSTMCell(num_units=n_hidden_rnn, forget_bias=3.0),
        input_keep_prob=self.dropout_ph,
        output_keep_prob=self.dropout_ph,
        state_keep_prob=self.dropout_ph
    )

    embeddings = tf.nn.embedding_lookup(embedding_matrix_variable, self.input_batch)

    (rnn_output_fw, rnn_output_bw), _ =  tf.nn.bidirectional_dynamic_rnn(
        cell_fw=forward_cell, cell_bw=backward_cell,
        dtype=tf.float32,
        inputs=embeddings,
        sequence_length=self.lengths
    )

    rnn_output = tf.concat([rnn_output_fw, rnn_output_bw], axis=2)
    self.logits = tf.layers.dense(rnn_output, n_tags, activation=None)


def compute_loss(self, n_tags, PAD_index):
    """Computes masked cross-entopy loss with logits."""
    ground_truth_tags_one_hot = tf.one_hot(self.ground_truth_tags, n_tags)
    loss_tensor = tf.nn.softmax_cross_entropy_with_logits(labels=ground_truth_tags_one_hot, logits=self.logits)

    mask = tf.cast(tf.not_equal(self.input_batch, PAD_index), tf.float32)
    self.loss = tf.reduce_mean(tf.reduce_sum(tf.multiply(loss_tensor, mask), axis=-1) / tf.reduce_sum(mask, axis=-1))

1 ответ

В TensorFlow переменные обычно не обновляются напрямую (т. Е. Путем ручного задания им определенного значения), а обучаются с использованием алгоритма оптимизации и автоматического дифференцирования.

Когда вы определяете переменную tf.Variable, вы добавляете узел (который поддерживает состояние) к графу вычислений. Во время обучения, если узел потерь зависит от состояния переменной, которую вы определили, TensorFlow вычислит градиент функции потерь по отношению к этой переменной, автоматически следуя правилу цепочки через вычислительный граф. Затем алгоритм оптимизации будет использовать вычисленные градиенты для обновления значений обучаемых переменных, которые принимали участие в вычислении потерь.

Конкретно, код, который вы предоставляете, создает граф TensorFlow, в котором потеря self.loss зависит от веса в embedding_matrix_variable (т.е. есть путь между этими узлами на графике), поэтому TensorFlow вычислит градиент относительно этой переменной, а оптимизатор обновит его значения при минимизации потерь. Возможно, было бы полезно проверить график TensorFlow с помощью TensorBoard.

Другие вопросы по тегам