muooon commited on
Commit
be97c9c
·
verified ·
1 Parent(s): 73d5b42

Upload 4 files

Browse files
2Gv38_AutoLR/emoairy.py CHANGED
@@ -1,180 +1,180 @@
1
- import torch
2
- from torch.optim import Optimizer
3
- import math
4
-
5
- """
6
- EmoAiry v3.8.0 (260130) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
- emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
- EmoAiry v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
- EmoFact v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
10
- emoPulse 機構により完全自動化を目指す(ユーザーによる emoScope 調整可/改善度反映率)
11
- dNR係数により emoPulse に履歴を混ぜて安定させた(d / N 履歴 による信頼度の維持)
12
- Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
13
- """
14
-
15
- class EmoAiry(Optimizer):
16
- # クラス定義&初期化
17
- def __init__(self, params, lr=1.0, eps=1e-8, betas=(0.9, 0.995),
18
- weight_decay=0.01, use_shadow:bool=False):
19
- defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
20
- super().__init__(params, defaults)
21
- self._init_lr = lr
22
- self.should_stop = False # 停止フラグの初期化
23
- self.use_shadow = use_shadow # 🔸shadow 使用フラグを保存
24
- self.emoScope = lr # 動的学習率の調和とリズム
25
- self.dNR_hist = 1.0 # emoPulse hist 初期化
26
- self.noise_est = 1.0 # emoPulse nest 初期化
27
- self.d_est = 0.02 # emoPulse dest 初期化
28
-
29
- # 感情EMA更新(緊張と安静)
30
- def _update_ema(self, state, loss_val):
31
- ema = state.setdefault('ema', {})
32
- ema['short'] = 0.3 * loss_val + 0.7 * ema.get('short', loss_val)
33
- ema['medium'] = 0.05 * loss_val + 0.95 * ema.get('medium', loss_val)
34
- ema['long'] = 0.01 * loss_val + 0.99 * ema.get('long', loss_val)
35
- return ema
36
-
37
- # 感情スカラー値生成(EMA差分、滑らかな非線形スカラー、tanh(diff) ±1.0 で有界性)
38
- # 係数"1":ema差分 のスケール調整処理に活用(感度調節係数)/通常は1(タスクに応じ調整可(非推奨))
39
- # scale_base:Loss値とema値の乖離を修正(分母 ema(long) 「改善率」共通化/loss種に非依存)
40
- # 1e-5(デフォルト)/1e-6(感度向上)/1e-4(安定性向上):分母を0にせず安定させる
41
- # トラウマ的反応や慣れによる鈍化で安定性向上(ema-medium 安定と急変を信頼度で感知)
42
- def _compute_scalar(self, ema):
43
- scale_base_l = max(ema['long'], 1e-5)
44
- scale_base_m = max(ema['medium'], 1e-5)
45
- diff_base = ema['long'] - ema['short']
46
- diff_l = diff_base / scale_base_l
47
- diff_m = diff_base / scale_base_m
48
- # longが十分静かなら、常にlongを優先
49
- if abs(diff_l) < 0.05:
50
- return math.tanh(diff_l)
51
- # longが静かでない時のみ、mediumの静けさを条件付きで採用
52
- if abs(diff_m) * scale_base_m < abs(diff_l) * scale_base_l:
53
- return math.tanh(diff_m)
54
- else:
55
- return math.tanh(diff_l)
56
-
57
- # (重要)現在は shadow-effect を参考に得た動的フィルタ効果の近似により use_shadow=False です
58
- # しかし全機能は shadow なしで全て成立します/コード確認時はこの shadow を考慮外として無視してください
59
- # Shadow混合比 3段階構成 タスクに応じ調整可、以下を参考に 開始値・範囲量・変化幅を調整
60
- # return 開始値 + ((scalar) - 閾値) / 範囲量 * 変化幅 も可能(特殊用途向け)
61
- def _decide_ratio(self, scalar):
62
- if not self.use_shadow:
63
- return 0.0 # 🔸use_shadow = False のとき常に比率を 0 にする
64
- if abs(scalar) > 0.625:
65
- return 1.0 - abs(scalar) # 急変|強抑制|tanh 0.73(0.27)
66
- else:
67
- return 0.0 # return<0 の場合は leap 専用(書き戻しはしないが履歴更新のみ)
68
-
69
- # 損失取得(損失値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
70
- @torch.no_grad()
71
- def step(self, closure=None):
72
- loss = closure() if closure is not None else None
73
- loss_val = loss.item() if loss is not None else 0.0
74
-
75
- # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
76
- ema = self._update_ema(self.state, loss_val)
77
- scalar = self._compute_scalar(ema)
78
- ratio = self._decide_ratio(scalar)
79
- trust = math.copysign((1.0 - abs(scalar)), scalar)
80
-
81
- # --- Start emoPulse (完全自動LR生成) ---
82
- # emoPulse (loss 時系列から D / Noise を推定し完全自動LRを生成)
83
- # d / N 履歴 (時間的D推定)
84
- self.noise_est = 0.97 * self.noise_est + 0.03 * abs(scalar)
85
- self.d_est = 0.97 * self.d_est + 0.03 * abs(trust)
86
- noise = max(self.noise_est, 1e-10) # max:1e-12程度(変更後:要アーリーストップ見直し)
87
- d = self.d_est
88
- # scalar、trust、の差分(瞬間的D推定)と各時間軸の確度推定(疑念と信頼の綱引き)
89
- Noise_base = abs(scalar - trust) + 0.1
90
- d_base = abs(noise - d) + 0.1
91
- # SNRにより異なる時間的確度比率から更新力を導出し2乗で出力最大化
92
- dNR_now_val = (d_base / Noise_base) ** 2
93
- # db / Nb dNR(SNR) 履歴化と最大値の成長率の増減
94
- if dNR_now_val >= self.dNR_hist and trust >= 0.5:
95
- # 加速:どんなに SNR が高くても、1.50倍という「歩幅」の成長制限
96
- self.dNR_hist = min(dNR_now_val, self.dNR_hist * 1.50)
97
- elif -0.5 <= trust <= 0.5:
98
- # 減速:怪しい時は即座に比率を下げる(確実に信頼できない場合に下げ圧力を溜める)
99
- self.dNR_hist = dNR_now_val * 0.80
100
- # emoPulse 最終決定: emoScorp によるユーザー意思の反映と安全値による制限
101
- emoPulse = max(min(self.dNR_hist * (self.emoScope * 1e-4), 3e-3), 1e-6)
102
- # --- End emoPulse (完全自動LR生成) ---
103
-
104
- for group in self.param_groups:
105
- for p in group['params']:
106
- if p.grad is None:
107
- continue
108
-
109
- grad = p.grad
110
- state = self.state[p]
111
- d_p = grad.shape
112
-
113
- # 動的学習率補正により shadow 形成を信頼度で調整(trustは正値化(負にならない))
114
- # shadow:必要時のみ(スパイクp部分に現在値を最大10%追従させる動的履歴更新)
115
- # 混合比率:スカラーが閾値を超える場合にのみ計算される(信頼できる感情信号かどうかの選別)
116
- # 急変時は感情機構による shadow 混合で強く抑制する(急制動による安定性の確保)
117
- # shadow-system は動的学習率と信頼度で協調し選択的スパース性も発揮する
118
- if self.use_shadow :
119
- if 'shadow' not in state: # 🔸shadow = False (デフォルト)
120
- state['shadow'] = p.clone()
121
- if ratio > 0: # 書き戻しと履歴更新(急変時の強い抑制と弱めの履歴更新)
122
- p.mul_(1-ratio).add_(state['shadow'], alpha=abs(trust))
123
- else: # 書き戻しせず履歴更新のみ:10%×trust
124
- leap_ratio = 0.1 * abs(trust)
125
- state['shadow'].lerp_(p, leap_ratio)
126
-
127
- # --- Start Gradient Update Logic ---
128
- # 行列の形状が2次元以上の場合、分散情報ベースのAB近似を使用
129
- # 判定:2次元以上かつ「低ランク化」でメモリコストが全体の 5% 以下の場合に適用
130
- if grad.dim() >= 2 and ((d_p[0] + d_p[1]) / p.numel()) < 0.05:
131
- # 行と列の2乗平均を計算 (分散の軽量な近似)
132
- r_sq = torch.mean(grad * grad, dim=tuple(range(1, grad.dim())), keepdim=True).add_(group['eps'])
133
- c_sq = torch.mean(grad * grad, dim=0, keepdim=True).add_(group['eps'])
134
-
135
- # 分散情報から勾配の近似行列を生成
136
- # AB行列として見立てたものを直接生成し更新項を計算する
137
- # A = sqrt(r_sq), B = sqrt(c_sq) AB行列の近似を再現しEMAで平滑化する
138
- beta1, beta2 = group['betas']
139
- state.setdefault('exp_avg_r', torch.zeros_like(r_sq)).mul_(beta1).add_(torch.sqrt(r_sq), alpha=1 - beta1)
140
- state.setdefault('exp_avg_c', torch.zeros_like(c_sq)).mul_(beta1).add_(torch.sqrt(c_sq), alpha=1 - beta1)
141
-
142
- # 再構築した近似勾配の平方根の積で正規化
143
- denom = torch.sqrt(state['exp_avg_r'] * state['exp_avg_c']).add_(group['eps'])
144
- # 最終的な更新項を計算
145
- update_term = grad / denom
146
-
147
- # 1次元(ベクトル)/小行列の勾配補正
148
- else:
149
- # 今の勾配の平均絶対値でスケーリング
150
- # 現在の勾配の符号のみ履歴を持たずメモリ消費を抑える
151
- denom = grad.abs().mean().add_(group['eps'])
152
- # 最終的な更新項を計算
153
- update_term = grad / denom
154
-
155
- # 最終的なパラメータ更新 (decoupled weight decayも適用)
156
- # sign化で2次momentと1次ベクトルのバランス改善
157
- p.add_(p, alpha=-group['weight_decay'] * emoPulse)
158
- p.add_(update_term.sign_(), alpha=-emoPulse)
159
- # --- End Gradient Update Logic ---
160
-
161
- # ���ーザー指定初期LRを実効値(emoPulse)で可視化する(PyTorch標準)
162
- for group in self.param_groups:
163
- group['lr'] = emoPulse
164
-
165
- # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
166
- # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
167
- # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
168
- if abs(scalar) <= 1e-6 and abs(Noise_base - d_base) <= 1e-7:
169
- self.should_stop = True # 💡 外部からこれを見て判断可
170
- self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
171
- else:
172
- self.should_stop = False # 💡 誤判定などの取り消し
173
-
174
- return
175
-
176
- """
177
- https://github.com/muooon/EmoSens
178
- Airy is inspired by Adafactor, and emofact,
179
- and its VRAM-friendly design is something everyone loves.
180
- """
 
1
+ import torch
2
+ from torch.optim import Optimizer
3
+ import math
4
+
5
+ """
6
+ EmoAiry v3.8.1 (260202) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
+ emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
+ EmoAiry v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
+ EmoFact v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
10
+ emoPulse 機構により完全自動化を目指す(ユーザーによる emoScope 調整可/改善度反映率)
11
+ dNR係数により emoPulse に履歴を混ぜて安定させた(d / N 履歴 による信頼度の維持)
12
+ Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
13
+ """
14
+
15
+ class EmoAiry(Optimizer):
16
+ # クラス定義&初期化
17
+ def __init__(self, params,
18
+ lr=1.0,
19
+ eps=1e-8,
20
+ betas=(0.9, 0.995),
21
+ weight_decay=0.01,
22
+ use_shadow:bool=False):
23
+ defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
24
+ super().__init__(params, defaults)
25
+ self._init_lr = lr
26
+ self.should_stop = False # 停止フラグの初期化
27
+ self.use_shadow = use_shadow # 🔸shadow 使用フラグを保存
28
+ self.emoScope = lr # 動的学習率の調和とリズム
29
+ self.dNR_hist = 1.0 # emoPulse hist 初期化
30
+ self.noise_est = 1.0 # emoPulse nest 初期化
31
+ self.d_est = 0.02 # emoPulse dest 初期化
32
+
33
+ # 感情EMA更新(緊張と安静)
34
+ def _update_ema(self, state, loss_val):
35
+ ema = state.setdefault('ema', {})
36
+ ema['short'] = 0.3 * loss_val + 0.7 * ema.get('short', loss_val)
37
+ ema['medium'] = 0.05 * loss_val + 0.95 * ema.get('medium', loss_val)
38
+ ema['long'] = 0.01 * loss_val + 0.99 * ema.get('long', loss_val)
39
+ return ema
40
+
41
+ # 感情スカラー値生成(EMA差分、滑らかな非線形スカラー、tanh(diff) は ±1.0 で有界性)
42
+ # 係数"1":ema差分 のスケール調整処理に活用(感度調節係数)/通常は1(タスクに応じ調整可(非推奨))
43
+ # scale_base:Loss値とema値の乖離を修正(分母 ema(long) 「改善率」共通化/loss種に非依存)
44
+ # 1e-5(デフォルト)/1e-6(感度向上)/1e-4(安定性向上):分母を0にせず安定させる
45
+ # トラウマ的反応や慣れによる鈍化で安定性向上(ema-medium 安定と急変を信頼度で感知)
46
+ def _compute_scalar(self, ema):
47
+ scale_base_l = max(ema['long'], 1e-5)
48
+ scale_base_m = max(ema['medium'], 1e-5)
49
+ diff_base = ema['long'] - ema['short']
50
+ diff_l = diff_base / scale_base_l
51
+ diff_m = diff_base / scale_base_m
52
+ # longが十分静かなら、常にlongを優先
53
+ if abs(diff_l) < 0.05:
54
+ return math.tanh(diff_l)
55
+ # longが静かでない時のみ、mediumの静けさを条件付きで採用
56
+ if abs(diff_m) * scale_base_m < abs(diff_l) * scale_base_l:
57
+ return math.tanh(diff_m)
58
+ else:
59
+ return math.tanh(diff_l)
60
+
61
+ # (重要)現在は shadow-effect を参考に得た動的フィルタ効果の近似により use_shadow=False です
62
+ # しかし全機能は shadow なしで全て成立します/コード確認時はこの shadow を考慮外として無視してください
63
+ # Shadow混合比 3段階構成 タスクに応じ調整可、以下を参考に 開始値・範囲量・変化幅を調整
64
+ # return 開始値 + ((scalar) - 閾値) / 範囲量 * 変化幅 も可能(特殊用途向け)
65
+ def _decide_ratio(self, scalar):
66
+ if not self.use_shadow:
67
+ return 0.0 # 🔸use_shadow = False のとき常に比率を 0 にする
68
+ if abs(scalar) > 0.625:
69
+ return 1.0 - abs(scalar) # 急変|強抑制|tanh 0.73(0.27)
70
+ else:
71
+ return 0.0 # return<0 の場合は leap 専用(書き戻しはしないが履歴更新のみ)
72
+
73
+ # 損失取得(損���値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
74
+ @torch.no_grad()
75
+ def step(self, closure=None):
76
+ loss = closure() if closure is not None else None
77
+ loss_val = loss.item() if loss is not None else 0.0
78
+
79
+ # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
80
+ ema = self._update_ema(self.state, loss_val)
81
+ scalar = self._compute_scalar(ema)
82
+ ratio = self._decide_ratio(scalar)
83
+ trust = math.copysign((1.0 - abs(scalar)), scalar)
84
+
85
+ # --- Start emoPulse (完全自動LR生成) ---
86
+ # emoPulse (loss 時系列から D / Noise を推定し完全自動LRを生成)
87
+ # d / N 履歴 (時間的D推定)
88
+ self.noise_est = 0.97 * self.noise_est + 0.03 * abs(scalar)
89
+ self.d_est = 0.97 * self.d_est + 0.03 * abs(trust)
90
+ noise = max(self.noise_est, 1e-10) # max:1e-12程度(変更後:要アーリーストップ見直し)
91
+ d = self.d_est
92
+ # scalar、trust、の差分(瞬間的D推定)と各時間軸の確度推定(疑念と信頼の綱引き)
93
+ Noise_base = abs(scalar - trust) + 0.1
94
+ d_base = abs(noise - d) + 0.1
95
+ # SNRにより異なる時間的確度比率から更新力を導出し2乗で出力最大化
96
+ dNR_now_val = (d_base / Noise_base) ** 2
97
+ # db / Nb dNR(SNR) 履歴化と最大値の成長率の増減
98
+ if dNR_now_val >= self.dNR_hist and trust >= 0.5:
99
+ # 加速:どんなに SNR が高くても、1.50倍という「歩幅」の成長制限
100
+ self.dNR_hist = min(dNR_now_val, self.dNR_hist * 1.50)
101
+ elif -0.5 <= trust <= 0.5:
102
+ # 減速:怪しい時は即座に比率を下げる(確実に信頼できない場合に下げ圧力を溜める)
103
+ self.dNR_hist = dNR_now_val * 0.80
104
+ # emoPulse 最終決定: emoScorp によるユーザー意思の反映と安全値による制限
105
+ emoPulse = max(min(self.dNR_hist * (self.emoScope * 1e-4), 3e-3), 1e-6)
106
+ # --- End emoPulse (完全自動LR生成) ---
107
+
108
+ for group in self.param_groups:
109
+ beta1, beta2 = group['betas']
110
+ for p in group['params']:
111
+ if p.grad is None:
112
+ continue
113
+
114
+ grad = p.grad
115
+ state = self.state[p]
116
+
117
+ # 動的学習率補正により shadow 形成を信頼度で調整(trustは正値化(負にならない))
118
+ # shadow:必要時のみ(スパイクp部分に現在値を最大10%追従させる動的履歴更新)
119
+ # 混合比率:スカラーが閾値を超える場合にのみ計算される(信頼できる感情信号かどうかの選別)
120
+ # 急変時は感情機構による shadow 混合で強く抑制する(急制動による安定性の確保)
121
+ # shadow-system は動的学習率と信頼度で協調し選択的スパース性も発揮する
122
+ if self.use_shadow :
123
+ if 'shadow' not in state: # 🔸shadow = False (デフォルト)
124
+ state['shadow'] = p.clone()
125
+ if ratio > 0: # 書き戻しと履歴更新(急変時の強い抑制と弱めの履歴更新)
126
+ p.mul_(1-ratio).add_(state['shadow'], alpha=abs(trust))
127
+ else: # 書き戻しせず履歴更新のみ:10%×trust
128
+ leap_ratio = 0.1 * abs(trust)
129
+ state['shadow'].lerp_(p, leap_ratio)
130
+
131
+ # --- Start Gradient Update Logic ---
132
+ # 行列の形状が2次元以上の場合、分散情報ベースのAB近似を使用
133
+ if grad.dim() >= 2:
134
+ # 行と列の2乗平均を計算 (分散の軽量な近似)
135
+ r_sq = torch.mean(grad * grad, dim=tuple(range(1, grad.dim())), keepdim=True).add_(group['eps'])
136
+ c_sq = torch.mean(grad * grad, dim=0, keepdim=True).add_(group['eps'])
137
+
138
+ # 分散情報から勾配の近似行列を生成
139
+ # AB行列として見立てたものを直接生成し更新項を計算する
140
+ # A = sqrt(r_sq), B = sqrt(c_sq) AB行列近似を再現し履歴化で平滑化する
141
+ state.setdefault('exp_avg_r', torch.zeros_like(r_sq)).mul_(beta1).add_(torch.sqrt(r_sq), alpha=1 - beta1)
142
+ state.setdefault('exp_avg_c', torch.zeros_like(c_sq)).mul_(beta1).add_(torch.sqrt(c_sq), alpha=1 - beta1)
143
+
144
+ # 再構築した近似勾配の平方根の積で正規化
145
+ denom = torch.sqrt(state['exp_avg_r'] * state['exp_avg_c']).add_(group['eps'])
146
+ # 最終的な更新項を計算
147
+ update_term = grad / denom
148
+
149
+ # 1次元(ベクトル)の勾配(履歴化せず瞬間値にする)
150
+ else:
151
+ # 最終的な更新項を計算
152
+ update_term = grad
153
+
154
+ # 最終的なパラメータ更新 (decoupled weight decayも適用)
155
+ # [テンソル]2D以上:不正確、1D:正確、[履歴]2D以上:正確化、1D:ナシ、でバランス改善
156
+ # sign化で2次momentと1次ベクトルのデータの質(粒度)を揃える
157
+ p.mul_(1.0 - group['weight_decay'] * emoPulse)
158
+ p.add_(update_term.sign_(), alpha=-emoPulse)
159
+ # --- End Gradient Update Logic ---
160
+
161
+ # ユーザー指定初期LRを実効値(emoPulse)で可視化する(PyTorch標準)
162
+ for group in self.param_groups:
163
+ group['lr'] = emoPulse
164
+
165
+ # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
166
+ # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
167
+ # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
168
+ if abs(scalar) <= 5e-6 and abs(Noise_base - d_base) <= 5e-7:
169
+ self.should_stop = True # 💡 外部からこれを見て判断可
170
+ self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
171
+ else:
172
+ self.should_stop = False # 💡 誤判定などの取り消し
173
+
174
+ return
175
+
176
+ """
177
+ https://github.com/muooon/EmoSens
178
+ Airy is inspired by Adafactor, and emofact,
179
+ and its VRAM-friendly design is something everyone loves.
180
+ """
2Gv38_AutoLR/emocats.py CHANGED
@@ -1,10 +1,9 @@
1
  import torch
2
  from torch.optim import Optimizer
3
  import math
4
- from typing import Callable
5
 
6
  """
7
- EmoCats v3.8.0 (260130) shadow-system v3.1 -moment v3.1 emoPulse v3.7.1
8
  emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
9
  EmoCats v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
10
  EmoLynx v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
@@ -13,14 +12,14 @@ dNR係数により emoPulse に履歴を混ぜて安定させた(d / N 履歴
13
  Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
14
  """
15
 
16
- # Helper function
17
- def exists(val):
18
- return val is not None
19
-
20
  class EmoCats(Optimizer):
21
- # クラス定義&初期化 ベータ・互換性の追加
22
- def __init__(self, params, lr=1.0, eps=1e-8, betas=(0.9, 0.995),
23
- weight_decay=0.01, use_shadow:bool=False):
 
 
 
 
24
  defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
25
  super().__init__(params, defaults)
26
  self._init_lr = lr
@@ -73,11 +72,8 @@ class EmoCats(Optimizer):
73
 
74
  # 損失取得(損失値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
75
  @torch.no_grad()
76
- def step(self, closure: Callable | None = None): # クロージャの型ヒントを追加
77
- loss = None
78
- if exists(closure): # 一貫性のためにexistsヘルパーを使う
79
- with torch.enable_grad():
80
- loss = closure()
81
  loss_val = loss.item() if loss is not None else 0.0
82
 
83
  # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
@@ -110,10 +106,8 @@ class EmoCats(Optimizer):
110
  # --- End emoPulse (完全自動LR生成) ---
111
 
112
  for group in self.param_groups:
113
- # 共通パラメータ抽出
114
- _wd_actual, beta1, beta2 = group['weight_decay'], *group['betas']
115
- # PGチェックにフィルタ
116
- for p in filter(lambda p: exists(p.grad), group['params']):
117
 
118
  grad = p.grad
119
  state = self.state[p]
@@ -138,15 +132,14 @@ class EmoCats(Optimizer):
138
  state['exp_avg'] = torch.zeros_like(p)
139
  exp_avg = state['exp_avg']
140
 
141
- # Stepweight decay : decoupled_wd
142
- p.mul_(1 - emoPulse * _wd_actual)
143
- beta1, beta2 = group['betas']
144
 
145
  # 勾配ブレンド
146
  blended_grad = grad.mul(1 - beta1).add(exp_avg, alpha=beta1)
147
 
148
  # 最終的なパラメータ更新
149
- p.add_(blended_grad.sign(), alpha = -emoPulse)
150
  exp_avg.mul_(beta2).add_(grad, alpha = 1 - beta2)
151
  # --- End Gradient Update Logic ---
152
 
@@ -169,5 +162,4 @@ class EmoCats(Optimizer):
169
  https://github.com/muooon/EmoSens
170
  Cats was developed with inspiration from Lion, Tiger, and emolynx,
171
  which we deeply respect for their lightweight and intelligent design.
172
- Cats also integrates EmoNAVI to enhance its capabilities.
173
  """
 
1
  import torch
2
  from torch.optim import Optimizer
3
  import math
 
4
 
5
  """
6
+ EmoCats v3.8.1 (260202) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
  emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
  EmoCats v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
  EmoLynx v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
 
12
  Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
13
  """
14
 
 
 
 
 
15
  class EmoCats(Optimizer):
16
+ # クラス定義&初期化
17
+ def __init__(self, params,
18
+ lr=1.0,
19
+ eps=1e-8,
20
+ betas=(0.9, 0.995),
21
+ weight_decay=0.01,
22
+ use_shadow:bool=False):
23
  defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
24
  super().__init__(params, defaults)
25
  self._init_lr = lr
 
72
 
73
  # 損失取得(損失値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
74
  @torch.no_grad()
75
+ def step(self, closure=None):
76
+ loss = torch.enable_grad()(closure)() if closure is not None else None
 
 
 
77
  loss_val = loss.item() if loss is not None else 0.0
78
 
79
  # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
 
106
  # --- End emoPulse (完全自動LR生成) ---
107
 
108
  for group in self.param_groups:
109
+ beta1, beta2 = group['betas']
110
+ for p in (p for p in group['params'] if p.grad is not None):
 
 
111
 
112
  grad = p.grad
113
  state = self.state[p]
 
132
  state['exp_avg'] = torch.zeros_like(p)
133
  exp_avg = state['exp_avg']
134
 
135
+ # decoupled weight decay
136
+ p.mul_(1.0 - group['weight_decay'] * emoPulse)
 
137
 
138
  # 勾配ブレンド
139
  blended_grad = grad.mul(1 - beta1).add(exp_avg, alpha=beta1)
140
 
141
  # 最終的なパラメータ更新
142
+ p.add_(blended_grad.sign_(), alpha = -emoPulse)
143
  exp_avg.mul_(beta2).add_(grad, alpha = 1 - beta2)
144
  # --- End Gradient Update Logic ---
145
 
 
162
  https://github.com/muooon/EmoSens
163
  Cats was developed with inspiration from Lion, Tiger, and emolynx,
164
  which we deeply respect for their lightweight and intelligent design.
 
165
  """
2Gv38_AutoLR/emosens.py CHANGED
@@ -3,7 +3,7 @@ from torch.optim import Optimizer
3
  import math
4
 
5
  """
6
- EmoSens v3.8.0 (260130) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
  emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
  EmoSens v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
  EmoNavi v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
@@ -14,8 +14,12 @@ Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減
14
 
15
  class EmoSens(Optimizer):
16
  # クラス定義&初期化
17
- def __init__(self, params, lr=1.0, eps=1e-8, betas=(0.9, 0.995),
18
- weight_decay=0.01, use_shadow:bool=False):
 
 
 
 
19
  defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
20
  super().__init__(params, defaults)
21
  self._init_lr = lr
@@ -102,6 +106,7 @@ class EmoSens(Optimizer):
102
  # --- End emoPulse (完全自動LR生成) ---
103
 
104
  for group in self.param_groups:
 
105
  for p in group['params']:
106
  if p.grad is None:
107
  continue
@@ -124,17 +129,17 @@ class EmoSens(Optimizer):
124
  state['shadow'].lerp_(p, leap_ratio)
125
 
126
  # --- Start Gradient Update Logic ---
127
- # 1次・2次モーメントを使った勾配補正(decoupled weight decay 構造に近い)
128
  exp_avg = state.setdefault('exp_avg', torch.zeros_like(p))
129
  exp_avg_sq = state.setdefault('exp_avg_sq', torch.zeros_like(p))
130
- beta1, beta2 = group['betas']
131
 
132
  exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1)
133
  exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
 
134
  denom = exp_avg_sq.sqrt().add_(group['eps'])
135
 
136
  if group['weight_decay']:
137
- p.add_(p, alpha=-group['weight_decay'] * emoPulse)
138
  p.addcdiv_(exp_avg, denom, value=-emoPulse)
139
  # --- End Gradient Update Logic ---
140
 
@@ -145,7 +150,7 @@ class EmoSens(Optimizer):
145
  # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
146
  # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
147
  # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
148
- if abs(scalar) <= 1e-6 and abs(Noise_base - d_base) <= 1e-7:
149
  self.should_stop = True # 💡 外部からこれを見て判断可
150
  self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
151
  else:
 
3
  import math
4
 
5
  """
6
+ EmoSens v3.8.1 (260202) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
  emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
  EmoSens v3.7.6 (260109) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
  EmoNavi v3.6 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
 
14
 
15
  class EmoSens(Optimizer):
16
  # クラス定義&初期化
17
+ def __init__(self, params,
18
+ lr=1.0,
19
+ eps=1e-8,
20
+ betas=(0.9, 0.995),
21
+ weight_decay=0.01,
22
+ use_shadow:bool=False):
23
  defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
24
  super().__init__(params, defaults)
25
  self._init_lr = lr
 
106
  # --- End emoPulse (完全自動LR生成) ---
107
 
108
  for group in self.param_groups:
109
+ beta1, beta2 = group['betas']
110
  for p in group['params']:
111
  if p.grad is None:
112
  continue
 
129
  state['shadow'].lerp_(p, leap_ratio)
130
 
131
  # --- Start Gradient Update Logic ---
132
+ # 1次・2次モーメントを使った勾配補正(decoupled weight decay)
133
  exp_avg = state.setdefault('exp_avg', torch.zeros_like(p))
134
  exp_avg_sq = state.setdefault('exp_avg_sq', torch.zeros_like(p))
 
135
 
136
  exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1)
137
  exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
138
+
139
  denom = exp_avg_sq.sqrt().add_(group['eps'])
140
 
141
  if group['weight_decay']:
142
+ p.mul_(1.0 - group['weight_decay'] * emoPulse)
143
  p.addcdiv_(exp_avg, denom, value=-emoPulse)
144
  # --- End Gradient Update Logic ---
145
 
 
150
  # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
151
  # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
152
  # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
153
+ if abs(scalar) <= 5e-6 and abs(Noise_base - d_base) <= 5e-7:
154
  self.should_stop = True # 💡 外部からこれを見て判断可
155
  self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
156
  else:
2Gv38_AutoLR/emotion.py CHANGED
@@ -1,185 +1,185 @@
1
- import torch
2
- from torch.optim import Optimizer
3
- import math
4
- from typing import Callable
5
-
6
- """
7
- EmoTion v3.8.0 (260130) shadow-system v3.1 -moment v3.1 emoPulse v3.8
8
- emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
9
- EmoTion v3.7.6 (260120) shadow-system v3.1 -moment v3.1 emoPulse v3.7
10
- All-Emo v3.6, v3.7 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
11
- emoPulse 機構により完全自動化を目指す(ユーザーによる emoScope 調整可/改善度反映率)
12
- dNR係数により emoPulse に履歴を混ぜて安定させた(d / N 履歴 による信頼度の維持)
13
- Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
14
- """
15
-
16
- # Helper function
17
- def exists(val):
18
- return val is not None
19
-
20
- class EmoTion(Optimizer):
21
- # クラス定義&初期化 ベータ・互換性の追加
22
- def __init__(self, params, lr=1.0, eps=1e-8, betas=(0.9, 0.995),
23
- weight_decay=0.01, use_shadow:bool=False):
24
- defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
25
- super().__init__(params, defaults)
26
- self._init_lr = lr
27
- self.should_stop = False # 停止フラグの初期化
28
- self.use_shadow = use_shadow # 🔸shadow 使用フラグを保存
29
- self.emoScope = lr # 動的学習率の調和とリズム
30
- self.dNR_hist = 1.0 # emoPulse hist 初期化
31
- self.noise_est = 1.0 # emoPulse nest 初期化
32
- self.d_est = 0.02 # emoPulse dest 初期化
33
-
34
- # 感情EMA更新(緊張と安静)
35
- def _update_ema(self, state, loss_val):
36
- ema = state.setdefault('ema', {})
37
- ema['short'] = 0.3 * loss_val + 0.7 * ema.get('short', loss_val)
38
- ema['medium'] = 0.05 * loss_val + 0.95 * ema.get('medium', loss_val)
39
- ema['long'] = 0.01 * loss_val + 0.99 * ema.get('long', loss_val)
40
- return ema
41
-
42
- # 感情スカラー値生成(EMA差分、滑らかな非線形スカラー、tanh(diff) は ±1.0 で有界性)
43
- # 係数"1":ema差分 のスケール調整処理に活用(感度調節係数)/通常は1(タスクに応じ調整可(非推奨))
44
- # scale_base:Loss値とema値の乖離を修正(分母 ema(long) 「改善率」共通化/loss種に非依存)
45
- # 1e-5(デフォルト)/1e-6(感度向上)/1e-4(安定性向上):分母を0にせず安定させる
46
- # トラウマ的反応や慣れによる鈍化で安定性向上(ema-medium 安定と急変を信頼度で感知)
47
- def _compute_scalar(self, ema):
48
- scale_base_l = max(ema['long'], 1e-5)
49
- scale_base_m = max(ema['medium'], 1e-5)
50
- diff_base = ema['long'] - ema['short']
51
- diff_l = diff_base / scale_base_l
52
- diff_m = diff_base / scale_base_m
53
- # longが十分静かなら、常にlongを優先
54
- if abs(diff_l) < 0.05:
55
- return math.tanh(diff_l)
56
- # longが静かでない時のみ、mediumの静けさを条件付きで採用
57
- if abs(diff_m) * scale_base_m < abs(diff_l) * scale_base_l:
58
- return math.tanh(diff_m)
59
- else:
60
- return math.tanh(diff_l)
61
-
62
- # (重要)現在は shadow-effect を参考に得た動的フィルタ効果の近似により use_shadow=False です
63
- # しかし全機能は shadow なしで全て成立します/コード確認時はこの shadow を考慮外として無視してください
64
- # Shadow混合比 3段階構成 タスクに応じ調整可、以下を参考に 開始値・範囲量・変化幅を調整
65
- # return 開始値 + ((scalar) - 閾値) / 範囲量 * 変化幅 も可能(特殊用途向け)
66
- def _decide_ratio(self, scalar):
67
- if not self.use_shadow:
68
- return 0.0 # 🔸use_shadow = False のとき常に比率を 0 にする
69
- if abs(scalar) > 0.625:
70
- return 1.0 - abs(scalar) # 急変|強抑制|tanh 0.73(0.27)
71
- else:
72
- return 0.0 # return<0 の場合は leap 専用(書き戻しはしないが履歴更新のみ)
73
-
74
- # 損失取得(損失値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
75
- @torch.no_grad()
76
- def step(self, closure: Callable | None = None):
77
- loss = None
78
- if exists(closure):
79
- with torch.enable_grad():
80
- loss = closure()
81
- loss_val = loss.item() if loss is not None else 0.0
82
-
83
- # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
84
- ema = self._update_ema(self.state, loss_val)
85
- scalar = self._compute_scalar(ema)
86
- ratio = self._decide_ratio(scalar)
87
- trust = math.copysign((1.0 - abs(scalar)), scalar)
88
-
89
- # --- Start emoPulse (完全自動LR生成) ---
90
- # emoPulse (loss 時系列から D / Noise を推定し完全自動LRを生成)
91
- # d / N 履歴 (時間的D推定)
92
- self.noise_est = 0.97 * self.noise_est + 0.03 * abs(scalar)
93
- self.d_est = 0.97 * self.d_est + 0.03 * abs(trust)
94
- noise = max(self.noise_est, 1e-10) # max:1e-12程度(変更後:要アーリーストップ見直し)
95
- d = self.d_est
96
- # scalar、trust、の差分(瞬間的D推定)と各時間軸の確度推定(疑念と信頼の綱引き)
97
- Noise_base = abs(scalar - trust) + 0.1
98
- d_base = abs(noise - d) + 0.1
99
- # SNRにより異なる時間的確度比率から更新力を導出し2乗で出力最大化
100
- dNR_now_val = (d_base / Noise_base) ** 2
101
- # db / Nb dNR(SNR) 履歴化と最大値の成長率の増減
102
- if dNR_now_val >= self.dNR_hist and trust >= 0.5:
103
- # 加速:どんなに SNR が高くても、1.50倍という「歩幅」の成長制限
104
- self.dNR_hist = min(dNR_now_val, self.dNR_hist * 1.50)
105
- elif -0.5 <= trust <= 0.5:
106
- # 減速:怪しい時は即座に比率を下げる(確実に信頼できない場合に下げ圧力を溜める)
107
- self.dNR_hist = dNR_now_val * 0.80
108
- # emoPulse 最終決定: emoScorp によるユーザー意思の反映と安全値による制限
109
- emoPulse = max(min(self.dNR_hist * (self.emoScope * 1e-4), 3e-3), 1e-6)
110
- # --- End emoPulse (完全自動LR生成) ---
111
-
112
- for group in self.param_groups:
113
- beta1, beta2 = group['betas']
114
- for p in filter(lambda p: exists(p.grad), group['params']):
115
- grad = p.grad
116
- state = self.state[p]
117
- d_p = grad.shape
118
-
119
- # 動的学習率補正により shadow 形成を信頼度で調整(trustは正値化(負にならない))
120
- # shadow:必要時のみ(スパイクp部分に現在値を最大10%追従させる動的履歴更新)
121
- # 混合比率:スカラーが閾値を超える場合にのみ計算される(信頼できる感情信号かどうかの選別)
122
- # 急変時は感情機構による shadow 混合で強く抑制する(急制動による安定性の確保)
123
- # shadow-system は動的学習率と信頼度で協調し選択的スパース性も発揮する
124
- if self.use_shadow :
125
- if 'shadow' not in state: # 🔸shadow = False (デフォルト)
126
- state['shadow'] = p.clone()
127
- if ratio > 0: # 書き戻しと履歴更新(急変時の強い抑制と弱めの履歴更新)
128
- p.mul_(1-ratio).add_(state['shadow'], alpha=abs(trust))
129
- else: # 書き戻しせず履歴更新のみ:10%×trust
130
- leap_ratio = 0.1 * abs(trust)
131
- state['shadow'].lerp_(p, leap_ratio)
132
-
133
- # --- Start Gradient Update Logic ---
134
- # 2次元以上かつ一定サイズ以上を行列近似対象とする
135
- # 判定:2次元以上かつ「低ランク化」でメモリコストが全体の 5% 以下の場合に適用
136
- if grad.dim() >= 2 and ((d_p[0] + d_p[1]) / p.numel()) < 0.05:
137
- # 4次元を2次元(行列)として解釈する
138
- grad_matrix = grad.view(d_p[0], -1)
139
- d0, d1 = grad_matrix.shape
140
- # --- Low-Rank Moment Logic ---
141
- if 'exp_avg_row' not in state:
142
- state['exp_avg_row'] = torch.zeros(d0, dtype=grad.dtype, device=grad.device)
143
- state['exp_avg_col'] = torch.zeros(d1, dtype=grad.dtype, device=grad.device)
144
-
145
- row, col = state['exp_avg_row'], state['exp_avg_col']
146
-
147
- # 1次モーメントを低ランクで復元
148
- # Lion-style update with blended gradient
149
- update = row.view(-1, 1).mul(col).mul_(beta1).add_(grad_matrix, alpha=1 - beta1).sign_()
150
-
151
- # 行列分解形式での履歴更新
152
- row.mul_(beta2).add_(grad_matrix.mean(dim=1), alpha=1 - beta2)
153
- col.mul_(beta2).add_(grad_matrix.mean(dim=0), alpha=1 - beta2)
154
- # 元のテンソル形状(4次元など)に戻す
155
- update = update.view(d_p)
156
-
157
- else:
158
- # --- Momentless Update (1次元/小行列) ---
159
- # 現在の勾配の符号のみとし履歴を持たずメモリ消費を抑える
160
- update = grad.sign()
161
- # Weight Decay
162
- p.add_(p, alpha=-group['weight_decay'] * emoPulse)
163
- p.add_(update, alpha=-emoPulse)
164
- # --- End Gradient Update Logic ---
165
-
166
- # ユーザー指定初期LRを実効値(emoPulse)で可視化する(PyTorch��準)
167
- for group in self.param_groups:
168
- group['lr'] = emoPulse
169
-
170
- # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
171
- # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
172
- # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
173
- if abs(scalar) <= 5e-6 and abs(Noise_base - d_base) <= 5e-7:
174
- self.should_stop = True # 💡 外部からこれを見て判断可
175
- self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
176
- else:
177
- self.should_stop = False # 💡 誤判定などの取り消し
178
-
179
- return
180
-
181
- """
182
- https://github.com/muooon/EmoSens
183
- An emotion-driven optimizer that feels loss and navigates accordingly.
184
- Don't think. Feel. Don't stop. Keep running. Believe in what's beyond.
185
- """
 
1
+ import torch
2
+ from torch.optim import Optimizer
3
+ import math
4
+
5
+ """
6
+ EmoTion v3.8.1 (260202) shadow-system v3.1 -moment v3.1 emoPulse v3.8
7
+ emoScorp、emoPulse、についてアグレッシブな更新にも耐えられるように調整し安全性を向上
8
+ EmoTion v3.7.6 (260120) shadow-system v3.1 -moment v3.1 emoPulse v3.7
9
+ All-Emo v3.6, v3.7 継承 emoDrive 機構を emoPulse へ統合し簡略化(循環器的機構)
10
+ emoPulse 機構により完全自動化を目指す(ユーザーによる emoScope 調整可/改善度反映率)
11
+ dNR係数により emoPulse に履歴を混ぜて安定させた(d / N 履歴 による信頼度の維持)
12
+ Early scalar、Early Stop、効率化しつつ精度向上させ負荷も軽減する等の改修と微調整
13
+ """
14
+
15
+ class EmoTion(Optimizer):
16
+ # クラス定義&初期化
17
+ def __init__(self, params,
18
+ lr=1.0,
19
+ eps=1e-8,
20
+ betas=(0.9, 0.995),
21
+ weight_decay=0.01,
22
+ use_shadow:bool=False):
23
+ defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
24
+ super().__init__(params, defaults)
25
+ self._init_lr = lr
26
+ self.should_stop = False # 停止フラグの初期化
27
+ self.use_shadow = use_shadow # 🔸shadow 使用フラグを保存
28
+ self.emoScope = lr # 動的学習率の調和とリズム
29
+ self.dNR_hist = 1.0 # emoPulse hist 初期化
30
+ self.noise_est = 1.0 # emoPulse nest 初期化
31
+ self.d_est = 0.02 # emoPulse dest 初期化
32
+
33
+ # 感情EMA更新(緊張と安静)
34
+ def _update_ema(self, state, loss_val):
35
+ ema = state.setdefault('ema', {})
36
+ ema['short'] = 0.3 * loss_val + 0.7 * ema.get('short', loss_val)
37
+ ema['medium'] = 0.05 * loss_val + 0.95 * ema.get('medium', loss_val)
38
+ ema['long'] = 0.01 * loss_val + 0.99 * ema.get('long', loss_val)
39
+ return ema
40
+
41
+ # 感情スカラー値生成(EMA差分、滑らかな非線形スカラー、tanh(diff) は ±1.0 で有界性)
42
+ # 係数"1":ema差分 のスケール調整処理に活用(感度調節係数)/通常は1(タスクに応じ調整可(非推奨))
43
+ # scale_baseLoss値とema値の乖離を修正(分母 ema(long) 「改善率」共通化/loss種に非依存)
44
+ # 1e-5(デフォルト)/1e-6(感度向上)/1e-4(安定性向上):分母を0にせず安定させる
45
+ # トラウマ的反応や慣れによる鈍化で安定性向上(ema-medium 安定と急変を信頼度で感知)
46
+ def _compute_scalar(self, ema):
47
+ scale_base_l = max(ema['long'], 1e-5)
48
+ scale_base_m = max(ema['medium'], 1e-5)
49
+ diff_base = ema['long'] - ema['short']
50
+ diff_l = diff_base / scale_base_l
51
+ diff_m = diff_base / scale_base_m
52
+ # longが十分静かなら、常にlongを優先
53
+ if abs(diff_l) < 0.05:
54
+ return math.tanh(diff_l)
55
+ # longが静かでない時のみ、mediumの静けさを条件付きで採用
56
+ if abs(diff_m) * scale_base_m < abs(diff_l) * scale_base_l:
57
+ return math.tanh(diff_m)
58
+ else:
59
+ return math.tanh(diff_l)
60
+
61
+ # (重要)現在は shadow-effect を参考に得た動的フィルタ効果の近似により use_shadow=False です
62
+ # しかし全機能は shadow なしで全て成立します/コード確認時はこの shadow を考慮外として無視してください
63
+ # Shadow混合比 3段階構成 タスクに応じ調整可、以下を参考に 開始値・範囲量・変化幅を調整
64
+ # return 開始値 + ((scalar) - 閾値) / 範囲量 * 変化幅 も可能(特殊用途向け)
65
+ def _decide_ratio(self, scalar):
66
+ if not self.use_shadow:
67
+ return 0.0 # 🔸use_shadow = False のとき常に比率を 0 にする
68
+ if abs(scalar) > 0.625:
69
+ return 1.0 - abs(scalar) # 急変|強抑制|tanh 0.73(0.27)
70
+ else:
71
+ return 0.0 # return<0 の場合は leap 専用(書き戻しはしないが履歴更新のみ)
72
+
73
+ # 損失取得(損失値 loss_val を数値化��感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
74
+ @torch.no_grad()
75
+ def step(self, closure=None):
76
+ loss = torch.enable_grad()(closure)() if closure is not None else None
77
+ loss_val = loss.item() if loss is not None else 0.0
78
+
79
+ # EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
80
+ ema = self._update_ema(self.state, loss_val)
81
+ scalar = self._compute_scalar(ema)
82
+ ratio = self._decide_ratio(scalar)
83
+ trust = math.copysign((1.0 - abs(scalar)), scalar)
84
+
85
+ # --- Start emoPulse (完全自動LR生成) ---
86
+ # emoPulse (loss 時系列から D / Noise を推定し完全自動LRを生成)
87
+ # d / N 履歴 (時間的D推定)
88
+ self.noise_est = 0.97 * self.noise_est + 0.03 * abs(scalar)
89
+ self.d_est = 0.97 * self.d_est + 0.03 * abs(trust)
90
+ noise = max(self.noise_est, 1e-10) # max:1e-12程度(変更後:要アーリーストップ見直し)
91
+ d = self.d_est
92
+ # scalar、trust、の差分(瞬間的D推定)と各時間軸の確度推定(疑念と信頼の綱引き)
93
+ Noise_base = abs(scalar - trust) + 0.1
94
+ d_base = abs(noise - d) + 0.1
95
+ # SNRにより異なる時間的確度比率から更新力を導出し2乗で出力最大化
96
+ dNR_now_val = (d_base / Noise_base) ** 2
97
+ # db / Nb dNR(SNR) 履歴化と最大値の成長率の増減
98
+ if dNR_now_val >= self.dNR_hist and trust >= 0.5:
99
+ # 加速:どんなに SNR が高くても、1.50倍という「歩幅」の成長制限
100
+ self.dNR_hist = min(dNR_now_val, self.dNR_hist * 1.50)
101
+ elif -0.5 <= trust <= 0.5:
102
+ # 減速:怪しい時は即座に比率を下げる(確実に信頼できない場合に下げ圧力を溜める)
103
+ self.dNR_hist = dNR_now_val * 0.80
104
+ # emoPulse 最終決定: emoScorp によるユーザー意思の反映と安全値による制限
105
+ emoPulse = max(min(self.dNR_hist * (self.emoScope * 1e-4), 3e-3), 1e-6)
106
+ # --- End emoPulse (完全自動LR生成) ---
107
+
108
+ for group in self.param_groups:
109
+ beta1, beta2 = group['betas']
110
+ for p in (p for p in group['params'] if p.grad is not None):
111
+
112
+ grad = p.grad
113
+ state = self.state[p]
114
+ d_p = grad.shape
115
+
116
+ # 動的学習率補正により shadow 形成を信頼度で調整(trustは正値化(負にならない))
117
+ # shadow:必要時のみ(スパイクp部分に現在値を最大10%追従させる動的履歴更新)
118
+ # 混合比率:スカラーが閾値を超える場合にのみ計算される(信頼できる感情信号かどうかの選別)
119
+ # 急変時は感情機構による shadow 混合で強く抑制する(急制動による安定性の確保)
120
+ # shadow-system は動的学習率と信頼度で協調し選択的スパース性も発揮する
121
+ if self.use_shadow :
122
+ if 'shadow' not in state: # 🔸shadow = False (デフォルト)
123
+ state['shadow'] = p.clone()
124
+ if ratio > 0: # 書き戻しと履歴更新(急変時の強い抑制と弱めの履歴更新)
125
+ p.mul_(1-ratio).add_(state['shadow'], alpha=abs(trust))
126
+ else: # 書き戻しせず履歴更新のみ:10%×trust
127
+ leap_ratio = 0.1 * abs(trust)
128
+ state['shadow'].lerp_(p, leap_ratio)
129
+
130
+ # --- Start Gradient Update Logic ---
131
+ # 2次元以上かつ一定サイズ以上を行列近似対象とする
132
+ # 判定:2次元以上かつ「低ランク化」でメモリコストが全体の 5% 以下の場合に適用
133
+ if grad.dim() >= 2 and ((d_p[0] + d_p[1]) / p.numel()) < 0.05:
134
+ # 4次元を2次元(行列)として解釈する
135
+ grad_matrix = grad.view(d_p[0], -1)
136
+ d0, d1 = grad_matrix.shape
137
+ # 低ランク近似にする
138
+ if 'exp_avg_row' not in state:
139
+ state['exp_avg_row'] = torch.zeros(d0, dtype=grad.dtype, device=grad.device)
140
+ state['exp_avg_col'] = torch.zeros(d1, dtype=grad.dtype, device=grad.device)
141
+
142
+ row, col = state['exp_avg_row'], state['exp_avg_col']
143
+
144
+ # 履歴の更新(行列の構造的統計量)
145
+ row.mul_(beta2).add_(grad_matrix.mean(dim=1), alpha=1 - beta2)
146
+ col.mul_(beta2).add_(grad_matrix.mean(dim=0), alpha=1 - beta2)
147
+
148
+ # 行列フィルタ生成「1次モーメントの慣性」を近似的に含む
149
+ r_filter = row / (row.norm() + group['eps'])
150
+ c_filter = col / (col.norm() + group['eps'])
151
+ # grad_matrix 構造情報で「更新ベクトル場」��変換する
152
+ grad_matrix.mul_(r_filter.unsqueeze(1)).mul_(c_filter.unsqueeze(0))
153
+
154
+ # 多次元行列の更新準備
155
+ update = grad
156
+
157
+ else:
158
+ # 1次元/小行列の更新準備
159
+ update = grad
160
+
161
+ # Weight Decay
162
+ p.mul_(1.0 - group['weight_decay'] * emoPulse)
163
+ p.add_(update.sign_(), alpha=-emoPulse)
164
+ # --- End Gradient Update Logic ---
165
+
166
+ # ユーザー指定初期LRを実効値(emoPulse)で可視化する(PyTorch標準)
167
+ for group in self.param_groups:
168
+ group['lr'] = emoPulse
169
+
170
+ # 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
171
+ # Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
172
+ # 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
173
+ if abs(scalar) <= 5e-6 and abs(Noise_base - d_base) <= 5e-7:
174
+ self.should_stop = True # 💡 外部からこれを見て判断可
175
+ self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
176
+ else:
177
+ self.should_stop = False # 💡 誤判定などの取り消し
178
+
179
+ return
180
+
181
+ """
182
+ https://github.com/muooon/EmoSens
183
+ Thank you Adafactor and Lion.
184
+ Believing in a future for democratic AI learning.
185
+ """