Аугментация данных: методы борьбы с переобучением на примере кошек | AiManual
AiManual Logo Ai / Manual.
20 Янв 2026 Гайд

Аугментация данных для борьбы с переобучением: практические методы на примере классификации кошек

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

Почему ваша нейросеть запоминает, а не учится?

Вы собрали 500 фотографий кошек и 500 фотографий не-кошек. Обучили модель. На обучающей выборке точность 99%. Радостно запускаете на новых данных — и получаете 60%. Что пошло не так? Модель просто запомнила ваши 500 кошек, а не поняла концепцию «кошачести». Это переобучение в чистом виде, и главная причина — недостаток разнообразия в данных.

И вот здесь появляется аугментация. Не просто «увеличение датасета», а создание новых, правдоподобных вариаций из существующих данных. Цель — заставить модель обращать внимание на инвариантные признаки (форма ушей, усы, нос), а не на шум (фон, освещение, угол съемки).

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

Базовые методы: что можно делать с кошкой (без вреда для животного)

Начнем с простых пространственных преобразований. Они дешевы в вычислении и часто дают самый большой прирост.

1Поворот, отражение и сдвиг

Кошки не всегда стоят прямо. Поворот на случайный угол (например, ±30 градусов) учит модель, что ориентация — не главный признак. Горизонтальное отражение (flip) — мощнейший прием, особенно для симметричных объектов. Сдвиг (translation) имитирует неточное кадрирование.

Осторожно с поворотом на 90 или 180 градусов! Для задачи «кошка/не кошка» это, возможно, окей. Но если вы различаете, скажем, буквы «И» и «N», поворот уничтожит различия. Всегда думайте о семантике.

2Масштабирование и кроппинг

Кошка может быть близко или далеко. Случайный кроп (вырезка части изображения) заставляет модель искать признаки в разных частях кадра. Часто комбинируют с изменением масштаба. Важно: после кропа обычно приводят изображение к исходному размеру (например, 224x224), иначе не получится батч.

3Цветовые искажения

Яркость, контрастность, насыщенность, оттенок (Hue). Освещение в жизни меняется. Солнечный свет, лампочка, тень — у всех разная цветовая температура. Слегка меняя эти параметры, вы готовите модель к любым условиям. Ключевое слово — слегка. Не делайте из рыжей кошки зеленую.

# Пример слабых цветовых искажений в Albumentations (версия 1.4.x, актуальна на 20.01.2026)
import albumentations as A

transform = A.Compose([
    A.RandomBrightnessContrast(brightness_limit=0.1, contrast_limit=0.1, p=0.5),
    A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=20, val_shift_limit=10, p=0.5),
])

Продвинутые методы: когда базовых уже мало

Если ваш датасет очень маленький или объекты имеют сложную геометрию, подключайте тяжелую артиллерию.

CutMix и MixUp: Эти методы не просто смешивают изображения, они создают принципиально новые точки данных. CutMix вырезает прямоугольную область с одного изображения и вставляет на другое, соответствующим образом смешивая лейблы (например, 70% «кошка», 30% «собака»). Модель учится обращать внимание на части объектов, а не на целое. MixUp линейно интерполирует между двумя изображениями и их лейблами. Оба метода — отличный способ регуляризации, но требуют аккуратной настройки.

Стирание (Random Erasing, Cutout): Случайно закрашиваем прямоугольную область на изображении черным цветом или шумом. Зачем? Чтобы модель не зацикливалась на одном, самом ярком признаке (например, если все ваши кошки с красным ошейником). Вынуждает искать другие, дополнительные признаки.

Геометрические искажения (Grid Distortion, Elastic Transform): Имитируют нелинейные деформации, как будто объект сфотографирован через стекло или на гибкой поверхности. Для кошек — не самый частый сценарий, но для медицинских изображений (рентген) или снимков текстиля — бесценно.

💡
Задумывались о том, чтобы вообще не размечать данные? Методы Self-Supervised Learning позволяют получить хорошие эмбеддинги из горы немаркированных фотографий кошек, а потом дообучить на маленьком размеченном наборе. Это мощная альтернатива чистому увеличению данных.

Практика: собираем пайплайн аугментации на PyTorch

Теория — это хорошо, но код — лучше. Давайте соберем реалистичный пайплайн для классификации кошек с помощью torchvision.transforms и albumentations. Почему albumentations? Он быстрее, особенно для больших разрешений, и имеет более богатый набор преобразований.

import torch
from torch.utils.data import Dataset, DataLoader
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
import os

# Определяем аугментации для обучающей выборки
train_transform = A.Compose([
    A.RandomResizedCrop(height=224, width=224, scale=(0.8, 1.0)),
    A.HorizontalFlip(p=0.5),
    A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.05, rotate_limit=15, p=0.5),
    A.OneOf([
        A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2),
        A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=20, val_shift_limit=10),
    ], p=0.5),
    A.CoarseDropout(max_holes=8, max_height=16, max_width=16, fill_value=0, p=0.3), # аналог Cutout
    A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
    ToTensorV2(),
])

# Для валидации — только ресайз и нормализация. НИКАКИХ случайных преобразований!
val_transform = A.Compose([
    A.Resize(224, 224),
    A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
    ToTensorV2(),
])

class CatDataset(Dataset):
    def __init__(self, file_paths, labels, transform=None):
        self.file_paths = file_paths
        self.labels = labels
        self.transform = transform

    def __len__(self):
        return len(self.file_paths)

    def __getitem__(self, idx):
        img_path = self.file_paths[idx]
        label = self.labels[idx]
        # Читаем изображение в BGR (формат OpenCV)
        image = cv2.imread(img_path)
        # Конвертируем в RGB
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        if self.transform:
            augmented = self.transform(image=image)
            image = augmented['image']

        return image, label

# Создаем даталоадеры
train_dataset = CatDataset(train_files, train_labels, transform=train_transform)
val_dataset = CatDataset(val_files, val_labels, transform=val_transform)

train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)

Обратите внимание на ключевое различие: для обучения — богатый набор случайных аугментаций, для валидации — детерминированный пайплайн (только ресайз и нормализация). Если вы будете применять случайные аугментации к валидации, ваши метрики будут «прыгать» от эпохи к эпохе, и вы не сможете адекватно оценить прогресс модели.

Распространенные ошибки и как их избежать

ОшибкаПоследствиеРешение
Применение аугментаций к валидационной/тестовой выборкеНесопоставимые метрики, невозможно понять, улучшилась ли модельИспользуйте разные пайплайны для train и val/test
Слишком агрессивные преобразованияИзображение становится нереалистичным, модель учится на артефактахНачинайте с мягких параметров. Увеличивайте силу постепенно, если видите недообучение
Игнорирование доменной спецификиАугментации, противоречащие физике объекта (вертикальный flip для текста)Продумывайте, какие преобразования имеют смысл для ваших данных. Не используйте всё подряд
Аугментация «на лету» без кеширования на медленном хранилищеГПУ простаивает, обучение упирается в скорость чтения/аугментации данныхИспользуйте быстрые библиотеки (albumentations). Рассмотрите предварительную аугментацию и сохранение на SSD для маленьких датасетов

Самая коварная ошибка — утечка данных через аугментацию. Представьте, у вас есть 10 уникальных фото кошки Барсика. Вы делаете 100 аугментированных версий каждого. Потом случайно разбиваете данные на train/val так, что аугментированные версии одного исходного фото попадают и в train, и в val. Модель увидит почти идентичные изображения в обеих выборках и покажет завышенную валидационную точность. Разбивайте данные по исходным, уникальным идентификаторам до аугментации.

А если данных все равно мало?

Аугментация — не панацея. Если у вас 50 фотографий, даже создав из них 5000 вариантов, вы не охватите всё разнообразие мира. Здесь нужно думать стратегически:

  • Сбор большего количества данных — банально, но эффективно. Используйте открытые датасеты или скрапинг.
  • Использование предобученных моделей (Transfer Learning). Возьмите модель, обученную на ImageNet (где есть кошки!), и дообучите (fine-tune) на своих данных. Она уже знает базовые признаки вроде граней и текстур.
  • Генеративные модели (GANs, Diffusion Models). На 20.01.2026 модели типа Stable Diffusion 3 или DALL-E 3 способны генерировать фотореалистичные изображения кошек по текстовому описанию. Вы можете использовать их для расширения датасета. Но будьте осторожны: модель может научиться на артефактах генерации. Всегда смешивайте сгенерированные данные с реальными.

Помните про data poisoning? Если вы скачиваете данные из непроверенных источников или используете сгенерированные изображения без фильтрации, вы рискуете отравить свой датасет. Несколько вредоносных образцов с неверной разметкой могут существенно снизить качество модели.

Финальный совет: аугментация — это эксперимент

Не существует идеального набора аугментаций «для кошек». Для уличных кошек важны изменения освещения и погодных условий (добавьте имитацию дождя или снега?). Для породистых — возможно, более важны геометрические искажения, чтобы модель не зациклилась на «идеальном» профиле.

Создайте несколько конфигураций (легкая, средняя, агрессивная). Обучите модель с каждой. Смотрите не только на валидационную точность, но и на разницу между train и val loss. Если train loss намного ниже val loss — у вас все еще переобучение, можно усиливать аугментацию или добавлять другие методы регуляризации (Dropout, Weight Decay).

Аугментация превращает вашу модель из заучки, которая зубрит конкретные картинки, в сообразительного ученика, который понимает суть. И теперь, когда вы видите очередной мем про «кота в коробке», ваша нейросеть — если вы всё сделали правильно — уверенно скажет: «Да, это кошка». Даже если видна только половина.