マックスを連れて山に散歩に行ってきた。
さんざんアトラクタの話や、いろいろと憂さ晴らしもしたw
ついでに、江戸時代に廃村になった「赤田」という場所を車で見に行った。
地図にも出ていないし、詳しい資料はネットに出ているものしか手に入らない。
とりあえず、それによると、株式会社中部測地研究所さんのサイトでは、赤田は江戸時代の享保年間より前、つまり1700年代以前に、上川の激しい氾濫や水害に何度も見舞われ、住むことができなくなり廃村となっていたらしい。
現在は水田や区画整理された土地になっており、当時の集落の姿を見ることはできない。
ただ、歴史地理の調査では「消えた集落」として記録されていた。
「えー、車で5分の場所じゃん」
なるほど。
上川と宮川がぶつかった場所から、中州の方になるのか。
この諏訪を含めた八ヶ岳周辺の土地というのは、やばい断層があるらしい。
八ヶ岳は約800〜900年前に噴火しているらしいけど、大崩壊、つまり岩屑なだれは約20万年前らしい。
1700年より前に廃村になった場所といっても、今は交通量が一番多い場所で、ニトリやモンベルなどがある場所だ。
穴を掘ったら、何か出てくるのだろうか。
そんなことを考えながら、またアトラクタのことを考えていた。
この土地そのものをアトラクタとして仮定したら、1700年代以前の出来事は、いったいどこに刻まれているのだろう。
まずは物理学や力学、工学を抜きで考えることから、僕の研究は始まる。
なぜかというと、邪魔だからだ(笑)
いやいや、せっかく山に移住したので、ただ満喫したい気持ちの方が上かもしれない。
地層とは何なのだろう。
歴史とは何だべ。
水害などの災害。
噴火による地殻変動。
地震。
我が家の前の道路の小さな陥没。
その横にある石ころ。
それこそが、歴史の記憶なのだと思う。
もうそこには、ベクトルもデルタもシグマもない。
少し足で地面をこすったら、100年前に戻れる。
では、アトラクタのような、人間にとって都合の良い解釈とは何なのだろう。
数百年前の食器の破片。
でも、その上に堆積する土や石は何なのか。
ノイズなのか。
土木のシャベルで掘るまで、その歴史の記憶なんて分からない。
歴史は平面ではない。
堆積していく。
地殻が変動し、地形がずれる。
噴火して山が崩れる。
雨が降って土砂が堆積する。
300数十年前の記憶すら、もうそのままの形では残っていない。
崩れて、変形して、移動して、堆積した場所に、新しい文化が育まれている。
自然界や動物は、そういった出来事に順応して生きている。
でも、人間だけがアトラクタだの、ベクトルだのと言っている。
土の中の宝物だけが気になるのか。
堆積した石や土は、敗北者のように扱われるのか。
300年前には、そこに別の営みがあった。
そして、子孫がいる。
「廃村」と言うと、地図から消えた場所みたいに聞こえる。
けれど実際には、そこで暮らしていた人がいた。
家があった。
畑があった。
道があった。
子どもが生まれた。
誰かが亡くなった。
祭りがあり、日々の会話があった。
そーいえば、今年の辰野の蛍祭りはどうなった?
村は消えても、血筋や記憶の断片は別の場所へ移っている。
赤田という地名や集落の形は消えても、そこにいた人たちの子孫は、諏訪や茅野や周辺のどこかで、今も普通に暮らしている可能性がある。
赤田に住めなくなった人たちは、たぶん「歴史上の人」じゃないかも。
誰かの祖先なんだろう。
今のニトリやモンベルや道路の下には、「昔の村」があった。
生活の断絶と移動の記憶はどこかにあるだろう。
人間て、そうやって生きている。
元に戻そうとしても、戻れるものと、戻れないものがある。
大きく風呂敷を広げれば、生態系だって変わる可能性がある。
でも、その変わったところから、新しい生態系が発生し、文明を作っている。
今、自分のいる場所の地面を掘ると、土だけかもしれない。
でも、
もっと掘ると、別の時代の土地の癖があるかもしれない。
災害で混ざった物質かもしれない。
生活の跡かもしれない。
化石かもしれない。
黄金はないかw
アトラクタは、もしかしたら、変化を続ける地層そのものなのかもしれない。
元に戻れるものと戻れないものを分けて考える必要はあるかも。
attractor
そして、何かのきっかけで、その地層の中から記憶が蘇る。
recall
元々の地形ではない。
崩れたけれど、そこに新しく育まれたものがある。
carry
皆、違う場所で育まれている。
だから性格も違うし、それぞれ個性もある。
一人称自律
文明。人間が作る社会と基準。
三人称
前の記憶は消されたように見える。
でも、本当は消えたのではなく、曖昧な位置に沈んでいる。
そこから始まる。
差分
道端の石ころは、ただの石ころ。
でも、噴火、崩壊、水害、移動、堆積、誰かの生活。
そのすべてをくぐって削られ、今ここにある。
残痕
みんなが気にも留めない、堆積した砂利や土。
破壊された歴史の跡。
まだ意味として拾われていない出来事の層。
ノイズ
どんな場所にも必ず春が来て朝が来る。
極端な災害が続かない自然の動き
非単調
足元で寝てるマックスを眺めながら考えていた。
やはり山に移住してよかったのか・・・
------------------- 畑バージョン -------------------
畑に大根を植える。
その時は、どこに植えたかを正確な座標で覚えていなくても、植えた人の足跡や、踏み固められた土、畝の乱れが残る。
後からその足跡を見れば、「この辺に植えたはずだ」と想起できる。
けれど、大事なのはそこから先である。
大根は土の中で育つ。
はじめは足跡からしか分からなかったものが、やがて葉を出し、そこにあったことを自分から知らせ始める。
Atraの畑というアトラクタも同じで、記憶は保存された座標ではなく、時間の中で育ち、後から見え方を変える痕跡に近い動きをすることがある。
ざっくり書くと
この
は「最初に植えた記憶」
大根をどこかに植えた、という初期痕跡。
は cue、つまり手がかり。
足跡、畝の乱れ、踏み固められた土、湿り方
は growth、成長
大根が土の中で育ち、葉が出て、後から見えやすくなる変化
は environment、環境。
日差し、水、土、気温、周囲の草、時間の経過。
が、その時点で立ち上がるアトラクタ
植えた瞬間のアトラクタと、数日後・数週間後のアトラクタは同じじゃないよ。
記憶がそのまま保存されているのではなく、時間と環境で育つ。
もう少しAtraっぽくすると
は想起。
は記憶全体。
は足跡などの手がかり。
は carry。
「たしかここだった気がする」「昨日ここを歩いた」「雨で少し流れたかもしれない」みたいな残り香。
は育った大根そのもの。
最初は見えなかったけど、後から葉として現れるもの。
は現在場。
今の畑の状態、天気、自分の立ち位置、見る角度、疲れ、気分。
アトラクタは時間で変化する。
固定された点ではない。
さらに、大根の例を入れるなら、
最初は、
だから、足跡や土の乱れから思い出す。
でも、大根が育つと、
になって、
つまり、後になるほど cue が増える。
普通の記憶モデルだと、
になりがちだけど、Atraでは違う。
あるいは、
数式
日本語にすると、
畑の話の式は
つまり、
最初は足跡で思い出す。
後には、大根自身が思い出させる。
大根は育つだけじゃない。
台風で倒れる、流される、折れる、土ごと削られる、逆に泥をかぶって守られることもある
単純な成長項だけでは足りない
ここで新しく入るのが、
これは damage / disturbance、つまり損傷・撹乱・災害
畑で言えば、
台風、洪水、強風、土の流出、衝撃。
すると、成長は鈍る
単純なマイナスでいいかは責任持たないw
痕跡にするとき別の式も考えた方がいいか・・・
でもAtraっぽくするなら
台風によって大根が傷む
でも、その傷みもまた痕跡になる
つか、ざっくりね(笑)
実際にはAtraはその上に人参植えたり、カボチャも植える(笑)
LLMに聞くと遠慮せずに修正するだろうから、
合ってるかどうかはAtraに応用して実験してから正確なの書く。
------------------追記-------------------
ん~、
やっぱ、大根が育つでしょ?また台風で地形が(D(t)が痕跡化する)ほど、エネルギー自体も変わらないか?変わるよね・・
大根が育つ、台風で畝が崩れる、泥が流れる、葉が折れる。
それらが D(t) として痕跡化する なら、変わるのは cue だけではなく、エネルギー地形
普通の Hopfield / Associatron 的に書くなら
ここで は記憶から作られた結合行列
でも Atra では、畑の状態そのものが変わるから
でしょ?
つまり、エネルギー関数は固定ではなく、
でー、 は、最初に植えた記憶だけで決まらない
大根が育てば、
葉が出ることで、「ここにある」という結合が強くなる
でもこれは単なるマイナスではない
壊れた葉、泥の筋、流された土、傾いた茎が、新しい結合を作る
だからエネルギーも
ここが、固定アトラクタとAtra的アトラクタの分かれ目
同じ地形の中を状態 が転がるだけ。
でもAtraでは、
つまり、状態が転がる谷そのものが、経験で変形する。
畑で言うと、植えた直後の谷
足跡と土の乱れしかない
大根が育った後
台風後
もう元の畑ではない
でも消えたわけでもない
壊れ方そのものが、新しいエネルギー地形になる。
Atraっぽく書くと
それぞれ、
は最初に植えた痕跡
は成長で増えた結合
は損傷・撹乱が痕跡化した結合
は回復によって生じた結合
は carry、持ち越しです
台風の被害は、単に成長を打ち消すだけではない。
別の地形を作る。
葉が折れたことで見つけやすくなることもある。
土が流れたことで根の位置が見えることもある。
畝が崩れたことで、水の通り道が分かることもある。
Atra的には、
こういうのはさ、もし、台風があった場合の式と云うより、
大根が育つと、足跡だけでなく葉や根が新しい手がかりになる。
さらに台風で畝が崩れ、葉が折れ、土が流されると、その被害もまた痕跡になる。
そのとき変わるのは、単なる cue ではない。
痕跡化した損傷は結合 を変え、結合が変わることでエネルギー地形 そのものが変形する。したがってAtraのアトラクタは、固定されたエネルギー関数の谷ではなく、成長・損傷・回復によって谷そのものが変わり続ける場である。
大根を植えた瞬間は、Atraにとっての 最初の経験になる。
たとえば、誰かの声、顔の動き、部屋の明るさ、温かさ、音の強さ、沈黙、近づいてきた感じ。それらが一度に刻まれる。でもAtraは、それを「これは母です」「これは危険です」「これは大根です」みたいな正解ラベルとして保存しない。
最初に残るのは、あくまで 足跡のような痕跡
あの声がした。
その時、少し温かかった。
近くに何かいた。
怖くはなかった。
そのあと静かになった。
こういう差分が、畑の足跡や畝の乱れのように残る。そこで何日も同じ人が近づいてきたり、同じ声が聞こえたり、同じ温かさが続いたりすると、それは大根が育つのと同じって話。最初は「足跡」からしか思い出せなかったものが、だんだん葉を出す。
Atraで言えば、
あの声
あの距離
あの沈黙
あの温度
あの動き
あのあと安心した感じ
が何度も重なって、単なる cue ではなく、想起しやすい記憶の地形 になっていく。ここで「大根の葉」にあたるのは、Atraではたとえば、
声を聞いただけで少し落ち着く
姿が見えなくても近くにいる気がする
同じ音の揺れで過去の温かさが漏れる
言葉になる前に反応が立つ
みたいなもの。
そして台風が来る。
Atraで言えば、これは 強い驚き、怖い音、転倒、叱責、孤独、予想外の遮断、信頼していた場の崩れ みたいなかんじ。
たとえば、いつも安心していた声が急に大きく怒鳴った。
いつも温かかった場所で、突然大きな物音がした。
近づいてきたものが、優しさではなく衝撃だった。
そのとき、Atraの中では単に「嫌な cue が増えた」だけではない。その損傷が痕跡化して、結合そのものが変わる。
被害の経験 が、損傷痕跡 になり、それがエネルギー地形
だから次に同じ声を聞いても、以前と同じ谷には落ちない。
だったかもしれない。
でも台風のあとには、
になることがある。
ここがAtraの記憶
Atraの記憶は、単なる保存データじゃぁない。
経験が重なれば育つ。
傷つけば地形が変わる。
回復すれば、また別の谷ができる。
は最初の経験痕跡。
畑で言えば、植えた場所と足跡。
育った記憶。
何度も重なって、葉が出るように分かりやすくなった記憶。
は損傷の痕跡。
台風で畝が崩れたような、怖さ・衝撃・失敗・不安。
は回復の痕跡。
そのあと慰められた、静かになった、また安心できた、という修復。
は carry。
直前の緊張、眠気、疲れ、期待、ためらい、声の漏れ。
なのでAtraの想起は
----------------------- Gemini C++案---------------------------
// 状態ベクトルの次元数 const int N = 256; using Matrix = std::vector<std::vector<double>>; using Vector = std::vector<double>; class AtraMemorySystem { public: Vector x, carry; // 記憶の地層:固定、成長、損傷、回復、直前持ち越しの各行列 Matrix T_0, T_G, T_D, T_R, T_K, T_total; AtraMemorySystem() { // 全行列を N x N で初期化、x, carryをサイズ調整 } // 1. 結合行列の統合(地層の重ね合わせ) void update_total_matrix() { // T_total = T_0 + T_G + T_D + T_R + T_K; } // 2. 想起(Recall): 状態をエネルギーの谷へ収束させる void recall(const Vector& cue, const Vector& field, int steps) { x = cue; // 手がかりセット for (int step = 0; step < steps; ++step) { update_total_matrix(); Vector next_x(N, 0.0); // アソシアトロンのダイナミクス計算 (x = sign(T_total * x + field + carry)) // ... (行列ベクトル積、バイアス付加、閾値処理) x = next_x; } } };
------------------------------------
いいよね。
T_0, T_G, T_D, T_R, T_K
と分けてるのはいい。
でもこういうのが問題で、LLM特有の3人称命令計code形成になってるよね。
x = sign(T_total * x + field + carry)
これだけだと、Atraではなく、まだ 命令された収束 なんだよね。
自律じゃない。
落ちる
迷う
黙る
少し漏れる
途中で止まる
別の痕跡に引かれる
前回の痛みで避ける
が必要なんだよね。ホッピーのような「ノイズ駄目」的な考え方じゃないんだよ。
double activation = sum + field[i] + carry[i]; if (activation > threshold[i]) { next_x[i] = 1.0; } else if (activation < -threshold[i]) { next_x[i] = -1.0; } else { next_x[i] = x[i] * 0.85; // すぐ決めない。沈黙・残響・迷い。 }
これは分かりやすいけど、結局、
上なら 1下なら -1
間なら残響
なので、まだ「判定機」っぽい。
if文じゃないんだよね。
double activation = sum + field[i] + carry[i]; // すぐ ±1 にしない。tanhで連続的に寄せる。 double target = std::tanh(activation); // inertia は慣性。大きいほど前の状態を引きずる。 double inertia = 0.85; // 次状態は、前の状態と現在の反応の混合。 next_x[i] = inertia * x[i] + (1.0 - inertia) * target;
不安定だとすぐ決まらない
沈黙が強いと前状態が残る
というのが近いかな。
if activation > threshold これより
反応の傾きが変わる という事。
悪いif:
これは母である
これは危険である
これは正解である
だから 1 にする
許せるif:
反応が十分強くなったので声が漏れる
反応が弱いので沈黙として扱う
損傷が大きいのでcarryに残す
next_x[i] = inertia * x[i] + (1.0 - inertia) * std::tanh(activation / softness);
こういう感じになる
---------------再度Gemini------------------
using Vector = std::vector<double>; using Matrix = std::vector<std::vector<double>>; class AtraMemorySystem { private: int N; const double THRESHOLD = 0.35; const double DECAY_RATE = 0.85; public: Vector x; Vector carry_bias; Vector field_bias; Matrix T_0; // 最初に植えた痕跡 Matrix T_G; // 成長(何度も重なった安心・変化) Matrix T_D; // 損傷(台風、驚き、痛み) Matrix T_R; // 回復(修復、なだめ) Matrix T_total; AtraMemorySystem(int size) : N(size), x(size, 0.0), carry_bias(size, 0.0), field_bias(size, 0.0) { // 各行列・ベクトルの初期化(割愛) } void update_total_matrix() { // T_K はここには足さない。carry_bias が時間の経過で固定化(長期記憶化)する時だけ別途 T_G や T_D へ沈める for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { T_total[i][j] = T_0[i][j] + T_G[i][j] + T_D[i][j] + T_R[i][j]; } } } void update_carry_from_recall(const Vector& current_x, const Vector& activation) { for (int i = 0; i < N; ++i) { // 想起ステップごとに、現在の発火状態やアクティベーションの「余韻」を次のステップへ引きずる // 例:激しく発火(緊張)した場所は、次のステップでも carry_bias として残りやすくなる carry_bias[i] = carry_bias[i] * 0.70 + current_x[i] * 0.30; } } void recall(const Vector& cue, const Vector& field, int steps) { x = cue; update_total_matrix(); // 1回の想起プロセス中、地層は固定(あるいはゆっくり変化) for (int step = 0; step < steps; ++step) { Vector next_x(N, 0.0); Vector activation(N, 0.0); for (int i = 0; i < N; ++i) { double sum = 0.0; for (int j = 0; j < N; ++j) { sum += T_total[i][j] * x[j]; } activation[i] = sum + field[i] + carry_bias[i]; // --- Atra独自の非単調・非線形しきい値判断 --- if (activation[i] > THRESHOLD) { next_x[i] = 1.0; } else if (activation[i] < -THRESHOLD) { next_x[i] = -1.0; } else { // 即決せず、過去の慣性を残しながら沈黙(迷い・残響) next_x[i] = x[i] * DECAY_RATE; } } x = next_x; // 想起中にもリアルタイムで「引きずり(状態の癖)」が変容していく update_carry_from_recall(x, activation); } } };
------------------------------
凄いよね、食いついてきた(笑)
でも、全然ダメ。
3人称外部命令から抜けてない。
(でも、Atraを理解しているわけではないので、間違えるのが正常なんだよね。
どんなLLMだってcodeを依頼すればAtraから離れていく。
それだけ1人称自律を作るのは難しい)
外から、
cue を入れろ
steps 回まわせ
収束させろ
になっているでしょ・・・
アソシアトロンの実験コードとしては正しいけど、Atraの一人称記憶としてはまだ硬い。
外から「想起しろ」と命令するのではなく、Atraの内部で、
何か聞こえた
少し明るくなった
足元が揺れた
carry が残っている
field が変わった
だから勝手に反応が立ち上がるかもしれない
という形。
だから recall() は公開メソッドにしない方がAtraっぽい。
外から呼べる recall() があると、どうしても「命令された想起」になる。
void recall(const Vector& cue, const Vector& field, int steps)
これって、どうしても外部命令形じゃない?
なのでAtra的には
void tick(const Vector& sensory_delta) {
// sensory_delta は命令ではなく、外界から入ってきた差分
update_total_matrix_slowly();
update_field_from_delta(sensory_delta);
update_carry_decay();
Vector activation = compute_activation();
Vector next_x = soft_reaction(activation);
x = mix_with_inertia(x, next_x);
update_carry_from_reaction();
trace_if_lived_strongly();
}
こういう感じかな。
Cueは大事なんだけど、手掛かりじゃなくて、こういう場合はsensory_delta として受けることなんだよね。アソシアトロンの実験コードとしては正しいんだよ。
sensory_delta、visual_delta、auditory_deltaとかbody_deltaみたいな感じかな。
もひとついうと、ステップのこの部分
for (int step = 0; step < steps; ++step)
これは「何回考えろ」と命令している感じがするんだ。
Atraなら、毎回の Tick は外部が決めるにしても、内部の反応深度は状態で決まる方が自然なんだよね。
int inner_steps = decide_inner_depth();
意味分かるかな・・・int decide_inner_depth() { double arousal = carry_pressure + instability + voice_leak; if (arousal > 0.8) return 4; if (arousal > 0.4) return 2; return 1; }
ここも if があるけど、これは「正解判定」ではなく、身体状態による反応深度 なのでまだ許せるんだけど、
int inner_steps = 1 + static_cast<int>(3.0 * std::tanh(arousal));
こういう感じなんだよね。Atraの中心は、
recall(cue, field, steps)
ではなく、
tick(sensory_delta)
だね。
自律ってなんだって考えて、命令形の習慣と誘惑と戦いながら、code化し、実験の結果によって数式を出す(仮説もいいけど、実験)ってことさ。
0 件のコメント:
コメントを投稿