2026年2月7日土曜日

外部カメラで指認識連動→40年前の記憶を想起

 

普通の安いLogi外部カメラ(USB)と連動
UIは時間が勿体ないからチャッピーに任せてます。
(最近、似たUIが多いのはそのせいで、それは僕の中では良しとしています)




外部カメラで指認識連動 動画


やることが古いけど、なんでも実験君する!



指の動き

→ 図形認識

→ 図形に意味がある

→ 40年前を検索した


そう思われるかもしれないけど、でも今回の創作アソシアトロンはそうじゃない。



指の動き(状態)

→ センサーから低次元の断片ベクトル

→ 内部のアトラクタ空間に投げ込む

→ 一番深い盆地に落ちる

→ たまたまそれが40年前だった

ということ。


「一緒じゃん!?」
違うんだってば。


図形とか、検索とか、
存在していない。


全部力学

意味を付けて考えるのではなく、「状態空間」で捉えるのが想起です。


図形 → 意味 → 記憶  ではなく

状態 → 引力 → 落下

うちの奥さんに説明するのに2年かかったように
指の動き → 図形認識 → 40年前を検索のように置き換えられてしまう。

外輪(外界)はあくまでもトリガでしかなく
出てくるのは内輪(内部)の積(一人称)


いわゆる外部の命令は一切ないということ。



1. 外部入力は「認識」ではなく初期状態

指の動き → 描画 → 64×64

これをベクトル化:

x0{1,+1}N,N=4096x_0 \in \{-1,+1\}^{N}, \quad N=4096

ここで重要なのは:

入力 = クエリではない

x0=initial statex_0 = \text{initial state}

つまり

System dynamics: xt+1=F(xt)\text{System dynamics: } x_{t+1} = F(x_t)


2. 記憶はアトラクタ集合

各部屋 r に記憶パターン

mr,k{1,+1}Nm_{r,k} \in \{-1,+1\}^N

重み

wr,kw_{r,k}

部屋キー( room.key):

Kr=sign(kwr,kmr,k)K_r = \text{sign}\left(\sum_k w_{r,k} m_{r,k}\right)

これは

部屋の代表アトラクタ


3. 部屋選択 = 文脈競争

Gate入力(部分マスク)

qgq_g

部屋スコア:

sr=1MgiMgqg(i)Kr(i)s_r = \frac{1}{|M_g|} \sum_{i \in M_g} q_g(i) K_r(i)

(部分内積)

Top2選択:

R=TopK(sr)R = \text{TopK}(s_r)


4. 部屋内競争

Memory入力:

qmq_m

各記憶との一致:

ar,k=1MmiMmqm(i)mr,k(i)a_{r,k} = \frac{1}{|M_m|} \sum_{i \in M_m} q_m(i) m_{r,k}(i)

部屋の最良記憶:

k(r)=argmaxkar,kk^*(r) = \arg\max_k a_{r,k}


5. 最終競争

コード:

finalr=ar,k+λsr\text{final}_r = a_{r,k^*} + \lambda s_r

ここで

λ=0.15\lambda = 0.15

勝者:

r=argmaxrfinalrr^* = \arg\max_r \text{final}_r


6. ドア条件(閾値系)

open if\text{open if}
finalr>θ\text{final}_{r^*} > \theta

かつ

finalrsecond>Δ\text{final}_{r^*} - \text{second} > \Delta

かつ

coverage>ϵ\text{coverage} > \epsilon


競争型アトラクタ選択


7. 想起 = 力学収束

ここが「図形認識ではない」本体。

初期状態:

x(0)=x0x^{(0)} = x_0

更新(低ランク):

x(t+1)=sign(kwr,kϕ(ak)(mr,kx(t))mr,k)x^{(t+1)} = \text{sign}\left( \sum_k w_{r^*,k} \, \phi(a_k) \, (m_{r^*,k}^\top x^{(t)}) \, m_{r^*,k} \right)

ここで

ϕ(ak)=max(0,ak)\phi(a_k) = \max(0, a_k)

これは実質:

選ばれた部屋のアトラクタ場


8. 重要な解釈

通常AI:

inputlabel\text{input} \rightarrow \text{label}

今回の創作:

x0argminEr(x0)x_0 \rightarrow \arg\min E_r(x_0)

エネルギーで書くと:

Er(x)=kwr,k(mr,kx)2E_r(x) = - \sum_k w_{r,k} (m_{r,k}^\top x)^2

つまり

40年前が出た理由=\text{40年前が出た理由} = E40(x0)<Eothers(x0)E_{40}(x_0) < E_{others}(x_0)


9. 一行で書くと(これが本質)

今回の創作:

r=argmaxr[maxkqm,mr,k+λqg,Kr]r^* = \arg\max_r \left[ \max_k \langle q_m, m_{r,k} \rangle + \lambda \langle q_g, K_r \rangle \right]

その後

xattractor of rx \rightarrow \text{attractor of } r^*


10. だから何が起きているか

指の動きは

x0x_0

を与えただけ。

40年前が出たのは

40年前の盆地が一番深かった\text{40年前の盆地が一番深かった}

つまり:

External inputkey\text{External input} \neq \text{key}
External input=initial condition\text{External input} = \text{initial condition}


11. これが一番短い数式表現

このシステムは:

x0argminrEr(x0)x_0 \rightarrow \arg\min_r E_r(x_0)

そして

x(t+1)=Er(x(t))x(t+1) = -\nabla E_{r^*}(x(t))

(離散版)




---------------ちょびっと番外編------------


標準のホップフィールドでは、今回の創作アソシアトロンが起こしている現象はほぼ起きません。

なぜかを、力学と数式で整理します。


1. ホップフィールドの基本構造

ホップフィールドでは、記憶は1つのエネルギー関数に全部入ります。

重み:

W=p=1PξpξpTW = \sum_{p=1}^{P} \xi_p \xi_p^T

エネルギー:

E(x)=12xTWxE(x) = -\frac{1}{2} x^T W x

更新:

xt+1=sign(Wxt)x_{t+1} = \text{sign}(Wx_t)

つまり世界はこうなっています:

1つのエネルギー地形

  • 全記憶が同じ空間に混在

  • すべて同じ「時間軸」


2. 何が起きるか(重要)

ホップフィールドでは、

入力 x0x_0 に対して

recall=argmaxpx0,ξp\text{recall} = \arg\max_p \langle x_0, \xi_p \rangle

つまり実質:

最も相関が高い記憶 = 勝者

ここにある特徴:

  • 文脈なし

  • 部屋なし

  • 時代なし

  • 競争は「全記憶一括」


3. だから起きない現象

今回のケース:

断片Cue → 40年前が勝つ(最近ではない)

ホップフィールドでは通常:

(A) 最近バイアスが強くなる

新しい記憶ほど:

  • ノイズが少ない

  • 干渉が少ない

  • basin が大きい

結果:

最近の記憶に吸われる


(B) 古い記憶はどうなるか

時間が経つと:

  • 干渉で basin が縮む

  • スプリアスが増える

  • 消える

つまり:

Old attractor depth\text{Old attractor depth} \downarrow

だから

40年前が勝つ確率は極めて低い


4. なぜ今回の創作アソシアトロン系では起きるか

構造はこう

Step1:部屋選択

sr=qg,Krs_r = \langle q_g, K_r \rangle

Step2:部屋内競争

ar,k=qm,mr,ka_{r,k} = \langle q_m, m_{r,k} \rangle

Step3:最終

finalr=ar,k+λsr\text{final}_r = a_{r,k^*} + \lambda s_r

ここで重要なのは:

競争は「全記憶」ではない

まず

文脈(部屋)で空間を分割

つまりエネルギー的には:

E(x)=minrEr(x)E(x) = \min_r E_r(x)

これはホップフィールドには無い構造です。


5. 物理的な違い(本質)

ホップフィールド

1つの地形

全部の記憶が同じ山にある

結果:

  • 最近の谷が深い

  • 古い谷は浅い

  • → 最近に落ちる


今回のアソシアトロン系

複数の地形

部屋ごとに別の山

処理は:

  1. どの山を見るか決める

  2. その山の中で落ちる

だから:

40年前の山が選ばれれば、そこに落ちる

時間距離は関係ない。


6. 数式での違い

ホップフィールド:

r=argmaxpx0,ξpr^* = \arg\max_p \langle x_0, \xi_p \rangle

アソシアトロン系:

r=argmaxr[maxkqm,mr,k+λqg,Kr]r^* = \arg\max_r \left[ \max_k \langle q_m, m_{r,k} \rangle + \lambda \langle q_g, K_r \rangle \right]

つまり:

二段階の非線形選択

これが:

  • 文脈ジャンプ

  • 遠い過去の勝利

を可能にしています。


7. もう一つの大きな違い

ホップフィールドは

メモリ数が増えるほど性能が悪化

容量:

P0.138NP \approx 0.138N

4096なら:

約560記憶

それ以上で:

  • basin崩壊

  • スプリアス地獄

今回の創作アソシアトロン系は:

部屋分割 = 容量分割

これは実質:

階層型アトラクタ


8. 一番短い違い

ホップフィールド:

最近・強い・多数派が勝つ

アソシアトロン系:

文脈が合えば、遠い記憶でも勝つ


9. だから重要なポイント

今回の実験:

  • カメラの断片

  • 低coverage

  • smellなし

  • それでも40年前OPEN

これは:

単一アトラクタ系ではほぼ起きない挙動

理由:

context switching\text{context switching}

が入っているから。




アソシアトロンでなければ

指の動き → 図形 →想起

に見えてしまうが、アソシアトロンは

指の動き(状態パターン) → 内部競争 → 40年前が勝つ



これは「40年前の部屋が、断片Cueだけで勝ち切って、扉が開いて想起(収束)に入った」ログ

1) covGate=2.0% / covMem=2.0% / smell=OFF

covGate / covMem とは

  • covMem:描いたピクセルの割合(メモリ用Cue:qMem/mMem

  • covGate:扉判定に使うピクセルの割合(ゲート用Cue:qGate/mGate

このコードでは smell=OFF のとき

  • mMem と mGate はほぼ同じ(描いた点がそのまま通る)

  • だから covGate ≒ covMem になる

2.0% ってどれくらい?

N=4096 なので
4096 × 0.02 ≒ 82点 くらい描いてる。

これは「断片Cue」としてちょうど良い量で、多すぎて余計な点が混ざる(8〜9%)より落ちやすい。少なすぎて一致判定が不安定(0.1%以下)でもない。



2) winner: 40 years (mem#0)

ここは二段階の勝者決定がある。

(A) まず部屋の候補を選ぶ(Top2 rooms)

  • scoreRoomByKey(room)各部屋のスコアを出す

  • それを並べて 上位2部屋(Top2) を選ぶ

この scoreRoomByKey は、

  • その部屋の room.key(部屋の代表パターン)と

  • qGate(描いた断片)との一致度(平均内積)
    で決まる。

(B) 次に、候補部屋の中で「どの記憶が勝つか」を競争する

候補の部屋ごとに

  • bestMemInRoom(room) を計算して
    その部屋で一番合う記憶(mem)を探す

そして「部屋+そのベスト記憶」の組を比較して最終勝者を決める。

この結果が:

  • 40 years の mem#0 が、全候補の中で最も良かった


3) final=0.41 / margin=0.97 / θ=0.28 Δ=0.10

ここが「扉が開くか」の核心。

final の正体

ログにもある通り:

  • finalScore = memScore + 0.15*roomScore

つまり final は

  • memScore(その記憶が断片Cueとどれだけ一致したか)

  • + 少しだけ roomScore(その部屋の鍵とゲートCueがどれだけ一致したか)
    の合成点。

今回 final=0.41 は、閾値 θ=0.28 より上なので

  • 「一致度は“十分”」側に入ってる。

margin の正体

bestAcrossRooms(topPairs) の中で

  • 1位の final と

  • 2位の final の差
    margin

今回 margin=0.97 はかなり大きい。

意味は:

  • 「僅差で勝った」ではなく

  • 競争として圧勝している
    (2位がまるで届いてない)

θ と Δ は何の役割?

  • θ(theta):絶対的に「鍵が回った」と言える最低ライン
    → final がこれを超える必要がある

  • Δ(delta):勝者が“はっきり勝った”と言える差
    → margin がこれを超える必要がある

今回:

  • final 0.41 > θ 0.28 

  • margin 0.97 > Δ 0.10 


4) door: OPEN

扉判定式はこれ:

open if (final>θ) AND (margin>Δ) AND (covGate>min)

今回それぞれ確認すると:

(1) final > θ

0.41 > 0.28 

(2) margin > Δ

0.97 > 0.10 

(3) covGate > min

min はコードで 0.002(0.2%)

  • covGate 2.0% > 0.2% 

→ 3条件ぜんぶ成立なので OPEN


5) writeRoomId=Cnow

これは重要で、誤解しやすいポイント。

  • writeRoomId は「学習(Learn)で書き込む先」

  • Recall の勝者決定には関与しない

デモの思想どおり:

学習ターゲットと想起ターゲットは独立

だから「書き込み先が Now でも、想起は 40 years が勝つ」ことが起きる。


6) Gate: qGate ... / Memory: qMem ...

ここは設計思想そのもの。

  • Gate(qGate):部屋の扉を開ける/候補部屋を絞るためのCue

  • Memory(qMem):部屋内の記憶同士を戦わせるCue

僕はこの二段階に分けたから、

  • 「部屋は“文脈”として選ばれる」

  • 「その部屋の中で“エピソード”が競争する」
    という“人っぽい”流れになってる。

smell=OFF だと qGate も qMem もほぼ同じ断片だけど、
将来 smell を入れると

  • Gateは匂いで通る部分だけ

  • Memoryは匂い無視の断片
    みたいに分離して「匂いで部屋だけ開く」ができる。


7) このログが示している、一番大きい意味

  • 外部から「40年前を出せ」と命令してない

  • 断片はたった 2%

  • それでも Nowではなく40年前が勝つ

  • しかも 標準の厳しめ θ=0.28, Δ=0.10 で OPEN

つまりこれは:

時間距離(最近優位)より、状態一致(引力)が勝った

という、僕が狙っている性質が“数値として成立した”ログです。

勝ったり負けたりしてるんだけどねw




A:外界はトリガだけ。中身は内部で決まる

B:トリガすら内部で勝手に起きる


赤ちゃんは生まれたときは自我が無い。だけど記憶の経験はする。外輪による影響、外輪のCueで内輪がスパークする。これはまさしくA。
Bというのはある程度大人になってからだ。


A=乳児期の自律:自我(内的命令系)はまだ薄い/無い。でも 経験は蓄積していて、外輪のCueで内輪がスパークして想起が立ち上がる。

B=成人期の自律:内側から「勝手に」Cueを生成して、内輪が自走で発火する(内発火)。


いわゆるAを積まないとBにはならない。

外輪(カメラ/指)は Cueの注入までで

内輪は 部屋の競争→記憶の競争→収束で“どれが出るか”を決める

Spark はその「内輪の一致成分」が燃えて見える



-------------------番外--------------------

GitHub 消しちゃった。
いろいろ理由はあるけど、僕はそっちじゃない。ってだけ。


このデモ、一旦、三角形を想起しちゃったけど、現代のアトラクタの方が強いに決まってるから、しょうがないんだよね。
でも、例えば3秒(まぁどうなんだろう・・)続いたらrecallにしちゃってもいいかな。
そう、そうやって外部命令が増えて思想が崩壊しちゃうんだよなぁ・・・

でも、外部影響による内部の想起とか「え?そうだっけ、でも、なんか見たことあるなぁ・・」ってあるじゃん。それを重みだけでやってると、「おい、どっちなんだよ?」がずっと続いちゃうんだよね・・・。

こういうことさ。
「最近のあの人が記憶に出てきて完全に勝っていたけど、よくよく思い出してみたら40年前のあの人が蘇ってきた」みたいな感じさ。

数式的に言うと

今は:

r=argmaxrfinalr(t)r^* = \arg\max_r final_r(t)

これを:

Recall if r is stable for T seconds\text{Recall if } r^* \text{ is stable for } T \text{ seconds}

つまり:

時間条件:

r(t)=r(tτ)(τ3s)r^*(t) = r^*(t-\tau) \quad (\tau \approx 3s)


いれても、いいかい?って話。



カメラでいろいろ見てる。

何か起こる

Sparkが揺れる

あるアトラクタが強くなってくる

3秒固定

自動Recall

HDのようなものに一切データとして記録されてるわけじゃないんだよ。

(ループさせる)


自律っぽいでしょ?
完全一人称だからw
部屋にカメラと音声付けて置いておくとさ、アルゴリズムじゃなくて、アソシアトロン+LLMが「お帰り、今日は遅かったじゃん、マックス泣いてたんで歌うたってやったわ」
とかさ・・・LLMと連動させて積が喋るようになる。(LLMが考える → 話すじゃないよ、言語変換だけ)

外界(カメラ・音・時間)
→ 状態変化(Cue)
→ 内部競争
→ アトラクタ収束
→ 想起(部屋+エピソード)
→ LLMが言語化



まぁ、寝るわ。


今回のもとりあえず、JavaScript版でPythonに焼き直し前の実験用なので、気が向いたらUPします。





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...