Перейти к содержимому

Обучение модели на данных разметки

Как свести метки нескольких разметчиков к обучающим целям, держать отложенную выборку test неизменной между раундами, записывать, что видела каждая модель, и оценить объём данных для первого запуска.

Чтобы обучить модель на данных разметки, сведите метки каждого объекта к одной цели или к распределению голосов разметчиков, распределяйте объекты по выборкам train, validation и test по правилу, которое остаётся неизменным между раундами, и сообщайте оценку на test всякий раз, когда контрольную точку выбирала выборка validation. Обучение моделей в Potato выполняет каждый из этих шагов на собственной разметке исследования и записывает, на каких объектах обучался каждый запуск.

Новое в v2.14.0

Данные разметки редко приходят в том виде, который читает тренер. В исследовании с перекрытием у каждого объекта несколько меток, и метки нередко расходятся. Исследование в процессе работы получает метки каждый день, и каждый раунд переобучения видит больше объектов, чем предыдущий. Тренеру нужна одна цель на объект и фиксированный набор объектов для оценки, а решения ниже дают и то и другое. Каждый раздел ниже называет настройку Potato, которая принимает это решение. О самой странице Training см. обзор обучения моделей и руководство, которое обучает первую модель. Чтобы обучать в собственном коде, материал Экспорт разметки для машинного обучения описывает форматы экспорта, и те же решения применимы к экспортированному файлу.

Сведение меток нескольких разметчиков к одной

Агрегация превращает метки, которые несколько разметчиков дали одному объекту, в единую метку, на которой обучается модель. Простейший метод — голосование большинством. Голосование большинством считает ответ каждого разметчика один раз и оставляет самый частый ответ. Dawid and Skene (1979) оценивают матрицу ошибок каждого разметчика методом EM (максимизация ожидания) и взвешивают каждый голос по оценённой надёжности разметчика. Небрежный разметчик тогда влияет на результат меньше, чем аккуратный. Материал Агрегация краудсорсинговых меток сравнивает эти два метода и модели, построенные на Dawid-Skene.

Запуск обучения в Potato сводит метки с помощью model_training.aggregation. Значение по умолчанию, consensus, запускает Dawid-Skene всякий раз, когда в проекте больше одного разметчика, и возвращается к голосованию большинством, если оценка не удалась. Другое значение, majority, запускает только голосование большинством. Оба метода считают весь ответ разметчика по схеме одним голосом. Поэтому два ответа multiselect считаются одним голосом, только если оба ответа отмечают один и тот же набор меток.

Параметр consensus запуска и экспорт консенсуса — разные возможности. Экспорт консенсуса даёт каждому разметчику один голос, сообщает число и долю для каждого ответа на каждом объекте и помечает каждый объект как retired или needs_review. Прочитайте экспорт перед обучением, если хотите увидеть объект за объектом, где разметчики разошлись. MACE оценивает компетентность каждого разметчика по тем же голосам.

Обучение на расхождениях

В субъективных задачах, таких как оскорбительность или эмоции, разметчики могут расходиться, потому что каждый читает объект по-своему, а единая метка по голосованию это расхождение отбрасывает. Uma et al. (2021) рассматривают методы, которые обучаются на расхождении, а не на одной агрегированной метке. Одно семейство таких методов обучается на мягких метках. Мягкая метка — это распределение вероятностей по меткам, построенное по доле разметчиков, выбравших каждую метку.

hf-text-classification принимает параметр soft_targets: true. Когда параметр задан, объект, который разметили двое или больше разметчиков, обучается в сторону распределения голосов разметчиков по перекрёстной энтропии относительно этого распределения. Когда двое из трёх разметчиков сказали positive, цель — 0,67 positive и 0,33 negative. Для схемы multiselect каждая метка обучается в сторону доли разметчиков, которые её отметили. Объект с одним разметчиком обучается на метке этого разметчика, как раньше. Тогда модель остаётся неуверенной там, где люди расходились, и каждое предсказание включает probabilities модели. На отложенных объектах с распределением голосов запуск сообщает три дополнительные метрики:

МетрикаЧто измеряет метрика
soft_jsdДивергенция Йенсена — Шеннона между распределением модели и распределением голосов разметчиков, в битах от 0 до 1
soft_cross_entropyПерекрёстная энтропия распределения голосов разметчиков относительно распределения модели
eceОжидаемая ошибка калибровки верхней метки относительно метки по голосованию, по 10 интервалам уверенности

В схеме мягких меток каждый разметчик задаёт распределение ползунками. hf-text-classification всегда обучает схему soft_label в сторону среднего распределения разметчиков, а предварительная метка выставляет ползунки в предсказанное распределение. Для мягких целей нужны две или больше меток на объект. Поэтому исследование, которое планирует обучаться на расхождениях, с самого начала собирает перекрывающиеся метки, а материал Сколько разметчиков вам нужно? описывает настройки перекрытия. Материал Расхождение — это сигнал, а не шум приводит доводы за то, чтобы сохранять распределение в данных.

Выборки train, validation и test

Обучающая, валидационная и тестовая выборки выполняют три разные задачи. Выборка train подгоняет веса модели. Выборка validation выбирает среди моделей-кандидатов, например эпоху, на которой остановиться. Выборка test оценивает качество на неизвестных данных и не участвует ни в одном из этих выборов. Выбор контрольной точки по validation — это форма подгонки под validation. У контрольной точки, сохранённой по лучшей оценке на validation, оценка на validation завышена, и только оценка на test получена на объектах, которых выбор не касался.

Запуск Potato по умолчанию делит размеченные объекты в пропорции 70/15/15 (splits). Выборка каждого объекта определяется хешем идентификатора объекта с начальным значением (split_seed). Поэтому объект, отложенный в одном запуске, остаётся отложенным и в следующем, пока split_seed и splits не меняются. Изменение любой из этих настроек может перенести отложенные объекты в обучение, и тогда каждая последующая оценка отчасти измеряет запоминание. Задайте обе настройки один раз, в начале исследования.

Тренеры дообучения, например hf-text-classification, сохраняют контрольную точку той эпохи, которая получила лучшую оценку на validation. Главная оценка такого запуска берётся с test. sklearn-text, setfit, rdkit-property, тренеры моделей решений и мосты к модели ничего не выбирают по validation, и запуск любого из этих тренеров берёт главную оценку с validation, когда в validation есть объекты. Всплывающая подсказка колонки Оценка на отложенных объектах в таблице Runs называет выборку и метрику, стоящие за каждым числом. Объект с меткой и без предсказания считается ошибкой. Тренер не может поднять оценку, пропуская трудные объекты, а <split>_coverage сообщает долю объектов, получивших предсказание.

Исправленные и закреплённые объекты

Два вида объектов попадают в выборку train каждого последующего запуска, какую бы выборку ни назначил хеш. Первый — объект, который проверяющий исправил при проверке модели, второй — объект, который кто-то закрепил кнопкой Train on these рядом со срезом на странице Catalog. Исправления приходят от объектов, на которых модель ошибалась сильнее всего, а в validation или test исправления оценивали бы модель на выборке её собственных ошибок. Запуск, перенёсший отложенные объекты в обучение, пишет в журнал предупреждение с числом объектов, и оценка этого запуска на отложенных объектах тогда непосредственно несравнима с оценкой более раннего запуска. Запуск, который обучается на исправленном объекте, отложенном более ранним запуском, тоже пишет предупреждение, потому что оценка на объектах validation или test более раннего запуска, или на датасете, сохранённом по этим объектам, тогда включает объекты, на которых обучалась новая модель. Правила приведены в разделе Исправления и закреплённые объекты всегда обучаются.

Запись того, на чём обучалась каждая модель

Чтобы сравнивать два запуска, нужно знать, на каких объектах каждый запуск обучался и оценивался. Каждый запуск Potato записывает пакет в <output_annotation_dir>/training/runs/<run_id>/bundle/ с файлами train.jsonl, val.jsonl, test.jsonl, labels.json и manifest.json. Манифест записывает начальное значение разбиения, метод агрегации, число объектов в каждой выборке, число объектов, принудительно отправленных в обучение, и дайджест SHA-256 файлов выборок. Ничто в пакете не ссылается на Potato, и скрипт вне Potato может читать пакет как самодостаточную копию сведённых меток и выборок.

База данных проекта project.sqlite ведёт журнал с одной строкой на запуск. Каждая строка записывает тренер, параметры, размеры выборок, начальное значение разбиения, метрики на отложенных объектах и дайджест пакета. Вторая таблица записывает, в какой выборке был каждый объект в каждом запуске. Обратная запись читает эту таблицу и никогда не ставит предварительную метку на объект, на котором обучался любой запуск, всё ещё остающийся в журнале (retain_runs по умолчанию хранит пять завершённых запусков). Модель уверена на объектах, на которых обучалась, по причинам, ничего не говорящим о новых данных.

Чтобы сравнивать более поздние модели на тех же самых объектах, раздел Keep this split as a dataset на странице запуска сохраняет объекты validation, test или train запуска как версию датасета вместе с согласованными человеческими метками. Сохранённая версия впоследствии не меняется. Каждая сохранённая версия содержит одну выборку и начинается с нуля, а не дополняет предыдущую версию. Объекты validation запуска 2, сохранённые поверх объектов запуска 1, иначе включали бы объекты, на которых обучался запуск 2. Оценка на сохранённой версии не может прочитать ответ модели, потому что сохранённые входные данные не содержат поля предварительной метки. Для сохранения нужно datasets.enabled: true. Когда модель или датасет покидает проект, материал Документирование датасетов и моделей описывает паспорта датасетов и карточки моделей.

Сколько данных нужно первой модели

Каждый тренер Potato отказывается обучаться, если в выборке train меньше min_instances объектов. Значения по умолчанию ниже — это числа, с которых запуск начинается:

Тренерmin_instances по умолчаниюПримечание
setfit8Создан для первых дней проекта, примерно от восьми объектов на метку
sklearn-text10Калибрует уверенность только начиная с 50 обучающих объектов
hf-audio-tagger10
hf-text-classification, hf-token-classification, hf-image-classification20
llm-sft, llm-dpo20

Порог считает только выборку train. При разбиении 70/15/15 по умолчанию запуск sklearn-text начинается, когда метка есть примерно у 15 объектов. Учебный пример обучения моделей в репозитории Potato даёт одну измеренную точку. Когда у 120 из 160 синтетических отзывов на товары примера было по одной метке, один запуск sklearn-text дал 0,84 macro-F1 на validation и опубликовал 80 предварительных меток. Цифра получена на одной синтетической задаче с двумя метками, и для вашей задачи читать нужно оценку ваших собственных запусков на отложенных объектах.

Начните с sklearn-text. Тренеру не нужно ничего, кроме обычной установки, и не нужен GPU. Переобучайтесь по мере поступления меток и следите за оценкой на отложенных объектах от запуска к запуску при неизменном split_seed. Предварительные метки закрепляют ответы разметчиков. Оставляйте writeback.schemas пустым, пока оценка на отложенных объектах не оправдает показ ответов модели. Материал Разметка с помощью модели описывает, что меняется, когда разметчики видят предварительные метки, а материал Как отличить проверку от механического принятия описывает, как проверить, что разметчики по-прежнему читают объекты.

Конфигурация, задающая каждое решение

Конфигурация ниже обучает модель на схеме тональности с двумя метками. Каждый ключ в model_training задаёт одно из решений выше:

yaml
annotation_task_name: "Review sentiment"
task_dir: "."
data_files:
  - "data/reviews.json"
item_properties:
  id_key: "id"
  text_key: "text"
output_annotation_dir: "annotation_output"
 
annotation_schemes:
  - annotation_type: "radio"
    name: "sentiment"
    description: "Is this review positive or negative?"
    labels: ["positive", "negative"]
 
model_training:
  enabled: true
  aggregation: consensus
  split_seed: 0
  splits: {train: 0.7, val: 0.15, test: 0.15}
  trainer_params:
    hf-text-classification:
      soft_targets: true

aggregation: consensus сводит перекрывающиеся метки с помощью Dawid-Skene. split_seed и splits выписаны со значениями по умолчанию, потому что ни одна из настроек не должна меняться на протяжении всего исследования. soft_targets: true заставляет каждый запуск hf-text-classification в проекте обучаться на распределениях голосов. Этому тренеру нужен pip install "potato-annotation[train-text]", а sklearn-text работает на той же конфигурации без дополнительной установки. Без блока writeback разметчики не видят предварительных меток. Перезапустите сервер с этой конфигурацией, откройте /admin/training, выберите тренер и схему sentiment и нажмите Train now. Справочник по конфигурации обучения моделей перечисляет каждый ключ, а руководство по модели в цикле добавляет обратную запись и автоматическое переобучение.

Дополнительные материалы

Источники

  • Dawid, A. P., and Skene, A. M. (1979). Maximum Likelihood Estimation of Observer Error-Rates Using the EM Algorithm. Applied Statistics, 28(1), 20. doi.org/10.2307/2346806
  • Uma, A. N., Fornaciari, T., Hovy, D., Paun, S., Plank, B., and Poesio, M. (2021). Learning from Disagreement: A Survey. Journal of Artificial Intelligence Research, 72, 1385–1470. doi.org/10.1613/jair.1.12752