our_knp/reports/2026-10-12/Отчёт_altai.md
2026-10-15 10:48:29 +03:00

8.9 KiB
Raw Permalink Blame History

Отчёт: модель altai на MNIST

Oct 12, 2026

Модель altai заметно лучше blifat: на полном MNIST без правок она даёт 73,3% верных ответов против 30,9%, а с порогом, подобранным на отдельной валидационной выборке, — 82,5%.

Что это

В примере mnist-learn две модели с одинаковой архитектурой: blifat (нейроны с вещественными параметрами) и altai (нейроны под чип «Алтай»). У altai все веса и пороги умножены на 1000, а перед проверкой сеть квантуется: веса и пороги сжимаются в целые числа в диапазоне ±255, как требует чип.

В прошлом отчёте выяснилось, что blifat теряет точность из-за порога, который застывает после обучения. Здесь проверено, есть ли та же проблема у altai.

Результаты

Все прогоны на одних и тех же 10 000 тестовых картинках, однопоточный CPU-бэкенд. Порог для altai выбран на валидационной выборке (обучающие картинки 50 000–59 999), тестовые картинки в подборе не участвовали.

Обучение blifat как есть altai как есть altai, act=40, без добавки к порогу
3 000 49,5% 76,2% 84,2%
30 000 42,0% 75,6% 84,1%
60 000 30,9% 73,3% 82,5%

Подробнее по altai (верно / ошибки / молчание):

Обучение Как есть С подобранным порогом Время прогона
3 000 7622 / 1545 / 833 8418 / 1521 / 61 1–3,5 мин
30 000 7563 / 787 / 1650 8409 / 1068 / 523 5,5–7 мин
60 000 7326 / 790 / 1884 8247 / 1235 / 518 14 мин
  • Почти весь выигрыш даёт ответ на картинки, на которые сеть раньше молчала: на полном MNIST молчаний стало 518 вместо 1884.
  • Для сравнения: blifat с подобранным порогом давал 75,5%, но тот порог подбирался прямо на тесте, так что оценка была оптимистичной.

Полный MNIST, altai с порогом act=40: результаты по цифрам

Цифра Верно Не отвечено Ложные срабатывания Precision Recall
0 825 63 92 0,900 0,929
1 1062 2 71 0,937 0,998
2 674 127 231 0,745 0,841
3 699 142 169 0,805 0,831
4 754 27 201 0,790 0,965
5 718 34 140 0,837 0,955
6 881 22 55 0,941 0,976
7 913 31 84 0,916 0,967
8 856 47 71 0,923 0,948
9 865 23 121 0,877 0,974
Итого 8247 (82,5%) 518 1235

Самые слабые цифры — 2 и 3 (их чаще всего путают), самые надёжные — 1 и 6.

Что выяснилось

  • Почему altai лучше. У blifat потенциал теряет треть за каждый шаг, и нейрон фактически видит только последние 2–3 шага картинки. У altai утечки нет (potential_leak = 0): нейрон суммирует все 10 шагов, то есть сравнивает с шаблоном всю картинку целиком.
  • Проблема с порогом та же. Порог входного нейрона — это основная часть плюс добавка, пропорциональная сумме положительных весов. Добавка растёт с длиной обучения (до квантования 1797 → 3008 → 3342 для 3k → 30k → 60k) и застывает на проверке. Поэтому и altai теряет точность при более длинном обучении.
  • Квантование почти ничего не стоит. После него веса становятся целыми от −6 до +2, и 37–60% из них нули. Но без квантования точность 76,8% против 76,2% (3 000 картинок). Вариант, где веса растягиваются на весь диапазон ±255, а порог масштабируется тем же множителем, дал 76,7%.
  • Потенциал переносится между картинками. Между картинками он не сбрасывается, и недобранный заряд переходит на следующую картинку. Сброс в офлайн-симуляции помогал только при высоком пороге; при подобранном пороге выигрыша нет, поэтому в сеть я его не добавлял.
  • Лучший порог не зависит от длины обучения. На валидации плато при act от 20 до 60 и для 3k, и для 30k; выбран act=40 для всех.
  • Altai воспроизводим. Повторные прогоны совпали до картинки (на 30k и 60k), коллапса весов, как у одного прогона blifat, не было.
  • Колонки из 20 нейронов и у altai работают как один нейрон: веса внутри колонки идентичны.

Как проверял

  1. Добавил в пример altai выгрузку весов и порогов входного слоя до и после квантования.
  2. Написал на numpy офлайн-симулятор нейрона AltAI по формулам бэкенда (без утечки, сброс в 0 при спайке, обнуление отрицательного потенциала, округление). Он совпадает с KNP до картинки: например, 8418 / 1521 / 61 и в KNP, и в симуляторе.
  3. На симуляторе перебрал пороги, утечку и сброс между картинками на валидационной выборке.
  4. Выбранный вариант подтвердил полными прогонами в KNP; все цифры в таблицах результатов — из KNP.

Что изменено

В examples/mnist-learn/models/altai/prepare_network_for_inference.cpp добавлены переменные окружения. Без них пример работает как раньше; изменение видно в git diff, его можно откатить.

Переменная Что делает
KNP_MNIST_THR заменяет порог входных нейронов на проверке (в единицах после квантования)
KNP_MNIST_ADD_THR_SCALE умножает добавку к порогу входных нейронов на проверке (0 — убрать)
KNP_MNIST_QUANT none — без квантования, weights — масштаб только по весам
KNP_MNIST_DUMP=<папка> сохраняет веса и пороги до (float_*.csv) и после (quant_*.csv) квантования

Как запускать

cd ~/run/exp
# лучший вариант для полного MNIST
MODEL=altai ./run.sh myrun 60000 KNP_MNIST_THR=40 KNP_MNIST_ADD_THR_SCALE=0
cat myrun/result.csv
Путь Что внутри
~/run/exp/tr<N>.bin, tr<N>.target N обучающих картинок + одни и те же 10 000 тестовых
~/run/exp/val<N>.bin, val<N>.target N обучающих картинок + валидация (картинки 50 000–59 999)
~/run/exp/run.sh запуск: MODEL=altai run.sh <имя> <N> [ПЕРЕМЕННАЯ=значение]
~/run/exp/altai*/ результаты прогонов altai и выгрузка весов

Следующие шаги

  • Исправить порог в самом обучении, а не только на проверке
  • Использовать колонки по-настоящему: развести 20 нейронов колонки, чтобы они учили разные варианты написания цифры
  • Запустить altai на GPU, когда заработает GPU-бэкенд