BERT, XLNet, RoBERTa и т. Д. Для классификации по нескольким меткам - пошаговое руководство
Как специалист по данным, изучавший современные технологии классификации текстов, я обнаружил, что существует не так много простых примеров для адаптации преобразователей (BERT, XLNet и т. Д.) Для многоуровневой классификации… поэтому я решил попробовать на себе и вот оно!
Как дань уважения другим сообщениям блога о классификации текста с несколькими ярлыками, я буду использовать набор данных Toxic Comment Classification Challenge.
К этой публикации прилагается интерактивный Блокнот Google Colab, так что вы можете попробовать это сами. Все, что вам нужно сделать, это загрузить файлы train.csv, test.csv и test_labels.csv в экземпляр. Давайте начнем.
В этом уроке я буду использовать библиотеку трансформаторов Hugging Face вместе с PyTorch (с GPU), хотя это можно легко адаптировать к TensorFlow - я могу написать отдельное руководство для этого позже, если это набирает обороты вместе с учебными пособиями по мультиклассовой классификации. Ниже я буду обучать модель BERT, но я покажу вам, насколько легко можно адаптировать этот код для других моделей трансформаторов по пути.
Импортировать библиотеки
Загрузка и предварительная обработка данных обучения
Токсичный набор данных уже очищен и разделен на обучающие и тестовые наборы, поэтому мы можем загрузить обучающий набор и использовать его напрямую.
Каждая модель преобразователя требует разных кодировок токенизации - это означает, что способ токенизации предложения и использования масок внимания может отличаться в зависимости от модели преобразователя, которую вы используете. К счастью, библиотека трансформаторов HuggingFace позволяет очень легко реализовать каждую модель. В приведенном ниже коде мы загружаем предварительно обученный токенизатор BERT и используем метод batch_encode_plus для получения токенов, типов токенов и масок внимания. Не стесняйтесь загружать токенизатор, который подходит для модели, которую вы хотите использовать для прогнозирования. например.,
BERT: tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', do_lower_case=True)
XLNet: tokenizer = XLNetTokenizer.from_pretrained('xlnet-base-cased', do_lower_case=False)
RoBERTa: tokenizer = RobertaTokenizer.from_pretrained('roberta-base', do_lower_case=False)
Затем мы будем использовать 10% наших обучающих входных данных в качестве набора для проверки, чтобы мы могли отслеживать производительность нашего классификатора во время обучения. Здесь мы хотим убедиться, что мы используем параметр «стратифицировать», чтобы в проверочном наборе не появлялись невидимые метки. Для соответствующей стратификации мы возьмем все метки, которые появляются в наборе данных только один раз, и включим их в обучающий набор. Нам также потребуется создать загрузчики данных PyTorch для загрузки данных для обучения / прогнозирования.
Загрузить модель и установить параметры
Загрузку соответствующей модели можно выполнить, как показано ниже, каждая модель уже содержит один плотный слой для классификации сверху.
BERT: model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=num_labels)
XLNet: model = XLNetForSequenceClassification.from_pretrained("xlnet-base-cased", num_labels=num_labels)
RoBERTa: model = RobertaForSequenceClassification.from_pretrained('roberta-base', num_labels=num_labels)
Параметры оптимизатора можно настроить несколькими способами. Здесь мы используем настраиваемые параметры оптимизации (с которыми я добился большего успеха), однако вы можете просто передать «model.parameters ()», как показано в комментариях.
Модель поезда
Библиотека HuggingFace настроена для мультиклассовой классификации "из коробки" с использованием «категориальной перекрестной энтропии» в качестве функции потерь. Следовательно, выход модели трансформатора будет сродни:
outputs = model(batch_input_ids, token_type_ids=None, attention_mask=batch_input_mask, labels=batch_labels) loss, logits = outputs[0], outputs[1]
Однако, если мы не будем передавать параметр меток, модель будет выводить только логиты, которые мы можем использовать для расчета собственных потерь для классификации по нескольким меткам.
outputs = model(batch_input_ids, token_type_ids=None, attention_mask=batch_input_mask, labels=batch_labels) logits = outputs[0]
Ниже приведен фрагмент кода, который делает именно это. Здесь мы используем «двоичную кросс-энтропию с логитами» в качестве функции потерь. С таким же успехом мы могли бы использовать стандартные «двоичную кросс-энтропию», «потерю Хэмминга» и т. Д.
Для проверки мы будем использовать точность микро F1, чтобы отслеживать эффективность обучения в разные эпохи. Для этого нам нужно будет использовать наши логиты из выходных данных нашей модели, передать их через сигмоидальную функцию (давая нам выходные данные между [0, 1] и порогом их (на 0,50) для генерации прогнозов. Эти прогнозы затем можно использовать для рассчитайте точность по истинным этикеткам.
Альт! Мы готовы к обучению, теперь запустим его ... время моего обучения варьировалось от 20 до 40 минут в эпоху в зависимости от максимальной длины токена и используемого графического процессора.
Прогноз и метрики
Прогноз для нашего тестового набора аналогичен нашему набору проверки. Здесь мы будем загружать, предварительно обрабатывать и прогнозировать тестовые данные.
Выходной DataFrame
Создание фреймворка выходных данных, показывающего предложения и их классификацию.
Бонус - Оптимизация порога для точности Micro F1
Перебор пороговых значений для максимизации точности Micro F1.
Вот и все! Прокомментируйте, если у вас есть вопросы. Вот еще раз ссылка на Блокнот Google Colab, если вы ее пропустили. Если у вас есть личные вопросы, не стесняйтесь обращаться ко мне в LinkedIn или Twitter.
Использованная литература:
Https://electricenjin.com/blog/look-out-google-bert-is-here-to-shake-up-search-queries
Https://github.com/google-research/bert
Https://github.com/huggingface/transformers