Tensorflow BERT для классификации токенов - исключите токены падов из точности при обучении и тестировании

Я делаю классификацию на основе токенов, используя предварительно обученную BERT-модель для tenorflow, чтобы автоматически отмечать причины и следствия в предложениях.

Для доступа к BERT я использую интерфейс TFBertForTokenClassification из huggingface: https://huggingface.co/transformers/model_doc/bert.html#tfbertfortokenclassification.

Все предложения, которые я использую для обучения, преобразуются в токены (в основном отображение слов в числа) в соответствии с BERT-токенизатором, а затем дополняются до определенной длины перед обучением, поэтому, когда одно предложение имеет только 50 токенов, а другое - только 30 первый заполняется 50 маркерами падов, а второй - 70 из них, чтобы получить универсальную длину предложения ввода 100.

Затем я обучаю свою модель предсказанию для каждого токена, к какой метке принадлежит этот токен; является ли это частью причины, следствия или ничего из них.

Однако во время обучения и оценки моя модель также делает прогнозы для PAD-токенов, и они также учитываются в точности модели. Поскольку PAD-токены очень легко предсказать для модели (они всегда имеют один и тот же токен, и все они имеют метку none, что означает, что они не относятся ни к причине, ни к следствию предложения), они действительно искажают точность моей модели.

Например, если у вас есть предложение, содержащее 30 слов - ›30 токенов, и вы дополняете все предложения до длины 100, тогда это предложение получит оценку 70%, даже если модель не предсказала правильно ни один из реальных токенов. Таким образом, я очень быстро получаю точность обучения и проверки 90 +%, хотя модель плохо работает на реальных токенах падов.

Я думал, что маска внимания предназначена для решения этой проблемы, но, похоже, это не так.

Наборы входных данных создаются следующим образом:

def example_to_features(input_ids,attention_masks,token_type_ids,label_ids):
  return {"input_ids": input_ids,
          "attention_mask": attention_masks},label_ids

train_ds = tf.data.Dataset.from_tensor_slices((input_ids_train,attention_masks_train,token_ids_train,label_ids_train)).map(example_to_features).shuffle(buffer_size=1000).batch(32)

Создание модели:

from transformers import TFBertForTokenClassification

num_epochs = 30

model = TFBertForTokenClassification.from_pretrained('bert-base-uncased', num_labels=3)

model.layers[-1].activation = tf.keras.activations.softmax

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-6)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')

model.compile(optimizer=optimizer, loss=loss, metrics=[metric])

model.summary()

А потом тренирую вот так:

history = model.fit(train_ds, epochs=num_epochs, validation_data=validate_ds)

Кто-нибудь сталкивался с этой проблемой до сих пор или знает, как исключить прогнозы на токенах падов из точности модели во время обучения и оценки?




Ответы (1)


Да это нормально.

Вывод BERT [batch_size, max_seq_len = 100, hidden_size] также будет включать значения или вложения для токенов [PAD]. Однако вы также предоставляете attention_masks модели BERT, чтобы она не принимала во внимание эти токены [PAD].

Точно так же вам необходимо МАСКИРОВАТЬ эти токены [PAD] перед передачей результатов BERT на последний полностью подключенный уровень, замаскировать их при вычислении потерь, а также для расчета таких показателей, как точность и отзыв.

person Anjani Dhrangadhariya    schedule 13.07.2020