Часть 2 модели для генерации имен из описаний продуктов

Описание нашей проблемы

Как я упоминал в своем предыдущем посте, в течение нескольких недель я исследовал различные модели и альтернативы в Huggingface для обучения модели генерации текста. У нас есть краткий список продуктов с их описанием, и наша цель - получить название продукта. Наконец, чтобы углубить использование преобразователей Huggingface, я решил подойти к проблеме с другим подходом - моделью кодер-декодер. Возможно, это был не лучший вариант, но я хотел узнать что-то новое о Huggingface Transformers.

Во-первых, я должен признать, что, вероятно, проблема генерации текста обычно не решается с помощью такого рода решений, используя такие модели кодировщиков, как BERT или RoBERTa. Но в этой задаче мы не собираемся генерировать «произвольный текст», поэтому мы можем упростить нашу задачу. Мы ищем подмножество слов из описания продукта, чтобы составить название продукта, и наш полный словарь присутствует во входных данных. С этой точки зрения мы можем кодировать описание продукта в векторное представление и декодировать его в текстовое имя. Поэтому использование кодера-декодера представлено как вариант для оценки.

Наша проблема может быть представлена ​​как задача от последовательности к последовательности, где нам нужно найти отображение входной последовательности (описания продукта) в выходную последовательность (название продукта). В сообщении блога Huggingface «Использование контрольных точек предварительно обученной языковой модели для моделей кодировщик-декодер» вы можете найти подробное объяснение и эксперименты по построению многих моделей кодировщика-декодера с использованием модели преобразователей BERT или GTP2. Я очень рекомендую вам ее прочитать.

В предыдущем посте на Medium мы создали собственный токенизатор и обучили модель RoBERTa Создать токенизатор и обучить модель Huggingface RoBERTa с нуля. Теперь мы будем использовать эту обученную модель для построения модели кодировщика-декодера, и мы настроим эту новую модель в нашем наборе данных. Мы будем описывать только наиболее интересные участки кода, полный код вы можете найти в моем репозитории на Github.

Набор данных

Как мы упоминали в моем сообщении, наш набор данных содержит около 31000 наименований одежды от крупного розничного продавца, включая длинное описание продукта и короткое название продукта, нашу целевую переменную. Сначала мы выполняем исследовательский анализ данных и видим, что количество строк со значениями выбросов невелико. Это частный набор данных, поэтому мы не можем сделать его общедоступным.

Архитектура кодировщика-декодера

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

По аналогии с моделями кодировщика-декодера на основе RNN, модели кодировщика-декодера на основе преобразователя состоят из кодировщика и декодера, которые являются стеками блоков остаточного внимания. Ключевым нововведением моделей кодировщика-декодера на основе преобразователя является то, что такие блоки остаточного внимания могут обрабатывать входную последовательность переменной длины без отображения повторяющейся структуры. Отсутствие использования рекуррентной структуры позволяет кодерам-декодерам на основе трансформаторов иметь высокую степень распараллеливания,… [2] Модели кодеров-декодеров на основе трансформаторов »

Цель этой архитектуры - найти функцию отображения между входной последовательностью и ее целевой выходной последовательностью. В случае преобразователей кодер кодирует входную последовательность в последовательность скрытых состояний, затем декодер принимает целевую последовательность и закодированные скрытые состояния для моделирования или изучения функции сопоставления. Но кодировщик работает только на первом шаге, на следующих шагах декодер получает следующий целевой токен и повторно использует скрытые состояния от кодировщика, созданного на шаге 1. Подробное объяснение можно найти в упомянутом посте [2] « Transformers на базе моделей кодировщиков-декодеров ».

Имея в виду эту идею, мы можем рассматривать модель кодировщика-декодера как модель только для кодировщика, такую ​​как BERT, и модель только для декодера, например GPT-2, которые объединены для создания целевой последовательности. На данный момент у нас есть много предварительно обученных моделей, доступных в концентраторе моделей Huggingface, поэтому первым вариантом для оценки является использование этих предварительно обученных моделей для создания нашего кодировщика-декодера и его точной настройки для нашей конкретной задачи.

В сообщении Использование контрольных точек предварительно обученной языковой модели для моделей кодировщик-декодер [1] объясняется и оценивается множество комбинаций, но в целом вам необходимо подумать о том, как инициализировать модели:

  • Инициализируйте кодировщик и декодер только из предварительно обученного кодировщика.
  • Инициализировать кодировщик из контрольной точки только для кодировщика и декодер из только для декодера.
  • Инициализировать только кодировщик или только декодер из предварительно обученного кодировщика или модели только для декодера
  • Совместное использование весов кодировщика с декодером
  • какую модель преобразователя использовать в кодировщике и декодере, это может быть модель BERT, GPT-2 или RoBERTa.

В нашем эксперименте мы попробуем стратегию RoBERTaShared, в которой и кодировщик, и декодер основаны на RoBERTa и имеют одинаковые веса. Эта комбинация показала отличные результаты во многих задачах.

Создайте модель кодировщика-декодера из предварительно обученной модели RoBERTa.

Загрузите обученный токенизатор на нашем конкретном языке

Как мы упоминали ранее, мы обучили токенизатор и модель RoBERTa с нуля, используя технику моделирования маскированного языка, пытаясь сфокусировать нашу модель на нашей конкретной задаче. Теперь мы можем настроить наш кодер-декодер, используя эту предварительно обученную модель.

Позвольте мне показать вам, какие библиотеки мы будем импортировать для этого проекта.

Первым шагом является загрузка токенизатора, который нам нужно применить для генерации наших входных и целевых токенов и преобразования их в векторное представление текстовых данных.

Подготовьте и создайте набор данных

На следующем этапе нам нужно сгенерировать набор данных для обучения нашей модели. Используя загруженный токенизатор, мы токенизируем текстовые данные, применяем метод заполнения и усекаем входные и выходные последовательности. Помните, что мы можем определить максимальную длину для входных данных и другую длину для выходных. Наконец, мы определяем размер пакета, чтобы разделить набор данных на пакеты для обучения и оценки.

RoBERTa - это вариант модели BERT, поэтому ожидаемые входные данные аналогичны: input_ids и attention_mask. Но у RoBERTa нет параметра token_type_ids, такого как BERT, это не имеет смысла, потому что он не обучался предсказанию следующего предложения, поэтому вам не нужно указывать, какой токен принадлежит какому сегменту. Просто разделите сегменты маркером разделения tokenizer.sep_token (или </s>).

Создайте модель кодера-декодера RoBERTa

Мы строим нашу модель на основе предварительно обученной модели, которую мы строим в Части 1 этой серии, благодаря библиотекам и оболочкам Hugginface создать модель очень просто. Нам просто нужно вызвать метод from_encoder_decoder_pretrained из класса EncoderDecoderModel библиотеки трансформеров Hugginface. Мы устанавливаем предварительно обученную модель кодировщика и декодера, передавая папку, в которой мы сохранили нашу обученную модель RoBERTa, и указываем, что мы хотим «связать» веса обеих моделей, чтобы они разделяли свои веса.

После того, как модель построена, нам нужно указать набор параметров, таких как специальные токены, чтобы начать предложение или bos и конец предложения или eos.

Очень важные параметры, которые необходимо объявить, относятся к стратегии декодирования. Любой текстовый генератор должен определять, как следующий вывод или токен выбирается из всех доступных возможностей. Такая архитектура пытается смоделировать вероятность следующего токена с учетом последовательности предыдущих токенов. На этом этапе мы генерируем вероятности того, что токены будут следующими, и нам нужен метод для выбора одного из них.

Стратегии декодирования

Мы не собираемся анализировать все возможности, но мы хотим упомянуть некоторые альтернативы, которые предоставляет библиотека Huggingface.

Нашим первым и наиболее интуитивным приближением является поиск Greddy, при котором на каждом этапе мы берем слово с наибольшей вероятностью из нашего словаря. К сожалению, эта стратегия имеет тенденцию создавать шаблоны и повторяться в циклических зависимостях. Это может быть очень детерминированный метод, и это не то, чем должен быть текстовый генератор. И эта стратегия создает проблему: токен с высокой вероятностью «прячется за» токеном с низкой вероятностью, который предшествует ему в порядке предложения. И мы можем застрять в неоптимальном решении.

Другой подход, который пытается минимизировать эту проблему, - это Поиск луча, который поддерживает несколько возможных путей или последовательностей для приближенного решения. На основе этого луча результатов применяется жадный поиск, позволяющий детерминированно аппроксимировать наиболее вероятную последовательность слов. Это не очень творческая процедура, но она отлично подходит для задач перевода, перевод предложений между языками не требует большого творчества. Если мы хотим создать историю или диалог, нам нужно «изучить» альтернативы и уменьшить детерминизм.

Методы выборки - это способ ввести случайный выбор в наш процесс создания текста. Но с помощью случайной выборки мы не можем контролировать, как производится вывод, и «управляемая» выборка - лучший подход. «Простая, но очень мощная схема выборки, которая называется Top-K sampling. В выборке Top-K фильтруются K наиболее вероятных следующих слов, и масса вероятности перераспределяется только между этими K следующими словами », [3]». Это имеет эффект ограничения процесс генерации для выбора слов, которые сама модель сочла более разумными в контексте ».

На этапе обучения мы применяем стратегию поиска луча с использованием 10 лучей и наказываем повторяющиеся n-граммы и длинные выходные данные.

Обучение кодировщика-декодера

Компонент Trainer библиотеки Huggingface будет обучать нашу новую модель очень простым способом, с помощью всего лишь нескольких строк кода. Trainer API предоставляет все возможности, необходимые для обучения практически любой модели трансформатора, и нам совсем не нужно кодировать циклы обучения.

При обучении модели машинного обучения нам нужна метрика оценки, мы выбрали метрику Rouge Score, которая используется для оценки задачи перевода и реферирования. Мы фокусируемся на нашей проблеме как на обобщении, от описания продукта до названия. Эта метрика кажется правильным выбором, но могут быть и другие интересные альтернативы.

Библиотека наборов данных предоставляет нам эту метрику, поэтому мы загружаем ее и определяем compute_metrics метод, в котором мы вычисляем метрику для целевого текста, описания продукта и прогнозируемого текста.

Теперь пришло время установить аргументы обучения: batch_size, периоды обучения, сохранить модель и т. Д. А затем мы можем создать экземпляр Seq2SeqTrainer, подкласса объекта Trainer, о котором мы упоминали, выбрав модель для обучения. , аргументы обучения, вычисление метрик, поезд и наборы данных оценки.

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

Оцените модель на тестовом наборе данных

После обучения нашей модели мы можем использовать ее для генерации названий наших продуктов и проверки результатов нашего процесса тонкой настройки для нашей объективной задачи.

Мы загружаем тестовый набор данных без меток и удаляем строки, содержащие нулевые значения.

Затем мы загружаем Tokenizer и настроенную модель из сохраненной версии.

Чтобы улучшить результаты, мы определим два метода для генерации текста, используя стратегию декодирования поиска луча и случайную выборку, и мы применим оба из них и сравним результаты.

Теперь мы можем делать прогнозы для тестового набора данных, используя стратегию поиска луча и метод выборки Top-k.

И мы готовы визуализировать результаты, используя поиск луча или метод выборки в качестве стратегии декодирования.

Описание товара: платье свободного кроя с круглым вырезом, длинными рукавами, складками, деталями, застегивающимися на спину, открытием. высота модели 69,6 ″

Название с использованием BS: струящееся платье со складками. Название с использованием

Top-K Sampling: платье с принтом и складками.

Заключение

Вы видели, как можно построить кодер-декодер на основе преобразователей и настроить его для решения конкретной задачи. Это простой, но мощный инструмент, который можно использовать для настройки ваших решений машинного обучения. Это всего лишь пример, и, вероятно, его можно значительно улучшить. Надеюсь, вам это понравится, и вы получите удовольствие от некоторых исследований.

Код доступен в моем репозитории на GitHub, вот ссылка на записную книжку.

использованная литература

[1] Патрик фон Платен, Использование контрольных точек предварительно обученной языковой модели для моделей кодировщика-декодера, ноябрь 2.020 г., сообщение Huggingface.

[2] Патрик фон Платен, Модели кодировщиков-декодеров на основе трансформаторов, октябрь 2.020 г., сообщение Huggingface.

[3] Патрик фон Платен, Как сгенерировать текст: использование различных методов декодирования для генерации языка с помощью Transformers, мар 2.020, пост Huggingface.

Стратегии декодирования для генерации текста, Dic 2.020