2025, Sep 25 03:16
Поворот изображений строго на ±45° в torchvision (50/50)
Разберём, как в PyTorch/torchvision задать аугментацию с поворотом строго на ±45° (50/50): RandomChoice и фиксированный RandomRotation без промежуточных углов.
При аугментации изображений часто добавляют случайные повороты, чтобы повысить устойчивость моделей. Но иногда требуется строгий контроль: поворачивать только на +45 или −45 градусов с равной вероятностью — и ни на какие промежуточные углы. Обычный интервал углов такую задачу не решает.
Постановка задачи
Простейшая попытка в torchvision выглядит так, но она выдаёт любой угол из интервала, а не строго два заданных значения.
import torchvision.transforms as T
pipeline = T.Compose([
    T.RandomRotation((-45, 45))
])
Что происходит на самом деле
Если передать интервал в RandomRotation, трансформация на каждом вызове выбирает случайный угол между нижней и верхней границами. Иными словами, результат охватывает весь диапазон от -45 до 45 градусов, а не только -45 и +45.
Точное решение с выбором 50/50
Чтобы гарантировать только два угла с равной вероятностью, сначала делаем равновероятный выбор, затем применяем поворот на фиксированный угол. В torchvision это естественно реализуется через RandomChoice, а фиксированный угол задаётся кортежем, в котором нижняя и верхняя границы совпадают.
import torchvision.transforms as T
augment_ops = T.Compose([
    T.RandomChoice([
        T.RandomRotation((45, 45)),
        T.RandomRotation((-45, -45)),
    ], p=[0.5, 0.5])
])
Такой конвейер обеспечивает 50% вероятность поворота на +45 градусов и 50% — на −45 градусов, без промежуточных значений.
Почему это важно
Аугментация должна соответствовать требованиям задачи. Если конвейер допускает углы, которых вы не планировали, преобразованные примеры будут отклоняться от нужного распределения. Жёстко фиксируя набор допустимых поворотов, вы избегаете нежелательной вариативности и держите датасет в рамках заданных ограничений.
Вывод
Когда требуются повороты на фиксированные углы в torchvision, не передавайте диапазон, включающий лишние значения. Вместо этого явно выбирайте между двумя фиксированными поворотами в пропорции 50/50 через RandomChoice, причём у каждого трансформера нижняя и верхняя границы должны совпадать. Так аугментация остаётся точной и предсказуемой.
Статья основана на вопросе на StackOverflow от Lézard и ответе Ahmad Abdallah.