Как создать и обучить классификатор в PyTorch
Что проверяют
Знаете ли вы стандартный цикл обучения и понимаете ли, зачем в нём каждая строка. Следом обычно спрашивают, почему в конце модели нет softmax и что изменится при дисбалансе классов.
Как отвечать
Пройдите по частям:
- данные: свой
Datasetс__len__и__getitem__либоTensorDataset, затемDataLoaderсbatch_sizeиshuffle=Trueтолько для train. Разбиение на train, validation и test, нормализация признаков по статистикам train; - модель: наследник
nn.Moduleс методомforwardилиnn.Sequential. Выход последнего слоя это логиты, по одному на класс; - функция потерь:
nn.CrossEntropyLossпринимает сырые логиты и метки классов типаlong, softmax внутри неё уже есть. Для бинарной задачи с одним выходом берутnn.BCEWithLogitsLoss; - оптимизатор:
torch.optim.AdamWкак разумный старт, по желанию планировщик скорости обучения; - цикл:
model.train(), затем на каждом батчеoptimizer.zero_grad(), прямой проход,loss.backward(),optimizer.step(); - валидация:
model.eval()иtorch.no_grad()илиtorch.inference_mode(), метрики после каждой эпохи, сохранение лучшегоstate_dictи ранняя остановка.
Модель и батчи переносятся на одно устройство через .to(device). Для ускорения на GPU есть смешанная точность через torch.autocast, в PyTorch 2 ещё и torch.compile. Метрику выбирайте под задачу: при дисбалансе accuracy обманывает, смотрите F1, ROC-AUC и матрицу ошибок, а в функцию потерь можно передать weight для редких классов.
Где спотыкаются
Ставят softmax перед CrossEntropyLoss. Softmax применяется дважды, градиенты слабеют, и модель учится хуже без всякой явной ошибки.
Забывают model.eval() на валидации и model.train() при возврате к обучению. Dropout и BatchNorm ведут себя в этих режимах по-разному, и метрики получаются искажёнными.
Оценивают модель на той же выборке, по которой подбирали гиперпараметры и эпоху остановки. Для честной оценки нужна отдельная тестовая часть, которую вы не трогали до самого конца.