Една конвенция за именуване, която ще промени всичко в твоя ML код
Суфикси за форми: най-простата промяна в кода ти за machine learning
Да си признаем — дебъгването на невронни мрежи е достатъчно трудно и без да се чудиш какво точно представлява поредната променлива с име outputs. Дали е с приоритет batch първо или последно? Има ли измерение за последователност? Някой ли я е преформатирал на някое място, което си пропуснал да провериш?
Има по-добър начин. И е учудващо прост.
Какво представляват shape суфиксите?
Това са малки букви, закачени към края на имената на променливите, които директно описват размерите на tensor-ите. Вместо outputs пишеш outputs_bc. Вместо activations пишеш activations_bcn.
На пръв поглед изглежда като допълнително писане. Повярвай ми — точно обратното е. Това е една от най-полезните конвенции, които можеш да въведеш в проект с machine learning.
Азбуката на измеренията
Ето стандартните означения:
- b — batch dimension
- p — позиция или индекс в последователността
- n — невронно измерение (обикновено резултат от умножение с тегловна матрица)
- c — брой канали
- h — височина (при изображения)
- w — ширина (при изображения)
- d — дълбочина (при 3D данни)
- k — размер на ядрото
Така logits_bc веднага подсказва, че става въпрос за batch от логити с канално измерение — точно каквото ти трябва за класификация. positional_embeddings_bpn пък означава, че имаш три измерения: batch, позиция и неврони, в този ред.
Защо си струва усилието
Моментална яснота. Когато видиш probs_bc, веднага разбираш, че гледаш вероятности, организирани по batch и клас. Без гадаене, без търсене на документация.
Вградена проверка за грешки. Тук нещата стават наистина мощни. Ако напишеш outputs_bc = torch.matmul(activations_bcn, weights_bcn), несъответствието изскача веднага. Тегловната матрица трябва да е weights_nc, за да се умножи правилно с activations_bcn. Самите имена стават статичен type checker за формите на tensor-ите.
Документация, която не остарява. Коментарите в кода рядко се обновяват при рефакторинг. Но embeddings_bpn си остава точен, докато поддържаш конвенцията — защото името на променливата СИ е документацията.
По-лесни code reviews. Ревювърите могат да забележат несъответствия в измеренията още в pull request-ите, без да пускат код или да проследяват функции. Пести се време и се хващат бъгове по-рано.
Практически модели, които да усвоиш
При конкатенации и стекове: Когато комбинираш tensor-и, обнови суфикса според новата структура. Слагаш два features_bc tensor-а по ново измерение? Вече е features_bck или features_bkc — зависи коя ос си избрал.
При редукции: Сумираш върху позиционното измерение и inputs_bp става inputs_b. Взимаш argmax през каналите и logits_bc става logits_b. Суфиксът се свива, за да отрази реалността.
При сложни tensor-и: Можеш да комбинираш няколко букви: attention_bpp за attention scores между двойки позиции, или gradients_bpn за градиенти, организирани по batch, позиция и неврон.
Как да го направиш навик
Ключът е последователността. Избра ли конвенцията, прилагай я навсякъде — входове, изходи и всеки междинен tensor. Да, дори онази променлива, дето си я създал с едно изречение само за дебъг.
Бъдещият ти self ще ти благодари. колегите също.
Ако правиш ML приложения и искаш чист, поддържаем код, който скалира с екипа, тези малки конвенции се натрупват в огромни печалби на продуктивност. Същият принцип стои зад доброто именуване навсякъде в софтуерната разработка — направи кода да се чете като документация.
Дай му една седмица в следващия си проект. Мисля, че ще се чудиш как си писал код без това.