examples/ is based on KasperskyLab/knp at 55470ed6 with local changes to the mnist-learn altai/blifat models, cuda-backend CMake and model_loader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9.9 KiB
Улучшение классификатора — второй эксперимент
Цель — улучшить настоящий STDP-классификатор KNP/AltAI, сохраняя обучение его весов в KNP. Готовая обученная нейросеть не используется. Фиксированные признаки вычисляет обычный предобработчик; весь путь от изображения до признаков пока не спайковый.
Что изменено
Вместо почти сырых пикселей используются гистограммы направлений контуров: градиенты, 9 направлений, ячейки 4×4, перекрывающиеся блоки из 2×2 ячеек, L2-Hys-нормализация. Получается 1764 признака. Для разреженного варианта оставляются 256 самых сильных признаков каждого изображения. Данные дополняются нулями до 2048 входов существующего бинарника. Алгоритм фиксирован, метки при вычислении признаков не используются. Описание подхода: официальная документация scikit-image о HOG. Реализация здесь HOG-подобная, с собственными правилами разреживания и перевода в спайковую интенсивность; она не заявлена побайтной копией scikit-image.
Плотные HOG/комбинированные признаки с прежними настройками дали преимущественно молчание. У probe_hog_20 после штатного квантования 65626 из 81920 весов стали нулями. Вариант квантования KNP_MNIST_QUANT=weights выбирает масштаб по весам, а не по порогу, и сохраняет больше значимых разрядов. Значения весов остаются в ±255. Порог теперь подбирается в другом масштабе. Проверяется CPU-эмуляция AltAI; совместимость этих порогов с конкретным поколением физического чипа не установлена.
Технические проверки test_features.py: чёрное изображение, ориентация вертикальных/горизонтальных границ, размер, нулевое дополнение, ограничение числа активных признаков и детерминированность. Дополнены параметры run.py: каталог данных, число нейронов на класс, seed, разброс весов, режим квантования. Прежние значения по умолчанию сохранены.
Данные и процедура
JPEG-зеркало CIFAR-10 закреплено на прежнем коммите d7d05618061fe37d830fb0419063d113c575ccbc.
- Обучение: по 2000 кошек и собак, train-файлы 0000–1999.
- Новая валидация: по 500, train-файлы 4500–4999. Они не участвовали в первом пилоте.
- Новый тест: по 500, test-файлы 0200–0699. Первый опыт проверял test 0000–0199, поэтому повторного подбора по старому тесту здесь нет.
- Seed перемешивания: 20261015. Имена исходных файлов записываются в
data-v2/manifest.json.
Проверки на старой валидации используются для отладки представления, а не для итоговой оценки. На новой валидации validate_v2.py проверяет 8 заранее заданных сочетаний: 20/60 нейронов на класс и пороги 600/1600/4000/8000, разреженный HOG, квантование по весам, seed 42. Выбор фиксируется в selection-v2.json до запуска теста.
evaluate_v2.py запускает выбранную новую сеть и исходную сеть первого опыта на одном и том же новом тесте. Исходная сеть заново обучается ровно на прежних 800 примерах и получает прежний контрастный вход. Для обеих сетей проверяется побайтное равенство CSV весов и порогов соответствующим валидационным прогонам. Итоги, интервалы Уилсона и проверки сохраняются в comparison-v2.json.
Команды на стенде
~/anvenv/bin/python /mnt/c/KNP/cats-dogs/prepare_v2.py
~/anvenv/bin/python /mnt/c/KNP/cats-dogs/prepare_features.py \
~/run/cats-dogs/data-v2 ~/run/cats-dogs/features-v2
~/anvenv/bin/python /mnt/c/KNP/cats-dogs/prepare_baseline_v2.py
python3 /mnt/c/KNP/cats-dogs/validate_v2.py
python3 /mnt/c/KNP/cats-dogs/evaluate_v2.py
Папки прогонов не перезаписываются. Повторный полный запуск требует новых имён прогонов или отдельного рабочего каталога.
Результат
Выбраны 20 нейронов на класс, порог 4000, разреженный HOG, квантование по весам. Validation: 626/1000 (62,6%). Увеличение до 60 нейронов на класс не помогло: лучший из проверенных порогов дал 60,2% на validation.
На одном и том же новом тесте из 1000 JPEG-изображений:
| Модель | Верно | Ошибка | Молчание | Точность |
|---|---|---|---|---|
| Прежняя сеть первого опыта | 522 | 450 | 28 | 52,2% |
| Новая сеть | 618 | 382 | 0 | 61,8% |
Прирост 9,6 процентного пункта. Новая сеть: кошки 304/500, собаки 314/500; это не улучшение за счёт постоянного ответа одним классом. Уилсон 95%: новая сеть 58,7–64,8%, прежняя 49,1–55,3%. Интервалы описывают неопределённость на этой выборке, а не универсальное качество на любых фотографиях.
Все четыре CSV весов и порогов новой сети побайтно совпали между выбранным валидационным и тестовым прогонами. Аналогичная проверка прежней сети подтвердила идентичность весов первому опыту. Test запускался после фиксации selection-v2.json; по результату test модель не перенастраивалась. Проверены уникальность файлов, баланс классов, отсутствие пересечений train/validation/test и отсутствие пересечения нового test с test первого опыта.
Python 3.14.4, numpy 2.5.4, Pillow 12.3.0. Синтаксические проверки скриптов и test_features.py прошли. Обучение+тест новой сети заняли 23,27 с на CPU, старой — 5,55 с; объём обучения у новой сети больше. Это не измерение производительности физического AltAI.
Полный результат: results-v2/comparison.json, выбор по validation: results-v2/selection.json, настройки: results-v2/test-settings.json. Архив весов: trained-weights-v2.tar.gz. На стенде итоговый прогон — /home/int/run/cats-dogs/v2_test, прежняя модель на новом тесте — v1_fresh_test; исходные логи сохранены.
Полезное улучшение достигнуто, но надёжный фотоклассификатор пока не получен. Проверен один seed; датасет — маленькие JPEG-копии, не канонический CIFAR. Одновременно изменены признаки, квантование и объём обучения, поэтому вклад каждого изменения отдельно не установлен.
Следующие кандидаты, пока не реализованы:
- Обучающие зеркальные отражения и небольшие сдвиги, чтобы уменьшить зависимость от положения объекта.
- Спайковый слой локальных признаков с последующим объединением ответов соседних участков. Сейчас фиксированный HOG считает обычный код, а STDP учит классификатор.
- Отдельное сравнение нескольких seed и способов обучения, включая суррогатный градиент для SNN, если локального STDP окажется недостаточно. Это было бы другим режимом обучения и потребовало бы отдельной проверки динамики AltAI.