Одно правило именования, которое полностью изменит ваш ML-код
Фишки в именах тензоров: маленькая привычка, которая изменит твою работу с ML-кодом
Будем честны — отладка нейросетевого кода и так непроста. А когда приходится разбираться с outputs, где непонятно: это batch-first или batch-last, есть ли там последовательность, и не пересобрал ли кто-то размерность где-то по дороге — хочется закрыть ноутбук и уйти в монастырь.
Есть способ проще. И он до смешного очевиден.
Что такое суффиксы размерностей?
Суффиксы размерностей — это строчные буквы, которые добавляются к именам тензорных переменных и описывают их структуру. Вместо outputs пишем outputs_bc. Вместо activations — activations_bcn.
Может показаться, что это лишняя работа. Поверьте — всё ровно наоборот. Это одна из тех привычек, которая окупается сторицей в любом ML-проекте.
Шпаргалка по буквам
Вот стандартный алфавит для измерений тензоров:
- b — batch, размер батча
- p — position, позиция в последовательности
- n — neuron, нейронное измерение (результат умножения на матрицу весов)
- c — channel, каналы
- h — height, высота (для картинок)
- w — width, ширина
- d — depth, глубина (для 3D-данных)
- k — kernel, ядро свёртки
Таким образом, logits_bc сразу говорит: перед нами батч логитов с каналами — классическая разметка для задач классификации. А positional_embeddings_bpn? Батч, позиция, нейроны — и ты уже видишь структуру, не залезая в документацию.
Почему это работает
Мгновенный контекст. Видишь probs_bc — и сразу понятно: вероятности, разбитые по батчу и классам. Никаких猜,你х, никаких поисков по коду.
Встроенная проверка ошибок. Вот где начинается магия. Написал outputs_bc = torch.matmul(activations_bcn, weights_bcn) — и несоответствие бросается в глаза. Дата-сайентист с ходу видит: весовая матрица должна быть weights_nc, чтобы корректно умножиться с activations_bcn. Имена переменных сами становятся статическим анализатором форм.
Документация, которая не устаревает. Комментарии имеют свойство умирать. Переписали функцию — комментарий остался старым. А embeddings_bpn всегда актуален, потому что имя переменной — это и есть документация.
Ускоренные code reviews. Ревьюер замечает mismatch в PR, не запуская код и не прокручивая десятки функций. Экономит время всем — и ловит баги раньше.
Паттерны на каждый день
Для конкатенаций и стеков. Склеил тензоры — обнови суффикс. За-stackал два features_bc по новому измерению? Получилось features_bck или features_bkc — смотри, какой оси добавил.
Для редукций. Просуммировал по позициям — inputs_bp превращается в inputs_b. Взял argmax по каналам — logits_bc становится logits_b. Суффикс сжимается вместе с тензором.
Для сложных структур. Комбинируй буквы как нужно: attention_bpp для attention scores по парам позиций или gradients_bpn для градиентов с разбивкой по батчу, позициям и нейронам.
Как приучить себя
Ключевое — консистентность. Выбрал convention — применяй везде. Входы, выходы, все промежуточные переменные. Даже ту, которую создал в одну строку для отладки и думаешь «всё равно удалю».
Будущий ты скажет спасибо. Команда — тоже.
Если ты строишь ML-приложения и хочешь чистый код, который масштабируется с командой — мелкие соглашения накапливаются в серьёзный выигрыш. Это тот же принцип, что и хорошие имена в любом программировании: код должен читаться как документация.
Дай этому неделю в следующем проекте. Готов поспорить — потом будешь думать, как ты жил без этого раньше.