Зачем приводить координату к float при делении?
Что проверяют
Знаете ли вы, как деление ведёт себя с целыми числами в вашем стеке, и видите ли, где это ломает расчёты: нормализация координат, центры рамок, доли и средние. Следом часто спрашивают, чем / отличается от // в Python и почему в NumPy проблема бывает не в делении, а в переполнении.
Как отвечать
Во многих языках деление двух целых даёт целое, дробная часть отбрасывается. В Go, Java и C++ 7 / 2 равно 3, поэтому пишут float64(x) / float64(w). В Go смешивать int и float64 в одном выражении нельзя вообще, приведение обязательно.
В Python 3 всё иначе, и это стоит сказать сразу:
/: всегда настоящее деление,7 / 2даёт3.5. Целочисленным оно было в Python 2;//: деление с округлением вниз, к минус бесконечности:-7 // 2равно-4, а в C и Go-7 / 2равно-3;- NumPy и pandas:
/над целочисленным массивом возвращаетfloat64; - PyTorch:
/над тензорамиint64тоже даёт float, аx /= 2на целочисленном тензоре падает с ошибкой приведения типа; - SQL: в PostgreSQL
count(*) / totalс целыми даёт целое, и доля превращается в ноль. Нужноcount(*)::numeric / total.
Где приведение действительно нужно в ML-коде. Первое: переполнение до деления. У изображений в uint8 выражение (img1 + img2) / 2 сначала сложит пиксели по модулю 256, и NumPy сделает это молча. Приводите к float32 до арифметики. Второе: нормализация координат рамок в диапазон от 0 до 1 для формата YOLO делается во float, а обратно в пиксели переводится явным round и int, потому что cv2.rectangle и срезы массивов принимают только целые. Третье: для географических координат float32 даёт точность порядка метра, для точных расчётов берите float64.
Где спотыкаются
Переносят правило из C на Python 3 и говорят, что 5 / 2 вернёт 2. Это устарело вместе с Python 2.
Считают центр рамки через // и накапливают смещение на пиксель при повторных преобразованиях.
Приводят к float уже после сложения или умножения, когда переполнение целого типа случилось.