Как лучше повысить macro f1 в задаче классификации изображения?

Ссылка скопирована
1 ответ

Сейчас ситуация такая: я решаю задачи классификации одного из 6 видов животных по его следу, датасет состоит из 3000 обучающих фото и 300 валидационных фото. Я использую ResNet 18 с предобученными весами, нормировка по ImageNet оптимизатор Adam, lr = 1e-3, batch = 32, 20 эпох, а также использую кросс энтропию. Проблема в том, что на обучении уже на 10 эпохе я получаю точность на обучении 97%, а на валидации у меня точность и macro f1 держатся на уровне 77% и не поднимаются особо выше.
Вот голова модели:

model_ft = models.resnet18(weights='IMAGENET1K_V1') num_ftrs = model_ft.fc.in_features model_ft.fc = nn.Sequential( nn.Linear(num_ftrs, 256), nn.ReLU(), nn.Linear(256, num_classes) )

Вот аугментации:

# train transforms.RandomResizedCrop(224, scale=(0.7, 1.0)), transforms.RandomHorizontalFlip(0.5), transforms.RandomRotation(15), transforms.ColorJitter(0.3, 0.3, 0.3, 0.1), transforms.RandomAffine(degrees=0, translate=(0.1, 0.1), scale=(0.9, 1.1)) # val transforms.Resize(256), transforms.CenterCrop(224)

Сейчас ситуация такая: я честно не особо понимаю что мне в данной ситуации делать, прошу каких-то советов!

Нужно решить такую задачу?

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

Заказать помощь
Лучший ответ
1
Анна SEO Ответ

По описанию модель быстро переобучается: train accuracy 97%, а validation macro F1 около 77%. Для 3000 фото и 6 классов это типичная ситуация, особенно если следы животных сняты в разных условиях, классы похожи, а валидация маленькая. Macro F1 обычно проседает не из-за общей точности, а из-за одного-двух слабых классов, поэтому сначала нужно смотреть не loss, а confusion matrix и F1 по каждому классу.

Первое, что я бы сделал: проверить split. Если в train и val попали разные серии снимков, разные камеры, разный фон или качество, модель может учить фон, а не след. Если есть несколько фото одного следа, их нельзя случайно раскидывать между train и val. Разделение лучше делать по группе: место съемки, животное, серия или источник.

Второе: снизить переобучение. Для ResNet18 часто помогает не усложнять голову, а сделать простую линейную голову, добавить weight decay и learning rate scheduler. Ваш Adam с lr=1e-3 может быть слишком агрессивным для fine-tuning всей сети.

optimizer = torch.optim.AdamW(model_ft.parameters(), lr=3e-4, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
 
model_ft.fc = nn.Linear(num_ftrs, num_classes)

optimizer = torch.optim.AdamW(model_ft.parameters(), lr=3e-4, weight_decay=1e-4) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20) model_ft.fc = nn.Linear(num_ftrs, num_classes)

Третье: усилить аугментации именно под следы. ColorJitter может быть полезен, но важнее имитировать реальную съемку: кроп, небольшой blur, изменение контраста, перспективы, шум. При этом слишком сильный RandomResizedCrop может вырезать важные части следа. Я бы попробовал scale=(0.85, 1.0), добавил RandomGrayscale/RandomAutocontrast и аккуратный GaussianBlur.

Четвертое: проверьте дисбаланс классов. Если один класс встречается реже, cross entropy без весов будет тянуть accuracy, но macro F1 останется низким. Можно использовать веса классов или WeightedRandomSampler. После каждой эпохи выводите classification_report, чтобы видеть, какой именно класс ломает macro F1.

Практический план: зафиксируйте корректный grouped split, обучите baseline с frozen backbone 5-7 эпох, затем разморозьте последние блоки и дообучайте на lr 1e-4 или 3e-5. Сравните не только accuracy, а macro F1, confusion matrix и ошибки глазами. Часто именно просмотр ошибок показывает, что модель путает не животных, а тип поверхности, освещение или масштаб следа.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно