Files
lr_miad_nn/HOW_IT_WORKS.md
T
Dmitry 26f4909ead
Build and Push / build (push) Successful in 9s
Добавление кнопки "домой" и гайда
2026-05-18 15:57:22 +03:00

3.5 KiB

Как работает приложение

Запуск

bundle install
ruby app.rb   # веб-интерфейс на http://localhost:4567
# или
ruby main.rb  # только CLI: загружает паттерны, обучает, выводит инфо

В Docker: собирается образ, generate_excel.rb генерирует patterns.xlsx при старте, Sinatra слушает на 4567.


Данные

Паттерны хранятся в patterns.xlsx. Каждый лист = один символ (T, H, E, X...).
Ячейка x1, остальное → -1. Размер: 8×8 = вектор из 64 значений.

loader.rb читает Excel через гем roo и возвращает {name => matrix_8x8}.
В вычислениях матрицы разворачиваются в векторы через flatten.

Если хочешь добавить/изменить паттерны — правь generate_excel.rb и перезапусти.


Веб-интерфейс

Одна страница (views/index.erb), тёмная тема, 8×8 кликабельная сетка ввода.

Что можно сделать:

  • Нарисовать паттерн кликами (или добавить шум кнопкой)
  • Нажать «Распознать» — сервер прогоняет через обе сети
  • Включить «Пошаговый режим» — видно, как Хопфилд сходится шаг за шагом
  • Включить «Показывать формулы» — рядом с анимацией появляются LaTeX-формулы вычислений

Маршруты (app.rb)

Маршрут Что делает
GET / Загружает паттерны, отдаёт HTML
POST /recall Быстро: вектор → итоговый результат обеих сетей
POST /recall_steps То же + все промежуточные состояния для анимации
POST /recall_trace То же + net-значения, сколько нейронов изменилось на каждом шаге, трассировка MAXNET

Все POST принимают JSON {vector: [...64 числа...]}, возвращают JSON.


Алгоритмы

Хопфилд (hopfield.rb)

Обучение — один раз при запуске:

W[i][j] += v[i] * v[j]  для каждого паттерна v, i ≠ j

Матрица весов 64×64, кэшируется в weights.cache.

Recall — итерации до сходимости:

new[i] = sign( Σ_j W[i][j] * x[j] )   # sign: ≥0 → 1, <0 → -1

Все нейроны обновляются синхронно. Стоп: состояние не изменилось (EPS=0.01) или 200 итераций.

Хэмминг (hamming.rb)

Шаг 1 — слой Хэмминга (один раз):

output[k] = (dot(pattern_k, input) + 64) / 2

Результат: число от 0 до 64 — сколько бит совпало с k-м эталоном.

Шаг 2 — MAXNET (итерации до одного победителя):

new[i] = max(output[i] - eps * Σ_{j≠i} output[j], 0)   # eps = 0.9 / кол-во паттернов

Нейроны конкурируют: слабые гаснут, остаётся один. Его индекс = ближайший паттерн.