Проблема пустого датасета: когда данных катастрофически мало

Представьте: вы строите классификатор для редкого медицинского диагноза. Реальных случаев — сотни, а не миллионы. Или запускаете NLP-систему для узкоспециализированной юридической тематики, где размеченных примеров практически нет. Что делать, когда собрать достаточно данных невозможно физически, финансово или этически?

Этот вопрос исследует Лилиан Венг (Lilian Weng, OpenAI) в своей серии статей «Learning with not Enough Data». Третья часть серии посвящена генерации синтетических данных — одному из самых мощных и быстро развивающихся инструментов современного ML. Рассматриваются два принципиальных подхода к генерации синтетических данных для обучения.

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


Подход 1: Аугментация существующих данных

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

Аугментация — это не «обман» модели. Это расширение пространства обучающих примеров так, чтобы модель научилась инвариантности к незначимым изменениям.

Аугментация изображений

Для компьютерного зрения арсенал трансформаций хорошо отработан:

МетодЧто делаетКогда применять
Горизонтальный флипЗеркальное отражениеОбъекты симметричны
Случайный кропВырезает фрагментКогда важна локализация
Color JitterМеняет яркость/насыщенностьИнвариантность к освещению
Cutout / RandomErasingСлучайно закрывает областиУстойчивость к окклюзиям
MixupСмешивает два изображенияРегуляризация
AutoAugmentПодбирает аугментации автоматическиКогда есть вычислительный ресурс
💡 Совет по AutoAugment
AutoAugment (Zhang et al., ICLR 2020) обучается выбирать оптимальные политики аугментации через reinforcement learning. Adversarial AutoAugment генерирует «сложные» примеры, на которых целевая сеть ошибается — это заставляет её учиться активнее.

Аугментация текста

С текстом сложнее: неловкая замена слова может изменить смысл. Популярные методы:

  • EDA (Easy Data Augmentation) — синонимическая замена, случайная вставка/удаление/перестановка слов.
  • Back-translation — перевод на другой язык и обратно: «Кошка сидит на коврике» → (EN) «The cat sits on the mat» → (RU) «Кошка сидит на циновке».
  • Conditional generation — дообучение GPT-2/BERT на малом корпусе с условием на метку класса.

Метод LAMBADA предполагает файн-тюнинг генератора языка под конкретную задачу через начальное обучение на существующих (обычно небольших) размеченных данных; затем с помощью настроенной модели и заданной метки класса генерируются новые предложения, которые фильтруются классификатором, обученным на исходных данных.

# Пример простой аугментации текста через back-translation
from transformers import MarianMTModel, MarianTokenizer

def back_translate(text: str, src_lang="ru", pivot_lang="en") -> str:
    # Шаг 1: ru → en
    model_ru_en = MarianMTModel.from_pretrained(f"Helsinki-NLP/opus-mt-{src_lang}-{pivot_lang}")
    tokenizer_ru_en = MarianTokenizer.from_pretrained(f"Helsinki-NLP/opus-mt-{src_lang}-{pivot_lang}")
    tokens = tokenizer_ru_en([text], return_tensors="pt", padding=True)
    translated = model_ru_en.generate(**tokens)
    en_text = tokenizer_ru_en.decode(translated[0], skip_special_tokens=True)

    # Шаг 2: en → ru
    model_en_ru = MarianMTModel.from_pretrained(f"Helsinki-NLP/opus-mt-{pivot_lang}-{src_lang}")
    tokenizer_en_ru = MarianTokenizer.from_pretrained(f"Helsinki-NLP/opus-mt-{pivot_lang}-{src_lang}")
    tokens2 = tokenizer_en_ru([en_text], return_tensors="pt", padding=True)
    back = model_en_ru.generate(**tokens2)
    return tokenizer_en_ru.decode(back[0], skip_special_tokens=True)

print(back_translate("Клиент недоволен качеством сервиса."))
# → «Заказчик не доволен уровнем обслуживания.»
ℹ Когда аугментация не поможет
Аугментация работает с уже имеющимися примерами. Если у вас 5 размеченных примеров одного класса — аугментация даст вам 50, но все они будут вариациями одних и тех же 5. Для реального разнообразия нужен следующий подход.

Подход 2: Генерация новых данных с нуля

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

Это принципиально другой уровень: мы не трансформируем существующее, а создаём принципиально новое.

GPT-3 и Few-Shot генерация для NLP

GPT-3 продемонстрировал выдающиеся результаты в zero-shot и few-shot задачах через prompt-based in-context learning; при этом in-context learning использует промпт, обычно состоящий из описания задачи и нескольких примеров, для решения новых задач без дорогостоящего файн-тюнинга.

Практически это выглядит так: вы даёте модели 3–5 размеченных примеров в промпте, и она генерирует десятки новых примеров того же типа.

GPT-3 — одна из крупнейших языковых моделей (175 миллиардов параметров) — может быть настроен для различных задач NLP; её значимость в том, что масштабирование языковых моделей способно существенно улучшить few-shot производительность, иногда даже превосходя предыдущие подходы с полным файн-тюнингом.

📝 Пример промпта для генерации данных

Задача: классификация намерений пользователя (intent classification)

Класс: «бронирование столика»
Пример 1: «Хочу забронировать стол на двоих на пятницу вечером»
Пример 2: «Можно зарезервировать место в вашем ресторане на субботу?»
Пример 3: «Мне нужен столик для четырёх человек на 19:00»

Сгенерируй 10 похожих фраз:

Модель создаст разнообразные перефразировки, которые пополнят обучающий набор.

Zero-Shot генерация: когда данных нет вообще

Амбициознее всего — zero-shot сценарий. Используя GPT-3 для генерации меток в zero-shot классификации, можно значительно сократить время и усилия, необходимые для создания обучающего набора.

Подход «Towards Zero-Label Language Learning» (Wang et al., 2021) предлагает цикл:

  1. Описать задачу в виде инструкции для языковой модели.
  2. Попросить модель сгенерировать примеры для каждого класса.
  3. Отфильтровать низкокачественные примеры с помощью классификатора.
  4. Обучить финальную модель на синтетическом датасете.

Generative Adversarial Networks (GAN) для изображений

GAN — это класс фреймворков машинного обучения, специально предназначенных для генерации синтетических данных; они состоят из двух нейронных сетей — генератора и дискриминатора — работающих друг против друга: генератор создаёт синтетические примеры, а дискриминатор оценивает их подлинность, и со временем этот состязательный процесс улучшает качество синтетических данных.

Однако у GAN есть ограничения. В эпоху GAN генеративные изображения давали минимальные преимущества по сравнению с реальными; в частности, использование только изображений BigGAN приводило к увеличению ошибки классификации.

Картина изменилась с приходом диффузионных моделей. Диффузионные модели — это генеративные модели, которые создают изображения путём постепенного добавления и удаления шума; Latent Diffusion Models (LDM) работают в латентном пространстве автоэнкодера, а не в пространстве пикселей, что значительно снижает вычислительную сложность и повышает эффективность модели.


Пайплайн генерации синтетических данных


graph TD
    A[Исходный датасет\nмало примеров] --> B{Стратегия}
    B -->|Есть хоть немного данных| C[Аугментация]
    B -->|Мало или нет данных| D[Генерация через LLM/GAN]
    C --> C1[Трансформации изображений\nBack-translation, EDA]
    C1 --> E[Расширенный датасет]
    D --> D1[Few-shot промптинг GPT]
    D --> D2[Fine-tuned генератор\nLAMBADA]
    D --> D3[Диффузионные модели\nСтабильная диффузия]
    D1 --> F[Фильтрация качества]
    D2 --> F
    D3 --> F
    F --> E
    E --> G[Обучение целевой модели]
    G --> H{Качество достаточно?}
    H -->|Нет| B
    H -->|Да| I[Деплой]


Фильтрация и контроль качества синтетических данных

Генерация — это полдела. Сырые синтетические данные часто содержат шум, противоречия и артефакты. Критически важна фильтрация.

Методы отбора качественных примеров

Classifier-based filtering — обучаем простой классификатор на исходных данных и отбираем только те синтетические примеры, которые он уверенно классифицирует правильно. Этот подход используется в LAMBADA.

Perplexity filtering — отбрасываем тексты с аномально низкой или высокой перплексией по языковой модели: слишком простые примеры неинформативны, слишком «странные» — шум.

Diversity sampling — следим за тем, чтобы синтетические примеры не дублировали друг друга. Для этого используют embedding-расстояния и кластеризацию.

⚠ Ловушка синтетических данных
Синтетические данные не содержат реальной информации из мира, что позволяет защищать конфиденциальность и снижать затраты на разработку новых AI-моделей — однако их использование требует тщательной оценки, планирования и системы проверок, чтобы предотвратить потерю качества при деплое модели.

Сравнение подходов: что выбрать?

КритерийАугментацияLLM-генерация (few-shot)GAN / Диффузия
Нужны исходные данныеДа (хотя бы немного)Минимум (3–10 примеров)Желательно
Тип данныхЛюбойПреимущественно текстИзображения, таблицы
СтоимостьНизкаяСредняя (API-запросы)Высокая (GPU)
Разнообразие генерацииОграниченоВысокоеОчень высокое
Риск шумаНизкийСреднийВысокий
Zero-shot возможностьНетДаЧастично

«Синтетические данные — это не замена реальным. Это мост, который позволяет перейти к обучению до того, как реальных данных станет достаточно.»


Реальные применения: где это работает прямо сейчас

Google, Apple, Meta, OpenAI — все делают акцент на важности использования синтетических данных в разработке своих AI-моделей.

Синтетические данные — это искусственно сгенерированные алгоритмами данные, имитирующие статистические свойства реальных данных, не содержа при этом информации из реального мира; по некоторым оценкам, более 60% данных для AI-приложений в 2024 году было синтетическим, и эта доля продолжает расти.

Медицина: Применяются продвинутые техники генерации, такие как SMOTE и Adaptive Synthetic Sampling (ADASYN), для улучшения представления миноритарных классов путём генерации синтетических примеров; кроме того, используются стратегии аугментации на базе Deep Conditional TGAN с ResNet для повышения надёжности и обобщаемости модели.

Автономный транспорт: Полностью синтетические данные позволяют создавать сценарии вождения, редко встречающиеся в реальности, что способствует созданию более надёжных ML-моделей для навигации и безопасности.

NLP / чат-боты: Исследователи Apple разработали фреймворк генерации данных для задачи отслеживания состояния диалога (dialogue state tracking), обнаружив, что простая схема диалога и несколько шаблонов позволяют синтезировать полноценные обучающие данные.


Заключение: стратегия работы с малыми датасетами

Генерация синтетических данных — не волшебная таблетка, но мощный инструмент в арсенале ML-инженера. Подведём итоги:

  1. Начните с аугментации — если хоть что-то есть, это самый дешёвый и надёжный способ расширить датасет.
  2. Используйте LLM для генерации текста — GPT-класс моделей великолепно справляется с созданием разнообразных примеров при минимальном количестве затравочных данных.
  3. Для изображений смотрите на диффузионные модели — они значительно превзошли GAN по качеству и разнообразию генерации.
  4. Всегда фильтруйте синтетические данные — сырая генерация содержит шум; classifier-based и perplexity-фильтрация обязательны.
  5. Измеряйте реальное качество — синтетические данные нередко лучше реальных при обучении AI, а ML-алгоритмы показывают более высокое качество на дополненных, аугментированных и скорректированных по смещению данных, лучше улавливая паттерны без переобучения.

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