Вопрос или проблема
Я новичок на 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
. Это может происходить по нескольким причинам, и я постараюсь предложить вам несколько путей решения.
-
Проверка данных: Хотя вы проверили наличие
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))
-
Обработка переполнения границ: Нередко проблемы с обучением возникают из-за слишком большого или слишком малого значения learning rate. Убедитесь, что
initial_learning_rate
(в вашем случае5e-5
) не слишком велик. Попробуйте понизить его, например, до2e-5
. -
Инициализация модели: Вы получили предупреждение о том, что некоторые слои не были инициализированы из-за использования модели, ранее обученной на другой задаче. Убедитесь, что вы используете правильный класс модели. Например, убедитесь, что вы используете
TFDistilBertForSequenceClassification
, если ваша задача — классификация.from transformers import TFAutoModelForSequenceClassification model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=3)
-
Данные входов: Убедитесь, что
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 )
-
Мониторинг обучения: Включите дополнительные метрики, чтобы легче понимать, как проходит обучение, возможно, через
TensorBoard
, что поможет вам выявить проблему более детально. -
Проверка функции потерь: Убедитесь, что функция потерь и метрики правильно настроены. Для многоклассовой классификации на основе целочисленных меток (
SparseCategoricalCrossentropy
) ваш настройка выглядит правильно, но стоит удостовериться, что у вас нет конфликтов по версии Transformers и TensorFlow.
Если все вышеперечисленные шаги не решат вашу проблему, попробуйте минимизировать свои данные до простого набора, чтобы отладить модель с одной или двумя наблюдениями. Это может помочь вам быстрее идентифицировать, где именно проблема.
Я надеюсь, что эти рекомендации помогут вам разобраться с проблемой. Если вам нужно больше подробностей или примеров кода, дайте знать!