Фон
В 2022 году, если вы не новичок в NLP (обработка естественного языка), вы должны были слышать о BERT (двунаправленные представления кодировщика из преобразований). Это недавняя языковая модель, предложенная Google в 2019 году. К 2020 году она очень успешно превзошла SOTA как для задач НЛП, так и для применения в полевых условиях.
Краткое содержание
Я расскажу, как обучить (тонко настроить) одну из моделей BERT, а именно модель DistilBERT, для выполнения анализа настроений в наборе данных отзывов клиентов Amazon Mobile Electronic. Цель состоит в том, чтобы продемонстрировать, как легко это сделать с помощью Google Colab и добиться достаточно хороших результатов.
Поскольку подсветка синтаксиса плохо работает на Medium, не стесняйтесь проверить исходный пост здесь, если хотите следовать коду.
Знания, которые будут рассмотрены в этом уроке
- Дистилляция знаний — я решил использовать дистиллированную версию BERT, потому что это модель меньшего размера. Это более доступно для таких любителей, как я, у которых нет мощной машины для работы над супербольшими моделями.
- Huggingface — я использую предварительно обученную модель от HuggingFace, которая предоставляет очень простой в использовании API в популярных фреймворках, таких как Tensorflow и PyTorch.
- Базовый обучающий API Keras с model.fit
- Набор данных Tensorflow — я использую набор данных amazon_us_reviews/Mobile_Electronics_v1_00, который является относительно небольшим набором данных, чтобы показать возможности переносного обучения.
- Сохранение модели — сериализация
Начните с установки/импорта библиотек
Сначала вы должны установить зависимость, если ее еще нет в вашей среде.
! pip install datasets transformers[sentencepiece]
Затем импортируйте библиотеку, необходимую для этого руководства.
import tensorflow as tf import tensorflow_datasets as tfds from tensorflow.keras.optimizers.schedules import PolynomialDecay from tensorflow.keras.optimizers import Adam import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from transformers import AutoTokenizer from transformers import TFAutoModelForSequenceClassification
Убедитесь, что графический процессор доступен в среде.
num_gpus_available = len(tf.config.experimental.list_physical_devices('GPU')) print("Num GPUs Available: ", num_gpus_available) assert num_gpus_available > 0
Подготовка данных
Затем мы загружаем данные из подмножества отзывов клиентов Amazon, представленных в каталоге наборов данных Tensorflow: https://www.tensorflow.org/datasets/catalog/amazon_us_reviews#amazon_us_reviewsmobile_electronics_v1_00.
ds = tfds.load('amazon_us_reviews/Mobile_Electronics_v1_00', split='train', shuffle_files=True) df = tfds.as_dataframe(ds.take(2000))
Готовим нужно подготовить данные для обучения
- Преобразуйте звезды всего в 2 класса (положительный и отрицательный)
- Преобразуйте текст обзора в utf-8, так как модель/токенизатор, который мы будем использовать, ожидает только utf-8.
- Извлеките столбец функций, который является столбцом обзора и метки, в виде массивов numpy.
df["label"] = df["data/star_rating"].apply(lambda score: 1 if score >= 3 else 0) df['review'] =df['data/review_body'].str.decode("utf-8") df = df[["review", "label", ]] # Get the underlying numpy arrays reviews = df['review'].values labels = df['label'].values
Разделите набор данных на обучающую и проверочную части.
train_reviews, val_reviews, train_labels, val_labels = train_test_split(reviews, labels, test_size=.3)
Токенизация
О токенизации нужно говорить отдельно, потому что мы используем токенизатор, связанный с используемой нами моделью distilbert-base-uncased.
checkpoint = "distilbert-base-uncased" #Assign tokenizer object to the tokenizer class tokenizer = AutoTokenizer.from_pretrained(checkpoint)
Попробуйте токенизатор на одном примере.
tokenizer([ 'This is a nice phone.', 'It sucks'], truncation=True, padding=True, max_length=128)
Мы видим, что выходные данные содержат «input_ids» и «attention_mask», которые необходимы для модели BERT.
{ 'input_ids': [[101, 2023, 2003, 1037, 3835, 3042, 1012, 102], [101, 2009, 19237, 102, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 0, 0]] }
Затем мы токенизируем как поезд, так и валидацию.
def tokenize_dataset(reviews): encoded = tokenizer( reviews, padding=True, truncation=True, return_tensors='np', ) return encoded.data # Need to convert to List[str] because the tokenizer expects List but not np.array tokenized_datasets = { "train": tokenize_dataset(train_reviews.tolist()), "validation": tokenize_dataset(val_reviews.tolist()), }
Построение модели
Настройте оптимизатор с некоторыми гиперпараметрами. Я сделал несколько проб и ошибок, чтобы придумать их, так что они ни в коем случае не являются оптимизированными параметрами.
- Используйте оптимизатор Адама
- Используйте график скорости обучения с линейным затуханием
- Размер пакета составляет 8 с ограничением GPU в Colab.
batch_size = 8 num_epochs = 5 num_train_steps = (len(train_reviews) // batch_size) * num_epochs # We let the declay goes from 1e-5 to 0 over course of training. # Feel free to tweak these parameters lr_scheduler = PolynomialDecay( initial_learning_rate=1e-5, end_learning_rate=0., decay_steps=num_train_steps ) # The optimizer is Adam with the learning rate schedule as specified opt = Adam(learning_rate=lr_scheduler)
Создайте и скомпилируйте модель
# Use the pretrained model from the same checkpoint as the tokenizer # The num_label is 2 because we have a binary classification problem (Positive # and negative) model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2) # The model return logit (not probability), so we need to make sure to use the # matching loss function to calculate the Cross Entropy from logits. loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) # Compile the model and monitor the accuracy model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])
Обучение
Теперь собираем все вместе с обучением
history = model.fit( tokenized_datasets['train'], train_labels, validation_data=(tokenized_datasets['validation'], val_labels), batch_size=batch_size, epochs=num_epochs )
Далее постройте метрики
import matplotlib.pyplot as plt # summarize history for accuracy for m in ('accuracy', 'loss'): plt.plot(history.history[m]) plt.plot(history.history['val_'+m]) plt.title('model '+m) plt.ylabel(m) plt.xlabel('epoch') plt.legend(['Train', 'Validation'], loc='upper left') plt.show()
Мы видим, что точность проверки уже выше 90% после первой эпохи. Точность обучения продолжает приближаться к 100%, но она уже переобучения.
Сохранение модели
Мы также можем сохранить модель в локальном каталоге (вы можете изменить его на монтирование в каталог Google Диска).
model.save_pretrained("./saved_model") # load the model back again loaded_model = TFAutoModelForSequenceClassification.from_pretrained("./saved_model")
Вывод
Протестируйте необработанные строки обзора, чтобы увидеть, может ли модель правильно предсказать тональность.
test_reviews = [ "This is a great phone", "The item is dead on arrival", "Had to return it because the charging cable was broken" "I am not sure if I like this Iphone", "I think it's an okay product, but I might not buy again", ] # it's important to use the same tokenize function to feed to the model tokenized_inputs = tokenize_dataset(test_reviews)
Давайте вызовем model.predict
tf_output = model.predict(tokenized_inputs) tf_prediction = tf.nn.softmax(tf_output.logits, axis=1) labels = ['Negative','Positive'] label = tf.argmax(tf_prediction, axis=1) for i in range(len(test_reviews)): print("Sentense [{}]: {}".format(i, test_reviews[i])) print("Probabilities:", tf_prediction[i]) print("Predition:", labels[label[i]]) print()
Выведите получившиеся предсказанные вероятности класса и результат:
Sentense [0]: This is a great phone Probabilities: tf.Tensor([0.22118647 0.7788135 ], shape=(2,), dtype=float32) Predition: Positive Sentense [1]: The item is dead on arrival Probabilities: tf.Tensor([0.31097457 0.68902546], shape=(2,), dtype=float32) Predition: Positive Sentense [2]: Had to return it because the charging cable was brokenI am not sure if I like this Iphone Probabilities: tf.Tensor([0.25614288 0.7438571 ], shape=(2,), dtype=float32) Predition: Positive Sentense [3]: I think it's an okay product, but I might not buy again Probabilities: tf.Tensor([0.26244852 0.73755145], shape=(2,), dtype=float32) Predition: Positive
Краткое содержание
Это все об этом уроке. Это предварительный пример того, как точно настроить предварительно обученную модель Hugging Face и использовать ее для классификации настроений. Есть еще несколько вещей, которые я хочу попробовать дальше
- Я только сделал некоторую специальную настройку гиперпараметров методом проб и ошибок, но я хотел бы увидеть максимальную производительность, которую можно выжать из всех данных. Одна из идей состоит в том, чтобы исследовать влияние размера тренировки на производительность.
- Является ли этикетка правильной или приемлемой? Я читал некоторые обзоры, в которых я чувствовал, что текст отзыва звучит положительно, но помеченное настроение было отрицательным. Необходимо провести дополнительный анализ ошибок.
- Поэкспериментируйте с другой предварительно обученной моделью, отличной от DistillBERT.
Первоначально опубликовано на https://datajello.com 29 июня 2022 г.