https://cside-associatron.blogspot.com/2026/01/associatron-demo-cue-competition-spark.html
デモの数式
扉(部屋候補)を絞る=Gate段(匂いマスクが効く)
記憶同士を競争させる=Memory段(匂いは効かない/描いた断片を全部使う)
その上で最後に OPEN条件 を満たしたら「扉が開く」。
Cueの作り方(ゲート用/記憶用)
画面で描いた入力を とします(描いたピクセル +1、背景 −1)。
デモでは「描いた場所だけ」を手がかりに使うので、観測マスクを
(a) 記憶競争用 cue(匂い無関係)
(b) 扉(部屋選別)用 cue(匂いで通行制限)
匂いマスクを si∈[0,1](匂いが通る場所は>0)とし、匂いONなら
匂いOFFなら mgate=mm^{\text{gate}}=mmgate=m と同じ。
カバレッジ(断片量)も条件に使ってます:
covgate=1N∑imigate,covmem=1N∑imimem\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}}_i
m^{\text{mem}}_i = m_i,\qquad q^{\text{mem}}_i = \mathbf{1}[x_i=+1]
「部屋が開きそう度」=部屋キーとの類似度
各部屋 rr はキー kr∈{−1,+1}N を持つ(部屋内の記憶の重み付き多数決で作るやつ)。
扉用cueで部屋を採点:
sr = simgate(kr) = ∑imigate qigate kr,i∑imigate(分母0なら −1)
これがコードの scoreRoomByKey() → simGateToPattern() に相当。
この srsr の上位2つを Top2 rooms として残す。
3) 記憶同士の競争(Top2だけでやる)
部屋 rrr の中に記憶が複数ある: {vr,j∈{−1,+1}N}\{v_{r,j}\in\{-1,+1\}^N\}{vr,j∈{−1,+1}N} と重み wr,j>0w_{r,j}>0wr,j>0。
記憶の採点は「匂い無関係」cueで:
μr,j = simmem(vr,j) = ∑imimem qimem vr,j,i∑imimem\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}
部屋 rrr の最強記憶スコア:
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α=0.15。
Top2の中で勝者:
r\*=argmaxr∈Top2Frr^\*=\arg\max_{r\in\text{Top2}} F_r
次点との差(マージン):
margin=Fr\*−maxr∈Top2, r≠r\*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}
直感(短く)
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}\}
各部屋 rrr は、その年代に属する記憶の集合(パターン群)を持つ:
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}
ここで
「Learnを押すと追加される」はこの Mr\mathcal{M}_rMr への追記です。
3) “部屋のキー”=その時代の代表ベクトル
コードでいう room.key は、
その年代の記憶を要約した “部屋の鍵” です。
重み wr(μ)>0w_r^{(\mu)}>0wr(μ)>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_rtr を中心とした分布」として定義できます。
5) Cue(匂い+描画)=観測マスク付きの入力
ここがデモの肝です。
描画入力は xin∈{−1,+1}Nx^{in}\in\{-1,+1\}^Nxin∈{−1,+1}N。
ただし部屋を開けるときの Cue は 匂いマスクで通る次元が制限される。
匂いマスク:
s∈[0,1]Ns\in[0,1]^N
匂いON/OFFを δ∈{0,1}\delta\in\{0,1\}δ∈{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) 部屋を開ける=「部屋キーとの一致度」で競争
部屋 rrr の扉スコアは
Srgate=1∣G∣∑i∈Gqigate kr,i(G={i∣gi=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だと GGG が狭くなる(選別される)
-
そのぶん「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=1∣M∣∑i∈Mqimem mr,i(μ)S_{r,\mu}^{mem}
=
\frac{1}{|M|}
\sum_{i\in M} q_i^{mem}\, m_{r,i}^{(\mu)}
最終勝者は
(r\*,μ\*)=argmaxr∈Top2, μ(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λ=0.15。
8) 扉が開く条件(θ と Δ)
勝者が決まっても、
「鍵が回る(OPEN)」には条件を課す。
勝者スコア:
F\*=Sr\*,μ\*mem+λSr\*gate
次点スコアを F(2)F(2) とすると、マージン:
ΔF=F\*−F(2)
また、観測率( covGate)は
cov=∣G∣Ncov=N∣G∣
扉OPEN条件:
F\*>θ∧ΔF>Δ∧cov>ε
これが「扉を開ける」という概念の数式化です。
θ(閾値)と Δ(迷い)で“扉の厳しさ”を制御している。
9) Spark(重なり)=勝者部屋の “共通部分” の可視化
勝者部屋 r\*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 件のコメント:
コメントを投稿