やったー2月だ!
特に意味はありませんが・・・
なるべく難しいものを省いて説明します。
なぜ JavaScript ではなく Python か
今まで、公開したものは非常に簡単なデモ、構造的に理解するために
index.html一発で開ける軽めのものを作ってきましたが、
実験のプロセスや結果によって今後改良を加えるとなると、
配列というものを主語にしていかなくてはいけなくなります。
今回のAssociatronのコアは64×64 の uint8 です。
それを(できれば)ベクトル化して内積・閾値・更新・反復(steps)が必要になり、配列演算が中心となります。
Python + NumPy はここが「標準装備」で、
●速い(C実装のNumPyに乗る)
●書くコードが短い
●形(dtype/shape)を固定しやすい
●npz/npy が自然に扱えるという利点があります。
JavaScriptでも typed array ではできるけど、
▲行列/配列の演算を自前で組む量が増える
▲精度・速度・バグ混入の管理が難しくなる
▲保存形式(npy/npz)との相性が弱い
という“遠回り”が出やすい。
別な言い方をすると、実験結果によって改良をするのに結果が出るまで開発労力がかかります。
ですから、研究、定義、ざっくりJavaScript、それを元にPythonで研究ソフトを作り実験をしまくり、実装はPythonとCで組立てる。 みたいな感じです。
assoc/
├─ .venv/ # Python 仮想環境(実行専用・研究対象外)
├─ __pycache__/ # Python キャッシュ(無視してよい)
│
├─ app.py # API司令塔(LLM / ルーティングのみ)
│
├─ learn64.py # Learnエンジン(入力→64x64パターン生成)
├─ recall_engine.py # Recallコア(連想収束・アトラクタ計算)
│
├─ recall_to_png.py # Recall結果のPNG可視化アダプタ
├─ recall_from_memory_to_png.py # 既存メモリのPNG化(確認・展示用)
│
├─ room_manager.py # room / scene 管理(場所の台帳)
├─ year_key_logic.py # 年代キー推定(外輪ロジック・意味寄り)
├─ ensure_scene_storage.py # 保存先ディレクトリ整備(OS寄り)
│
├─ mem/ # 記憶本体(npy / npz / パターン)
│ ├─ year_xxxx/
│ │ ├─ scene_xxxx/
│ │ │ ├─ patterns.npz
│ │ │ └─ meta.json
│ │ └─ ...
│ └─ ...
│
├─ web/ # UI・表示用生成物
│ ├─ png/
│ │ ├─ original.png
│ │ ├─ cue.png
│ │ └─ recalled.png
│ └─ index.html # UI(JavaScript側)
│
├─ rooms.json # 現在の room / scene 定義
├─
├─
│
├─ tmp_recall_log.txt # Recall一時ログ(デバッグ用)
├─ start.ps1 # 起動スクリプト(Windows)
そこに、今後、音声、カメラ、匂いセンサーが追加されていくわけですが、各チャネル → 64×64(または固定次元)の0/1(またはuint8)に落としそれを learn64 / recall_engine に渡す・・・
つまり、コアは変えない! 「えーーー!」
アトラクタ/エネルギー最小化/収束などの同じ性質をもつアソシアトロン系じゃないと、その構造は難しい話なのかもしれません。
音声・映像・匂いって、入力の性質が全部違うもので、通常は次元数もスケールも違うし、ノイズの入り方も違う、時系列か静止かも違います。普通の機械学習だと、入力が変わるたびにモデル構造、学習方式、表現(embedding)、正規化をモデル側で吸収しないといけないですよね。
そうなるとコアが入力に依存になってしまう。
アソシアトロン(アトラクタ系)が強い理由
コアが要求するのは 同じ型の状態(state)だけなんです。
fixed size(例:64×64)
fixed dtype(uint8 / 0-1)
fixed update rule(収束則)
だけで、音声だろうが映像だろうが匂いだろうが関係ない。
違いはすべて 前段(adapter)で吸収できるんです。
「嘘だぁ・・」
いや、ほんと。
じゃなきゃ、アソシアトロンの研究は最初からやってないです。
Hopfield系(1982)は?
アソシアトロンの弟みたいな存在ですが、「コア不変」を長期に守るのは厳しいんじゃないかと思います。
現代 Hopfield(Dense / Attention型)は?
容量が事実上増える、Transformerとの理論的接続、高次元埋め込みに強い、ノイズ耐性が高い。内部が「意味空間」になると負荷になる。ベクトル空間が 意味分布依存。アトラクタに入るために、最初から“意味を持った表現”を要求する。
ここがアソシアトロンと大きな違いなので後で話しますね。
Associatron(1972)的発想
「入力は雑でもいい。同じ型の state にさえなれば、あとはコアが責任を持つ」
表現は粗くていい、意味は要らない、分布が変わっても、コアは見ない、state だけ見る。
(初めは僕も意味を持たせてましたが、これはアソシアトロンから一脱してる。というより、そこの境界を越えると全て外部命令に占領され、後に気づいた一人称から外れてしまうということで、実験の結果、少し誘惑に引っ張られましたが全て基本に戻しました。 基本っすよ、基本。ただ、誘惑は半端なく多いです)
簡単に言うと実験の結果が出ずらいので、誘惑に負けるんです。
このくらい、いいよね・・・という発想だと、必ずコアが歪み拡張で破綻します。
別名「誘惑耐性のテスト装置」みたいなものなので・・・
assoc_stage2/
├─ app.py
├─ learn64.py
├─ recall_engine.py
├─ room_manager.py
├─ ensure_scene_storage.py
├─ year_key_logic.py
│
├─ sensors/ # ★追加:入力チャネル(外付け)
│ ├─ audio_capture.py # 収録(マイク→wav等)
│ ├─ audio_embed.py # 特徴抽出→固定次元化
│ ├─ camera_capture.py # 撮影(カメラ→jpg/png等)
│ ├─ camera_embed.py # 特徴抽出→固定次元化
│ ├─ odor_capture.py # 匂いセンサー値取得
│ ├─ odor_embed.py # 正規化→固定次元化
│ └─ fuse.py # ★融合:複数チャネル→1つのcue
│
├─ adapters/ # ★追加:共通変換
│ ├─ to_pattern64.py # embed(ベクトル等)→64x64 uint8
│ └─ io_formats.py # npy/npz保存・読み出し共通化
│
├─ mem/
└─ web/
バカだろ?
と思うかもしれませんが、いや、これがアソシアトロンなんですよ。
赤ちゃんが、「ママ」と発する言葉に意味をいれたら、
育つんじゃなく、飼育になるって話。
そもそものスタートに違いがあるんです。
0 件のコメント:
コメントを投稿