HuggingFace Transformers выдает потерю: nan – точность: 0.0000e+00

Вопрос или проблема

Я новичок на HuggingFace и подгоняю модель BERT (distilbert-base-cased) с использованием библиотеки Transformers, но значение функции потерь не снижается, вместо этого я получаю loss: nan - accuracy: 0.0000e+00.

Мой код в основном соответствует шаблону на [курсе HuggingFace][1]:-

model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=3)

opt = Adam(learning_rate=lr_scheduler)

model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])

model.fit(
    encoded_train.data,
    np.array(y_train),
    validation_data=(encoded_val.data, np.array(y_val)),
    batch_size=8,
    epochs=3
)

Где моя функция потерь следующая:-

loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

Скорость обучения рассчитывается так:-

lr_scheduler = PolynomialDecay(
    initial_learning_rate=5e-5,
    end_learning_rate=0.,
    decay_steps=num_train_steps
    )

Количество шагов обучения вычисляется следующим образом:-

batch_size = 8
num_epochs = 3

num_train_steps = (len(encoded_train['input_ids']) // batch_size) * num_epochs

Пока что все очень похоже на шаблонный код.

Мои данные выглядят так:-

{'input_ids': <tf.Tensor: shape=(1040, 512), dtype=int32, numpy=
array([[  101,   155,  1942, ...,     0,     0,     0],
       [  101, 27900,  7641, ...,     0,     0,     0],
       [  101,   155,  1942, ...,     0,     0,     0],
       ...,
       [  101,   109,  7414, ...,     0,     0,     0],
       [  101,  2809,  1141, ...,     0,     0,     0],
       [  101,  1448,  1111, ...,     0,     0,     0]], dtype=int32)>, 'attention_mask': <tf.Tensor: shape=(1040, 512), dtype=int32, numpy=
array([[1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0],
       ...,
       [1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0],
       [1, 1, 1, ..., 0, 0, 0]], dtype=int32)>}

И выглядят так:-

10     2
147    1
342    1
999    3
811    3
Name: sentiment, dtype: int64

Я изучил форумы и сделал самые очевидные проверки:-

Здесь я проверяю, есть ли NaN в данных:-

print("Есть ли NaN в y_train? ",np.isnan(np.array(y_train)).any())

print("Есть ли NaN в y_val? ",np.isnan(np.array(y_val)).any())

Что дает:-

Есть ли NaN в y_train?  False
Есть ли NaN в y_val?  False

Я также попробовал:-

print("Есть ли NaN в encoded_train['input_ids']? ",np.isnan(np.array(encoded_train['input_ids'])).any())
print("Есть ли NaN в 'encoded_train['attention_mask']'? ",np.isnan(np.array(encoded_train['attention_mask'])).any())

но получил только:-

Есть ли NaN в encoded_train['input_ids']?  False
Есть ли NaN в 'encoded_train['attention_mask']'?  False

Я не знаю, в каком направлении двигаться с этим кодом.

Полный трассировочный вывод ошибки выглядит так, вы можете увидеть точность и потери на каждой эпохе, и, очевидно, эта модель вообще не обучается:-

Некоторые слои из контрольной модели на distilbert-base-cased не были использованы при инициализации TFDistilBertForSequenceClassification: ['vocab_layer_norm', 'vocab_projector', 'activation_13', 'vocab_transform']
- Это ожидаемое поведение, если вы инициализируете TFDistilBertForSequenceClassification из контрольной точки модели, обученной на другой задаче или с другой архитектурой (например, инициализация модели BertForSequenceClassification из модели BertForPreTraining).
- Это НЕ ожидаемое поведение, если вы инициализируете TFDistilBertForSequenceClassification из контрольной точки модели, которая должна быть точно идентична (инициализация модели BertForSequenceClassification из модели BertForSequenceClassification).
Некоторые слои TFDistilBertForSequenceClassification не были инициализированы из контрольной модели на distilbert-base-cased и были инициализированы заново: ['pre_classifier', 'classifier', 'dropout_59']
Вам, возможно, стоит ОБУЧИТЬ эту модель на задаче ниже по потоку, чтобы иметь возможность использовать ее для предсказаний и вывода.
Эпоха 1/3
ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметры `output_attentions`, `output_hidden_states` и `use_cache` не могут быть обновлены при вызове модели. Их необходимо установить в True/False в объекте конфигурации (т.е.: `config=XConfig.from_pretrained('name', output_attentions=True)`).
ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметр `return_dict` не может быть установлен в графовом режиме и всегда будет установлен в `True`.
ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметры `output_attentions`, `output_hidden_states` и `use_cache` не могут быть обновлены при вызове модели. Их необходимо установить в True/False в объекте конфигурации (т.е.: `config=XConfig.from_pretrained('name', output_attentions=True)`).
ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметр `return_dict` не может быть установлен в графовом режиме и всегда будет установлен в `True`.
130/130 [==============================] - ETA: 0s - loss: nan - accuracy: 0.0019ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметры `output_attentions`, `output_hidden_states` и `use_cache` не могут быть обновлены при вызове модели. Их необходимо установить в True/False в объекте конфигурации (т.е.: `config=XConfig.from_pretrained('name', output_attentions=True)`).
ПРЕДУПРЕЖДЕНИЕ:tensorflow:Параметр `return_dict` не может быть установлен в графовом режиме и всегда будет установлен в `True`.
130/130 [==============================] - 63s 452ms/step - loss: nan - accuracy: 0.0019 - val_loss: nan - val_accuracy: 0.0000e+00
Эпоха 2/3
130/130 [==============================] - 57s 438ms/step - loss: nan - accuracy: 0.0000e+00 - val_loss: nan - val_accuracy: 0.0000e+00
Эпоха 3/3
130/130 [==============================] - 57s 441ms/step - loss: nan - accuracy: 0.0000e+00 - val_loss: nan - val_accuracy: 0.0000e+00
<tensorflow.python.keras.callbacks.History at 0x7f304f714fd0>

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

Это касается предупреждения, что у вас “Параметры output_attentions, output_hidden_states и use_cache не могут быть обновлены при вызове модели. Их необходимо установить в True/False в объекте конфигурации (т.е.: config=XConfig.from_pretrained('name', output_attentions=True)).”

Вы можете попробовать следующий код.

from transformers import BertConfig, BertModel
# Скачать модель и конфигурацию с huggingface.co и закэшировать.
model = BertModel.from_pretrained('bert-base-uncased')
# Модель была сохранена с использованием `save_pretrained('./test/saved_model/')` (пример для иллюстрации, не может быть выполнен).
model = BertModel.from_pretrained('./test/saved_model/')
# Обновить конфигурацию во время загрузки.
model = BertModel.from_pretrained('bert-base-uncased', output_attentions=True)
assert model.config.output_attentions == True

Ответ или решение

Проблема, с которой вы столкнулись, связана с тем, что во время выполнения обучения модель выдает loss: nan и accuracy: 0.0000e+00. Это может происходить по нескольким причинам, и я постараюсь предложить вам несколько путей решения.

  1. Проверка данных: Хотя вы проверили наличие NaN в ваших данных, стоит убедиться, что ваши метки не превышают количество классов, заданных в num_labels. Например, если у вас всего 3 класса (0, 1, 2), убедитесь, что метки (y_train и y_val) находятся в этих пределах. Убедитесь, что метки, например, 3 в y_train не присутствуют, если доступны только 3 класса.

    print("Unique labels in y_train: ", np.unique(y_train))
  2. Обработка переполнения границ: Нередко проблемы с обучением возникают из-за слишком большого или слишком малого значения learning rate. Убедитесь, что initial_learning_rate (в вашем случае 5e-5) не слишком велик. Попробуйте понизить его, например, до 2e-5.

  3. Инициализация модели: Вы получили предупреждение о том, что некоторые слои не были инициализированы из-за использования модели, ранее обученной на другой задаче. Убедитесь, что вы используете правильный класс модели. Например, убедитесь, что вы используете TFDistilBertForSequenceClassification, если ваша задача — классификация.

    from transformers import TFAutoModelForSequenceClassification
    
    model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=3)
  4. Данные входов: Убедитесь, что encoded_train.data и encoded_val.data содержат правильные формы (ширину и типы данных) для input_ids и attention_mask. Правильные входные данные должны быть tuples (input_ids, attention_mask).

    Попробуйте следующее:

    model.fit(
        [encoded_train['input_ids'], encoded_train['attention_mask']],
        np.array(y_train),
        validation_data=(
            [encoded_val['input_ids'], encoded_val['attention_mask']],
            np.array(y_val)
        ),
        batch_size=8,
        epochs=3
    )
  5. Мониторинг обучения: Включите дополнительные метрики, чтобы легче понимать, как проходит обучение, возможно, через TensorBoard, что поможет вам выявить проблему более детально.

  6. Проверка функции потерь: Убедитесь, что функция потерь и метрики правильно настроены. Для многоклассовой классификации на основе целочисленных меток (SparseCategoricalCrossentropy) ваш настройка выглядит правильно, но стоит удостовериться, что у вас нет конфликтов по версии Transformers и TensorFlow.

Если все вышеперечисленные шаги не решат вашу проблему, попробуйте минимизировать свои данные до простого набора, чтобы отладить модель с одной или двумя наблюдениями. Это может помочь вам быстрее идентифицировать, где именно проблема.

Я надеюсь, что эти рекомендации помогут вам разобраться с проблемой. Если вам нужно больше подробностей или примеров кода, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...