2026年1月21日水曜日

Associatron Demo: Cue → Competition → Spark → Recallの数式

 

https://cside-associatron.blogspot.com/2026/01/associatron-demo-cue-competition-spark.html


デモの数式


扉(部屋候補)を絞る=Gate段(匂いマスクが効く)

  1. 記憶同士を競争させる=Memory段(匂いは効かない/描いた断片を全部使う)

その上で最後に OPEN条件 を満たしたら「扉が開く」。


Cueの作り方(ゲート用/記憶用)

画面で描いた入力を x{1,+1}Nx\in\{-1,+1\}^N とします(描いたピクセル +1+1、背景 1-1)。

デモでは「描いた場所だけ」を手がかりに使うので、観測マスクを

mi=1[xi=+1]m_i=\mathbf{1}[x_i=+1]


(a) 記憶競争用 cue(匂い無関係)

mimem=mi,qimem=1[xi=+1]

(b) 扉(部屋選別)用 cue(匂いで通行制限)

匂いマスクを si[0,1]s_i\in[0,1](匂いが通る場所は>0)とし、匂いONなら

migate=mi1[si>0],qigate=1[migate=1]m^{\text{gate}}_i = m_i\cdot \mathbf{1}[s_i>0],\qquad q^{\text{gate}}_i=\mathbf{1}[m^{\text{gate}}_i=1]

匂いOFFなら mgate=mm^{\text{gate}}=m と同じ。

カバレッジ(断片量)も条件に使ってます:

covgate=1Nimigate,covmem=1Nimimem\mathrm{cov}_{\text{gate}}=\frac{1}{N}\sum_i m^{\text{gate}}_i,\qquad \mathrm{cov}_{\text{mem}}=\frac{1}{N}\sum_i m^{\text{mem}}_im^{\text{mem}}_i = m_i,\qquad q^{\text{mem}}_i = \mathbf{1}[x_i=+1]


「部屋が開きそう度」=部屋キーとの類似度

各部屋 r はキー kr{1,+1}N を持つ(部屋内の記憶の重み付き多数決で作るやつ)。

扉用cueで部屋を採点:

sr  =  simgate(kr)  =  imigateqigatekr,iimigate(分母0なら 1)

これがコードの scoreRoomByKey() → simGateToPattern() に相当。

この sr の上位2つを Top2 rooms として残す。


3) 記憶同士の競争(Top2だけでやる)

部屋 rr の中に記憶が複数ある: {vr,j{1,+1}N}\{v_{r,j}\in\{-1,+1\}^N\} と重み wr,j>0w_{r,j}>0

記憶の採点は「匂い無関係」cueで:

μr,j  =  simmem(vr,j)  =  imimemqimemvr,j,iimimem\mu_{r,j} \;=\; \mathrm{sim}_{\text{mem}}(v_{r,j}) \;=\; \frac{\sum_i m^{\text{mem}}_i\, q^{\text{mem}}_i\, v_{r,j,i}} {\sum_i m^{\text{mem}}_i}

部屋 rr の最強記憶スコア:

Mr=maxjμr,jM_r=\max_j \mu_{r,j}


4) 最終スコア(部屋スコア+記憶スコア)

デモでは「部屋の雰囲気」を少しだけ足すために:

Fr=Mr+αsrF_r = M_r + \alpha s_r

コードだと α=0.15\alpha=0.15

Top2の中で勝者:

r\*=argmaxrTop2Frr^\*=\arg\max_{r\in\text{Top2}} F_r

次点との差(マージン):

margin=Fr\*maxrTop2,rr\*Fr\mathrm{margin}=F_{r^\*}-\max_{r\in\text{Top2},\,r\neq r^\*}F_r


5) 「扉が開く」判定(条件つき)

コードの条件はほぼこれ:

OPEN    (Fr\*>θ)    (margin>Δ)    (covgate>ε)\text{OPEN} \iff \bigl(F_{r^\*}>\theta \bigr) \;\wedge\; \bigl(\mathrm{margin}>\Delta \bigr) \;\wedge\; \bigl(\mathrm{cov}_{\text{gate}}>\varepsilon \bigr)

  • θ\theta:鍵が回る最低ライン(theta

  • Δ\Delta:迷い(勝ち方が弱いと開かない)(delta

  • ε\varepsilon:断片が少なすぎると開かない(コードは 0.002)

匂いONのときはデモ上、迷いを少し小さくして「開きやすく」してる:

Δ={0.75Δ0smell ONΔ0smell OFF\Delta = \begin{cases} 0.75\,\Delta_0 & \text{smell ON}\\ \Delta_0 & \text{smell OFF} \end{cases}


直感(短く)

  • 匂いON:観測点が減る(マスク)→ 部屋キーとの一致が取りやすくなり、Top2が安定しやすい

  • でも観測点が減りすぎると covgate\mathrm{cov}_{\text{gate}} が小さくなって OPENしない



1) 基本:部屋=高次元ベクトル空間(4096畳)

デモの「体育館の絵」は

  • 64×64 = 4096 次元

  • 1マス(画素)=畳1枚

なので部屋の状態は

x{1,+1}N,N=4096

(描いた = +1、背景 = -1)


2) 時代別の部屋=「部屋の集合」=記憶領域の分割

時代(現在 / 10年前 / …)は 部屋インデックスです。

R={r0,r10,r20,r30,r40}\mathcal{R}=\{r_0,r_{10},r_{20},r_{30},r_{40}\}

各部屋 rr は、その年代に属する記憶の集合(パターン群)を持つ:

Mr={mr(1),mr(2),,mr(Pr)},mr(μ){1,+1}N\mathcal{M}_r=\left\{\, m_r^{(1)},m_r^{(2)},\dots,m_r^{(P_r)} \right\}, \qquad m_r^{(\mu)}\in\{-1,+1\}^{N}

ここで

  • PrP_r = その年代の記憶数

「Learnを押すと追加される」はこの Mr\mathcal{M}_r への追記です。


3) “部屋のキー”=その時代の代表ベクトル

コードでいう room.key は、
その年代の記憶を要約した “部屋の鍵” です。

重み wr(μ)>0w_r^{(\mu)}>0 を持つとして:

kr=sign(μ=1Prwr(μ)mr(μ)),kr{1,+1}Nk_r=\operatorname{sign}\left(\sum_{\mu=1}^{P_r} w_r^{(\mu)}\, m_r^{(\mu)}\right), \qquad k_r\in\{-1,+1\}^{N}

(実装では「平均→符号」に相当)


4) 畳(8×8)=「部屋の位置/場所」表現(粗視化)

畳は 8×8=64 次元の別空間:

pr[0,1]T,T=64p_r \in [0,1]^{T},\qquad T=64

各部屋は固有の「畳配置(場所)」を持つ。
デモでは hotspot(1点+周辺減衰)なので

pr=hotspot(tr)p_r = \operatorname{hotspot}(t_r)

みたいに「場所 trt_r を中心とした分布」として定義できます。


5) Cue(匂い+描画)=観測マスク付きの入力

ここがデモの肝です。

描画入力は xin{1,+1}Nx^{in}\in\{-1,+1\}^N

ただし部屋を開けるときの Cue は 匂いマスクで通る次元が制限される。

匂いマスク:

s[0,1]Ns\in[0,1]^N

匂いON/OFFを δ{0,1}\delta\in\{0,1\} とすると、
“扉用観測マスク” は

gi={1(xiin=+1)  (δ=0  si>0)0otherwiseg_i = \begin{cases} 1 & (x^{in}_i=+1)\ \wedge\ (\delta=0\ \lor\ s_i>0)\\ 0 & \text{otherwise} \end{cases}

これがコードの mGate です。

そして扉用Cueは

qigate={+1gi=10gi=0q^{gate}_i = \begin{cases} +1 & g_i=1\\ 0 & g_i=0 \end{cases}


6) 部屋を開ける=「部屋キーとの一致度」で競争

部屋 rr の扉スコアは

Srgate=1GiGqigatekr,i(G={igi=1})S_r^{gate} = \frac{1}{|G|} \sum_{i\in G} q_i^{gate}\,k_{r,i} \qquad \left(G=\{i\mid g_i=1\}\right)

  • 匂いONだと GG が狭くなる(選別される)

  • そのぶん「40年前の鍵」に一致しやすくなる


7) Top2 → 記憶競争(部屋またぎの最終勝者)

まず部屋候補:

Top2=arg top2r Srgate\text{Top2}=\operatorname{arg\,top2}_r \ S_r^{gate}

次に、記憶自体(パターン)で競争する。

この設計では記憶競争は匂いの影響を受けないので、
記憶用Cueは単に描画:

qimem={+1xiin=+10otherwiseq^{mem}_i= \begin{cases} +1 & x^{in}_i=+1\\ 0 & \text{otherwise} \end{cases}

記憶 μ\mu の一致度:

Sr,μmem=1MiMqimemmr,i(μ)S_{r,\mu}^{mem} = \frac{1}{|M|} \sum_{i\in M} q_i^{mem}\, m_{r,i}^{(\mu)}

最終勝者は

(r\*,μ\*)=argmaxrTop2, μ(Sr,μmem+λSrgate)(r^\*,\mu^\*) = \arg\max_{r\in Top2,\ \mu} \Bigl( S_{r,\mu}^{mem} + \lambda S_r^{gate} \Bigr)

コードだと λ=0.15\lambda=0.15


8) 扉が開く条件(θ と Δ)

勝者が決まっても、
「鍵が回る(OPEN)」には条件を課す。

勝者スコア:

F\*=Sr\*,μ\*mem+λSr\*gate

次点スコアを F(2) とすると、マージン:

ΔF=F\*F(2)

また、観測率( covGate)は

cov=GN

扉OPEN条件:

F\*>θΔF>Δcov>ε

これが「扉を開ける」という概念の数式化です。
θ(閾値)と Δ(迷い)で“扉の厳しさ”を制御している


9) Spark(重なり)=勝者部屋の “共通部分” の可視化

勝者部屋 r\*r^\* 内の記憶群の重なりを

Sparki=μ=1Pr\*αμ 1[mr\*,i(μ)=+1]\text{Spark}_i = \sum_{\mu=1}^{P_{r^\*}} \alpha_\mu\ \mathbf{1}[m_{r^\*,i}^{(\mu)}=+1]

\alpha_\mu = w_{r^\*}^{(\mu)} \cdot \max(0,S_{r^\*,\mu}^{mem})

として光らせている。

つまり Spark は

  • 一致度が高い記憶ほど

  • 重みが大きい記憶ほど

  • +1だった場所が燃える

これは「重ね書きされた痕跡」そのもの。





※ この古いBloggerは翻訳機能を標準では持ってないんですけど、数式(LaTeX/MathJax)がそのまま綺麗に出るので使ってます。


※ 今回のデモファイルはJavaScriptで作ってますが公開ダウンロードは出来ません。
テスト用なのですが、PythonとCに渡す前の実験なので、考え方の心臓部でもあるため、どこかで別のものを公開します。





0 件のコメント:

コメントを投稿

アソシアトロン論文 the Associatron paper by Nakano (1972)

  中野馨先生の論文 Kaoru Nakano(中野馨) “Learning Process in a Model of Associative Memory” Nakano, K. (1971). Learning Process in a Model of Associati...