File size: 12,976 Bytes
be97c9c 334852f aafb7f8 334852f aafb7f8 334852f be97c9c 334852f be97c9c 334852f be97c9c 714f46b 334852f 8d1abb4 be97c9c 8d1abb4 be97c9c aafb7f8 be97c9c 714f46b 8d1abb4 be97c9c 58f475c be97c9c 8d1abb4 be97c9c 8d1abb4 be97c9c 334852f be97c9c 334852f 714f46b 334852f 8d1abb4 714f46b 334852f 8d1abb4 334852f be97c9c 8d1abb4 be97c9c 8d1abb4 be97c9c 8d1abb4 aafb7f8 05d62ba 811af01 aafb7f8 714f46b aafb7f8 05d62ba aafb7f8 05d62ba aafb7f8 334852f 714f46b 334852f 714f46b 334852f be97c9c 334852f 05d62ba be97c9c aafb7f8 334852f be97c9c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | import torch
from torch.optim import Optimizer
import math
"""
EmoTion v3.8.6 (260220) Moment-Free Edition FFT適応統合版(CPU-GPUデータ転送対応)
shadow-system v3.1 -moment v3.1 emoPulse v3.8 FFT-Swap-Aware
これまでの emo系 のすべてを継承し、独自更新式の特徴を受け継ぐ完全オリジナル最適化器
The “geometric relationship” between "W"eight and "G"radient Method
幾何学的最適化アルゴリズム Approx W-Ref Geometry 近似アシスト更新に変更し負荷低減
過去の慣性と現在の勾配を動的にブレンドする、1次モーメント単一保持型の幾何学的最適化アルゴリズム
### FFT適応 cuDNN 等で厳格なデータ配置を求める仕様により中間テンソル(コピー)生じる ###
"""
class EmoTion(Optimizer):
# クラス定義&初期化
def __init__(self, params,
lr=1.0,
eps=1e-8,
betas=(0.9, 0.995),
weight_decay=0.01,
use_shadow:bool=False,
fftmode:bool=False):
defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
super().__init__(params, defaults)
self._init_lr = lr
self.should_stop = False # 停止フラグの初期化
self.fftmode = fftmode # FFT切替 フルファインチューニングモード
self.use_shadow = use_shadow # 🔸shadow 使用フラグを保存
self.emoScope = lr # 動的学習率の調和とリズム
self.dNR_hist = 1.0 # emoPulse hist 初期化
self.noise_est = 1.0 # emoPulse nest 初期化
self.d_est = 0.02 # emoPulse dest 初期化
# use_shadow 緊急時モデル保護:通常 False (将来の特殊アーキテクチャへの保護機能)
# fftmode 学習モード切替え:通常 False (学習スケールをFFTとそれ以外で適正化)
if self.fftmode:
self.base_scale, self.max_lim, self.min_lim = 1e-5, 3e-4, 1e-8
self.stop_scalar,self.stop_dNRsub = 5e-7, 5e-8
else:
self.base_scale, self.max_lim, self.min_lim = 1e-4, 3e-3, 1e-6
self.stop_scalar,self.stop_dNRsub = 5e-6, 5e-7
# 感情EMA更新(緊張と安静)/3次4次5次モーメント近似相当(感覚神経系)
def _update_ema(self, state, loss_val):
ema = state.setdefault('ema', {})
ema['short'] = 0.3 * loss_val + 0.7 * ema.get('short', loss_val)
ema['medium'] = 0.05 * loss_val + 0.95 * ema.get('medium', loss_val)
ema['long'] = 0.01 * loss_val + 0.99 * ema.get('long', loss_val)
return ema
# 感情スカラー値生成(EMA差分、滑らかな非線形スカラー、tanh(diff) は ±1.0 で有界性)(内分泌系)
# 係数"1":ema差分 のスケール調整処理に活用(感度調節係数)/通常は1(タスクに応じ調整可(非推奨))
# scale_base:Loss値とema値の乖離を修正(分母 ema(long) 「改善率」共通化/loss種に非依存)
# 1e-5(デフォルト)/1e-6(感度向上)/1e-4(安定性向上):分母を0にせず安定させる
# トラウマ的反応や慣れによる鈍化で安定性向上(ema-medium 安定と急変を信頼度で感知)
def _compute_scalar(self, ema):
scale_base_l = max(ema['long'], 1e-5)
scale_base_m = max(ema['medium'], 1e-5)
diff_base = ema['long'] - ema['short']
diff_l = diff_base / scale_base_l
diff_m = diff_base / scale_base_m
# longが十分静かなら、常にlongを優先
if abs(diff_l) < 0.05:
return math.tanh(diff_l)
# longが静かでない時のみ、mediumの静けさを条件付きで採用
if abs(diff_m) * scale_base_m < abs(diff_l) * scale_base_l:
return math.tanh(diff_m)
else:
return math.tanh(diff_l)
# (重要)現在は shadow-effect を参考に得た動的フィルタ効果の近似により use_shadow=False です
# しかし全機能は shadow なしで全て成立します/通常のVRAM負荷は shadow を考慮外として無視してください
# emoPulse機構によるLR推定はWt打ち消しODE近似相当のためshadowは未知のアーキテクチャへの保険(免疫系)
# Shadow混合比 3段階構成 タスクに応じ調整可、以下を参考に 開始値・範囲量・変化幅を調整
# return 開始値 + ((scalar) - 閾値) / 範囲量 * 変化幅 も可能(特殊用途向け)
def _decide_ratio(self, scalar):
if not self.use_shadow:
return 0.0 # 🔸use_shadow = False のとき常に比率を 0 にする
if abs(scalar) > 0.625:
return 1.0 - abs(scalar) # 急変|強抑制|tanh 0.73(0.27)
else:
return 0.0 # return<0 の場合は leap 専用(書き戻しはしないが履歴更新のみ)
# 損失取得(損失値 loss_val を数値化、感情判定に使用、存在しないパラメータ(更新不要)はスキップ)
@torch.no_grad()
def step(self, closure=None):
loss = torch.enable_grad()(closure)() if closure is not None else None
loss_val = loss.item() if loss is not None else 0.0
# EMA更新・スカラー生成(EMA差分からスカラーを生成しスパイク比率等を決定)
ema = self._update_ema(self.state, loss_val)
scalar = self._compute_scalar(ema)
ratio = self._decide_ratio(scalar)
trust = math.copysign((1.0 - abs(scalar)), scalar)
# --- Start emoPulse (完全自動LR生成) ---
# emoPulse (loss 時系列から D / Noise を推定し完全自動LRを生成)(循環器系)
# d / N 履歴 (時間的D推定)/d / N 履歴差分は6次モーメント近似相当
self.noise_est = 0.97 * self.noise_est + 0.03 * abs(scalar)
self.d_est = 0.97 * self.d_est + 0.03 * abs(trust)
noise = max(self.noise_est, 1e-10) # max:1e-12程度(変更後:要アーリーストップ見直し)
d = self.d_est
# scalar、trust、の差分(瞬間的D推定)と各時間軸の確度推定(疑念と信頼の綱引き)
Noise_base = abs(scalar - trust) + 0.1
d_base = abs(noise - d) + 0.1
# SNRにより異なる時間的確度比率から更新力を導出し2乗で出力最大化(心拍)7次近似相当
dNR_now_val = (d_base / Noise_base) ** 2
# db / Nb dNR(SNR) 履歴化と最大値の成長率の増減
if dNR_now_val >= self.dNR_hist and trust >= 0.5:
# 加速:どんなに SNR が高くても、1.50倍という「歩幅」の成長制限
self.dNR_hist = min(dNR_now_val, self.dNR_hist * 1.50)
elif -0.5 <= trust <= 0.5:
# 減速:怪しい時は即座に比率を下げる(確実に信頼できない場合に下げ圧力を溜める)
self.dNR_hist = dNR_now_val * 0.80
# emoPulse 最終決定: emoScorp によるユーザー意思の反映と安全値による制限
emoPulse = float(max(min(self.dNR_hist * (self.emoScope * self.base_scale),
self.max_lim), self.min_lim))
# --- End emoPulse (完全自動LR生成) ---
# --- Start Approx W-Ref Geometry [Tion] 近似アシスト ---
# Weight Reference Geometry ("W"eight and "G"radient Method)
# 中間テンソルによるVRAM負荷やcos類似度測定の計算負荷を実質0に(平衡感覚器系)
with torch.no_grad():
# 現在の全パラメータのL1ノルムを一括計算(計算負荷: 低)
# foreach_norm は各層のノルムをリストで返す。sumで1つの数値に集約。
params = self.param_groups[0]['params']
point_gl1 = sum(torch._foreach_norm(params, 1))
prev = getattr(self, "prev_gl1", None)
# 前回のノルムと比較して「一括修正」
if prev is not None:
# 前回のエネルギーを維持するための比率(スライス的な全層一律係数)
gratio = (abs(point_gl1 - prev) / (prev + 1e-8)).item()
# freshness: 全域の動きが激しいほど 1.0 に近づく(係数0.05前後で安定)
self.g_freshness = min(gratio / 0.03, 1.0)
# 現在の修正したノルムを復元(近似)スケール調整で打ち消し
point_gl1 *= gratio
else:
# 1ステップ目は「過去」がないので現在の勾配を信頼する
self.g_freshness = 1.0 # 初期値
# 今回のノルムを次回の比較用に保存
self.prev_gl1 = point_gl1
# --- End Approx W-Ref Geometry [Tion] 近似アシスト ---
for group in self.param_groups:
beta1, beta2 = group['betas']
for p in group['params']:
if p.grad is None:
continue
grad = p.grad
state = self.state[p]
# 動的学習率補正により shadow 形成を信頼度で調整(trustは正値化(負にならない))
# shadow:必要時のみ(スパイクp部分に現在値を最大10%追従させる動的履歴更新)
# 混合比率:スカラーが閾値を超える場合にのみ計算される(信頼できる感情信号かどうかの選別)
# 急変時は感情機構による shadow 混合で強く抑制する(急制動による安定性の確保)
# 新 shadow-system は動的学習率と信頼度で協調し選択的スパース性も発揮する
# emoPulse機構はODE近似相当のためshadowは未知のアーキテクチャへの保険(免疫系)
if self.use_shadow :
if 'shadow' not in state: # 🔸shadow = False (デフォルト)
state['shadow'] = p.clone()
if ratio > 0: # 書き戻しと履歴更新(急変時の強い抑制と弱めの履歴更新)
p.mul_(1-ratio).add_(state['shadow'], alpha=abs(trust))
else: # 書き戻しせず履歴更新のみ:10%×trust
leap_ratio = 0.1 * abs(trust)
state['shadow'].lerp_(p, leap_ratio)
# --- Start Gradient Update Logic ---
# --- EmoTion (Approx W-Ref Geometry) ---
# 1次モーメント(exp_avg)の初期化:O(N) のみ
if 'exp_avg' not in state:
state['exp_avg'] = torch.zeros_like(p)
exp_avg = state['exp_avg']
# exp_avg = beta1 * exp_avg + (1 - beta1) * grad の「幾何学的拡張」
# 慣性と現時点の勾配を、直交性に基づいて混ぜ合わせる
# freshness が 0 のときは alpha=0 となり、exp_avg は減衰せず 100% 維持される
g_alpha = (1.0 - beta1) * self.g_freshness
exp_avg.mul_(1.0 - g_alpha).add_(grad.to(p.device), alpha=g_alpha)
# 重みの更新 (emoPulse = 絶対歩幅)
if group['weight_decay'] != 0:
p.mul_(1.0 - group['weight_decay'] * emoPulse)
# FFT版と通常版を統合する分岐(デバイス状態判定)
if p.device != exp_avg.device:
# FFTモード:デバイス間の計算を同じ場所へ統一
update = exp_avg.sign().to(p.device)
else:
# 通常モード:同じ場所の場合は負荷軽減
update = exp_avg.sign()
p.add_(update, alpha=-emoPulse)
# --- End Gradient Update Logic ---
# ユーザー指定初期LRを実効値(emoPulse)で可視化する(PyTorch標準)
for group in self.param_groups:
group['lr'] = emoPulse
# 感情機構の穏やかさ"安定状態"を外部伝達する(自動停止ではない)
# Early Stop:瞬間値と33step分の履歴の差分で True にするだけ
# 誤判定防止をしないのは点灯頻度で停止準備(予兆)にするため
if abs(scalar) <= self.stop_scalar and abs(Noise_base - d_base) <= self.stop_dNRsub:
if not self.should_stop:
self.emoScope = 1.0 # ユーザー意思を目的の収束へ整える
self.should_stop = True # 💡 外部からこれを見て判断可
else:
self.should_stop = False # 💡 誤判定などの取り消し
return
"""
https://github.com/muooon/EmoSens
Pure W-Ref Geometry. Believing in a future for democratic AI learning.
Taking decisive steps forward, Weight-Reference Optimizer.
"""
|