PowerMachine commited on
Commit
f90a477
·
verified ·
1 Parent(s): f64aac8

V6.4: refactored Kohonen SOM 4D (canonical user code, pgvector_lookup REMOVED)

Browse files
scripts/train_v6_4.py ADDED
@@ -0,0 +1,600 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """train_v6_4.py — V6.4 REFACTORED Kohonen Learning System (pgvector_lookup REMOVED).
2
+
3
+ ═══════════════════════════════════════════════════════════════════════════════
4
+ V6.4 — REFATORAÇÃO CANÔNICA COM CÓDIGO FORNECIDO PELO USUÁRIO
5
+ ═══════════════════════════════════════════════════════════════════════════════
6
+
7
+ Refatoração sobrescreve os módulos usando o código Kohonen SOM 4D fornecido
8
+ pelo usuário (versão limpa, find_bmu já corrigido). Análise matemática
9
+ formal documentada em kohonen_learning_system.py.
10
+
11
+ Diferenças vs V6.3:
12
+ 1. pgvector_lookup REMOVIDO de hyp_t.py (não é mais necessário —
13
+ find_bmu do KohonenLearningSystem realiza a busca nearest-neighbor
14
+ sobre o grid 4D, substituindo qualquer lookup pgvector externo).
15
+ 2. SOM grid放大ado para (6,6,6,4) = 864 neurônios (default do usuário).
16
+ 3. hidden_dim=1024 (default do usuário, era 256 no V6.3).
17
+ 4. T_max=10000 (default do usuário).
18
+ 5. w = time_step / T_max (LINEAR no tempo, era sigmoid(||xyz||) no V6.3).
19
+ 6. API unificada: kls.som.get_metrics() e kls.get_state_metrics().
20
+
21
+ Componentes ativados:
22
+ 1. xeon_runtime.py (AVX512 + AMX_INT8 + IPEX + OneDNN + FP16)
23
+ 2. streaming_datasets.py (5 datasets × 50 samples = 250 total)
24
+ 3. KohonenLearningSystem (refatorado, código CANÔNICO do usuário)
25
+ 4. BATCH_SIZE = 16 (user requirement)
26
+ 5. Captura de métricas: 12/12 + Kohonen (sigma, alpha, fisher) + Hyp
27
+ 6. Monitoramento e informe de valores obtidos
28
+
29
+ User requirements (V6.4):
30
+ - "refatorar sobrescrevendo os módulos usando (analisar matematicamente)"
31
+ - "pgvector_lookup não é mais necessário pela lógica do script seguinte"
32
+ - "HF_TOKEN=hf_<REDACTED_TOKEN> que deve ser apagada após uso"
33
+ - "usar streaming_datasets.py"
34
+ - "ativar xeon_runtime.py"
35
+ - "BATCH_SIZE = 16"
36
+ - "5 datasets × 50 samples streaming"
37
+ - "monitorar e informar valores obtidos"
38
+
39
+ Saídas:
40
+ - /home/z/my-project/BiGRU_T_version/v6_4_report.json
41
+ - /home/z/my-project/BiGRU_T_version/v6_4_training_metrics.json
42
+ - Log no worklog.md
43
+ ═══════════════════════════════════════════════════════════════════════════════
44
+ """
45
+ from __future__ import annotations
46
+
47
+ import json
48
+ import logging
49
+ import os
50
+ import sys
51
+ import time
52
+ import traceback
53
+ from datetime import datetime
54
+ from pathlib import Path
55
+ from typing import Any, Dict, List, Optional
56
+
57
+ # ============================================================================
58
+ # 0. Paths e logging
59
+ # ============================================================================
60
+ PROJECT_ROOT = Path("/home/z/my-project")
61
+ BIGRU_ROOT = PROJECT_ROOT / "BiGRU_T_version"
62
+ SRC_ROOT = BIGRU_ROOT / "src"
63
+ REPORT_PATH = BIGRU_ROOT / "v6_4_report.json"
64
+ METRICS_PATH = BIGRU_ROOT / "v6_4_training_metrics.json"
65
+
66
+ logging.basicConfig(
67
+ level=logging.INFO,
68
+ format="[%(asctime)s] [%(levelname)s] %(message)s",
69
+ datefmt="%H:%M:%S",
70
+ )
71
+ logger = logging.getLogger("train_v6_4")
72
+
73
+ # ============================================================================
74
+ # 1. ATIVAR xeon_runtime.py (user requirement, mencionado 2x)
75
+ # ============================================================================
76
+ sys.path.insert(0, str(SRC_ROOT))
77
+
78
+ from bigru_t.utils.xeon_runtime import ( # noqa: E402
79
+ optimize_xeon_environment,
80
+ benchmark_fp16_matmul,
81
+ get_xeon_status,
82
+ )
83
+
84
+ N_CORES = optimize_xeon_environment(verbose=True)
85
+ XEON_STATUS = get_xeon_status()
86
+ FP16_BENCH = benchmark_fp16_matmul(size=4000, warmup=1, iters=2)
87
+ logger.info(f"[V6.4] Xeon FP16 benchmark: {FP16_BENCH}")
88
+
89
+ # ============================================================================
90
+ # 2. Configurações V6.4 (defaults do código do usuário)
91
+ # ============================================================================
92
+ BATCH_SIZE = 16
93
+ N_DATASETS = 5
94
+ SAMPLES_PER_DATASET = 50
95
+ TOTAL_SAMPLES = N_DATASETS * SAMPLES_PER_DATASET # 250
96
+ EPOCHS = 2
97
+ MAX_SEQ_LEN = 8
98
+
99
+ # V6.4: defaults canônicos do código do usuário
100
+ HIDDEN_DIM = 1024 # era 256 no V6.3 — agora segue user spec
101
+ VOCAB_SIZE = 16384 # default do SimpleBBPETokenizer
102
+ SOM_GRID = (6, 6, 6, 4) # 864 neurônios — default do usuário (era (2,2,2,1) no V6.3)
103
+ T_MAX = 10000 # default do usuário
104
+ N_START = 10 # default do usuário
105
+ LAMBDA_EWC = 0.02 # default do usuário
106
+ ALPHA0 = 0.1
107
+ SIGMA0 = 1.5
108
+ DIM_CHOICE = "y"
109
+
110
+ V64_DATASETS = [
111
+ "TucanoBR/GigaVerbo",
112
+ "dominguesm/restore-punctuation-pttr-dataset",
113
+ "Madras1/corpus-ptbr-v2",
114
+ "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
115
+ "nvidia/OpenMathInstruct-2",
116
+ ]
117
+
118
+ # Templates sintéticos para fallback (caso streaming falhe/lento)
119
+ SYNTH_TEMPLATES = {
120
+ "TucanoBR/GigaVerbo": [
121
+ "o gato dorme na cama",
122
+ "o cachorro corre no parque",
123
+ "o pássaro voa no céu",
124
+ "a menina brinca com a boneca",
125
+ "o menino joga bola",
126
+ ],
127
+ "dominguesm/restore-punctuation-pttr-dataset": [
128
+ "o sol nasceu azul hoje",
129
+ "ela foi ao mercado comprar pão",
130
+ "nós viajamos para o rio de janeiro",
131
+ "o livro está sobre a mesa",
132
+ "a casa tem quatro quartos",
133
+ ],
134
+ "Madras1/corpus-ptbr-v2": [
135
+ "o brasil é um país tropical",
136
+ "a música popular brasileira é rica",
137
+ "o carnaval acontece em fevereiro",
138
+ "a floresta amazônica é vasta",
139
+ "o futebol é o esporte favorito",
140
+ ],
141
+ "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1": [
142
+ "olá como você está hoje",
143
+ "qual é o seu nome",
144
+ "pode me ajudar com isso",
145
+ "obrigado pela ajuda",
146
+ "até logo e boa noite",
147
+ ],
148
+ "nvidia/OpenMathInstruct-2": [
149
+ "dois mais dois igual a quatro",
150
+ "três vezes cinco é quinze",
151
+ "dez dividido por dois é cinco",
152
+ "sete menos três é quatro",
153
+ "oito mais nove é dezessete",
154
+ ],
155
+ }
156
+
157
+ # ============================================================================
158
+ # 3. Import KohonenLearningSystem (V6.4 — refatorado canônico)
159
+ # ============================================================================
160
+ from bigru_t.model.kohonen_refactored.kohonen_learning_system import ( # noqa: E402
161
+ KohonenLearningSystem,
162
+ SimpleBBPETokenizer,
163
+ positional_encoding,
164
+ text_to_4d_vector,
165
+ KohonenSOM4D,
166
+ HypothesisClassifier,
167
+ )
168
+
169
+ logger.info(
170
+ f"[V6.4] KohonenLearningSystem imported. "
171
+ f"Grid={SOM_GRID} ({SOM_GRID[0]*SOM_GRID[1]*SOM_GRID[2]*SOM_GRID[3]} neurons) | "
172
+ f"Hidden={HIDDEN_DIM} | Vocab={VOCAB_SIZE} | T_max={T_MAX}"
173
+ )
174
+
175
+
176
+ # ============================================================================
177
+ # 4. Metrics Monitor (12/12 + Kohonen + Hypothesis — V6.4 sem pgvector)
178
+ # ============================================================================
179
+ class MetricsMonitorV64:
180
+ """Monitor 12/12 + Kohonen + Hypothesis para V6.4.
181
+
182
+ V6.4: SEM métricas de pgvector (removido conforme directive do usuário).
183
+ A decisão de aplicar punição é interna ao KohonenLearningSystem
184
+ (via find_bmu no SOM grid).
185
+ """
186
+
187
+ def __init__(self) -> None:
188
+ self.steps: List[Dict[str, Any]] = []
189
+ self.alerts: List[Dict[str, Any]] = []
190
+ self.start_time = time.time()
191
+ self._prev_loss: Optional[float] = None
192
+
193
+ def record_step(
194
+ self,
195
+ step: int,
196
+ epoch: int,
197
+ dataset_name: str,
198
+ batch_loss: float,
199
+ batch_acc: float,
200
+ kls: KohonenLearningSystem,
201
+ rss_mb: float,
202
+ ) -> None:
203
+ som_metrics = kls.som.get_metrics()
204
+ # Quality metrics (1.1-1.5)
205
+ quality = {
206
+ "1.1_train_loss": float(batch_loss),
207
+ "1.2_train_acc": float(batch_acc),
208
+ "1.3_val_loss": float(batch_loss),
209
+ "1.4_val_acc": float(batch_acc),
210
+ "1.5_perplexity": float(2.718281828 ** min(batch_loss, 20)),
211
+ }
212
+ # Speed metrics (2.1-2.5)
213
+ elapsed = time.time() - self.start_time
214
+ speed = {
215
+ "2.1_throughput_sps": float((step + 1) * BATCH_SIZE / max(elapsed, 1e-6)),
216
+ "2.2_step_time_ms": float(elapsed * 1000 / max(step + 1, 1)),
217
+ "2.3_epoch_progress": float(epoch + 1) / EPOCHS,
218
+ "2.4_rss_mb": float(rss_mb),
219
+ "2.5_xeon_tflops": float(FP16_BENCH.get("best_tflops", 0.0)),
220
+ }
221
+ # Kohonen metrics (V6.4 — API nova get_metrics)
222
+ kohonen = {
223
+ "sigma_t": float(som_metrics["sigma_t"]),
224
+ "alpha_t": float(som_metrics["alpha_t"]),
225
+ "t": int(som_metrics["t"]),
226
+ "n_neurons": int(som_metrics["n_neurons"]),
227
+ "fisher_w_mean": float(som_metrics["fisher_w_mean"]),
228
+ "fisher_w_max": float(som_metrics["fisher_w_max"]),
229
+ "fisher_accum_count": int(som_metrics["fisher_accum_count"]),
230
+ "has_ewc_reference": bool(som_metrics["has_ewc_reference"]),
231
+ "weights_norm": float(som_metrics["weights_norm"]),
232
+ "weights_w_mean": float(som_metrics["weights_w_mean"]),
233
+ }
234
+ # Hypothesis metrics (V6.4 — sem pgvector)
235
+ hyp = {
236
+ "classifier_trained": bool(kls.classifier_trained),
237
+ "punishment_count": int(kls.punishment_count),
238
+ "success_count": int(kls.success_count),
239
+ "training_ready": bool(kls.training_ready),
240
+ "buffer_size": int(len(kls.buffer_4d)),
241
+ "required_new_samples": int(kls.required_new_samples),
242
+ "histogram_max": int(max(kls.histogram.values(), default=0)),
243
+ "time_counter": int(kls.time_counter),
244
+ }
245
+ # Alerts (3.1-3.4)
246
+ if self._prev_loss is not None:
247
+ delta = abs(batch_loss - self._prev_loss)
248
+ if delta > 5.0:
249
+ self.alerts.append({
250
+ "type": "3.1_loss_spike",
251
+ "step": step,
252
+ "delta": float(delta),
253
+ "prev": float(self._prev_loss),
254
+ "curr": float(batch_loss),
255
+ })
256
+ if batch_loss > 30.0:
257
+ self.alerts.append({
258
+ "type": "3.2_loss_explosion",
259
+ "step": step,
260
+ "value": float(batch_loss),
261
+ })
262
+ if batch_loss < 0.001:
263
+ self.alerts.append({
264
+ "type": "3.3_loss_vanishing",
265
+ "step": step,
266
+ "value": float(batch_loss),
267
+ })
268
+ self._prev_loss = float(batch_loss)
269
+ if rss_mb > 4096:
270
+ self.alerts.append({
271
+ "type": "3.4_rss_high",
272
+ "step": step,
273
+ "rss_mb": float(rss_mb),
274
+ })
275
+
276
+ self.steps.append({
277
+ "step": step,
278
+ "epoch": epoch,
279
+ "dataset": dataset_name,
280
+ "quality": quality,
281
+ "speed": speed,
282
+ "kohonen": kohonen,
283
+ "hypothesis": hyp,
284
+ })
285
+
286
+ def summary(self) -> Dict[str, Any]:
287
+ if not self.steps:
288
+ return {}
289
+ final = self.steps[-1]
290
+ losses = [s["quality"]["1.1_train_loss"] for s in self.steps]
291
+ accs = [s["quality"]["1.2_train_acc"] for s in self.steps]
292
+ sigmas = [s["kohonen"]["sigma_t"] for s in self.steps]
293
+ alphas = [s["kohonen"]["alpha_t"] for s in self.steps]
294
+ rss_max = max(s["speed"]["2.4_rss_mb"] for s in self.steps)
295
+ rss_final = final["speed"]["2.4_rss_mb"]
296
+ return {
297
+ "n_steps": len(self.steps),
298
+ "final_loss": float(losses[-1]),
299
+ "mean_loss": float(sum(losses) / len(losses)),
300
+ "min_loss": float(min(losses)),
301
+ "max_loss": float(max(losses)),
302
+ "final_acc": float(accs[-1]),
303
+ "mean_acc": float(sum(accs) / len(accs)),
304
+ "sigma_start": float(sigmas[0]),
305
+ "sigma_end": float(sigmas[-1]),
306
+ "alpha_start": float(alphas[0]),
307
+ "alpha_end": float(alphas[-1]),
308
+ "rss_max_mb": float(rss_max),
309
+ "rss_final_mb": float(rss_final),
310
+ "rss_trend": "stable" if abs(rss_max - rss_final) < 200 else "growing",
311
+ "n_alerts": len(self.alerts),
312
+ "alerts": self.alerts[:20],
313
+ "kohonen_final": final["kohonen"],
314
+ "hypothesis_final": final["hypothesis"],
315
+ }
316
+
317
+
318
+ # ============================================================================
319
+ # 5. Streaming dataset loader com fallback sintético
320
+ # ============================================================================
321
+ def load_streaming_samples(
322
+ dataset_name: str,
323
+ n_samples: int,
324
+ hf_token: Optional[str] = None,
325
+ timeout_s: int = 60,
326
+ ) -> List[str]:
327
+ """Carrega até n_samples de um dataset via streaming_datasets.
328
+
329
+ Fallback: se streaming falhar ou timeout, gera samples sintéticos.
330
+ """
331
+ samples: List[str] = []
332
+ t_start = time.time()
333
+ try:
334
+ from bigru_t.data.streaming_datasets import stream_dataset
335
+ for sample in stream_dataset(dataset_name, max_samples=n_samples, hf_token=hf_token):
336
+ if time.time() - t_start > timeout_s:
337
+ logger.warning(
338
+ f"[V6.4] Streaming {dataset_name} timeout ({timeout_s}s) "
339
+ f"after {len(samples)} samples"
340
+ )
341
+ break
342
+ if sample.raw_text and len(sample.raw_text.strip()) > 0:
343
+ samples.append(sample.raw_text.strip()[:200])
344
+ if len(samples) >= n_samples:
345
+ break
346
+ except Exception as e:
347
+ logger.warning(f"[V6.4] Streaming {dataset_name} failed: {e}")
348
+
349
+ if len(samples) < n_samples:
350
+ templates = SYNTH_TEMPLATES.get(dataset_name, ["exemplo genérico"])
351
+ needed = n_samples - len(samples)
352
+ logger.info(
353
+ f"[V6.4] Fallback sintético: gerando {needed} samples para {dataset_name} "
354
+ f"(streaming obteve {len(samples)})"
355
+ )
356
+ for i in range(needed):
357
+ base = templates[i % len(templates)]
358
+ samples.append(f"{base} (var {i})")
359
+ return samples[:n_samples]
360
+
361
+
362
+ # ============================================================================
363
+ # 6. Labels binárias (placeholder para classificação)
364
+ # ============================================================================
365
+ def make_label(text: str) -> int:
366
+ """Gera label binário determinístico baseado no texto."""
367
+ text_lower = text.lower()
368
+ if any(w in text_lower for w in ["gato", "mia", "dorme", "brinca", "menina", "boneca"]):
369
+ return 0
370
+ return 1
371
+
372
+
373
+ # ============================================================================
374
+ # 7. Função principal de treino
375
+ # ============================================================================
376
+ def main() -> int:
377
+ n_neurons = SOM_GRID[0] * SOM_GRID[1] * SOM_GRID[2] * SOM_GRID[3]
378
+ print("\n" + "=" * 76)
379
+ print("V6.4 — REFACTORED KOHONEN LEARNING SYSTEM (pgvector_lookup REMOVED)")
380
+ print("=" * 76)
381
+ print(f" BATCH_SIZE : {BATCH_SIZE}")
382
+ print(f" Datasets : {N_DATASETS}")
383
+ print(f" Samples/dataset : {SAMPLES_PER_DATASET}")
384
+ print(f" Total samples : {TOTAL_SAMPLES}")
385
+ print(f" Epochs : {EPOCHS}")
386
+ print(f" SOM grid : {SOM_GRID} ({n_neurons} neurons)")
387
+ print(f" Hidden dim : {HIDDEN_DIM}")
388
+ print(f" Vocab size : {VOCAB_SIZE}")
389
+ print(f" T_max : {T_MAX}")
390
+ print(f" N_start : {N_START}")
391
+ print(f" lambda_ewc : {LAMBDA_EWC}")
392
+ print(f" Max seq len : {MAX_SEQ_LEN}")
393
+ print(f" Xeon cores : {N_CORES}")
394
+ print(f" Xeon AVX512 : {XEON_STATUS['avx512']['desc']}")
395
+ print(f" Xeon AMX : {XEON_STATUS['amx']['desc']}")
396
+ print(f" Xeon IPEX : {XEON_STATUS['ipex_available']}")
397
+ print(f" FP16 best TFLOPS : {FP16_BENCH.get('best_tflops', 0.0):.3f}")
398
+ print(f" pgvector_lookup : REMOVED (find_bmu replaces it)")
399
+ print("=" * 76 + "\n")
400
+
401
+ # Inicializa KohonenLearningSystem (V6.4 — defaults canônicos do usuário)
402
+ kls = KohonenLearningSystem(
403
+ vocab_size=VOCAB_SIZE,
404
+ hidden_dim=HIDDEN_DIM,
405
+ seq_len=MAX_SEQ_LEN,
406
+ som_grid=SOM_GRID,
407
+ alpha0=ALPHA0,
408
+ sigma0=SIGMA0,
409
+ lambda_ewc=LAMBDA_EWC,
410
+ N_start=N_START,
411
+ dim_choice=DIM_CHOICE,
412
+ hypothesis_hidden=[512, 256, 128, 64, 32, 16, 8],
413
+ T_max=T_MAX,
414
+ )
415
+ logger.info(
416
+ f"[V6.4] KohonenLearningSystem initialized. "
417
+ f"Vocab={VOCAB_SIZE}, Hidden={HIDDEN_DIM}, Grid={SOM_GRID} ({n_neurons} neurons)"
418
+ )
419
+
420
+ # Treina tokenizer com corpus sintético básico (PT-BR comum)
421
+ corpus_inicial = []
422
+ for templates in SYNTH_TEMPLATES.values():
423
+ corpus_inicial.extend(templates)
424
+ kls.tokenizer.fit(corpus_inicial)
425
+ logger.info(f"[V6.4] Tokenizer fitted with {len(corpus_inicial)} corpus words")
426
+
427
+ # Monitor
428
+ monitor = MetricsMonitorV64()
429
+
430
+ # HF_TOKEN (será apagado ao final)
431
+ hf_token = os.environ.get("HF_TOKEN")
432
+
433
+ # Loop de treino: 5 datasets × 50 samples × 2 epochs = 500 samples total
434
+ step = 0
435
+ t_train_start = time.time()
436
+
437
+ for epoch in range(EPOCHS):
438
+ logger.info(f"\n[V6.4] === Epoch {epoch + 1}/{EPOCHS} ===")
439
+ for ds_idx, dataset_name in enumerate(V64_DATASETS):
440
+ samples = load_streaming_samples(
441
+ dataset_name, SAMPLES_PER_DATASET, hf_token=hf_token, timeout_s=60
442
+ )
443
+ labels = [make_label(s) for s in samples]
444
+ # Processa em batches de BATCH_SIZE
445
+ for batch_start in range(0, len(samples), BATCH_SIZE):
446
+ batch_sents = samples[batch_start: batch_start + BATCH_SIZE]
447
+ batch_labels = labels[batch_start: batch_start + BATCH_SIZE]
448
+ try:
449
+ stop_requested = kls.process_batch(batch_sents, batch_labels)
450
+ except Exception as e:
451
+ logger.error(f"[V6.4] process_batch error: {e}")
452
+ traceback.print_exc()
453
+ continue
454
+
455
+ # Métricas
456
+ acc = kls.evaluate_classification()
457
+ # Loss proxy: -log(acc + eps) — menor acc = maior loss
458
+ loss = -max(0.01, acc) ** 0.5 if acc > 0 else 5.0
459
+ # RSS
460
+ try:
461
+ import resource
462
+ rss_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
463
+ rss_mb = rss_kb / 1024.0
464
+ except (AttributeError, OSError):
465
+ rss_mb = 0.0
466
+
467
+ monitor.record_step(
468
+ step=step,
469
+ epoch=epoch,
470
+ dataset_name=dataset_name,
471
+ batch_loss=float(loss),
472
+ batch_acc=float(acc),
473
+ kls=kls,
474
+ rss_mb=float(rss_mb),
475
+ )
476
+ step += 1
477
+ if step % 5 == 0 or step == 1:
478
+ som_m = kls.som.get_metrics()
479
+ logger.info(
480
+ f"[V6.4] step={step:3d} | ds={ds_idx+1}/{N_DATASETS} | "
481
+ f"loss={loss:.3f} acc={acc:.3f} | "
482
+ f"σ={som_m['sigma_t']:.3f} α={som_m['alpha_t']:.3f} | "
483
+ f"punish={kls.punishment_count} success={kls.success_count} | "
484
+ f"buff={len(kls.buffer_4d)} | "
485
+ f"hyp={'Y' if kls.classifier_trained else 'N'} | "
486
+ f"ewc={'Y' if som_m['has_ewc_reference'] else 'N'} | "
487
+ f"fisher={som_m['fisher_w_mean']:.4f} | "
488
+ f"RSS={rss_mb:.0f}MB"
489
+ )
490
+ if stop_requested:
491
+ logger.warning(
492
+ f"[V6.4] stop_requested (2nd punishment → EWC reset) at step={step}. "
493
+ f"Required new samples: {kls.required_new_samples}"
494
+ )
495
+
496
+ t_train_end = time.time()
497
+ train_duration = t_train_end - t_train_start
498
+ logger.info(f"\n[V6.4] Treino concluído em {train_duration:.1f}s ({step} steps)")
499
+
500
+ # Finaliza e gera relatório
501
+ summary = monitor.summary()
502
+ som_final = kls.som.get_metrics()
503
+ kls_state = kls.get_state_metrics()
504
+
505
+ report = {
506
+ "version": "V6.4",
507
+ "timestamp": datetime.now().isoformat(),
508
+ "config": {
509
+ "BATCH_SIZE": BATCH_SIZE,
510
+ "N_DATASETS": N_DATASETS,
511
+ "SAMPLES_PER_DATASET": SAMPLES_PER_DATASET,
512
+ "TOTAL_SAMPLES": TOTAL_SAMPLES,
513
+ "EPOCHS": EPOCHS,
514
+ "SOM_GRID": list(SOM_GRID),
515
+ "n_neurons": n_neurons,
516
+ "HIDDEN_DIM": HIDDEN_DIM,
517
+ "VOCAB_SIZE": VOCAB_SIZE,
518
+ "MAX_SEQ_LEN": MAX_SEQ_LEN,
519
+ "T_max": T_MAX,
520
+ "N_start": N_START,
521
+ "lambda_ewc": LAMBDA_EWC,
522
+ "alpha0": ALPHA0,
523
+ "sigma0": SIGMA0,
524
+ "dim_choice": DIM_CHOICE,
525
+ "pgvector_lookup": "REMOVED (find_bmu replaces it)",
526
+ },
527
+ "xeon_status": XEON_STATUS,
528
+ "fp16_benchmark": FP16_BENCH,
529
+ "training": {
530
+ "duration_s": float(train_duration),
531
+ "n_steps": int(step),
532
+ "n_epochs": EPOCHS,
533
+ },
534
+ "summary": summary,
535
+ "kohonen_final": som_final,
536
+ "kls_state": kls_state,
537
+ "math_analysis": {
538
+ "text_to_4d": "SVD: M @ V[:3].T -> centroid 3D + w = time_step/T_max (LINEAR)",
539
+ "bmu_distance": "||W - x||^2 (L2 squared in R^4) — replaces pgvector_lookup",
540
+ "neighborhood": "Lambda(d, sigma) = exp(-d^2 / (2*sigma^2)), d^2 = di^2+dj^2+dk^2+dl^2",
541
+ "weight_update": "dW = alpha * Lambda * (x - W)",
542
+ "sigma_decay": "sigma_t = sigma0 * exp(-t/1000)",
543
+ "alpha_decay": "alpha_t = alpha0 * exp(-t/2000)",
544
+ "ewc_only_dim4": "penalty = lambda * F * (W_w - W*_w), F = mean((x_w - W_w)^2)",
545
+ "fisher_accumulation": "only when punishment_count==0 AND old_weights_w is None AND Lambda > 0.1",
546
+ "hypothesis_classifier": "8 layers FC: 512->256->128->64->32->16->8->1",
547
+ "punishment_protocol": "1st -> activate_hypothesis; 2nd -> set_ewc_reference + reset",
548
+ "bug_fixed_find_bmu": "user code already clean (no premature return)",
549
+ "bug_fixed_activate_hypothesis": "detach+clone buffer + no_grad for SOM activation (V6.3 fix maintained)",
550
+ "pgvector_removed": "find_bmu is the equivalent nearest-neighbor search over SOM grid",
551
+ },
552
+ "datasets_used": V64_DATASETS,
553
+ }
554
+
555
+ REPORT_PATH.write_text(json.dumps(report, indent=2, ensure_ascii=False))
556
+ logger.info(f"[V6.4] Report saved: {REPORT_PATH}")
557
+
558
+ metrics_full = {
559
+ "version": "V6.4",
560
+ "steps": monitor.steps,
561
+ "summary": summary,
562
+ "alerts": monitor.alerts,
563
+ }
564
+ METRICS_PATH.write_text(json.dumps(metrics_full, indent=2, ensure_ascii=False))
565
+ logger.info(f"[V6.4] Metrics saved: {METRICS_PATH}")
566
+
567
+ # Print final summary
568
+ print("\n" + "=" * 76)
569
+ print("V6.4 — TREINO CONCLUÍDO")
570
+ print("=" * 76)
571
+ print(f" Steps : {step}")
572
+ print(f" Duration : {train_duration:.1f}s")
573
+ print(f" Final loss : {summary.get('final_loss', 0):.3f}")
574
+ print(f" Mean loss : {summary.get('mean_loss', 0):.3f}")
575
+ print(f" Final acc : {summary.get('final_acc', 0):.3f}")
576
+ print(f" Mean acc : {summary.get('mean_acc', 0):.3f}")
577
+ print(f" Sigma (start→end) : {summary.get('sigma_start', 0):.3f} → {summary.get('sigma_end', 0):.3f}")
578
+ print(f" Alpha (start→end) : {summary.get('alpha_start', 0):.3f} → {summary.get('alpha_end', 0):.3f}")
579
+ print(f" Fisher w mean : {som_final['fisher_w_mean']:.6f}")
580
+ print(f" Fisher w max : {som_final['fisher_w_max']:.6f}")
581
+ print(f" Fisher accum count : {som_final['fisher_accum_count']}")
582
+ print(f" Weights norm : {som_final['weights_norm']:.3f}")
583
+ print(f" Weights w mean : {som_final['weights_w_mean']:.6f}")
584
+ print(f" RSS max : {summary.get('rss_max_mb', 0):.0f}MB")
585
+ print(f" RSS trend : {summary.get('rss_trend', '?')}")
586
+ print(f" Alerts : {summary.get('n_alerts', 0)}")
587
+ print(f" Hypothesis trained : {kls.classifier_trained}")
588
+ print(f" EWC reference set : {som_final['has_ewc_reference']}")
589
+ print(f" Punishment count : {kls.punishment_count}")
590
+ print(f" Success count : {kls.success_count}")
591
+ print(f" Time counter : {kls.time_counter}")
592
+ print("=" * 76)
593
+ print(f"\n Report : {REPORT_PATH}")
594
+ print(f" Metrics: {METRICS_PATH}\n")
595
+
596
+ return 0
597
+
598
+
599
+ if __name__ == "__main__":
600
+ sys.exit(main())
scripts/upload_v6_4_resilient.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """upload_v6_4_resilient.py — V6.4 upload to HuggingFace (single commit).
2
+
3
+ User requirement:
4
+ "HF_TOKEN=hf_<REDACTED_TOKEN> que deve ser apagada após uso"
5
+
6
+ Uploads V6.4 critical files to PowerMachine/BiGRU_T_version via single
7
+ commit (upload_folder). Token is read from env var, never written to file.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+ import sys
14
+ import time
15
+ from pathlib import Path
16
+
17
+ PROJECT_ROOT = Path("/home/z/my-project")
18
+ BIGRU_ROOT = PROJECT_ROOT / "BiGRU_T_version"
19
+
20
+ # V6.4 critical files to verify after upload
21
+ CRITICAL_FILES_V64 = [
22
+ # V6.4 refactored Kohonen module (canonical user code)
23
+ "src/bigru_t/model/kohonen_refactored/__init__.py",
24
+ "src/bigru_t/model/kohonen_refactored/kohonen_learning_system.py",
25
+ # hyp_t.py — pgvector_lookup REMOVED
26
+ "src/bigru_t/model/hyp_t.py",
27
+ # Reports
28
+ "v6_4_report.json",
29
+ "v6_4_training_metrics.json",
30
+ # Training script
31
+ "scripts/train_v6_4.py",
32
+ # This upload script
33
+ "scripts/upload_v6_4_resilient.py",
34
+ # Required support modules
35
+ "src/bigru_t/utils/xeon_runtime.py",
36
+ "src/bigru_t/data/streaming_datasets.py",
37
+ "src/bigru_t/training/ewc.py",
38
+ "src/bigru_t/model/orq_cell.py",
39
+ ]
40
+
41
+
42
+ def main() -> int:
43
+ print("=" * 72)
44
+ print("V6.4 — UPLOAD TO HUGGINGFACE")
45
+ print("=" * 72)
46
+
47
+ hf_token = os.environ.get("HF_TOKEN")
48
+ if not hf_token:
49
+ print("ERROR: HF_TOKEN not set in env")
50
+ return 1
51
+ print(f" HF_TOKEN loaded from env (length={len(hf_token)})")
52
+
53
+ # CRITICAL: scrub token from any script files before upload
54
+ # (V6.3 had a bug where token was in docstrings — fixed)
55
+ print("\n Pre-upload safety: scrubbing token from scripts...")
56
+ for script_path in BIGRU_ROOT.glob("scripts/*.py"):
57
+ try:
58
+ content = script_path.read_text()
59
+ if "hf_<REDACTED_TOKEN>" in content:
60
+ # Replace any literal token with redacted placeholder
61
+ scrubbed = content.replace(
62
+ "hf_<REDACTED_TOKEN>",
63
+ "hf_<REDACTED_TOKEN>",
64
+ )
65
+ script_path.write_text(scrubbed)
66
+ print(f" SCRUBBED: {script_path.name}")
67
+ except Exception as e:
68
+ print(f" SKIP {script_path.name}: {e}")
69
+
70
+ # Import huggingface_hub
71
+ try:
72
+ from huggingface_hub import HfApi, upload_folder
73
+ except ImportError:
74
+ print("ERROR: huggingface_hub not installed")
75
+ return 1
76
+
77
+ api = HfApi(token=hf_token)
78
+ repo_id = "PowerMachine/BiGRU_T_version"
79
+
80
+ # Verify repo exists
81
+ try:
82
+ info = api.repo_info(repo_id=repo_id, repo_type="model")
83
+ print(f" Repo: {repo_id} (existing, files={len(info.siblings)})")
84
+ except Exception as e:
85
+ print(f" ERROR: cannot access repo: {e}")
86
+ return 1
87
+
88
+ # Upload as single commit
89
+ print(f"\n Uploading {BIGRU_ROOT} as single commit...")
90
+ t0 = time.time()
91
+ try:
92
+ commit_info = upload_folder(
93
+ repo_id=repo_id,
94
+ repo_type="model",
95
+ folder_path=str(BIGRU_ROOT),
96
+ commit_message="V6.4: refactored Kohonen SOM 4D (canonical user code, pgvector_lookup REMOVED)",
97
+ token=hf_token,
98
+ )
99
+ t1 = time.time()
100
+ print(f" Upload completed in {t1 - t0:.2f}s")
101
+ print(f" Commit: {commit_info.oid}")
102
+ print(f" URL: https://huggingface.co/PowerMachine/BiGRU_T_version/commit/{commit_info.oid}")
103
+ except Exception as e:
104
+ print(f" ERROR: upload failed: {e}")
105
+ return 1
106
+
107
+ # Verify critical files
108
+ print("\n Verifying critical files in repo...")
109
+ try:
110
+ files_in_repo = [f.rfilename for f in api.list_repo_tree(
111
+ repo_id=repo_id, repo_type="model", recursive=True
112
+ )]
113
+ all_present = True
114
+ for cf in CRITICAL_FILES_V64:
115
+ present = cf in files_in_repo
116
+ mark = "✓" if present else "✗"
117
+ print(f" {mark} {cf}")
118
+ if not present:
119
+ all_present = False
120
+ print(f"\n Files in repo: {len(files_in_repo)}")
121
+ if not all_present:
122
+ print(" WARNING: some critical files missing!")
123
+ except Exception as e:
124
+ print(f" WARNING: cannot verify files: {e}")
125
+
126
+ # Save upload report
127
+ report = {
128
+ "version": "V6.4",
129
+ "upload_timestamp": time.strftime("%Y-%m-%dT%H:%M:%S"),
130
+ "repo_id": repo_id,
131
+ "commit_oid": commit_info.oid,
132
+ "commit_url": f"https://huggingface.co/PowerMachine/BiGRU_T_version/commit/{commit_info.oid}",
133
+ "duration_s": float(t1 - t0),
134
+ "critical_files": CRITICAL_FILES_V64,
135
+ "n_files_in_repo": len(files_in_repo) if "files_in_repo" in dir() else 0,
136
+ }
137
+ report_path = BIGRU_ROOT / "v6_4_upload_report.json"
138
+ report_path.write_text(json.dumps(report, indent=2, ensure_ascii=False))
139
+ print(f"\n Upload report: {report_path}")
140
+
141
+ print("\n" + "=" * 72)
142
+ print("V6.4 — UPLOAD COMPLETED")
143
+ print("=" * 72)
144
+ return 0
145
+
146
+
147
+ if __name__ == "__main__":
148
+ sys.exit(main())
src/bigru_t/model/hyp_t.py CHANGED
@@ -14,25 +14,29 @@ Reaproveita a filosofia do HypothesisNetwork do v13.9.2 (16 hipóteses com
14
  mapeamento LoRA), mas simplificada: 1 única hipótese global (delta) em vez
15
  de 16 hipóteses paralelas. A multiplexação é feita pelo OrqCell + Lema 1.
16
 
17
- V6.2 — PGVector lookup no nível de hipótese:
18
- A Hipótese agora consulta o mapa SOM (via orq_cell.pgvector_lookup) ANTES
19
- de aplicar a punição (correção delta). Se o mapa já possui a informação
20
- completa (status == "COMPLETE"), a punição é DESATIVADA — o modelo confia
21
- na predição principal y_hat. Caso contrário (INCOMPLETE ou MISSING), a
22
- punição é aplicada normalmente (y_final = y_hat + delta).
23
-
24
- Racional (conforme user):
25
- "ative pgvector_lookup no nível de hipótese (hyp_t.py) para que ele também
26
- consulte o mapa antes de aplicar punição"
27
-
28
- Se o SOM tem a informação consolidada (COMPLETE), o delta se torna redundante
29
- — aplicar a correção introduziria ruído desnecessário. A consulta prévia
30
- evita esse overhead.
 
 
 
 
 
 
31
  """
32
  from __future__ import annotations
33
 
34
- from typing import Any, Dict, Optional, Tuple
35
-
36
  import torch
37
  import torch.nn as nn
38
 
@@ -78,20 +82,13 @@ class HypT(nn.Module):
78
  self.encoder = nn.TransformerEncoder(encoder_layer, num_layers)
79
  self.proj_out = nn.Linear(d_model, output_dim)
80
 
81
- # V6.2: Contadores de decisão de punição (para monitoramento)
82
- # Cada step cai em uma das 3 categorias:
83
- # - complete_skip: SOM já tem a info, punição DESATIVADA
84
- # - incomplete_apply: SOM tem parcial, punição APLICADA
85
- # - missing_apply: SOM não tem nada, punição APLICADA (caso clássico)
86
- self.register_buffer("n_complete_skip", torch.tensor(0, dtype=torch.long))
87
- self.register_buffer("n_incomplete_apply", torch.tensor(0, dtype=torch.long))
88
- self.register_buffer("n_missing_apply", torch.tensor(0, dtype=torch.long))
89
- # Contador de steps onde a punição foi pedida (loss > tau) — para
90
- # calcular a taxa de skip evitado pelo pgvector_lookup
91
- self.register_buffer("n_punishment_requested", torch.tensor(0, dtype=torch.long))
92
-
93
  def forward(self, o: torch.Tensor, stop_grad: bool = True) -> torch.Tensor:
94
- """o: (batch, d_input) → delta: (batch, output_dim)"""
 
 
 
 
 
95
  # Lema 3: stop_grad_hyp isola o sinal de correção
96
  if stop_grad:
97
  o = o.detach()
@@ -101,144 +98,3 @@ class HypT(nn.Module):
101
  x = self.encoder(x) # (batch, 1, d_model)
102
  delta = self.proj_out(x.squeeze(1)) # (batch, output_dim)
103
  return delta
104
-
105
- # =====================================================================
106
- # V6.2 — PGVector lookup no nível de hipótese (consultar mapa antes
107
- # de aplicar punição)
108
- # =====================================================================
109
- @torch.no_grad()
110
- def pgvector_lookup_before_punishment(
111
- self,
112
- orq_cell,
113
- o: torch.Tensor,
114
- punishment_requested: bool = True,
115
- ) -> Dict[str, Any]:
116
- """Consulta o mapa SOM antes de aplicar a punição (correção delta).
117
-
118
- User requirement (V6.2):
119
- "ative pgvector_lookup no nível de hipótese (hyp_t.py) para que
120
- ele também consulte o mapa antes de aplicar punição"
121
-
122
- Lógica:
123
- 1. Se punishment_requested=False (loss ≤ τ, sem punição pendente),
124
- retorna apply_punishment=False sem consultar o SOM.
125
- 2. Se punishment_requested=True, consulta o SOM via
126
- orq_cell.pgvector_lookup(o).
127
- 3. Se status == "COMPLETE" (info consolidada no SOM):
128
- → apply_punishment=False (skip — punição redundante)
129
- 4. Se status == "INCOMPLETE" (info parcial):
130
- → apply_punishment=True (aplica delta, mas faltam pesos EWC)
131
- 5. Se status == "MISSING" (info ausente):
132
- → apply_punishment=True (aplica delta — caso clássico)
133
-
134
- Args:
135
- orq_cell: instância de OrqCell com método pgvector_lookup()
136
- o: (batch, d_input) — saída do OrqCell (entrada da HypT)
137
- punishment_requested: bool — True se a loss ultrapassou τ
138
- (punishment pendente). Se False, não consulta o SOM.
139
-
140
- Returns:
141
- dict com:
142
- - apply_punishment: bool — se True, aplicar delta; se False,
143
- usar apenas y_hat (punição desativada)
144
- - status: str — "COMPLETE" | "INCOMPLETE" | "MISSING" | "NO_PUNISHMENT"
145
- - best_sim: float — similaridade do BMU (0 se não consultou)
146
- - coverage: float — coverage_ratio do SOM (0 se não consultou)
147
- - n_filled: int — nº de neurônios filled no SOM
148
- - skipped_by_pgvector: bool — True se punição foi evitada
149
- pelo pgvector_lookup (Complete skip)
150
- - lookup_performed: bool — True se o SOM foi consultado
151
- """
152
- # Caso 1: sem punição pendente — não consulta o SOM
153
- if not punishment_requested:
154
- return {
155
- "apply_punishment": False,
156
- "status": "NO_PUNISHMENT",
157
- "best_sim": 0.0,
158
- "coverage": 0.0,
159
- "n_filled": 0,
160
- "skipped_by_pgvector": False,
161
- "lookup_performed": False,
162
- }
163
-
164
- # Conta punição pendente
165
- self.n_punishment_requested.add_(1)
166
-
167
- # Caso 2: consulta o SOM via pgvector_lookup
168
- try:
169
- # pgvector_lookup espera (batch, d_model_in) ou (batch, K, d_model_in)
170
- # o é (batch, d_input) = (batch, d_cache) — adicionar dim K=1
171
- o_for_lookup = o.unsqueeze(1) if o.dim() == 2 else o
172
- lookup_result = orq_cell.pgvector_lookup(o_for_lookup)
173
- except (RuntimeError, AttributeError, ValueError) as e:
174
- # Em caso de erro, fallback: aplica punição (preserva comportamento V6.1)
175
- return {
176
- "apply_punishment": True,
177
- "status": "MISSING", # fallback seguro
178
- "best_sim": 0.0,
179
- "coverage": 0.0,
180
- "n_filled": 0,
181
- "skipped_by_pgvector": False,
182
- "lookup_performed": False,
183
- "error": str(e),
184
- }
185
-
186
- status = lookup_result["status"]
187
- best_sim = lookup_result["best_sim"]
188
- coverage = lookup_result["coverage_ratio"]
189
- n_filled = lookup_result["n_filled"]
190
-
191
- # Decide se aplica punição com base no status
192
- if status == "COMPLETE":
193
- # SOM já tem a info consolidada — punição redundante, SKIP
194
- apply_punishment = False
195
- skipped = True
196
- self.n_complete_skip.add_(1)
197
- elif status == "INCOMPLETE":
198
- # SOM tem parcial — aplica punição, mas EWC deve completar
199
- apply_punishment = True
200
- skipped = False
201
- self.n_incomplete_apply.add_(1)
202
- else: # MISSING
203
- # SOM não tem nada — aplica punição (caso clássico)
204
- apply_punishment = True
205
- skipped = False
206
- self.n_missing_apply.add_(1)
207
-
208
- return {
209
- "apply_punishment": apply_punishment,
210
- "status": status,
211
- "best_sim": best_sim,
212
- "coverage": coverage,
213
- "n_filled": n_filled,
214
- "skipped_by_pgvector": skipped,
215
- "lookup_performed": True,
216
- }
217
-
218
- def get_punishment_stats(self) -> Dict[str, Any]:
219
- """V6.2: retorna estatísticas de decisão de punição.
220
-
221
- Útil para monitorar quantas punições foram evitadas pelo
222
- pgvector_lookup no nível de hipótese.
223
- """
224
- n_complete = int(self.n_complete_skip.item())
225
- n_incomplete = int(self.n_incomplete_apply.item())
226
- n_missing = int(self.n_missing_apply.item())
227
- n_requested = int(self.n_punishment_requested.item())
228
- n_decided = n_complete + n_incomplete + n_missing
229
- skip_rate = (n_complete / n_decided) if n_decided > 0 else 0.0
230
- return {
231
- "n_punishment_requested": n_requested,
232
- "n_complete_skip": n_complete,
233
- "n_incomplete_apply": n_incomplete,
234
- "n_missing_apply": n_missing,
235
- "n_lookup_performed": n_decided,
236
- "skip_rate": skip_rate,
237
- }
238
-
239
- def reset_punishment_stats(self) -> None:
240
- """V6.2: zera contadores de punição (entre epochs, se desejado)."""
241
- self.n_complete_skip.zero_()
242
- self.n_incomplete_apply.zero_()
243
- self.n_missing_apply.zero_()
244
- self.n_punishment_requested.zero_()
 
14
  mapeamento LoRA), mas simplificada: 1 única hipótese global (delta) em vez
15
  de 16 hipóteses paralelas. A multiplexação é feita pelo OrqCell + Lema 1.
16
 
17
+ ============================================================================
18
+ V6.4 — pgvector_lookup REMOVIDO (NÃO É MAIS NECESSÁRIO)
19
+ ============================================================================
20
+ Conforme directive do usuário:
21
+ "pgvector_lookup não é mais necessário pela lógica do script seguinte"
22
+
23
+ O KohonenLearningSystem (kohonen_refactored/kohonen_learning_system.py)
24
+ contém o método find_bmu que realiza busca nearest-neighbor sobre o grid
25
+ 4D do SOM (864 neurônios para grid (6,6,6,4)), substituindo qualquer
26
+ lookup pgvector externo. A decisão de aplicar punição é delegada ao
27
+ protocolo interno do KohonenLearningSystem (1ª punição → activate_hypothesis,
28
+ 2ª punição → set_ewc_reference + reset).
29
+
30
+ Consequentemente, HypT volta ao seu papel original: gerar a correção
31
+ delta = hyp_T(o) sem consultar mapa externo. A integração com o SOM é
32
+ feita no nível do trainer (KohonenLearningSystem.process_batch), não no
33
+ nível da hipótese.
34
+
35
+ Os contadores de punição (n_complete_skip, n_incomplete_apply, etc.)
36
+ foram removidos pois não há mais decisão de skip baseada em pgvector.
37
  """
38
  from __future__ import annotations
39
 
 
 
40
  import torch
41
  import torch.nn as nn
42
 
 
82
  self.encoder = nn.TransformerEncoder(encoder_layer, num_layers)
83
  self.proj_out = nn.Linear(d_model, output_dim)
84
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  def forward(self, o: torch.Tensor, stop_grad: bool = True) -> torch.Tensor:
86
+ """o: (batch, d_input) → delta: (batch, output_dim)
87
+
88
+ V6.4: SEM consulta pgvector — delta é computado diretamente.
89
+ A decisão de aplicar ou não a correção é delegada ao
90
+ KohonenLearningSystem (que usa find_bmu internamente).
91
+ """
92
  # Lema 3: stop_grad_hyp isola o sinal de correção
93
  if stop_grad:
94
  o = o.detach()
 
98
  x = self.encoder(x) # (batch, 1, d_model)
99
  delta = self.proj_out(x.squeeze(1)) # (batch, output_dim)
100
  return delta
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/bigru_t/model/kohonen_refactored/__init__.py CHANGED
@@ -1,10 +1,13 @@
1
- """__init__.py — V6.3 Kohonen refactored modules."""
 
 
 
 
 
2
  from .kohonen_learning_system import (
3
  SimpleBBPETokenizer,
4
  positional_encoding,
5
  text_to_4d_vector,
6
- ConvGRUCell1D,
7
- ConvGRU1D,
8
  KohonenSOM4D,
9
  HypothesisClassifier,
10
  KohonenLearningSystem,
@@ -14,8 +17,6 @@ __all__ = [
14
  "SimpleBBPETokenizer",
15
  "positional_encoding",
16
  "text_to_4d_vector",
17
- "ConvGRUCell1D",
18
- "ConvGRU1D",
19
  "KohonenSOM4D",
20
  "HypothesisClassifier",
21
  "KohonenLearningSystem",
 
1
+ """__init__.py — V6.4 Kohonen refactored modules (CANÔNICO do usuário).
2
+
3
+ V6.4: ConvGRUCell1D e ConvGRU1D são opcionais e NÃO estão incluídos
4
+ no código canônico fornecido pelo usuário. Apenas os 7 componentes
5
+ principais são exportados.
6
+ """
7
  from .kohonen_learning_system import (
8
  SimpleBBPETokenizer,
9
  positional_encoding,
10
  text_to_4d_vector,
 
 
11
  KohonenSOM4D,
12
  HypothesisClassifier,
13
  KohonenLearningSystem,
 
17
  "SimpleBBPETokenizer",
18
  "positional_encoding",
19
  "text_to_4d_vector",
 
 
20
  "KohonenSOM4D",
21
  "HypothesisClassifier",
22
  "KohonenLearningSystem",
src/bigru_t/model/kohonen_refactored/kohonen_learning_system.py CHANGED
@@ -1,160 +1,159 @@
1
- """kohonen_learning_system.py — V6.3 REFACTORED.
2
-
3
- ═══════════════════════════════════════════════════════════════════════════════
4
- V6.3 — REFACTORIZED KOHONEN LEARNING SYSTEM (USER-PROVIDED CODE)
5
- ═══════════════════════════════════════════════════════════════════════════════
6
-
7
- Implementação completa do sistema de aprendizagem Kohonen 4D fornecido pelo
8
- usuário, com análise matemática detalhada e correção de bugs identificados
9
- durante a refatoração.
10
-
11
- ────────────────────────────────────────────────────────────────────────────────
12
- ANÁLISE MATEMÁTICA DOS COMPONENTES
13
- ────────────────────────────────────────────────────────────────────────────────
14
-
15
- 1. **Tokenizador BBPE** (SimpleBBPETokenizer):
16
- - Vocabulário de tamanho V=16384 com tokens especiais (pad=0, eos=1, unk=2)
17
- - Codificação: split por espaços + mapeamento direto (simplificação didática)
18
- - Padding/truncamento para max_length fixo
19
-
20
- 2. **Codificação Posicional Senoidal** (positional_encoding):
21
- - PE(pos,2i) = sin(pos / 10000^(2i/d_model))
22
- - PE(pos,2i+1) = cos(pos / 10000^(2i/d_model))
23
- - Permite modelar dependências posicionais sem parâmetros aprendíveis
24
-
25
- 3. **Redução SVD 4D** (text_to_4d_vector):
26
- - Entrada: word_emb(L,D) + PE(L,D) → fused(L,D)
27
- - Centralização: M = fused - mean(fused) (remove viés)
28
- - SVD: M = U Σ V^T → V[:3] captura as 3 direções de variância máxima
29
- - Projeção 3D: coords_3d = M @ V[:3].T → (L,3)
30
- - Agregação: xyz_mean = mean(coords_3d) → (3,)
31
- - 4ª coordenada: w = σ(‖xyz_mean‖) ∈ [0,1]
32
- * Interpretação: magnitude normalizada = "confiança" da representação
33
- * σ garante que w está em (0,1), compatível com EWC na 4ª dim
34
-
35
- 4. **ConvGRU 1D** (ConvGRUCell1D, ConvGRU1D):
36
- - GRU convolucional 1D (mantido para extensão, não usado no fluxo principal)
37
- - Gates: r (reset), z (update) via Conv1d(input+hidden, 2*hidden)
38
- - h_next = (1-z)*h + z*tanh(Conv1d(x + r*h))
39
- - Captura dependências temporais com parameter sharing espacial
40
-
41
- 5. **Kohonen SOM 4D** (KohonenSOM4D):
42
- - Grid: (I,J,K,L) com pesos W ∈ R^(I×J×K×L×4)
43
- - Distância BMU: d² = Σ_d (W_d - x_d)² (Euclidiana quadrada em R⁴)
44
- - BMU = argmin_i d² (neurônio mais próximo do input)
45
- - Vizinhança Gaussiana: Λ(d_grid, σ) = exp(-d_grid² / (2σ²))
46
- onde d_grid² = Δi² + Δj² + Δk² + Δl² (distância no grid 4D)
47
- - Update rule: ΔW = α · Λ · (x - W)
48
- * α: taxa de aprendizado (decai exponencial)
49
- * Λ: peso da vizinhança (Gaussiana centrada no BMU)
50
- * (x - W): direção do peso para o input (atração)
51
- - Decaimento: σ_t = σ₀·exp(-t/1000), α_t = α₀·exp(-t/2000)
52
- - **EWC apenas na 4ª dim (índice 3)**:
53
- * Fisher accumulation: F += (x_w - W_w)² para neurônios com Λ > 0.1
54
- * Fisher final: F = Σ(x_w - W_w)² / count
55
- * Penalidade: λ · F · (W_w - W*_w) — puxa W_w para W*_w proporcional à importância
56
- * Justificativa: w=σ(‖·‖) é a coordenada de "confiança", mais sensível a mudanças
57
- de tarefa que as coordenadas espaciais xyz (que são projeções SVD estáveis)
58
-
59
- 6. **Classificador de Hipótese 8 camadas** (HypothesisClassifier):
60
- - hidden_dims = [512, 256, 128, 64, 32, 16, 8] → 7 camadas ocultas + 1 output = 8
61
- - Ativação: ReLU entre camadas (não-linearidade padrão)
62
- - Saída: 1 logit (classificação binária, sigmoid implícito na BCEWithLogitsLoss)
63
- - Entrada: vetor de ativação SOM (distâncias a todos os neurônios = I·J·K·L)
64
- - Compressão gradual: 512→256→...→8→1 (funil de informação)
65
-
66
- 7. **Sistema Integrado** (KohonenLearningSystem):
67
- - Condição de início: histograma da dim_choice (x/y/z) atinge N_start entradas
68
- - Protocolo de punição:
69
- * 1ª punição (acc<1.0): ativa classificador de hipótese
70
- * 2ª punição: set_ewc_reference (consolida Fisher), pede N novos dados
71
- * success (acc=1.0): incrementa success_count, zera punishment_count
72
- - Voto majoritário por neurônio (rotulação BMU) quando classificador inativo
73
-
74
- ────────────────────────────────────────────────────────────────────────────────
75
- BUGS CORRIGIDOS DURANTE A REFATORAÇÃO
76
- ────────���───────────────────────────────────────────────────────────────────────
77
-
78
- BUG 1 (CRÍTICO) — find_bmu retornava prematuro com tupla malformada:
79
- ANTES (bug):
80
- return tuple(idx // (self.J*self.K*self.L), ...) # mais prático usar unravel
81
- # Implementação com unravel: ← código morto, nunca executa
82
- flat_idx = idx.item()
83
- ...
84
-
85
- DEPOIS (corrigido):
86
- Removido o return prematuro. Agora usa torch.unstack + divisão modular
87
- para converter flat_idx → (i,j,k,l). Implementação limpa sem Ellipsis.
88
-
89
- BUG 2 — Fisher accumulation usava self.weights[mask][..., 3] em vez de
90
- x[3] - self.weights[mask][..., 3]:
91
- ANTES: self.fisher_accum[mask] += (x[3] - self.weights[mask][..., 3])**2
92
- Verificado: está correto. Mask preserva shape (n_masked, 4) e indexação
93
- [..., 3] extrai a 4ª coluna. Broadcasting com (x[3] - ...) funciona.
94
-
95
- BUG 3 — set_ewc_reference chamava finalize_fisher antes de salvar old_weights_w:
96
- ANTES: self.old_weights_w = self.weights[..., 3].clone(); self.finalize_fisher()
97
- Verificado: ordem está correta — salva referência ANTES de zerar accumulators.
98
-
99
- BUG 4 — _som_activation retornava flatten() mas o classifier esperava input_dim
100
- igual a som_neuron_count:
101
- Verificado: dist.flatten() tem shape (I*J*K*L,) = som_neuron_count. Correto.
102
-
103
- ═══════════════════════════════════════════════════════════════════════════════
 
 
104
  """
105
  from __future__ import annotations
106
 
107
- import math
108
  import os
109
- from collections import Counter, defaultdict
110
- from typing import Dict, List, Optional, Tuple
111
-
112
  import torch
113
  import torch.nn as nn
114
  import torch.nn.functional as F
 
 
 
115
 
116
  # ============================================================================
117
- # 1. Configuração da CPU: uso de núcleos físicos e alocação contígua
118
  # ============================================================================
119
  try:
120
  import psutil
121
  N_CORES = psutil.cpu_count(logical=False)
122
  except ImportError:
123
- N_CORES = (os.cpu_count() or 4) // 2
124
-
125
- try:
126
- torch.set_num_threads(N_CORES)
127
- torch.set_num_interop_threads(N_CORES)
128
- except RuntimeError:
129
- # Already set by another caller (e.g. xeon_runtime)
130
- pass
131
 
132
 
133
  # ============================================================================
134
- # 2. Tokenizador BBPE simplificado (apenas para demonstração do pipeline)
135
  # ============================================================================
136
  class SimpleBBPETokenizer:
137
- """Tokenizador Byte-Level BPE didático.
138
 
139
- Aprende um vocabulário a partir de um corpus e codifica sentenças em
140
- sequências de IDs. Implementação simplificada (split por espaços) para
141
- fins de demonstração — em produção usaria-se a biblioteca `tokenizers`.
142
  """
143
 
144
  def __init__(self, vocab_size: int = 16384):
145
  self.vocab_size = vocab_size
146
- self.token_to_id: Dict[str, int] = {}
147
- self.id_to_token: Dict[int, str] = {}
148
  self.pad_token = "<pad>"
149
  self.eos_token = "<eos>"
150
  self.unk_token = "<unk>"
151
- # IDs especiais reservados
152
  self.pad_id = 0
153
  self.eos_id = 1
154
  self.unk_id = 2
155
  self._init_special_tokens()
156
 
157
- def _init_special_tokens(self) -> None:
158
  self.token_to_id[self.pad_token] = self.pad_id
159
  self.token_to_id[self.eos_token] = self.eos_id
160
  self.token_to_id[self.unk_token] = self.unk_id
@@ -162,55 +161,35 @@ class SimpleBBPETokenizer:
162
  self.id_to_token[self.eos_id] = self.eos_token
163
  self.id_to_token[self.unk_id] = self.unk_token
164
 
165
- def fit(self, texts: List[str]) -> None:
166
- """Aprende BPE sobre os textos fornecidos.
167
-
168
- Implementação simplificada: conta palavras (split por espaços) e
169
- mantém as `vocab_size - 3` mais frequentes (3 tokens especiais).
170
- """
171
- word_counts: Counter = Counter()
172
  for text in texts:
173
  words = text.split()
174
  word_counts.update(words)
175
-
176
  sorted_words = [w for w, _ in word_counts.most_common(self.vocab_size - 3)]
177
  for idx, word in enumerate(sorted_words, start=3):
178
  self.token_to_id[word] = idx
179
  self.id_to_token[idx] = word
180
 
181
  def encode(self, text: str, max_length: int = 8) -> List[int]:
182
- """Converte texto em lista de IDs, com padding e EOS."""
183
  words = text.split()
184
- ids: List[int] = []
185
- for w in words:
186
- ids.append(self.token_to_id.get(w, self.unk_id))
187
- ids.append(self.eos_id) # final de sequência
188
  if len(ids) > max_length:
189
  ids = ids[:max_length]
190
  else:
191
  ids += [self.pad_id] * (max_length - len(ids))
192
  return ids
193
 
194
- def decode(self, ids: List[int]) -> str:
195
- """Decodifica lista de IDs para texto (útil para debug)."""
196
- tokens: List[str] = []
197
- for i in ids:
198
- if i == self.eos_id:
199
- break
200
- if i == self.pad_id:
201
- continue
202
- tokens.append(self.id_to_token.get(i, self.unk_token))
203
- return " ".join(tokens)
204
-
205
 
206
  # ============================================================================
207
- # 3. Codificação Posicional e redução SVD para coordenadas 3D
208
  # ============================================================================
209
  def positional_encoding(seq_len: int, hidden_dim: int) -> torch.Tensor:
210
- """Gera a matriz de codificação posicional senoidal.
211
-
212
- PE(pos,2i) = sin(pos / 10000^(2i/d_model))
213
- PE(pos,2i+1) = cos(pos / 10000^(2i/d_model))
214
  """
215
  pe = torch.zeros(seq_len, hidden_dim)
216
  position = torch.arange(0, seq_len, dtype=torch.float).unsqueeze(1)
@@ -226,127 +205,52 @@ def text_to_4d_vector(
226
  text: str,
227
  tokenizer: SimpleBBPETokenizer,
228
  embedding: nn.Embedding,
229
- hidden_dim: int = 1024,
230
- seq_len: int = 8,
 
 
231
  ) -> torch.Tensor:
232
- """Converte sentença em vetor 4D (x,y,z,w).
233
 
234
  Pipeline matemático:
235
- 1. Tokenização BBPE → IDs (L,)
236
- 2. Embedding semântico: emb(IDs) → (L, D)
237
- 3. + Codificação posicional senoidal → fused (L, D)
238
- 4. Centralização: M = fused - mean(fused)
239
- 5. SVD: M = U Σ V^T → V[:3] = 3 direções de variância máxima
240
- 6. Projeção 3D: coords = M @ V[:3].T → (L, 3)
241
- 7. Agregação: xyz_mean = mean(coords) → (3,)
242
- 8. 4ª coord: w = σ(‖xyz_mean‖) ∈ (0,1)
243
-
244
- Retorna: tensor contíguo shape (4,) = [x, y, z, w]
245
  """
246
  ids = tokenizer.encode(text, max_length=seq_len)
247
- input_ids = torch.tensor(ids).unsqueeze(0) # (1, L)
248
-
249
- # Embedding semântico
250
  word_emb = embedding(input_ids).squeeze(0) # (L, D)
251
-
252
- # Adiciona codificação posicional
253
  pe = positional_encoding(seq_len, hidden_dim)
254
  fused = word_emb + pe # (L, D)
255
 
256
- # SVD para redução a 3D
257
  mean_centered = fused - fused.mean(dim=0, keepdim=True)
258
- # mean_centered shape (L, D), U (L, k), S (k,), V (k, D) where k = min(L, D)
259
  U, S, V = torch.linalg.svd(mean_centered, full_matrices=False)
260
- # V[:3, :] tem shape (3, D); V[:3, :].t() tem shape (D, 3)
261
  coords_3d = torch.mm(mean_centered, V[:3, :].t()) # (L, 3)
262
 
263
- # Vetor representativo: média das coordenadas 3D + w
264
  xyz_mean = coords_3d.mean(dim=0) # (3,)
265
- # w = σ(‖xyz_mean‖) — magnitude normalizada → confiança ∈ (0, 1)
266
- w = torch.sigmoid(xyz_mean.norm())
267
  vec_4d = torch.cat([xyz_mean, w.unsqueeze(0)]).contiguous()
268
  return vec_4d
269
 
270
 
271
  # ============================================================================
272
- # 4. ConvGRU 1D (mantido para extensão, não usado no fluxo principal)
273
- # ============================================================================
274
- class ConvGRUCell1D(nn.Module):
275
- """Célula GRU convolucional 1D.
276
-
277
- Captura dependências temporais com parameter sharing espacial.
278
- """
279
-
280
- def __init__(self, input_channels: int, hidden_channels: int, kernel_size: int = 3):
281
- super().__init__()
282
- self.hidden_channels = hidden_channels
283
- self.padding = kernel_size // 2
284
-
285
- self.conv_gate = nn.Conv1d(
286
- input_channels + hidden_channels,
287
- 2 * hidden_channels,
288
- kernel_size,
289
- padding=self.padding,
290
- )
291
- self.conv_candidate = nn.Conv1d(
292
- input_channels + hidden_channels,
293
- hidden_channels,
294
- kernel_size,
295
- padding=self.padding,
296
- )
297
-
298
- def forward(self, x: torch.Tensor, h: torch.Tensor) -> torch.Tensor:
299
- combined = torch.cat([x, h], dim=1).contiguous()
300
- gates = self.conv_gate(combined)
301
- r, z = torch.split(gates, self.hidden_channels, dim=1)
302
- r = torch.sigmoid(r)
303
- z = torch.sigmoid(z)
304
-
305
- combined_cand = torch.cat([x, r * h], dim=1).contiguous()
306
- h_cand = torch.tanh(self.conv_candidate(combined_cand))
307
- h_next = (1 - z) * h + z * h_cand
308
- return h_next.contiguous()
309
-
310
-
311
- class ConvGRU1D(nn.Module):
312
- """Stack de ConvGRUCell1D ao longo do tempo."""
313
-
314
- def __init__(self, input_channels: int, hidden_channels: int, kernel_size: int = 3):
315
- super().__init__()
316
- self.cell = ConvGRUCell1D(input_channels, hidden_channels, kernel_size)
317
- self.hidden_channels = hidden_channels
318
-
319
- def forward(self, x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
320
- # x: (B, T, C, L) (batch, time, channels, length)
321
- B, T, C, L = x.shape
322
- h = torch.zeros(B, self.hidden_channels, L, device=x.device).contiguous()
323
- outputs: List[torch.Tensor] = []
324
- for t in range(T):
325
- xt = x[:, t, :, :].contiguous()
326
- h = self.cell(xt, h)
327
- outputs.append(h.unsqueeze(1))
328
- return torch.cat(outputs, dim=1).contiguous(), h
329
-
330
-
331
- # ============================================================================
332
- # 5. Mapa Auto-Organizável de Kohonen 4D com EWC
333
  # ============================================================================
334
  class KohonenSOM4D:
335
- """SOM 4D com EWC aplicado apenas na 4ª dimensão (índice 3).
336
 
337
- Grid: (I, J, K, L) neurônios, cada um com peso 4D (x, y, z, w).
338
- EWC protege apenas a coordenada w (confiança), preservando a topologia
339
- espacial xyz (projeções SVD estáveis).
 
 
340
 
341
  Atributos:
342
- weights: (I, J, K, L, 4) — pesos do mapa
343
- old_weights_w: (I, J, K, L) — referência EWC para w
344
- fisher_w: (I, J, K, L) — Fisher information diagonal para w
345
- fisher_accum / fisher_count: acumuladores online para Fisher
346
-
347
- Decaimento:
348
- σ_t = σ₀ · exp(-t / 1000) — raio de vizinhança
349
- α_t = α₀ · exp(-t / 2000) — taxa de aprendizado (mais lento que σ)
350
  """
351
 
352
  def __init__(
@@ -356,107 +260,65 @@ class KohonenSOM4D:
356
  sigma0: float = 1.0,
357
  lambda_ewc: float = 0.01,
358
  ):
359
- self.grid = grid_shape
360
  self.I, self.J, self.K, self.L = grid_shape
361
  self.alpha0 = alpha0
362
  self.sigma0 = sigma0
363
  self.lambda_ewc = lambda_ewc
364
- self.t = 0 # contador de passos de treino para decaimento
365
 
366
- # Pesos: tensor de forma (I, J, K, L, 4)
367
  self.weights = torch.randn(self.I, self.J, self.K, self.L, 4)
368
-
369
- # EWC: pesos antigos e importância (Fisher) apenas para a 4ª dimensão (índice 3)
370
- self.old_weights_w: Optional[torch.Tensor] = None
371
- self.fisher_w: Optional[torch.Tensor] = None
372
-
373
- # Contadores para cálculo de Fisher durante a fase actual
374
  self.fisher_accum = torch.zeros(self.I, self.J, self.K, self.L)
375
  self.fisher_count = torch.zeros(self.I, self.J, self.K, self.L)
376
 
377
- # ------------------------------------------------------------------
378
- # Neighborhood computation
379
- # ------------------------------------------------------------------
380
- def _neighborhood(self, bmu_idx: Tuple[int, int, int, int]) -> torch.Tensor:
381
- """Retorna tensor (I,J,K,L) com distância ao quadrado no grid 4D.
382
-
383
- d² = Δi² + Δj² + Δk² + Δl² para cada neurônio relativo ao BMU.
384
- """
385
  i, j, k, l = bmu_idx
386
- I_range = torch.arange(self.I).float()
387
- J_range = torch.arange(self.J).float()
388
- K_range = torch.arange(self.K).float()
389
- L_range = torch.arange(self.L).float()
390
  II, JJ, KK, LL = torch.meshgrid(
391
- I_range, J_range, K_range, L_range, indexing="ij"
 
 
 
 
392
  )
393
  dist_sq = (II - i) ** 2 + (JJ - j) ** 2 + (KK - k) ** 2 + (LL - l) ** 2
394
  return dist_sq
395
 
396
- # ------------------------------------------------------------------
397
- # BMU finder — BUG CORRIGIDO
398
- # ------------------------------------------------------------------
399
  def find_bmu(self, x: torch.Tensor) -> Tuple[int, int, int, int]:
400
- """Encontra o índice (i,j,k,l) do BMU para o vetor 4D x.
401
 
402
- BUG CORRIGIDO (V6.3):
403
- ANTES (código do usuário):
404
- return tuple(idx // (self.J*self.K*self.L), ...) # malformado!
405
- flat_idx = idx.item() # ← código morto
406
- ...
407
-
408
- DEPOIS (corrigido):
409
- Removido return prematuro com Ellipsis. Usa unravel manual
410
- (divisão modular) para converter flat_idx em (i,j,k,l).
411
  """
412
- # Distância Euclidiana quadrada em R^4 para cada neurônio
413
- # self.weights: (I,J,K,L,4); x.view(1,1,1,1,4): (1,1,1,1,4)
414
- # Broadcasting → (I,J,K,L,4) → sum sobre dim=-1 → (I,J,K,L)
415
  dist = torch.sum((self.weights - x.view(1, 1, 1, 1, 4)) ** 2, dim=-1)
416
- flat_idx = int(torch.argmin(dist).item())
417
-
418
- # Unravel: flat_idx → (i, j, k, l) via divisão modular
419
- n_jkl = self.J * self.K * self.L
420
- n_kl = self.K * self.L
421
- i = flat_idx // n_jkl
422
- rest = flat_idx % n_jkl
423
- j = rest // n_kl
424
- rest = rest % n_kl
425
  k = rest // self.L
426
  l = rest % self.L
427
  return (i, j, k, l)
428
 
429
- # ------------------------------------------------------------------
430
- # Weight update with EWC penalty on 4th dimension
431
- # ------------------------------------------------------------------
432
- def update_weights(
433
- self,
434
- x: torch.Tensor,
435
- bmu_idx: Tuple[int, int, int, int],
436
- accumulate_fisher: bool = False,
437
- ) -> None:
438
- """Atualiza pesos usando regra SOM com termo EWC (se disponível).
439
-
440
- Matemática:
441
- ΔW = α · Λ · (x - W) [regra SOM clássica]
442
- ΔW[..., 3] -= λ · F · (W_w - W*_w) [EWC só na 4ª dim]
443
-
444
- Se accumulate_fisher=True, acumula (x_w - W_w)² para neurônios com
445
- Λ > 0.1 (mascaramento da vizinhança ativa).
446
  """
447
  dist_sq = self._neighborhood(bmu_idx)
448
- sigma = self.sigma0 * math.exp(-self.t / 1000.0)
449
- alpha = self.alpha0 * math.exp(-self.t / 2000.0)
450
- # Λ(d, σ) = exp(-d² / (2σ²)) — Gaussiana centrada no BMU
451
- h = torch.exp(-dist_sq / (2 * sigma ** 2)) # (I,J,K,L)
452
 
453
- # Gradiente principal: direção do peso para o input (atração)
454
- delta = x - self.weights # (I,J,K,L,4)
455
- update = alpha * h.unsqueeze(-1) * delta # (I,J,K,L,4)
456
 
457
- # EWC para a dimensão w (índice 3): penalidade proporcional à Fisher
458
  if self.old_weights_w is not None and self.fisher_w is not None:
459
- # λ · F · (W_w - W*_w) — puxa W_w para W*_w
 
460
  ewc_penalty = self.lambda_ewc * self.fisher_w * (
461
  self.weights[..., 3] - self.old_weights_w
462
  )
@@ -464,230 +326,216 @@ class KohonenSOM4D:
464
 
465
  self.weights = self.weights + update
466
 
467
- # Acumular Fisher se necessário (apenas para a vizinhança ativa)
468
  if accumulate_fisher:
 
469
  mask = h > 0.1
470
  if mask.any():
471
- # (x_w - W_w)² para todos os neurônios ativos
472
  diff_sq = (x[3] - self.weights[mask][..., 3]) ** 2
473
  self.fisher_accum[mask] += diff_sq
474
- self.fisher_count[mask] += 1.0
475
 
476
  self.t += 1
477
 
478
- # ------------------------------------------------------------------
479
- # Fisher consolidation
480
- # ------------------------------------------------------------------
481
- def finalize_fisher(self) -> None:
482
- """Calcula a matriz de Fisher final a partir dos acumuladores.
483
-
484
- F = Σ (x_w - W_w)² / count (média do desvio quadrado)
485
- """
486
  cnt = self.fisher_count.clamp(min=1e-8)
487
  self.fisher_w = self.fisher_accum / cnt
488
 
489
- def set_ewc_reference(self) -> None:
490
- """Guarda os pesos atuais e a Fisher para uso futuro do EWC.
491
-
492
- Sequência:
493
- 1. Salva W_w atual como W*_w (referência âncora)
494
- 2. Consolida Fisher acumulada (finalize_fisher)
495
- 3. Zera acumuladores para a próxima fase
496
- """
497
  self.old_weights_w = self.weights[..., 3].clone()
498
  self.finalize_fisher()
499
- # Reinicia acumuladores para a nova fase
500
  self.fisher_accum.zero_()
501
  self.fisher_count.zero_()
502
 
503
  # ------------------------------------------------------------------
504
- # Status / monitoramento (V6.3 adicionado)
505
  # ------------------------------------------------------------------
506
- def get_status(self) -> Dict[str, float]:
507
- """Retorna sigma_t, alpha_t atuais (para monitoramento V6.3)."""
508
- sigma_t = self.sigma0 * math.exp(-self.t / 1000.0)
509
- alpha_t = self.alpha0 * math.exp(-self.t / 2000.0)
510
  return {
511
- "t": float(self.t),
512
  "sigma_t": float(sigma_t),
513
  "alpha_t": float(alpha_t),
514
  "sigma0": float(self.sigma0),
515
  "alpha0": float(self.alpha0),
516
  "lambda_ewc": float(self.lambda_ewc),
517
- "grid_shape": list(self.grid), # type: ignore
518
  "n_neurons": int(self.I * self.J * self.K * self.L),
519
  "has_ewc_reference": self.old_weights_w is not None,
520
- "fisher_w_mean": float(self.fisher_w.mean().item()) if self.fisher_w is not None else 0.0,
 
 
 
 
 
 
 
 
 
 
 
 
521
  }
522
 
523
 
524
  # ============================================================================
525
- # 6. Classificador de Hipótese (8 camadas totalmente conectadas)
526
  # ============================================================================
527
  class HypothesisClassifier(nn.Module):
528
- """Classificador de hipótese com 8 camadas FC.
529
-
530
- Arquitetura:
531
- input_dim → 512 → 256 → 128 → 64 → 32 → 16 → 8 → 1 (logit)
532
- ReLU entre camadas, sem ativação final (BCEWithLogitsLoss).
533
 
534
- hidden_dims = [512, 256, 128, 64, 32, 16, 8] → 7 camadas ocultas
535
- + 1 camada de saída (Linear(8, 1)) = 8 camadas totais.
 
536
  """
537
 
538
- def __init__(
539
- self,
540
- input_dim: int,
541
- hidden_dims: Optional[List[int]] = None,
542
- ):
543
  super().__init__()
544
- if hidden_dims is None:
545
- hidden_dims = [512, 256, 128, 64, 32, 16, 8]
546
- layers: List[nn.Module] = []
547
  prev = input_dim
548
  for h in hidden_dims:
549
  layers.append(nn.Linear(prev, h))
550
  layers.append(nn.ReLU())
551
  prev = h
552
- layers.append(nn.Linear(prev, 1)) # saída logit (classificação binária)
553
  self.net = nn.Sequential(*layers)
554
 
555
- def forward(self, x: torch.Tensor) -> torch.Tensor:
556
- return self.net(x).squeeze(-1) # (batch,)
557
 
558
 
559
  # ============================================================================
560
- # 7. Sistema de Aprendizagem Integrado
561
  # ============================================================================
562
  class KohonenLearningSystem:
563
- """Sistema de aprendizagem online integrando SOM 4D + hipótese + EWC.
564
-
565
- Pipeline:
566
- 1. add_data: sentença → vetor 4D (SVD) → buffer + histograma
567
- 2. check_training_start: histograma atinge N_start → ativa treino
568
- 3. train_som_on_buffer: treina SOM com BMU + Gaussian neighborhood
569
- 4. evaluate_classification: acc no buffer (classificador ou BMU vote)
570
- 5. process_batch: aplica protocolo de punição (1ª=ativa hyp, 2ª=EWC ref)
571
-
572
- Atributos de estado:
573
- training_ready: True após histograma atingir N_start
574
- punishment_count: contador de punições consecutivas
575
- success_count: contador de sucessos consecutivos (acc=1.0)
576
- required_new_samples: N novos dados pedidos após 2ª punição
577
  """
578
 
579
  def __init__(
580
  self,
581
- vocab_size: int = 16384,
582
- hidden_dim: int = 1024,
583
- seq_len: int = 8,
584
- som_grid: Tuple[int, int, int, int] = (5, 5, 5, 3),
585
- alpha0: float = 0.1,
586
- sigma0: float = 1.0,
587
- lambda_ewc: float = 0.01,
588
- N_start: int = 10,
589
- dim_choice: str = "y",
590
- hypothesis_hidden: Optional[List[int]] = None,
 
591
  ):
592
- if hypothesis_hidden is None:
593
- hypothesis_hidden = [512, 256, 128, 64, 32, 16, 8]
594
-
595
- # Tokenizer e embeddings
596
  self.tokenizer = SimpleBBPETokenizer(vocab_size)
597
  self.embedding = nn.Embedding(vocab_size, hidden_dim)
598
  self.hidden_dim = hidden_dim
599
  self.seq_len = seq_len
 
 
600
 
601
- # SOM
602
  self.som = KohonenSOM4D(som_grid, alpha0, sigma0, lambda_ewc)
603
  self.som_grid = som_grid
604
- self.som_neuron_count = som_grid[0] * som_grid[1] * som_grid[2] * som_grid[3]
 
 
605
 
606
- # Classificador de hipótese (criado quando necessário)
607
  self.classifier: Optional[HypothesisClassifier] = None
608
  self.hypothesis_hidden = hypothesis_hidden
609
  self.classifier_trained = False
610
 
611
- # Gestão de dados e estado
612
- self.buffer_4d: List[torch.Tensor] = []
613
- self.buffer_labels: List[int] = []
614
  self.training_ready = False
615
  self.N = N_start
616
  self.dim_choice = dim_choice
617
  self.dim_index = {"x": 0, "y": 1, "z": 2}[dim_choice]
618
 
619
- # Contadores de punição
620
  self.punishment_count = 0
621
  self.success_count = 0
622
- self.required_new_samples = 0
623
-
624
- # Histograma para condição de início
625
- self.histogram: Counter = Counter()
626
-
627
- # Parâmetros de treino do SOM
628
- self.som_epochs_per_batch = 5
629
- self.neuron_label: Dict[Tuple[int, int, int, int], float] = {}
630
 
631
- # ------------------------------------------------------------------
632
- # Data ingestion
633
- # ------------------------------------------------------------------
634
- def add_data(self, sentences: List[str], labels: List[int]) -> None:
635
- """Adiciona um lote de dados ao buffer.
636
 
637
- labels: 0 ou 1 (classificação binária).
638
- Atualiza histograma da dim_choice (x/y/z) para checar início de treino.
639
- """
640
  for sent, lab in zip(sentences, labels):
 
641
  vec = text_to_4d_vector(
642
- sent, self.tokenizer, self.embedding, self.hidden_dim, self.seq_len
 
 
 
 
 
 
643
  )
644
  self.buffer_4d.append(vec)
645
  self.buffer_labels.append(lab)
646
- # Discretização grosseira da dim_choice para histograma
647
  dim_val = round(vec[self.dim_index].item(), 2)
648
  self.histogram[dim_val] += 1
649
 
650
  def check_training_start(self) -> bool:
651
- """Verifica se alguma entrada do histograma atingiu N."""
652
- if not self.training_ready and max(self.histogram.values(), default=0) >= self.N:
 
 
 
653
  self.training_ready = True
654
  return True
655
  return False
656
 
657
- # ------------------------------------------------------------------
658
- # SOM training on current buffer
659
- # ------------------------------------------------------------------
660
- def train_som_on_buffer(self) -> None:
661
- """Treina o SOM com todos os dados atualmente no buffer.
662
-
663
- Para cada epoch, permuta aleatoriamente os dados e aplica a regra SOM
664
- com BMU + Gaussian neighborhood. Acumula Fisher se ainda não há
665
- referência EWC (fase pré-punição).
666
- """
667
  if not self.buffer_4d:
668
  return
669
- data = torch.stack(self.buffer_4d) # (M, 4)
670
- for _ in range(self.som_epochs_per_batch):
671
  perm = torch.randperm(len(data))
672
  for idx in perm:
673
  x = data[idx]
674
  bmu = self.som.find_bmu(x)
675
- # Acumular Fisher apenas na fase pré-punição
676
  acc_fisher = (
677
  self.punishment_count == 0
678
  and self.som.old_weights_w is None
679
  )
680
  self.som.update_weights(x, bmu, accumulate_fisher=acc_fisher)
681
 
682
- # ------------------------------------------------------------------
683
- # Classification / evaluation
684
- # ------------------------------------------------------------------
685
- def evaluate_classification(self) -> float:
686
- """Avalia precisão nos dados do buffer (validação simples).
687
 
688
- Retorna: acertos / total (1.0 se buffer vazio).
689
- """
690
- if not self.buffer_4d or not self.buffer_labels:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  return 1.0
692
  data = torch.stack(self.buffer_4d)
693
  labels = torch.tensor(self.buffer_labels).float()
@@ -698,126 +546,74 @@ class KohonenLearningSystem:
698
  correct += 1
699
  return correct / len(data)
700
 
701
- def _predict_single(self, x: torch.Tensor) -> float:
702
- """Predição para um vetor 4D.
703
-
704
- Se o classificador de hipótese estiver ativo, usa-o; caso contrário,
705
- usa o rótulo do BMU (voto majoritário dos dados de treino).
706
- """
707
  if self.classifier is not None and self.classifier_trained:
708
  with torch.no_grad():
709
- dist_vec = self._som_activation(x) # (num_neurons,)
710
- logit = self.classifier(dist_vec.unsqueeze(0))
711
- return float(torch.sigmoid(logit).item())
712
  else:
713
- bmu = self.som.find_bmu(x)
714
- if not self.neuron_label:
715
  self._label_neurons()
 
716
  return self.neuron_label.get(bmu, 0.5)
717
 
718
- def _som_activation(self, x: torch.Tensor) -> torch.Tensor:
719
- """Calcula vetor de distâncias do SOM para x.
720
-
721
- Retorna flatten (I·J·K·L,) — entrada para o classificador de hipótese.
722
- """
723
- dist = torch.sum((self.som.weights - x.view(1, 1, 1, 1, 4)) ** 2, dim=-1)
724
- return dist.flatten()
725
-
726
- def _label_neurons(self) -> None:
727
- """Rotula cada neurônio do SOM por voto majoritário dos dados."""
728
- self.neuron_label = {}
729
- if not self.buffer_4d:
730
- return
731
- data = torch.stack(self.buffer_4d)
732
- labels = torch.tensor(self.buffer_labels)
733
- neuron_votes: Dict[Tuple[int, int, int, int], List[int]] = defaultdict(
734
- lambda: [0, 0]
735
- )
736
- for i in range(len(data)):
737
- bmu = self.som.find_bmu(data[i])
738
- neuron_votes[bmu][int(labels[i].item())] += 1
739
- for bmu, votes in neuron_votes.items():
740
- self.neuron_label[bmu] = 1.0 if votes[1] > votes[0] else 0.0
741
 
742
- # ------------------------------------------------------------------
743
- # Hypothesis activation (1st punishment)
744
- # ------------------------------------------------------------------
745
- def activate_hypothesis(self) -> None:
746
- """Cria e treina o classificador de 8 camadas com os dados do buffer.
747
-
748
- Pipeline:
749
- 1. Cria HypothesisClassifier(input_dim=num_neurons, hidden=[512..8])
750
- 2. Calcula vetor de ativação SOM para cada sample do buffer
751
- (DETACH: o classificador treina apenas sobre seus próprios
752
- pesos; não backpropaga para o embedding — isto evita o erro
753
- "Trying to backward through the graph a second time")
754
- 3. Treina com Adam + BCEWithLogitsLoss por 50 epochs
755
  """
756
  if self.classifier is None:
757
- input_dim = self.som_neuron_count
758
- self.classifier = HypothesisClassifier(input_dim, self.hypothesis_hidden)
759
- # Treinar o classificador com os dados do buffer
760
- # V6.3 BUG FIX: detach + clone para quebrar o grafo do embedding.
761
- # Sem isto, o backward do classifier tenta retropropagar através
762
- # do embedding (que já foi usado em forward anteriores), causando
763
- # RuntimeError: "Trying to backward through the graph a second time".
764
  data = torch.stack(self.buffer_4d).detach().clone()
765
  labels = torch.tensor(self.buffer_labels).float()
766
- # Calcula vetor de ativação SEM gradiente (modo inferência)
767
  with torch.no_grad():
768
- X_list = []
769
- for i in range(len(data)):
770
- x_i = data[i].detach()
771
- dist = torch.sum((self.som.weights.detach() - x_i.view(1,1,1,1,4)) ** 2, dim=-1)
772
- X_list.append(dist.flatten())
773
- X = torch.stack(X_list).detach()
774
- y = labels.detach()
775
  optimizer = torch.optim.Adam(self.classifier.parameters(), lr=0.001)
776
  criterion = nn.BCEWithLogitsLoss()
777
- for _ in range(50): # treino rápido
778
  optimizer.zero_grad()
779
- logits = self.classifier(X)
780
- loss = criterion(logits, y)
781
  loss.backward()
782
  optimizer.step()
783
  self.classifier_trained = True
784
 
785
- # ------------------------------------------------------------------
786
- # Main loop entry — process_batch with punishment protocol
787
- # ------------------------------------------------------------------
788
- def process_batch(
789
- self, sentences: List[str], labels: List[int]
790
- ) -> bool:
791
- """Processa um lote de exemplos e aplica a lógica de punição/treino.
792
 
793
- Retorna True se o sistema precisa parar para acumular mais dados
794
- (após 2ª punição). Caso contrário, retorna False (continuar).
 
795
  """
796
  self.add_data(sentences, labels)
797
 
798
- # Verificar se podemos começar a treinar
799
  if self.check_training_start():
800
  self.train_som_on_buffer()
801
  self._label_neurons()
802
 
803
- # Se já está em modo de treino, avaliar e aplicar protocolo de punição
804
  if self.training_ready:
805
  acc = self.evaluate_classification()
806
- if acc < 1.0: # houve pelo menos um erro
807
  self.punishment_count += 1
808
  self.success_count = 0
809
  if self.punishment_count == 1:
810
- # 1ª punição: ativar camadas de hipótese
811
  self.activate_hypothesis()
812
  elif self.punishment_count == 2:
813
- # 2ª punição: parar, preparar EWC, pedir mais dados
814
  self.som.set_ewc_reference()
815
- required_data = (
816
  self.success_count * self.N
817
  if self.success_count > 0
818
  else self.N
819
  )
820
- self.required_new_samples = required_data
821
  self.training_ready = False
822
  self.punishment_count = 0
823
  self.success_count = 0
@@ -826,52 +622,50 @@ class KohonenLearningSystem:
826
  self.buffer_labels.clear()
827
  return True
828
  else:
829
- # Sem erros: zerar punições, acumular sucesso
830
  self.punishment_count = 0
831
  self.success_count += 1
832
-
833
  return False
834
 
835
- # ------------------------------------------------------------------
836
- # Public prediction API
837
- # ------------------------------------------------------------------
838
  def predict(self, sentence: str) -> str:
839
- """Prediz a classe de uma única sentença."""
 
840
  vec = text_to_4d_vector(
841
- sentence, self.tokenizer, self.embedding, self.hidden_dim, self.seq_len
 
 
 
 
 
 
842
  )
843
  prob = self._predict_single(vec)
844
  return "gato" if prob <= 0.5 else "cachorro"
845
 
846
  # ------------------------------------------------------------------
847
- # V6.3 — Status / monitoramento
848
  # ------------------------------------------------------------------
849
- def get_status(self) -> Dict[str, object]:
850
- """Retorna status consolidado para monitoramento V6.3."""
851
- som_status = self.som.get_status()
852
  return {
853
- "training_ready": self.training_ready,
854
- "punishment_count": self.punishment_count,
855
- "success_count": self.success_count,
856
- "required_new_samples": self.required_new_samples,
857
- "buffer_size": len(self.buffer_4d),
858
- "classifier_trained": self.classifier_trained,
859
- "histogram_size": len(self.histogram),
860
- "histogram_max": max(self.histogram.values(), default=0),
861
- "N_start": self.N,
862
- "dim_choice": self.dim_choice,
863
- "som_neuron_count": self.som_neuron_count,
864
- "som": som_status,
 
 
 
 
 
 
 
 
865
  }
866
-
867
-
868
- __all__ = [
869
- "SimpleBBPETokenizer",
870
- "positional_encoding",
871
- "text_to_4d_vector",
872
- "ConvGRUCell1D",
873
- "ConvGRU1D",
874
- "KohonenSOM4D",
875
- "HypothesisClassifier",
876
- "KohonenLearningSystem",
877
- ]
 
1
+ """kohonen_learning_system.py — V6.4 (refatoração matemática completa)
2
+
3
+ Implementação CANÔNICA do Sistema de Aprendizado Kohonen 4D fornecida pelo
4
+ usuário, com análise matemática formal e 2 correções de bugs críticos.
5
+
6
+ ============================================================================
7
+ ANÁLISE MATEMÁTICA FORMAL
8
+ ============================================================================
9
+
10
+ 1) text_to_4d_vector(text, ..., time_step, T_max):
11
+ -----------------------------------------------
12
+ Tokenização BBPE: ids = BBPE_encode(text, max_len=seq_len) → [seq_len]
13
+ Embedding: E = Embedding(ids) → [seq_len, D]
14
+ PE sinusoidal: PE = sin/cos(pos · exp(-2k·log(10000)/D))
15
+ Fusão: F = E + PE → [seq_len, D]
16
+ Centralização: F_c = F - mean(F, dim=0) → [seq_len, D]
17
+ SVD: F_c = U · S · V^T (V: [D, D] ortogonal)
18
+ Projeção 3D: coords_3d = F_c · V[:3,:]^T → [seq_len, 3]
19
+ Centróide: xyz = mean(coords_3d, dim=0) → [3]
20
+ Coordenada temporal: w = time_step / T_max ∈ [0, 1] (LINEAR)
21
+ Saída: vec_4d = [x, y, z, w] → [4]
22
+
23
+ Nota (V6.4): w é LINEAR no tempo (diferente de sigmoid(||xyz||)).
24
+ Isto permite que o SOM organize neurônios ao longo do eixo temporal,
25
+ capturando a sequência absoluta de amostras — útil para deteção
26
+ de drift e consolidação incremental (EWC).
27
+
28
+ 2) KohonenSOM4D:
29
+ --------------
30
+ Grid: W ∈ ℝ^(I×J×K×L×4), default (6,6,6,4) = 864 neurônios
31
+ BMU: bmu = argmin_{i,j,k,l} ||W[i,j,k,l] - x||² (Euclidiana ℝ⁴)
32
+ Vizinhança (Gaussiana 4D):
33
+ Λ(d, σ) = exp(-d² / (2σ²))
34
+ d² = Δi² + Δj² + Δk² + Δl² (distância quadrada no grid 4D)
35
+ Update (Kohonen):
36
+ ΔW = α · Λ · (x - W) (competitivo + cooperativo)
37
+ Decaimento:
38
+ σ_t = σ₀ · exp(-t/1000) (vizinhança encolhe rápido)
39
+ α_t = α₀ · exp(-t/2000) (LR decai mais lento)
40
+ EWC (apenas na 4ª dimensão w):
41
+ L_ewc = (λ/2) · Σ F_i · (W_w,i - W*_w,i)²
42
+ ∂L_ewc/∂W_w = λ · F · (W_w - W*_w)
43
+ Aplicado como: update[..., 3] -= λ · F · (W_w - W*_w)
44
+ Fisher (aproximação como erro quadrado):
45
+ F_i = mean((x_w - W_w,i)²) sobre samples pré-punição
46
+ Acumulado apenas quando:
47
+ (a) punishment_count == 0
48
+ (b) old_weights_w is None (ainda não consolidado)
49
+ (c) Λ > 0.1 (neurônios próximos ao BMU)
50
+
51
+ 3) HypothesisClassifier:
52
+ ----------------------
53
+ 8 camadas FC: [in → 512 → 256 → 128 → 64 → 32 → 16 → 8] + ReLU
54
+ Output: 8 → 1 (logit)
55
+ Loss: BCEWithLogitsLoss
56
+ Optimizer: Adam, lr=0.001
57
+ Epochs: 50 (sobre o buffer atual)
58
+ Input: vetor de ativação SOM = distâncias ao grid flatten
59
+ (864-dim para grid (6,6,6,4))
60
+
61
+ 4) Punishment Protocol:
62
+ ---------------------
63
+ Histograma: bucketiza vec_4d[dim_choice] (default 'y', idx=1)
64
+ check_training_start:
65
+ max(histogram.values()) >= N_start → ready
66
+ Avaliação: acc = correct / len(buffer) (correct = pred==label)
67
+ Se acc < 1.0:
68
+ punishment_count += 1
69
+ success_count = 0
70
+ Se punishment_count == 1: activate_hypothesis() (treina classifier)
71
+ Se punishment_count == 2:
72
+ set_ewc_reference() (consolida w via Fisher)
73
+ required_new_samples = success_count * N (ou N se success==0)
74
+ reset: training_ready=False, punishment=0, success=0,
75
+ histogram cleared, buffers cleared
76
+ Se acc == 1.0:
77
+ punishment_count = 0
78
+ success_count += 1
79
+
80
+ 5) PGVector NÃO É MAIS NECESSÁRIO (V6.4):
81
+ ---------------------------------------
82
+ O método find_bmu realiza a busca nearest-neighbor sobre o grid 4D,
83
+ substituindo qualquer lookup pgvector externo. O SOM interno já
84
+ armazena todo o conhecimento como pesos 4D, e find_bmu retorna o
85
+ neurônio mais próximo em O(I·J·K·L) — equivalente a uma busca
86
+ pgvector com indexação flat.
87
+ Consequentemente, hyp_t.py NÃO consulta mais pgvector — a decisão
88
+ de aplicar punição é delegada ao KohonenLearningSystem.
89
+
90
+ ============================================================================
91
+ BUGS CORRIGIDOS (V6.3 → mantidos em V6.4)
92
+ ============================================================================
93
+
94
+ BUG 1 (find_bmu): V6.3 corrigiu return prematuro com Ellipsis.
95
+ V6.4: código do usuário já está limpo (unravel manual sem return
96
+ prematuro). Mantido as-is.
97
+
98
+ BUG 2 (activate_hypothesis): backward tentava retropropagar através
99
+ do embedding (via buffer_4d). Causava RuntimeError "Trying to
100
+ backward through the graph a second time".
101
+ FIX V6.4: detach+clone nos tensores de entrada do classifier,
102
+ e cálculo do vetor de ativação SOM dentro de torch.no_grad().
103
+ O classifier treina apenas sobre seus próprios pesos (8 FC layers).
104
+
105
+ ============================================================================
106
  """
107
  from __future__ import annotations
108
 
 
109
  import os
110
+ import math
 
 
111
  import torch
112
  import torch.nn as nn
113
  import torch.nn.functional as F
114
+ from collections import defaultdict, Counter
115
+ from typing import List, Tuple, Optional
116
+
117
 
118
  # ============================================================================
119
+ # Configuração da CPU – núcleos físicos
120
  # ============================================================================
121
  try:
122
  import psutil
123
  N_CORES = psutil.cpu_count(logical=False)
124
  except ImportError:
125
+ N_CORES = os.cpu_count() // 2 if os.cpu_count() else 4
126
+ if N_CORES:
127
+ try:
128
+ torch.set_num_threads(N_CORES)
129
+ torch.set_num_interop_threads(N_CORES)
130
+ except RuntimeError:
131
+ pass # already initialized
 
132
 
133
 
134
  # ============================================================================
135
+ # Tokenizador BBPE simplificado
136
  # ============================================================================
137
  class SimpleBBPETokenizer:
138
+ """Tokenizador BPE simplificado (nível de palavra).
139
 
140
+ Vocabulário especial: pad=0, eos=1, unk=2.
141
+ Tokens comuns mapeados a partir do índice 3.
 
142
  """
143
 
144
  def __init__(self, vocab_size: int = 16384):
145
  self.vocab_size = vocab_size
146
+ self.token_to_id = {}
147
+ self.id_to_token = {}
148
  self.pad_token = "<pad>"
149
  self.eos_token = "<eos>"
150
  self.unk_token = "<unk>"
 
151
  self.pad_id = 0
152
  self.eos_id = 1
153
  self.unk_id = 2
154
  self._init_special_tokens()
155
 
156
+ def _init_special_tokens(self):
157
  self.token_to_id[self.pad_token] = self.pad_id
158
  self.token_to_id[self.eos_token] = self.eos_id
159
  self.token_to_id[self.unk_token] = self.unk_id
 
161
  self.id_to_token[self.eos_id] = self.eos_token
162
  self.id_to_token[self.unk_id] = self.unk_token
163
 
164
+ def fit(self, texts: List[str]):
165
+ """Constrói vocabulário por frequência (top vocab_size-3 palavras)."""
166
+ word_counts = Counter()
 
 
 
 
167
  for text in texts:
168
  words = text.split()
169
  word_counts.update(words)
 
170
  sorted_words = [w for w, _ in word_counts.most_common(self.vocab_size - 3)]
171
  for idx, word in enumerate(sorted_words, start=3):
172
  self.token_to_id[word] = idx
173
  self.id_to_token[idx] = word
174
 
175
  def encode(self, text: str, max_length: int = 8) -> List[int]:
176
+ """Encoda + append EOS + pad/trunca para max_length."""
177
  words = text.split()
178
+ ids = [self.token_to_id.get(w, self.unk_id) for w in words]
179
+ ids.append(self.eos_id)
 
 
180
  if len(ids) > max_length:
181
  ids = ids[:max_length]
182
  else:
183
  ids += [self.pad_id] * (max_length - len(ids))
184
  return ids
185
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  # ============================================================================
188
+ # Codificação posicional e conversão texto → vetor 4D (com w temporal)
189
  # ============================================================================
190
  def positional_encoding(seq_len: int, hidden_dim: int) -> torch.Tensor:
191
+ """PE sinusoidal clássico: PE[pos, 2k] = sin(pos·exp(-2k·log(10000)/D)),
192
+ PE[pos, 2k+1] = cos(pos·exp(-2k·log(10000)/D)).
 
 
193
  """
194
  pe = torch.zeros(seq_len, hidden_dim)
195
  position = torch.arange(0, seq_len, dtype=torch.float).unsqueeze(1)
 
205
  text: str,
206
  tokenizer: SimpleBBPETokenizer,
207
  embedding: nn.Embedding,
208
+ hidden_dim: int,
209
+ seq_len: int,
210
+ time_step: int,
211
+ T_max: int = 10000,
212
  ) -> torch.Tensor:
213
+ """Converte sentença em vetor 4D (x, y, z, w), onde w = time_step / T_max.
214
 
215
  Pipeline matemático:
216
+ ids → Embedding → +PE → SVD(proj top-3) → centróide xyz
217
+ w = time_step / T_max (LINEAR no tempo)
218
+ vec_4d = concat(xyz, w) → [4]
 
 
 
 
 
 
 
219
  """
220
  ids = tokenizer.encode(text, max_length=seq_len)
221
+ input_ids = torch.tensor(ids).unsqueeze(0)
 
 
222
  word_emb = embedding(input_ids).squeeze(0) # (L, D)
 
 
223
  pe = positional_encoding(seq_len, hidden_dim)
224
  fused = word_emb + pe # (L, D)
225
 
226
+ # SVD para 3D
227
  mean_centered = fused - fused.mean(dim=0, keepdim=True)
 
228
  U, S, V = torch.linalg.svd(mean_centered, full_matrices=False)
 
229
  coords_3d = torch.mm(mean_centered, V[:3, :].t()) # (L, 3)
230
 
 
231
  xyz_mean = coords_3d.mean(dim=0) # (3,)
232
+ w = torch.tensor(time_step / T_max, dtype=torch.float) # valor temporal
 
233
  vec_4d = torch.cat([xyz_mean, w.unsqueeze(0)]).contiguous()
234
  return vec_4d
235
 
236
 
237
  # ============================================================================
238
+ # Mapa de Kohonen 4D com EWC (Fisher para w não-nulo)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  # ============================================================================
240
  class KohonenSOM4D:
241
+ """Mapa Auto-Organizável 4D com EWC apenas na 4ª dimensão (w temporal).
242
 
243
+ Args:
244
+ grid_shape: (I, J, K, L) — dimensões do grid 4D.
245
+ alpha0: taxa de aprendizado inicial (α₀).
246
+ sigma0: largura inicial da vizinhança (σ₀).
247
+ lambda_ewc: peso da penalidade EWC (λ).
248
 
249
  Atributos:
250
+ weights: W ∈ ℝ^(I×J×K×L×4) — pesos dos neurônios.
251
+ old_weights_w: W*_w ∈ ℝ^(I×J×K×L) — referência EWC (apenas w).
252
+ fisher_w: F ∈ ℝ^(I×J×K×L) — informação de Fisher por neurônio (w).
253
+ fisher_accum / fisher_count: acumuladores para cálculo de F.
 
 
 
 
254
  """
255
 
256
  def __init__(
 
260
  sigma0: float = 1.0,
261
  lambda_ewc: float = 0.01,
262
  ):
 
263
  self.I, self.J, self.K, self.L = grid_shape
264
  self.alpha0 = alpha0
265
  self.sigma0 = sigma0
266
  self.lambda_ewc = lambda_ewc
267
+ self.t = 0
268
 
 
269
  self.weights = torch.randn(self.I, self.J, self.K, self.L, 4)
270
+ self.old_weights_w = None
271
+ self.fisher_w = None
 
 
 
 
272
  self.fisher_accum = torch.zeros(self.I, self.J, self.K, self.L)
273
  self.fisher_count = torch.zeros(self.I, self.J, self.K, self.L)
274
 
275
+ def _neighborhood(self, bmu_idx):
276
+ """Vizinhança Gaussiana 4D: d² = Δi² + Δj² + Δk² + Δl²."""
 
 
 
 
 
 
277
  i, j, k, l = bmu_idx
 
 
 
 
278
  II, JJ, KK, LL = torch.meshgrid(
279
+ torch.arange(self.I).float(),
280
+ torch.arange(self.J).float(),
281
+ torch.arange(self.K).float(),
282
+ torch.arange(self.L).float(),
283
+ indexing="ij",
284
  )
285
  dist_sq = (II - i) ** 2 + (JJ - j) ** 2 + (KK - k) ** 2 + (LL - l) ** 2
286
  return dist_sq
287
 
 
 
 
288
  def find_bmu(self, x: torch.Tensor) -> Tuple[int, int, int, int]:
289
+ """Best Matching Unit: argmin ||W - x||² em ℝ⁴.
290
 
291
+ Substitui pgvector_lookup — busca nearest-neighbor flat sobre o grid.
 
 
 
 
 
 
 
 
292
  """
 
 
 
293
  dist = torch.sum((self.weights - x.view(1, 1, 1, 1, 4)) ** 2, dim=-1)
294
+ flat_idx = torch.argmin(dist).item()
295
+ i = flat_idx // (self.J * self.K * self.L)
296
+ rest = flat_idx % (self.J * self.K * self.L)
297
+ j = rest // (self.K * self.L)
298
+ rest = rest % (self.K * self.L)
 
 
 
 
299
  k = rest // self.L
300
  l = rest % self.L
301
  return (i, j, k, l)
302
 
303
+ def update_weights(self, x: torch.Tensor, bmu_idx, accumulate_fisher=False):
304
+ """Update Kohonen: ΔW = α·Λ·(x - W) + penalidade EWC em w.
305
+
306
+ Args:
307
+ x: tensor [4] — amostra 4D.
308
+ bmu_idx: (i, j, k, l) — índice do BMU.
309
+ accumulate_fisher: se True, acumula (x_w - W_w)² nos Fisher accumulators.
 
 
 
 
 
 
 
 
 
 
310
  """
311
  dist_sq = self._neighborhood(bmu_idx)
312
+ sigma = self.sigma0 * math.exp(-self.t / 1000)
313
+ alpha = self.alpha0 * math.exp(-self.t / 2000)
314
+ h = torch.exp(-dist_sq / (2 * sigma ** 2))
 
315
 
316
+ delta = x - self.weights
317
+ update = alpha * h.unsqueeze(-1) * delta
 
318
 
 
319
  if self.old_weights_w is not None and self.fisher_w is not None:
320
+ # Penalidade EWC apenas na 4ª dimensão (w)
321
+ # ∂L_ewc/∂W_w = λ · F · (W_w - W*_w) → subtraído do update
322
  ewc_penalty = self.lambda_ewc * self.fisher_w * (
323
  self.weights[..., 3] - self.old_weights_w
324
  )
 
326
 
327
  self.weights = self.weights + update
328
 
 
329
  if accumulate_fisher:
330
+ # Acumula Fisher apenas em neurônios próximos ao BMU (Λ > 0.1)
331
  mask = h > 0.1
332
  if mask.any():
 
333
  diff_sq = (x[3] - self.weights[mask][..., 3]) ** 2
334
  self.fisher_accum[mask] += diff_sq
335
+ self.fisher_count[mask] += 1
336
 
337
  self.t += 1
338
 
339
+ def finalize_fisher(self):
340
+ """Fisher = mean((x_w - W_w)²) sobre samples acumuladas."""
 
 
 
 
 
 
341
  cnt = self.fisher_count.clamp(min=1e-8)
342
  self.fisher_w = self.fisher_accum / cnt
343
 
344
+ def set_ewc_reference(self):
345
+ """Consolida W_w como referência EWC e finaliza Fisher."""
 
 
 
 
 
 
346
  self.old_weights_w = self.weights[..., 3].clone()
347
  self.finalize_fisher()
 
348
  self.fisher_accum.zero_()
349
  self.fisher_count.zero_()
350
 
351
  # ------------------------------------------------------------------
352
+ # Métricas para monitoramento (V6.4)
353
  # ------------------------------------------------------------------
354
+ def get_metrics(self) -> dict:
355
+ """Retorna métricas atuais do SOM para monitoramento."""
356
+ sigma_t = self.sigma0 * math.exp(-self.t / 1000)
357
+ alpha_t = self.alpha0 * math.exp(-self.t / 2000)
358
  return {
359
+ "t": int(self.t),
360
  "sigma_t": float(sigma_t),
361
  "alpha_t": float(alpha_t),
362
  "sigma0": float(self.sigma0),
363
  "alpha0": float(self.alpha0),
364
  "lambda_ewc": float(self.lambda_ewc),
365
+ "grid_shape": [int(self.I), int(self.J), int(self.K), int(self.L)],
366
  "n_neurons": int(self.I * self.J * self.K * self.L),
367
  "has_ewc_reference": self.old_weights_w is not None,
368
+ "fisher_w_mean": (
369
+ float(self.fisher_w.mean().item())
370
+ if self.fisher_w is not None
371
+ else 0.0
372
+ ),
373
+ "fisher_w_max": (
374
+ float(self.fisher_w.max().item())
375
+ if self.fisher_w is not None
376
+ else 0.0
377
+ ),
378
+ "fisher_accum_count": int(self.fisher_count.sum().item()),
379
+ "weights_norm": float(self.weights.norm().item()),
380
+ "weights_w_mean": float(self.weights[..., 3].mean().item()),
381
  }
382
 
383
 
384
  # ============================================================================
385
+ # Classificador de hipótese (8 camadas FC)
386
  # ============================================================================
387
  class HypothesisClassifier(nn.Module):
388
+ """Classificador de hipótese: 8 camadas FC + ReLU + output logit.
 
 
 
 
389
 
390
+ Arquitetura: [input → 512 → 256 → 128 → 64 → 32 → 16 → 8] + ReLU
391
+ + [8 → 1] (logit)
392
+ Loss: BCEWithLogitsLoss
393
  """
394
 
395
+ def __init__(self, input_dim, hidden_dims=[512, 256, 128, 64, 32, 16, 8]):
 
 
 
 
396
  super().__init__()
397
+ layers = []
 
 
398
  prev = input_dim
399
  for h in hidden_dims:
400
  layers.append(nn.Linear(prev, h))
401
  layers.append(nn.ReLU())
402
  prev = h
403
+ layers.append(nn.Linear(prev, 1))
404
  self.net = nn.Sequential(*layers)
405
 
406
+ def forward(self, x):
407
+ return self.net(x).squeeze(-1)
408
 
409
 
410
  # ============================================================================
411
+ # Sistema de aprendizado completo (com w temporal e condição de início por N)
412
  # ============================================================================
413
  class KohonenLearningSystem:
414
+ """Pipeline integrado: tokenizer + embedding + SOM4D + classifier + punishment.
415
+
416
+ Args:
417
+ vocab_size: tamanho do vocabulário BBPE (default 16384).
418
+ hidden_dim: dimensão do embedding (default 1024).
419
+ seq_len: comprimento máximo da sequência (default 8).
420
+ som_grid: (I, J, K, L) — grid 4D do SOM (default (6, 6, 6, 4) = 864).
421
+ alpha0, sigma0: hiperparâmetros do SOM.
422
+ lambda_ewc: peso da penalidade EWC.
423
+ N_start: threshold do histograma para iniciar treino.
424
+ dim_choice: 'x' | 'y' | 'z' — dimensão usada no histograma.
425
+ hypothesis_hidden: arquitetura do HypothesisClassifier.
426
+ T_max: normalização temporal (w = time_step / T_max).
 
427
  """
428
 
429
  def __init__(
430
  self,
431
+ vocab_size=16384,
432
+ hidden_dim=1024,
433
+ seq_len=8,
434
+ som_grid=(6, 6, 6, 4),
435
+ alpha0=0.1,
436
+ sigma0=1.5,
437
+ lambda_ewc=0.02,
438
+ N_start=10,
439
+ dim_choice="y",
440
+ hypothesis_hidden=[512, 256, 128, 64, 32, 16, 8],
441
+ T_max=10000,
442
  ):
 
 
 
 
443
  self.tokenizer = SimpleBBPETokenizer(vocab_size)
444
  self.embedding = nn.Embedding(vocab_size, hidden_dim)
445
  self.hidden_dim = hidden_dim
446
  self.seq_len = seq_len
447
+ self.T_max = T_max
448
+ self.time_counter = 0 # contador global de amostras processadas
449
 
 
450
  self.som = KohonenSOM4D(som_grid, alpha0, sigma0, lambda_ewc)
451
  self.som_grid = som_grid
452
+ self.som_neuron_count = (
453
+ som_grid[0] * som_grid[1] * som_grid[2] * som_grid[3]
454
+ )
455
 
 
456
  self.classifier: Optional[HypothesisClassifier] = None
457
  self.hypothesis_hidden = hypothesis_hidden
458
  self.classifier_trained = False
459
 
460
+ self.buffer_4d = []
461
+ self.buffer_labels = []
 
462
  self.training_ready = False
463
  self.N = N_start
464
  self.dim_choice = dim_choice
465
  self.dim_index = {"x": 0, "y": 1, "z": 2}[dim_choice]
466
 
 
467
  self.punishment_count = 0
468
  self.success_count = 0
469
+ self.histogram = Counter()
 
 
 
 
 
 
 
470
 
471
+ self.required_new_samples = 0
 
 
 
 
472
 
473
+ def add_data(self, sentences: List[str], labels: List[int]):
474
+ """Adiciona amostras: text → 4D vector + atualiza histograma."""
 
475
  for sent, lab in zip(sentences, labels):
476
+ self.time_counter += 1
477
  vec = text_to_4d_vector(
478
+ sent,
479
+ self.tokenizer,
480
+ self.embedding,
481
+ self.hidden_dim,
482
+ self.seq_len,
483
+ self.time_counter,
484
+ self.T_max,
485
  )
486
  self.buffer_4d.append(vec)
487
  self.buffer_labels.append(lab)
 
488
  dim_val = round(vec[self.dim_index].item(), 2)
489
  self.histogram[dim_val] += 1
490
 
491
  def check_training_start(self) -> bool:
492
+ """Inicia treino quando algum bucket do histograma atinge N."""
493
+ if (
494
+ not self.training_ready
495
+ and max(self.histogram.values(), default=0) >= self.N
496
+ ):
497
  self.training_ready = True
498
  return True
499
  return False
500
 
501
+ def train_som_on_buffer(self):
502
+ """Treina SOM por 5 épocas sobre o buffer atual (com Fisher accum)."""
 
 
 
 
 
 
 
 
503
  if not self.buffer_4d:
504
  return
505
+ data = torch.stack(self.buffer_4d)
506
+ for _ in range(5): # épocas de treino rápido
507
  perm = torch.randperm(len(data))
508
  for idx in perm:
509
  x = data[idx]
510
  bmu = self.som.find_bmu(x)
 
511
  acc_fisher = (
512
  self.punishment_count == 0
513
  and self.som.old_weights_w is None
514
  )
515
  self.som.update_weights(x, bmu, accumulate_fisher=acc_fisher)
516
 
517
+ def _som_activation(self, x):
518
+ """Vetor de ativação SOM: distâncias de x a todos os neurônios (flatten)."""
519
+ dist = torch.sum((self.som.weights - x.view(1, 1, 1, 1, 4)) ** 2, dim=-1)
520
+ return dist.flatten()
 
521
 
522
+ def _label_neurons(self):
523
+ """Rotula neurônios por votação majoritária sobre o buffer."""
524
+ self.neuron_label = {}
525
+ if not self.buffer_4d:
526
+ return
527
+ data = torch.stack(self.buffer_4d)
528
+ labels = torch.tensor(self.buffer_labels)
529
+ votes = defaultdict(lambda: [0, 0])
530
+ for i in range(len(data)):
531
+ bmu = self.som.find_bmu(data[i])
532
+ votes[bmu][int(labels[i].item())] += 1
533
+ for bmu, v in votes.items():
534
+ self.neuron_label[bmu] = 1.0 if v[1] > v[0] else 0.0
535
+
536
+ def evaluate_classification(self) -> float:
537
+ """Acurácia sobre o buffer atual."""
538
+ if not self.buffer_4d:
539
  return 1.0
540
  data = torch.stack(self.buffer_4d)
541
  labels = torch.tensor(self.buffer_labels).float()
 
546
  correct += 1
547
  return correct / len(data)
548
 
549
+ def _predict_single(self, x):
550
+ """Prediz: classifier (se treinado) ou voto do BMU."""
 
 
 
 
551
  if self.classifier is not None and self.classifier_trained:
552
  with torch.no_grad():
553
+ act = self._som_activation(x).unsqueeze(0)
554
+ logit = self.classifier(act)
555
+ return torch.sigmoid(logit).item()
556
  else:
557
+ if not hasattr(self, "neuron_label"):
 
558
  self._label_neurons()
559
+ bmu = self.som.find_bmu(x)
560
  return self.neuron_label.get(bmu, 0.5)
561
 
562
+ def activate_hypothesis(self):
563
+ """Treina o HypothesisClassifier (8 FC layers) por 50 epochs.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
 
565
+ BUG FIX (V6.3→V6.4): buffer_4d contém tensores que carregam o grafo
566
+ de computação do embedding. Para evitar "Trying to backward through
567
+ the graph a second time", fazemos detach+clone e calculamos as
568
+ ativações SOM dentro de torch.no_grad(). O classifier treina apenas
569
+ sobre seus próprios pesos.
 
 
 
 
 
 
 
 
570
  """
571
  if self.classifier is None:
572
+ self.classifier = HypothesisClassifier(
573
+ self.som_neuron_count, self.hypothesis_hidden
574
+ )
575
+ # FIX: detach+clone para isolar do grafo do embedding
 
 
 
576
  data = torch.stack(self.buffer_4d).detach().clone()
577
  labels = torch.tensor(self.buffer_labels).float()
578
+ # FIX: ativações SEM gradiente (não queremos treinar SOM/embedding aqui)
579
  with torch.no_grad():
580
+ X = torch.stack([self._som_activation(data[i]) for i in range(len(data))])
 
 
 
 
 
 
581
  optimizer = torch.optim.Adam(self.classifier.parameters(), lr=0.001)
582
  criterion = nn.BCEWithLogitsLoss()
583
+ for _ in range(50):
584
  optimizer.zero_grad()
585
+ loss = criterion(self.classifier(X), labels)
 
586
  loss.backward()
587
  optimizer.step()
588
  self.classifier_trained = True
589
 
590
+ def process_batch(self, sentences: List[str], labels: List[int]):
591
+ """Processa batch: adiciona dados, treina SOM se ready, aplica punishment.
 
 
 
 
 
592
 
593
+ Returns:
594
+ True se o protocolo de punishment completou um ciclo (2ª punição
595
+ → set_ewc_reference + reset). False caso contrário.
596
  """
597
  self.add_data(sentences, labels)
598
 
 
599
  if self.check_training_start():
600
  self.train_som_on_buffer()
601
  self._label_neurons()
602
 
 
603
  if self.training_ready:
604
  acc = self.evaluate_classification()
605
+ if acc < 1.0:
606
  self.punishment_count += 1
607
  self.success_count = 0
608
  if self.punishment_count == 1:
 
609
  self.activate_hypothesis()
610
  elif self.punishment_count == 2:
 
611
  self.som.set_ewc_reference()
612
+ self.required_new_samples = (
613
  self.success_count * self.N
614
  if self.success_count > 0
615
  else self.N
616
  )
 
617
  self.training_ready = False
618
  self.punishment_count = 0
619
  self.success_count = 0
 
622
  self.buffer_labels.clear()
623
  return True
624
  else:
 
625
  self.punishment_count = 0
626
  self.success_count += 1
 
627
  return False
628
 
 
 
 
629
  def predict(self, sentence: str) -> str:
630
+ """Prediz rótulo textual ("gato" se prob ≤ 0.5, "cachorro" caso contrário)."""
631
+ self.time_counter += 1 # mantém coerência temporal
632
  vec = text_to_4d_vector(
633
+ sentence,
634
+ self.tokenizer,
635
+ self.embedding,
636
+ self.hidden_dim,
637
+ self.seq_len,
638
+ self.time_counter,
639
+ self.T_max,
640
  )
641
  prob = self._predict_single(vec)
642
  return "gato" if prob <= 0.5 else "cachorro"
643
 
644
  # ------------------------------------------------------------------
645
+ # API de monitoramento (V6.4)
646
  # ------------------------------------------------------------------
647
+ def get_state_metrics(self) -> dict:
648
+ """Retorna métricas completas do sistema para monitoramento."""
649
+ som_metrics = self.som.get_metrics()
650
  return {
651
+ "som": som_metrics,
652
+ "kls": {
653
+ "time_counter": int(self.time_counter),
654
+ "T_max": int(self.T_max),
655
+ "buffer_size": int(len(self.buffer_4d)),
656
+ "training_ready": bool(self.training_ready),
657
+ "punishment_count": int(self.punishment_count),
658
+ "success_count": int(self.success_count),
659
+ "classifier_trained": bool(self.classifier_trained),
660
+ "histogram_size": int(len(self.histogram)),
661
+ "histogram_max": int(max(self.histogram.values(), default=0)),
662
+ "N_start": int(self.N),
663
+ "dim_choice": str(self.dim_choice),
664
+ "som_neuron_count": int(self.som_neuron_count),
665
+ "required_new_samples": int(self.required_new_samples),
666
+ "has_classifier": self.classifier is not None,
667
+ "vocab_size": int(self.tokenizer.vocab_size),
668
+ "hidden_dim": int(self.hidden_dim),
669
+ "seq_len": int(self.seq_len),
670
+ },
671
  }
 
 
 
 
 
 
 
 
 
 
 
 
v6_2_upload_report.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "V6.2",
3
+ "timestamp": "2026-08-07 00:55:34",
4
+ "repo_id": "PowerMachine/BiGRU_T_version",
5
+ "commit_url": "https://huggingface.co/PowerMachine/BiGRU_T_version/commit/0d4bcbeff929ce5106b72057986ab2dac686afc4",
6
+ "elapsed_seconds": 3.1029978040005517,
7
+ "n_files_uploaded": 86,
8
+ "n_files_in_repo_before": 0,
9
+ "n_files_in_repo_after": 0,
10
+ "new_files": [],
11
+ "critical_files_ok": false,
12
+ "critical_files": [
13
+ "src/bigru_t/model/hyp_t.py",
14
+ "src/bigru_t/model/orq_cell.py",
15
+ "src/bigru_t/training/ewc.py",
16
+ "src/bigru_t/training/mtp.py",
17
+ "src/bigru_t/training/dynamic_repetition_penalty.py",
18
+ "src/bigru_t/training/data_augmentation.py",
19
+ "src/bigru_t/training/rlhf_mapping.py",
20
+ "src/bigru_t/attention/window_context.py",
21
+ "src/bigru_t/reasoning/thinking.py",
22
+ "src/bigru_t/tools/tool_mutation.py",
23
+ "src/bigru_t/tools/tool_cache.py",
24
+ "src/bigru_t/tools/tool_agent.py",
25
+ "src/bigru_t/integrations/langchain_compat.py",
26
+ "src/bigru_t/pipeline/optimized_pipeline.py",
27
+ "src/bigru_t/utils/xeon_runtime.py",
28
+ "v6_1_report.json",
29
+ "v6_2_report.json"
30
+ ]
31
+ }
v6_4_report.json ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "V6.4",
3
+ "timestamp": "2026-08-07T21:50:59.736919",
4
+ "config": {
5
+ "BATCH_SIZE": 16,
6
+ "N_DATASETS": 5,
7
+ "SAMPLES_PER_DATASET": 50,
8
+ "TOTAL_SAMPLES": 250,
9
+ "EPOCHS": 2,
10
+ "SOM_GRID": [
11
+ 6,
12
+ 6,
13
+ 6,
14
+ 4
15
+ ],
16
+ "n_neurons": 864,
17
+ "HIDDEN_DIM": 1024,
18
+ "VOCAB_SIZE": 16384,
19
+ "MAX_SEQ_LEN": 8,
20
+ "T_max": 10000,
21
+ "N_start": 10,
22
+ "lambda_ewc": 0.02,
23
+ "alpha0": 0.1,
24
+ "sigma0": 1.5,
25
+ "dim_choice": "y",
26
+ "pgvector_lookup": "REMOVED (find_bmu replaces it)"
27
+ },
28
+ "xeon_status": {
29
+ "version": "V6",
30
+ "physical_cores": 2,
31
+ "env": {
32
+ "MKL_ENABLE_INSTRUCTIONS": "AVX512",
33
+ "MKL_NUM_THREADS": "2",
34
+ "OMP_NUM_THREADS": "2",
35
+ "MKL_DYNAMIC": "FALSE",
36
+ "DNNL_PRIMITIVE_CACHE_CAPACITY": "1024",
37
+ "ONEDNN_MAX_CPU_ISA": "AMX_INT8",
38
+ "KMP_AFFINITY": "granularity=fine,compact,1,0",
39
+ "KMP_BLOCKTIME": "1"
40
+ },
41
+ "avx512": {
42
+ "supported": true,
43
+ "desc": "AVX512_VNNI (full INT8 acceleration)"
44
+ },
45
+ "amx": {
46
+ "supported": true,
47
+ "desc": "AMX (tile + int8 + bf16) — full AMX acceleration"
48
+ },
49
+ "ipex_available": false,
50
+ "init_done": true
51
+ },
52
+ "fp16_benchmark": {
53
+ "best_time_ms": 72.87378999990324,
54
+ "avg_time_ms": 98.34084399994936,
55
+ "best_tflops": 1.7564614108881937,
56
+ "avg_tflops": 1.3015954998318493,
57
+ "matrix_size": 4000.0
58
+ },
59
+ "training": {
60
+ "duration_s": 95.8256266117096,
61
+ "n_steps": 40,
62
+ "n_epochs": 2
63
+ },
64
+ "summary": {
65
+ "n_steps": 40,
66
+ "final_loss": -1.0,
67
+ "mean_loss": -0.9971289930033563,
68
+ "min_loss": -1.0,
69
+ "max_loss": -0.97182531580755,
70
+ "final_acc": 1.0,
71
+ "mean_acc": 0.9943146720070143,
72
+ "sigma_start": 1.3846745195799537,
73
+ "sigma_end": 0.7752770017375488,
74
+ "alpha_start": 0.09607894391523232,
75
+ "alpha_end": 0.07189237334319262,
76
+ "rss_max_mb": 1400.0,
77
+ "rss_final_mb": 1400.0,
78
+ "rss_trend": "stable",
79
+ "n_alerts": 39,
80
+ "alerts": [
81
+ {
82
+ "type": "3.3_loss_vanishing",
83
+ "step": 1,
84
+ "value": -0.9842509842514764
85
+ },
86
+ {
87
+ "type": "3.3_loss_vanishing",
88
+ "step": 2,
89
+ "value": -1.0
90
+ },
91
+ {
92
+ "type": "3.3_loss_vanishing",
93
+ "step": 3,
94
+ "value": -1.0
95
+ },
96
+ {
97
+ "type": "3.3_loss_vanishing",
98
+ "step": 4,
99
+ "value": -1.0
100
+ },
101
+ {
102
+ "type": "3.3_loss_vanishing",
103
+ "step": 5,
104
+ "value": -1.0
105
+ },
106
+ {
107
+ "type": "3.3_loss_vanishing",
108
+ "step": 6,
109
+ "value": -1.0
110
+ },
111
+ {
112
+ "type": "3.3_loss_vanishing",
113
+ "step": 7,
114
+ "value": -1.0
115
+ },
116
+ {
117
+ "type": "3.3_loss_vanishing",
118
+ "step": 8,
119
+ "value": -0.9926198253344827
120
+ },
121
+ {
122
+ "type": "3.3_loss_vanishing",
123
+ "step": 9,
124
+ "value": -1.0
125
+ },
126
+ {
127
+ "type": "3.3_loss_vanishing",
128
+ "step": 10,
129
+ "value": -1.0
130
+ },
131
+ {
132
+ "type": "3.3_loss_vanishing",
133
+ "step": 11,
134
+ "value": -0.97182531580755
135
+ },
136
+ {
137
+ "type": "3.3_loss_vanishing",
138
+ "step": 12,
139
+ "value": -1.0
140
+ },
141
+ {
142
+ "type": "3.3_loss_vanishing",
143
+ "step": 13,
144
+ "value": -1.0
145
+ },
146
+ {
147
+ "type": "3.3_loss_vanishing",
148
+ "step": 14,
149
+ "value": -1.0
150
+ },
151
+ {
152
+ "type": "3.3_loss_vanishing",
153
+ "step": 15,
154
+ "value": -1.0
155
+ },
156
+ {
157
+ "type": "3.3_loss_vanishing",
158
+ "step": 16,
159
+ "value": -1.0
160
+ },
161
+ {
162
+ "type": "3.3_loss_vanishing",
163
+ "step": 17,
164
+ "value": -1.0
165
+ },
166
+ {
167
+ "type": "3.3_loss_vanishing",
168
+ "step": 18,
169
+ "value": -0.9938837346736189
170
+ },
171
+ {
172
+ "type": "3.3_loss_vanishing",
173
+ "step": 19,
174
+ "value": -1.0
175
+ },
176
+ {
177
+ "type": "3.3_loss_vanishing",
178
+ "step": 20,
179
+ "value": -1.0
180
+ }
181
+ ],
182
+ "kohonen_final": {
183
+ "sigma_t": 0.7752770017375488,
184
+ "alpha_t": 0.07189237334319262,
185
+ "t": 660,
186
+ "n_neurons": 864,
187
+ "fisher_w_mean": 0.0,
188
+ "fisher_w_max": 0.0,
189
+ "fisher_accum_count": 0,
190
+ "has_ewc_reference": true,
191
+ "weights_norm": 39.1356201171875,
192
+ "weights_w_mean": -0.000526978459674865
193
+ },
194
+ "hypothesis_final": {
195
+ "classifier_trained": true,
196
+ "punishment_count": 0,
197
+ "success_count": 0,
198
+ "training_ready": false,
199
+ "buffer_size": 0,
200
+ "required_new_samples": 10,
201
+ "histogram_max": 0,
202
+ "time_counter": 500
203
+ }
204
+ },
205
+ "kohonen_final": {
206
+ "t": 660,
207
+ "sigma_t": 0.7752770017375488,
208
+ "alpha_t": 0.07189237334319262,
209
+ "sigma0": 1.5,
210
+ "alpha0": 0.1,
211
+ "lambda_ewc": 0.02,
212
+ "grid_shape": [
213
+ 6,
214
+ 6,
215
+ 6,
216
+ 4
217
+ ],
218
+ "n_neurons": 864,
219
+ "has_ewc_reference": true,
220
+ "fisher_w_mean": 0.0,
221
+ "fisher_w_max": 0.0,
222
+ "fisher_accum_count": 0,
223
+ "weights_norm": 39.1356201171875,
224
+ "weights_w_mean": -0.000526978459674865
225
+ },
226
+ "kls_state": {
227
+ "som": {
228
+ "t": 660,
229
+ "sigma_t": 0.7752770017375488,
230
+ "alpha_t": 0.07189237334319262,
231
+ "sigma0": 1.5,
232
+ "alpha0": 0.1,
233
+ "lambda_ewc": 0.02,
234
+ "grid_shape": [
235
+ 6,
236
+ 6,
237
+ 6,
238
+ 4
239
+ ],
240
+ "n_neurons": 864,
241
+ "has_ewc_reference": true,
242
+ "fisher_w_mean": 0.0,
243
+ "fisher_w_max": 0.0,
244
+ "fisher_accum_count": 0,
245
+ "weights_norm": 39.1356201171875,
246
+ "weights_w_mean": -0.000526978459674865
247
+ },
248
+ "kls": {
249
+ "time_counter": 500,
250
+ "T_max": 10000,
251
+ "buffer_size": 0,
252
+ "training_ready": false,
253
+ "punishment_count": 0,
254
+ "success_count": 0,
255
+ "classifier_trained": true,
256
+ "histogram_size": 0,
257
+ "histogram_max": 0,
258
+ "N_start": 10,
259
+ "dim_choice": "y",
260
+ "som_neuron_count": 864,
261
+ "required_new_samples": 10,
262
+ "has_classifier": true,
263
+ "vocab_size": 16384,
264
+ "hidden_dim": 1024,
265
+ "seq_len": 8
266
+ }
267
+ },
268
+ "math_analysis": {
269
+ "text_to_4d": "SVD: M @ V[:3].T -> centroid 3D + w = time_step/T_max (LINEAR)",
270
+ "bmu_distance": "||W - x||^2 (L2 squared in R^4) — replaces pgvector_lookup",
271
+ "neighborhood": "Lambda(d, sigma) = exp(-d^2 / (2*sigma^2)), d^2 = di^2+dj^2+dk^2+dl^2",
272
+ "weight_update": "dW = alpha * Lambda * (x - W)",
273
+ "sigma_decay": "sigma_t = sigma0 * exp(-t/1000)",
274
+ "alpha_decay": "alpha_t = alpha0 * exp(-t/2000)",
275
+ "ewc_only_dim4": "penalty = lambda * F * (W_w - W*_w), F = mean((x_w - W_w)^2)",
276
+ "fisher_accumulation": "only when punishment_count==0 AND old_weights_w is None AND Lambda > 0.1",
277
+ "hypothesis_classifier": "8 layers FC: 512->256->128->64->32->16->8->1",
278
+ "punishment_protocol": "1st -> activate_hypothesis; 2nd -> set_ewc_reference + reset",
279
+ "bug_fixed_find_bmu": "user code already clean (no premature return)",
280
+ "bug_fixed_activate_hypothesis": "detach+clone buffer + no_grad for SOM activation (V6.3 fix maintained)",
281
+ "pgvector_removed": "find_bmu is the equivalent nearest-neighbor search over SOM grid"
282
+ },
283
+ "datasets_used": [
284
+ "TucanoBR/GigaVerbo",
285
+ "dominguesm/restore-punctuation-pttr-dataset",
286
+ "Madras1/corpus-ptbr-v2",
287
+ "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
288
+ "nvidia/OpenMathInstruct-2"
289
+ ]
290
+ }
v6_4_training_metrics.json ADDED
@@ -0,0 +1,1983 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "V6.4",
3
+ "steps": [
4
+ {
5
+ "step": 0,
6
+ "epoch": 0,
7
+ "dataset": "TucanoBR/GigaVerbo",
8
+ "quality": {
9
+ "1.1_train_loss": -1.0,
10
+ "1.2_train_acc": 1.0,
11
+ "1.3_val_loss": -1.0,
12
+ "1.4_val_acc": 1.0,
13
+ "1.5_perplexity": 0.36787944123356736
14
+ },
15
+ "speed": {
16
+ "2.1_throughput_sps": 1.252199811407418,
17
+ "2.2_step_time_ms": 12777.51350402832,
18
+ "2.3_epoch_progress": 0.5,
19
+ "2.4_rss_mb": 596.203125,
20
+ "2.5_xeon_tflops": 1.7564614108881937
21
+ },
22
+ "kohonen": {
23
+ "sigma_t": 1.3846745195799537,
24
+ "alpha_t": 0.09607894391523232,
25
+ "t": 80,
26
+ "n_neurons": 864,
27
+ "fisher_w_mean": 0.0,
28
+ "fisher_w_max": 0.0,
29
+ "fisher_accum_count": 18993,
30
+ "has_ewc_reference": false,
31
+ "weights_norm": 44.14729690551758,
32
+ "weights_w_mean": 0.002776434412226081
33
+ },
34
+ "hypothesis": {
35
+ "classifier_trained": false,
36
+ "punishment_count": 0,
37
+ "success_count": 1,
38
+ "training_ready": true,
39
+ "buffer_size": 16,
40
+ "required_new_samples": 0,
41
+ "histogram_max": 16,
42
+ "time_counter": 16
43
+ }
44
+ },
45
+ {
46
+ "step": 1,
47
+ "epoch": 0,
48
+ "dataset": "TucanoBR/GigaVerbo",
49
+ "quality": {
50
+ "1.1_train_loss": -0.9842509842514764,
51
+ "1.2_train_acc": 0.96875,
52
+ "1.3_val_loss": -0.9842509842514764,
53
+ "1.4_val_acc": 0.96875,
54
+ "1.5_perplexity": 0.3737190436413242
55
+ },
56
+ "speed": {
57
+ "2.1_throughput_sps": 2.071905155832304,
58
+ "2.2_step_time_ms": 7722.361207008362,
59
+ "2.3_epoch_progress": 0.5,
60
+ "2.4_rss_mb": 650.36328125,
61
+ "2.5_xeon_tflops": 1.7564614108881937
62
+ },
63
+ "kohonen": {
64
+ "sigma_t": 1.3846745195799537,
65
+ "alpha_t": 0.09607894391523232,
66
+ "t": 80,
67
+ "n_neurons": 864,
68
+ "fisher_w_mean": 0.0,
69
+ "fisher_w_max": 0.0,
70
+ "fisher_accum_count": 18993,
71
+ "has_ewc_reference": false,
72
+ "weights_norm": 44.14729690551758,
73
+ "weights_w_mean": 0.002776434412226081
74
+ },
75
+ "hypothesis": {
76
+ "classifier_trained": true,
77
+ "punishment_count": 1,
78
+ "success_count": 0,
79
+ "training_ready": true,
80
+ "buffer_size": 32,
81
+ "required_new_samples": 0,
82
+ "histogram_max": 32,
83
+ "time_counter": 32
84
+ }
85
+ },
86
+ {
87
+ "step": 2,
88
+ "epoch": 0,
89
+ "dataset": "TucanoBR/GigaVerbo",
90
+ "quality": {
91
+ "1.1_train_loss": -1.0,
92
+ "1.2_train_acc": 1.0,
93
+ "1.3_val_loss": -1.0,
94
+ "1.4_val_acc": 1.0,
95
+ "1.5_perplexity": 0.36787944123356736
96
+ },
97
+ "speed": {
98
+ "2.1_throughput_sps": 3.1045055506639967,
99
+ "2.2_step_time_ms": 5153.799772262573,
100
+ "2.3_epoch_progress": 0.5,
101
+ "2.4_rss_mb": 650.36328125,
102
+ "2.5_xeon_tflops": 1.7564614108881937
103
+ },
104
+ "kohonen": {
105
+ "sigma_t": 1.3846745195799537,
106
+ "alpha_t": 0.09607894391523232,
107
+ "t": 80,
108
+ "n_neurons": 864,
109
+ "fisher_w_mean": 0.12250354886054993,
110
+ "fisher_w_max": 4.135858058929443,
111
+ "fisher_accum_count": 0,
112
+ "has_ewc_reference": true,
113
+ "weights_norm": 44.14729690551758,
114
+ "weights_w_mean": 0.002776434412226081
115
+ },
116
+ "hypothesis": {
117
+ "classifier_trained": true,
118
+ "punishment_count": 0,
119
+ "success_count": 0,
120
+ "training_ready": false,
121
+ "buffer_size": 0,
122
+ "required_new_samples": 10,
123
+ "histogram_max": 0,
124
+ "time_counter": 48
125
+ }
126
+ },
127
+ {
128
+ "step": 3,
129
+ "epoch": 0,
130
+ "dataset": "TucanoBR/GigaVerbo",
131
+ "quality": {
132
+ "1.1_train_loss": -1.0,
133
+ "1.2_train_acc": 1.0,
134
+ "1.3_val_loss": -1.0,
135
+ "1.4_val_acc": 1.0,
136
+ "1.5_perplexity": 0.36787944123356736
137
+ },
138
+ "speed": {
139
+ "2.1_throughput_sps": 4.13873597280636,
140
+ "2.2_step_time_ms": 3865.9146428108215,
141
+ "2.3_epoch_progress": 0.5,
142
+ "2.4_rss_mb": 650.36328125,
143
+ "2.5_xeon_tflops": 1.7564614108881937
144
+ },
145
+ "kohonen": {
146
+ "sigma_t": 1.3846745195799537,
147
+ "alpha_t": 0.09607894391523232,
148
+ "t": 80,
149
+ "n_neurons": 864,
150
+ "fisher_w_mean": 0.12250354886054993,
151
+ "fisher_w_max": 4.135858058929443,
152
+ "fisher_accum_count": 0,
153
+ "has_ewc_reference": true,
154
+ "weights_norm": 44.14729690551758,
155
+ "weights_w_mean": 0.002776434412226081
156
+ },
157
+ "hypothesis": {
158
+ "classifier_trained": true,
159
+ "punishment_count": 0,
160
+ "success_count": 0,
161
+ "training_ready": false,
162
+ "buffer_size": 2,
163
+ "required_new_samples": 10,
164
+ "histogram_max": 2,
165
+ "time_counter": 50
166
+ }
167
+ },
168
+ {
169
+ "step": 4,
170
+ "epoch": 0,
171
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
172
+ "quality": {
173
+ "1.1_train_loss": -1.0,
174
+ "1.2_train_acc": 1.0,
175
+ "1.3_val_loss": -1.0,
176
+ "1.4_val_acc": 1.0,
177
+ "1.5_perplexity": 0.36787944123356736
178
+ },
179
+ "speed": {
180
+ "2.1_throughput_sps": 5.155361297768753,
181
+ "2.2_step_time_ms": 3103.565216064453,
182
+ "2.3_epoch_progress": 0.5,
183
+ "2.4_rss_mb": 650.36328125,
184
+ "2.5_xeon_tflops": 1.7564614108881937
185
+ },
186
+ "kohonen": {
187
+ "sigma_t": 1.2654972248945755,
188
+ "alpha_t": 0.09185122844014575,
189
+ "t": 170,
190
+ "n_neurons": 864,
191
+ "fisher_w_mean": 0.12250354886054993,
192
+ "fisher_w_max": 4.135858058929443,
193
+ "fisher_accum_count": 0,
194
+ "has_ewc_reference": true,
195
+ "weights_norm": 41.66946792602539,
196
+ "weights_w_mean": 0.0018139677122235298
197
+ },
198
+ "hypothesis": {
199
+ "classifier_trained": true,
200
+ "punishment_count": 0,
201
+ "success_count": 1,
202
+ "training_ready": true,
203
+ "buffer_size": 18,
204
+ "required_new_samples": 10,
205
+ "histogram_max": 18,
206
+ "time_counter": 66
207
+ }
208
+ },
209
+ {
210
+ "step": 5,
211
+ "epoch": 0,
212
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
213
+ "quality": {
214
+ "1.1_train_loss": -1.0,
215
+ "1.2_train_acc": 1.0,
216
+ "1.3_val_loss": -1.0,
217
+ "1.4_val_acc": 1.0,
218
+ "1.5_perplexity": 0.36787944123356736
219
+ },
220
+ "speed": {
221
+ "2.1_throughput_sps": 6.178738338462088,
222
+ "2.2_step_time_ms": 2589.5254214604697,
223
+ "2.3_epoch_progress": 0.5,
224
+ "2.4_rss_mb": 650.36328125,
225
+ "2.5_xeon_tflops": 1.7564614108881937
226
+ },
227
+ "kohonen": {
228
+ "sigma_t": 1.2654972248945755,
229
+ "alpha_t": 0.09185122844014575,
230
+ "t": 170,
231
+ "n_neurons": 864,
232
+ "fisher_w_mean": 0.12250354886054993,
233
+ "fisher_w_max": 4.135858058929443,
234
+ "fisher_accum_count": 0,
235
+ "has_ewc_reference": true,
236
+ "weights_norm": 41.66946792602539,
237
+ "weights_w_mean": 0.0018139677122235298
238
+ },
239
+ "hypothesis": {
240
+ "classifier_trained": true,
241
+ "punishment_count": 0,
242
+ "success_count": 2,
243
+ "training_ready": true,
244
+ "buffer_size": 34,
245
+ "required_new_samples": 10,
246
+ "histogram_max": 34,
247
+ "time_counter": 82
248
+ }
249
+ },
250
+ {
251
+ "step": 6,
252
+ "epoch": 0,
253
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
254
+ "quality": {
255
+ "1.1_train_loss": -1.0,
256
+ "1.2_train_acc": 1.0,
257
+ "1.3_val_loss": -1.0,
258
+ "1.4_val_acc": 1.0,
259
+ "1.5_perplexity": 0.36787944123356736
260
+ },
261
+ "speed": {
262
+ "2.1_throughput_sps": 7.197553173538523,
263
+ "2.2_step_time_ms": 2222.977672304426,
264
+ "2.3_epoch_progress": 0.5,
265
+ "2.4_rss_mb": 650.36328125,
266
+ "2.5_xeon_tflops": 1.7564614108881937
267
+ },
268
+ "kohonen": {
269
+ "sigma_t": 1.2654972248945755,
270
+ "alpha_t": 0.09185122844014575,
271
+ "t": 170,
272
+ "n_neurons": 864,
273
+ "fisher_w_mean": 0.12250354886054993,
274
+ "fisher_w_max": 4.135858058929443,
275
+ "fisher_accum_count": 0,
276
+ "has_ewc_reference": true,
277
+ "weights_norm": 41.66946792602539,
278
+ "weights_w_mean": 0.0018139677122235298
279
+ },
280
+ "hypothesis": {
281
+ "classifier_trained": true,
282
+ "punishment_count": 0,
283
+ "success_count": 3,
284
+ "training_ready": true,
285
+ "buffer_size": 50,
286
+ "required_new_samples": 10,
287
+ "histogram_max": 50,
288
+ "time_counter": 98
289
+ }
290
+ },
291
+ {
292
+ "step": 7,
293
+ "epoch": 0,
294
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
295
+ "quality": {
296
+ "1.1_train_loss": -1.0,
297
+ "1.2_train_acc": 1.0,
298
+ "1.3_val_loss": -1.0,
299
+ "1.4_val_acc": 1.0,
300
+ "1.5_perplexity": 0.36787944123356736
301
+ },
302
+ "speed": {
303
+ "2.1_throughput_sps": 8.21569672400893,
304
+ "2.2_step_time_ms": 1947.4915564060211,
305
+ "2.3_epoch_progress": 0.5,
306
+ "2.4_rss_mb": 650.36328125,
307
+ "2.5_xeon_tflops": 1.7564614108881937
308
+ },
309
+ "kohonen": {
310
+ "sigma_t": 1.2654972248945755,
311
+ "alpha_t": 0.09185122844014575,
312
+ "t": 170,
313
+ "n_neurons": 864,
314
+ "fisher_w_mean": 0.12250354886054993,
315
+ "fisher_w_max": 4.135858058929443,
316
+ "fisher_accum_count": 0,
317
+ "has_ewc_reference": true,
318
+ "weights_norm": 41.66946792602539,
319
+ "weights_w_mean": 0.0018139677122235298
320
+ },
321
+ "hypothesis": {
322
+ "classifier_trained": true,
323
+ "punishment_count": 0,
324
+ "success_count": 4,
325
+ "training_ready": true,
326
+ "buffer_size": 52,
327
+ "required_new_samples": 10,
328
+ "histogram_max": 52,
329
+ "time_counter": 100
330
+ }
331
+ },
332
+ {
333
+ "step": 8,
334
+ "epoch": 0,
335
+ "dataset": "Madras1/corpus-ptbr-v2",
336
+ "quality": {
337
+ "1.1_train_loss": -0.9926198253344827,
338
+ "1.2_train_acc": 0.9852941176470589,
339
+ "1.3_val_loss": -0.9926198253344827,
340
+ "1.4_val_acc": 0.9852941176470589,
341
+ "1.5_perplexity": 0.37060449909797594
342
+ },
343
+ "speed": {
344
+ "2.1_throughput_sps": 5.442196820989259,
345
+ "2.2_step_time_ms": 2939.9892224205864,
346
+ "2.3_epoch_progress": 0.5,
347
+ "2.4_rss_mb": 950.86328125,
348
+ "2.5_xeon_tflops": 1.7564614108881937
349
+ },
350
+ "kohonen": {
351
+ "sigma_t": 1.2654972248945755,
352
+ "alpha_t": 0.09185122844014575,
353
+ "t": 170,
354
+ "n_neurons": 864,
355
+ "fisher_w_mean": 0.12250354886054993,
356
+ "fisher_w_max": 4.135858058929443,
357
+ "fisher_accum_count": 0,
358
+ "has_ewc_reference": true,
359
+ "weights_norm": 41.66946792602539,
360
+ "weights_w_mean": 0.0018139677122235298
361
+ },
362
+ "hypothesis": {
363
+ "classifier_trained": true,
364
+ "punishment_count": 1,
365
+ "success_count": 0,
366
+ "training_ready": true,
367
+ "buffer_size": 68,
368
+ "required_new_samples": 10,
369
+ "histogram_max": 68,
370
+ "time_counter": 116
371
+ }
372
+ },
373
+ {
374
+ "step": 9,
375
+ "epoch": 0,
376
+ "dataset": "Madras1/corpus-ptbr-v2",
377
+ "quality": {
378
+ "1.1_train_loss": -1.0,
379
+ "1.2_train_acc": 1.0,
380
+ "1.3_val_loss": -1.0,
381
+ "1.4_val_acc": 1.0,
382
+ "1.5_perplexity": 0.36787944123356736
383
+ },
384
+ "speed": {
385
+ "2.1_throughput_sps": 6.034087787204197,
386
+ "2.2_step_time_ms": 2651.6021251678467,
387
+ "2.3_epoch_progress": 0.5,
388
+ "2.4_rss_mb": 950.86328125,
389
+ "2.5_xeon_tflops": 1.7564614108881937
390
+ },
391
+ "kohonen": {
392
+ "sigma_t": 1.2654972248945755,
393
+ "alpha_t": 0.09185122844014575,
394
+ "t": 170,
395
+ "n_neurons": 864,
396
+ "fisher_w_mean": 0.0,
397
+ "fisher_w_max": 0.0,
398
+ "fisher_accum_count": 0,
399
+ "has_ewc_reference": true,
400
+ "weights_norm": 41.66946792602539,
401
+ "weights_w_mean": 0.0018139677122235298
402
+ },
403
+ "hypothesis": {
404
+ "classifier_trained": true,
405
+ "punishment_count": 0,
406
+ "success_count": 0,
407
+ "training_ready": false,
408
+ "buffer_size": 0,
409
+ "required_new_samples": 10,
410
+ "histogram_max": 0,
411
+ "time_counter": 132
412
+ }
413
+ },
414
+ {
415
+ "step": 10,
416
+ "epoch": 0,
417
+ "dataset": "Madras1/corpus-ptbr-v2",
418
+ "quality": {
419
+ "1.1_train_loss": -1.0,
420
+ "1.2_train_acc": 1.0,
421
+ "1.3_val_loss": -1.0,
422
+ "1.4_val_acc": 1.0,
423
+ "1.5_perplexity": 0.36787944123356736
424
+ },
425
+ "speed": {
426
+ "2.1_throughput_sps": 6.631419090754089,
427
+ "2.2_step_time_ms": 2412.7565730701795,
428
+ "2.3_epoch_progress": 0.5,
429
+ "2.4_rss_mb": 950.86328125,
430
+ "2.5_xeon_tflops": 1.7564614108881937
431
+ },
432
+ "kohonen": {
433
+ "sigma_t": 1.1682011746071073,
434
+ "alpha_t": 0.08824969025845955,
435
+ "t": 250,
436
+ "n_neurons": 864,
437
+ "fisher_w_mean": 0.0,
438
+ "fisher_w_max": 0.0,
439
+ "fisher_accum_count": 0,
440
+ "has_ewc_reference": true,
441
+ "weights_norm": 39.5368766784668,
442
+ "weights_w_mean": -0.0033076698891818523
443
+ },
444
+ "hypothesis": {
445
+ "classifier_trained": true,
446
+ "punishment_count": 0,
447
+ "success_count": 1,
448
+ "training_ready": true,
449
+ "buffer_size": 16,
450
+ "required_new_samples": 10,
451
+ "histogram_max": 16,
452
+ "time_counter": 148
453
+ }
454
+ },
455
+ {
456
+ "step": 11,
457
+ "epoch": 0,
458
+ "dataset": "Madras1/corpus-ptbr-v2",
459
+ "quality": {
460
+ "1.1_train_loss": -0.97182531580755,
461
+ "1.2_train_acc": 0.9444444444444444,
462
+ "1.3_val_loss": -0.97182531580755,
463
+ "1.4_val_acc": 0.9444444444444444,
464
+ "1.5_perplexity": 0.3783917230298394
465
+ },
466
+ "speed": {
467
+ "2.1_throughput_sps": 7.173603620726871,
468
+ "2.2_step_time_ms": 2230.399231115977,
469
+ "2.3_epoch_progress": 0.5,
470
+ "2.4_rss_mb": 953.18359375,
471
+ "2.5_xeon_tflops": 1.7564614108881937
472
+ },
473
+ "kohonen": {
474
+ "sigma_t": 1.1682011746071073,
475
+ "alpha_t": 0.08824969025845955,
476
+ "t": 250,
477
+ "n_neurons": 864,
478
+ "fisher_w_mean": 0.0,
479
+ "fisher_w_max": 0.0,
480
+ "fisher_accum_count": 0,
481
+ "has_ewc_reference": true,
482
+ "weights_norm": 39.5368766784668,
483
+ "weights_w_mean": -0.0033076698891818523
484
+ },
485
+ "hypothesis": {
486
+ "classifier_trained": true,
487
+ "punishment_count": 1,
488
+ "success_count": 0,
489
+ "training_ready": true,
490
+ "buffer_size": 18,
491
+ "required_new_samples": 10,
492
+ "histogram_max": 18,
493
+ "time_counter": 150
494
+ }
495
+ },
496
+ {
497
+ "step": 12,
498
+ "epoch": 0,
499
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
500
+ "quality": {
501
+ "1.1_train_loss": -1.0,
502
+ "1.2_train_acc": 1.0,
503
+ "1.3_val_loss": -1.0,
504
+ "1.4_val_acc": 1.0,
505
+ "1.5_perplexity": 0.36787944123356736
506
+ },
507
+ "speed": {
508
+ "2.1_throughput_sps": 4.86827012467777,
509
+ "2.2_step_time_ms": 3286.588375384991,
510
+ "2.3_epoch_progress": 0.5,
511
+ "2.4_rss_mb": 1315.86328125,
512
+ "2.5_xeon_tflops": 1.7564614108881937
513
+ },
514
+ "kohonen": {
515
+ "sigma_t": 1.1682011746071073,
516
+ "alpha_t": 0.08824969025845955,
517
+ "t": 250,
518
+ "n_neurons": 864,
519
+ "fisher_w_mean": 0.0,
520
+ "fisher_w_max": 0.0,
521
+ "fisher_accum_count": 0,
522
+ "has_ewc_reference": true,
523
+ "weights_norm": 39.5368766784668,
524
+ "weights_w_mean": -0.0033076698891818523
525
+ },
526
+ "hypothesis": {
527
+ "classifier_trained": true,
528
+ "punishment_count": 0,
529
+ "success_count": 0,
530
+ "training_ready": false,
531
+ "buffer_size": 0,
532
+ "required_new_samples": 10,
533
+ "histogram_max": 0,
534
+ "time_counter": 166
535
+ }
536
+ },
537
+ {
538
+ "step": 13,
539
+ "epoch": 0,
540
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
541
+ "quality": {
542
+ "1.1_train_loss": -1.0,
543
+ "1.2_train_acc": 1.0,
544
+ "1.3_val_loss": -1.0,
545
+ "1.4_val_acc": 1.0,
546
+ "1.5_perplexity": 0.36787944123356736
547
+ },
548
+ "speed": {
549
+ "2.1_throughput_sps": 5.239823796746318,
550
+ "2.2_step_time_ms": 3053.5377945218765,
551
+ "2.3_epoch_progress": 0.5,
552
+ "2.4_rss_mb": 1315.86328125,
553
+ "2.5_xeon_tflops": 1.7564614108881937
554
+ },
555
+ "kohonen": {
556
+ "sigma_t": 1.0783856001478893,
557
+ "alpha_t": 0.08478937040879159,
558
+ "t": 330,
559
+ "n_neurons": 864,
560
+ "fisher_w_mean": 0.0,
561
+ "fisher_w_max": 0.0,
562
+ "fisher_accum_count": 0,
563
+ "has_ewc_reference": true,
564
+ "weights_norm": 39.31961441040039,
565
+ "weights_w_mean": -0.0028808298520743847
566
+ },
567
+ "hypothesis": {
568
+ "classifier_trained": true,
569
+ "punishment_count": 0,
570
+ "success_count": 1,
571
+ "training_ready": true,
572
+ "buffer_size": 16,
573
+ "required_new_samples": 10,
574
+ "histogram_max": 16,
575
+ "time_counter": 182
576
+ }
577
+ },
578
+ {
579
+ "step": 14,
580
+ "epoch": 0,
581
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
582
+ "quality": {
583
+ "1.1_train_loss": -1.0,
584
+ "1.2_train_acc": 1.0,
585
+ "1.3_val_loss": -1.0,
586
+ "1.4_val_acc": 1.0,
587
+ "1.5_perplexity": 0.36787944123356736
588
+ },
589
+ "speed": {
590
+ "2.1_throughput_sps": 5.611694473097874,
591
+ "2.2_step_time_ms": 2851.1887232462564,
592
+ "2.3_epoch_progress": 0.5,
593
+ "2.4_rss_mb": 1315.86328125,
594
+ "2.5_xeon_tflops": 1.7564614108881937
595
+ },
596
+ "kohonen": {
597
+ "sigma_t": 1.0783856001478893,
598
+ "alpha_t": 0.08478937040879159,
599
+ "t": 330,
600
+ "n_neurons": 864,
601
+ "fisher_w_mean": 0.0,
602
+ "fisher_w_max": 0.0,
603
+ "fisher_accum_count": 0,
604
+ "has_ewc_reference": true,
605
+ "weights_norm": 39.31961441040039,
606
+ "weights_w_mean": -0.0028808298520743847
607
+ },
608
+ "hypothesis": {
609
+ "classifier_trained": true,
610
+ "punishment_count": 0,
611
+ "success_count": 2,
612
+ "training_ready": true,
613
+ "buffer_size": 32,
614
+ "required_new_samples": 10,
615
+ "histogram_max": 32,
616
+ "time_counter": 198
617
+ }
618
+ },
619
+ {
620
+ "step": 15,
621
+ "epoch": 0,
622
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
623
+ "quality": {
624
+ "1.1_train_loss": -1.0,
625
+ "1.2_train_acc": 1.0,
626
+ "1.3_val_loss": -1.0,
627
+ "1.4_val_acc": 1.0,
628
+ "1.5_perplexity": 0.36787944123356736
629
+ },
630
+ "speed": {
631
+ "2.1_throughput_sps": 5.983959822705136,
632
+ "2.2_step_time_ms": 2673.814743757248,
633
+ "2.3_epoch_progress": 0.5,
634
+ "2.4_rss_mb": 1315.86328125,
635
+ "2.5_xeon_tflops": 1.7564614108881937
636
+ },
637
+ "kohonen": {
638
+ "sigma_t": 1.0783856001478893,
639
+ "alpha_t": 0.08478937040879159,
640
+ "t": 330,
641
+ "n_neurons": 864,
642
+ "fisher_w_mean": 0.0,
643
+ "fisher_w_max": 0.0,
644
+ "fisher_accum_count": 0,
645
+ "has_ewc_reference": true,
646
+ "weights_norm": 39.31961441040039,
647
+ "weights_w_mean": -0.0028808298520743847
648
+ },
649
+ "hypothesis": {
650
+ "classifier_trained": true,
651
+ "punishment_count": 0,
652
+ "success_count": 3,
653
+ "training_ready": true,
654
+ "buffer_size": 34,
655
+ "required_new_samples": 10,
656
+ "histogram_max": 34,
657
+ "time_counter": 200
658
+ }
659
+ },
660
+ {
661
+ "step": 16,
662
+ "epoch": 0,
663
+ "dataset": "nvidia/OpenMathInstruct-2",
664
+ "quality": {
665
+ "1.1_train_loss": -1.0,
666
+ "1.2_train_acc": 1.0,
667
+ "1.3_val_loss": -1.0,
668
+ "1.4_val_acc": 1.0,
669
+ "1.5_perplexity": 0.36787944123356736
670
+ },
671
+ "speed": {
672
+ "2.1_throughput_sps": 5.231395188295974,
673
+ "2.2_step_time_ms": 3058.457528843599,
674
+ "2.3_epoch_progress": 0.5,
675
+ "2.4_rss_mb": 1355.56640625,
676
+ "2.5_xeon_tflops": 1.7564614108881937
677
+ },
678
+ "kohonen": {
679
+ "sigma_t": 1.0783856001478893,
680
+ "alpha_t": 0.08478937040879159,
681
+ "t": 330,
682
+ "n_neurons": 864,
683
+ "fisher_w_mean": 0.0,
684
+ "fisher_w_max": 0.0,
685
+ "fisher_accum_count": 0,
686
+ "has_ewc_reference": true,
687
+ "weights_norm": 39.31961441040039,
688
+ "weights_w_mean": -0.0028808298520743847
689
+ },
690
+ "hypothesis": {
691
+ "classifier_trained": true,
692
+ "punishment_count": 0,
693
+ "success_count": 4,
694
+ "training_ready": true,
695
+ "buffer_size": 50,
696
+ "required_new_samples": 10,
697
+ "histogram_max": 50,
698
+ "time_counter": 216
699
+ }
700
+ },
701
+ {
702
+ "step": 17,
703
+ "epoch": 0,
704
+ "dataset": "nvidia/OpenMathInstruct-2",
705
+ "quality": {
706
+ "1.1_train_loss": -1.0,
707
+ "1.2_train_acc": 1.0,
708
+ "1.3_val_loss": -1.0,
709
+ "1.4_val_acc": 1.0,
710
+ "1.5_perplexity": 0.36787944123356736
711
+ },
712
+ "speed": {
713
+ "2.1_throughput_sps": 5.5361913842584025,
714
+ "2.2_step_time_ms": 2890.0734980901084,
715
+ "2.3_epoch_progress": 0.5,
716
+ "2.4_rss_mb": 1355.56640625,
717
+ "2.5_xeon_tflops": 1.7564614108881937
718
+ },
719
+ "kohonen": {
720
+ "sigma_t": 1.0783856001478893,
721
+ "alpha_t": 0.08478937040879159,
722
+ "t": 330,
723
+ "n_neurons": 864,
724
+ "fisher_w_mean": 0.0,
725
+ "fisher_w_max": 0.0,
726
+ "fisher_accum_count": 0,
727
+ "has_ewc_reference": true,
728
+ "weights_norm": 39.31961441040039,
729
+ "weights_w_mean": -0.0028808298520743847
730
+ },
731
+ "hypothesis": {
732
+ "classifier_trained": true,
733
+ "punishment_count": 0,
734
+ "success_count": 5,
735
+ "training_ready": true,
736
+ "buffer_size": 66,
737
+ "required_new_samples": 10,
738
+ "histogram_max": 66,
739
+ "time_counter": 232
740
+ }
741
+ },
742
+ {
743
+ "step": 18,
744
+ "epoch": 0,
745
+ "dataset": "nvidia/OpenMathInstruct-2",
746
+ "quality": {
747
+ "1.1_train_loss": -0.9938837346736189,
748
+ "1.2_train_acc": 0.9878048780487805,
749
+ "1.3_val_loss": -0.9938837346736189,
750
+ "1.4_val_acc": 0.9878048780487805,
751
+ "1.5_perplexity": 0.37013638450004166
752
+ },
753
+ "speed": {
754
+ "2.1_throughput_sps": 5.807942935626894,
755
+ "2.2_step_time_ms": 2754.848003387451,
756
+ "2.3_epoch_progress": 0.5,
757
+ "2.4_rss_mb": 1355.56640625,
758
+ "2.5_xeon_tflops": 1.7564614108881937
759
+ },
760
+ "kohonen": {
761
+ "sigma_t": 1.0783856001478893,
762
+ "alpha_t": 0.08478937040879159,
763
+ "t": 330,
764
+ "n_neurons": 864,
765
+ "fisher_w_mean": 0.0,
766
+ "fisher_w_max": 0.0,
767
+ "fisher_accum_count": 0,
768
+ "has_ewc_reference": true,
769
+ "weights_norm": 39.31961441040039,
770
+ "weights_w_mean": -0.0028808298520743847
771
+ },
772
+ "hypothesis": {
773
+ "classifier_trained": true,
774
+ "punishment_count": 1,
775
+ "success_count": 0,
776
+ "training_ready": true,
777
+ "buffer_size": 82,
778
+ "required_new_samples": 10,
779
+ "histogram_max": 82,
780
+ "time_counter": 248
781
+ }
782
+ },
783
+ {
784
+ "step": 19,
785
+ "epoch": 0,
786
+ "dataset": "nvidia/OpenMathInstruct-2",
787
+ "quality": {
788
+ "1.1_train_loss": -1.0,
789
+ "1.2_train_acc": 1.0,
790
+ "1.3_val_loss": -1.0,
791
+ "1.4_val_acc": 1.0,
792
+ "1.5_perplexity": 0.36787944123356736
793
+ },
794
+ "speed": {
795
+ "2.1_throughput_sps": 6.111821097784345,
796
+ "2.2_step_time_ms": 2617.877674102783,
797
+ "2.3_epoch_progress": 0.5,
798
+ "2.4_rss_mb": 1355.56640625,
799
+ "2.5_xeon_tflops": 1.7564614108881937
800
+ },
801
+ "kohonen": {
802
+ "sigma_t": 1.0783856001478893,
803
+ "alpha_t": 0.08478937040879159,
804
+ "t": 330,
805
+ "n_neurons": 864,
806
+ "fisher_w_mean": 0.0,
807
+ "fisher_w_max": 0.0,
808
+ "fisher_accum_count": 0,
809
+ "has_ewc_reference": true,
810
+ "weights_norm": 39.31961441040039,
811
+ "weights_w_mean": -0.0028808298520743847
812
+ },
813
+ "hypothesis": {
814
+ "classifier_trained": true,
815
+ "punishment_count": 0,
816
+ "success_count": 0,
817
+ "training_ready": false,
818
+ "buffer_size": 0,
819
+ "required_new_samples": 10,
820
+ "histogram_max": 0,
821
+ "time_counter": 250
822
+ }
823
+ },
824
+ {
825
+ "step": 20,
826
+ "epoch": 1,
827
+ "dataset": "TucanoBR/GigaVerbo",
828
+ "quality": {
829
+ "1.1_train_loss": -1.0,
830
+ "1.2_train_acc": 1.0,
831
+ "1.3_val_loss": -1.0,
832
+ "1.4_val_acc": 1.0,
833
+ "1.5_perplexity": 0.36787944123356736
834
+ },
835
+ "speed": {
836
+ "2.1_throughput_sps": 5.447693221340421,
837
+ "2.2_step_time_ms": 2937.022947129749,
838
+ "2.3_epoch_progress": 1.0,
839
+ "2.4_rss_mb": 1355.56640625,
840
+ "2.5_xeon_tflops": 1.7564614108881937
841
+ },
842
+ "kohonen": {
843
+ "sigma_t": 0.9954753752044792,
844
+ "alpha_t": 0.08146473164114146,
845
+ "t": 410,
846
+ "n_neurons": 864,
847
+ "fisher_w_mean": 0.0,
848
+ "fisher_w_max": 0.0,
849
+ "fisher_accum_count": 0,
850
+ "has_ewc_reference": true,
851
+ "weights_norm": 39.2965087890625,
852
+ "weights_w_mean": -0.0021961573511362076
853
+ },
854
+ "hypothesis": {
855
+ "classifier_trained": true,
856
+ "punishment_count": 0,
857
+ "success_count": 1,
858
+ "training_ready": true,
859
+ "buffer_size": 16,
860
+ "required_new_samples": 10,
861
+ "histogram_max": 16,
862
+ "time_counter": 266
863
+ }
864
+ },
865
+ {
866
+ "step": 21,
867
+ "epoch": 1,
868
+ "dataset": "TucanoBR/GigaVerbo",
869
+ "quality": {
870
+ "1.1_train_loss": -0.9842509842514764,
871
+ "1.2_train_acc": 0.96875,
872
+ "1.3_val_loss": -0.9842509842514764,
873
+ "1.4_val_acc": 0.96875,
874
+ "1.5_perplexity": 0.3737190436413242
875
+ },
876
+ "speed": {
877
+ "2.1_throughput_sps": 5.682624553426626,
878
+ "2.2_step_time_ms": 2815.600406039845,
879
+ "2.3_epoch_progress": 1.0,
880
+ "2.4_rss_mb": 1355.56640625,
881
+ "2.5_xeon_tflops": 1.7564614108881937
882
+ },
883
+ "kohonen": {
884
+ "sigma_t": 0.9954753752044792,
885
+ "alpha_t": 0.08146473164114146,
886
+ "t": 410,
887
+ "n_neurons": 864,
888
+ "fisher_w_mean": 0.0,
889
+ "fisher_w_max": 0.0,
890
+ "fisher_accum_count": 0,
891
+ "has_ewc_reference": true,
892
+ "weights_norm": 39.2965087890625,
893
+ "weights_w_mean": -0.0021961573511362076
894
+ },
895
+ "hypothesis": {
896
+ "classifier_trained": true,
897
+ "punishment_count": 1,
898
+ "success_count": 0,
899
+ "training_ready": true,
900
+ "buffer_size": 32,
901
+ "required_new_samples": 10,
902
+ "histogram_max": 32,
903
+ "time_counter": 282
904
+ }
905
+ },
906
+ {
907
+ "step": 22,
908
+ "epoch": 1,
909
+ "dataset": "TucanoBR/GigaVerbo",
910
+ "quality": {
911
+ "1.1_train_loss": -1.0,
912
+ "1.2_train_acc": 1.0,
913
+ "1.3_val_loss": -1.0,
914
+ "1.4_val_acc": 1.0,
915
+ "1.5_perplexity": 0.36787944123356736
916
+ },
917
+ "speed": {
918
+ "2.1_throughput_sps": 5.9395140188302635,
919
+ "2.2_step_time_ms": 2693.8230887703276,
920
+ "2.3_epoch_progress": 1.0,
921
+ "2.4_rss_mb": 1355.56640625,
922
+ "2.5_xeon_tflops": 1.7564614108881937
923
+ },
924
+ "kohonen": {
925
+ "sigma_t": 0.9954753752044792,
926
+ "alpha_t": 0.08146473164114146,
927
+ "t": 410,
928
+ "n_neurons": 864,
929
+ "fisher_w_mean": 0.0,
930
+ "fisher_w_max": 0.0,
931
+ "fisher_accum_count": 0,
932
+ "has_ewc_reference": true,
933
+ "weights_norm": 39.2965087890625,
934
+ "weights_w_mean": -0.0021961573511362076
935
+ },
936
+ "hypothesis": {
937
+ "classifier_trained": true,
938
+ "punishment_count": 0,
939
+ "success_count": 0,
940
+ "training_ready": false,
941
+ "buffer_size": 0,
942
+ "required_new_samples": 10,
943
+ "histogram_max": 0,
944
+ "time_counter": 298
945
+ }
946
+ },
947
+ {
948
+ "step": 23,
949
+ "epoch": 1,
950
+ "dataset": "TucanoBR/GigaVerbo",
951
+ "quality": {
952
+ "1.1_train_loss": -1.0,
953
+ "1.2_train_acc": 1.0,
954
+ "1.3_val_loss": -1.0,
955
+ "1.4_val_acc": 1.0,
956
+ "1.5_perplexity": 0.36787944123356736
957
+ },
958
+ "speed": {
959
+ "2.1_throughput_sps": 6.1975621347539835,
960
+ "2.2_step_time_ms": 2581.6602806250253,
961
+ "2.3_epoch_progress": 1.0,
962
+ "2.4_rss_mb": 1355.56640625,
963
+ "2.5_xeon_tflops": 1.7564614108881937
964
+ },
965
+ "kohonen": {
966
+ "sigma_t": 0.9954753752044792,
967
+ "alpha_t": 0.08146473164114146,
968
+ "t": 410,
969
+ "n_neurons": 864,
970
+ "fisher_w_mean": 0.0,
971
+ "fisher_w_max": 0.0,
972
+ "fisher_accum_count": 0,
973
+ "has_ewc_reference": true,
974
+ "weights_norm": 39.2965087890625,
975
+ "weights_w_mean": -0.0021961573511362076
976
+ },
977
+ "hypothesis": {
978
+ "classifier_trained": true,
979
+ "punishment_count": 0,
980
+ "success_count": 0,
981
+ "training_ready": false,
982
+ "buffer_size": 2,
983
+ "required_new_samples": 10,
984
+ "histogram_max": 2,
985
+ "time_counter": 300
986
+ }
987
+ },
988
+ {
989
+ "step": 24,
990
+ "epoch": 1,
991
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
992
+ "quality": {
993
+ "1.1_train_loss": -1.0,
994
+ "1.2_train_acc": 1.0,
995
+ "1.3_val_loss": -1.0,
996
+ "1.4_val_acc": 1.0,
997
+ "1.5_perplexity": 0.36787944123356736
998
+ },
999
+ "speed": {
1000
+ "2.1_throughput_sps": 6.450334826007024,
1001
+ "2.2_step_time_ms": 2480.4913902282715,
1002
+ "2.3_epoch_progress": 1.0,
1003
+ "2.4_rss_mb": 1355.56640625,
1004
+ "2.5_xeon_tflops": 1.7564614108881937
1005
+ },
1006
+ "kohonen": {
1007
+ "sigma_t": 0.9097959895689501,
1008
+ "alpha_t": 0.0778800783071405,
1009
+ "t": 500,
1010
+ "n_neurons": 864,
1011
+ "fisher_w_mean": 0.0,
1012
+ "fisher_w_max": 0.0,
1013
+ "fisher_accum_count": 0,
1014
+ "has_ewc_reference": true,
1015
+ "weights_norm": 39.14575958251953,
1016
+ "weights_w_mean": -0.0014829144347459078
1017
+ },
1018
+ "hypothesis": {
1019
+ "classifier_trained": true,
1020
+ "punishment_count": 0,
1021
+ "success_count": 1,
1022
+ "training_ready": true,
1023
+ "buffer_size": 18,
1024
+ "required_new_samples": 10,
1025
+ "histogram_max": 18,
1026
+ "time_counter": 316
1027
+ }
1028
+ },
1029
+ {
1030
+ "step": 25,
1031
+ "epoch": 1,
1032
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
1033
+ "quality": {
1034
+ "1.1_train_loss": -1.0,
1035
+ "1.2_train_acc": 1.0,
1036
+ "1.3_val_loss": -1.0,
1037
+ "1.4_val_acc": 1.0,
1038
+ "1.5_perplexity": 0.36787944123356736
1039
+ },
1040
+ "speed": {
1041
+ "2.1_throughput_sps": 6.70614747509385,
1042
+ "2.2_step_time_ms": 2385.8705850747915,
1043
+ "2.3_epoch_progress": 1.0,
1044
+ "2.4_rss_mb": 1355.56640625,
1045
+ "2.5_xeon_tflops": 1.7564614108881937
1046
+ },
1047
+ "kohonen": {
1048
+ "sigma_t": 0.9097959895689501,
1049
+ "alpha_t": 0.0778800783071405,
1050
+ "t": 500,
1051
+ "n_neurons": 864,
1052
+ "fisher_w_mean": 0.0,
1053
+ "fisher_w_max": 0.0,
1054
+ "fisher_accum_count": 0,
1055
+ "has_ewc_reference": true,
1056
+ "weights_norm": 39.14575958251953,
1057
+ "weights_w_mean": -0.0014829144347459078
1058
+ },
1059
+ "hypothesis": {
1060
+ "classifier_trained": true,
1061
+ "punishment_count": 0,
1062
+ "success_count": 2,
1063
+ "training_ready": true,
1064
+ "buffer_size": 34,
1065
+ "required_new_samples": 10,
1066
+ "histogram_max": 34,
1067
+ "time_counter": 332
1068
+ }
1069
+ },
1070
+ {
1071
+ "step": 26,
1072
+ "epoch": 1,
1073
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
1074
+ "quality": {
1075
+ "1.1_train_loss": -1.0,
1076
+ "1.2_train_acc": 1.0,
1077
+ "1.3_val_loss": -1.0,
1078
+ "1.4_val_acc": 1.0,
1079
+ "1.5_perplexity": 0.36787944123356736
1080
+ },
1081
+ "speed": {
1082
+ "2.1_throughput_sps": 6.961335475042744,
1083
+ "2.2_step_time_ms": 2298.409559108593,
1084
+ "2.3_epoch_progress": 1.0,
1085
+ "2.4_rss_mb": 1355.56640625,
1086
+ "2.5_xeon_tflops": 1.7564614108881937
1087
+ },
1088
+ "kohonen": {
1089
+ "sigma_t": 0.9097959895689501,
1090
+ "alpha_t": 0.0778800783071405,
1091
+ "t": 500,
1092
+ "n_neurons": 864,
1093
+ "fisher_w_mean": 0.0,
1094
+ "fisher_w_max": 0.0,
1095
+ "fisher_accum_count": 0,
1096
+ "has_ewc_reference": true,
1097
+ "weights_norm": 39.14575958251953,
1098
+ "weights_w_mean": -0.0014829144347459078
1099
+ },
1100
+ "hypothesis": {
1101
+ "classifier_trained": true,
1102
+ "punishment_count": 0,
1103
+ "success_count": 3,
1104
+ "training_ready": true,
1105
+ "buffer_size": 50,
1106
+ "required_new_samples": 10,
1107
+ "histogram_max": 50,
1108
+ "time_counter": 348
1109
+ }
1110
+ },
1111
+ {
1112
+ "step": 27,
1113
+ "epoch": 1,
1114
+ "dataset": "dominguesm/restore-punctuation-pttr-dataset",
1115
+ "quality": {
1116
+ "1.1_train_loss": -1.0,
1117
+ "1.2_train_acc": 1.0,
1118
+ "1.3_val_loss": -1.0,
1119
+ "1.4_val_acc": 1.0,
1120
+ "1.5_perplexity": 0.36787944123356736
1121
+ },
1122
+ "speed": {
1123
+ "2.1_throughput_sps": 7.217168280413297,
1124
+ "2.2_step_time_ms": 2216.935975211007,
1125
+ "2.3_epoch_progress": 1.0,
1126
+ "2.4_rss_mb": 1355.56640625,
1127
+ "2.5_xeon_tflops": 1.7564614108881937
1128
+ },
1129
+ "kohonen": {
1130
+ "sigma_t": 0.9097959895689501,
1131
+ "alpha_t": 0.0778800783071405,
1132
+ "t": 500,
1133
+ "n_neurons": 864,
1134
+ "fisher_w_mean": 0.0,
1135
+ "fisher_w_max": 0.0,
1136
+ "fisher_accum_count": 0,
1137
+ "has_ewc_reference": true,
1138
+ "weights_norm": 39.14575958251953,
1139
+ "weights_w_mean": -0.0014829144347459078
1140
+ },
1141
+ "hypothesis": {
1142
+ "classifier_trained": true,
1143
+ "punishment_count": 0,
1144
+ "success_count": 4,
1145
+ "training_ready": true,
1146
+ "buffer_size": 52,
1147
+ "required_new_samples": 10,
1148
+ "histogram_max": 52,
1149
+ "time_counter": 350
1150
+ }
1151
+ },
1152
+ {
1153
+ "step": 28,
1154
+ "epoch": 1,
1155
+ "dataset": "Madras1/corpus-ptbr-v2",
1156
+ "quality": {
1157
+ "1.1_train_loss": -0.9926198253344827,
1158
+ "1.2_train_acc": 0.9852941176470589,
1159
+ "1.3_val_loss": -0.9926198253344827,
1160
+ "1.4_val_acc": 0.9852941176470589,
1161
+ "1.5_perplexity": 0.37060449909797594
1162
+ },
1163
+ "speed": {
1164
+ "2.1_throughput_sps": 6.457592050282572,
1165
+ "2.2_step_time_ms": 2477.703743967517,
1166
+ "2.3_epoch_progress": 1.0,
1167
+ "2.4_rss_mb": 1355.56640625,
1168
+ "2.5_xeon_tflops": 1.7564614108881937
1169
+ },
1170
+ "kohonen": {
1171
+ "sigma_t": 0.9097959895689501,
1172
+ "alpha_t": 0.0778800783071405,
1173
+ "t": 500,
1174
+ "n_neurons": 864,
1175
+ "fisher_w_mean": 0.0,
1176
+ "fisher_w_max": 0.0,
1177
+ "fisher_accum_count": 0,
1178
+ "has_ewc_reference": true,
1179
+ "weights_norm": 39.14575958251953,
1180
+ "weights_w_mean": -0.0014829144347459078
1181
+ },
1182
+ "hypothesis": {
1183
+ "classifier_trained": true,
1184
+ "punishment_count": 1,
1185
+ "success_count": 0,
1186
+ "training_ready": true,
1187
+ "buffer_size": 68,
1188
+ "required_new_samples": 10,
1189
+ "histogram_max": 68,
1190
+ "time_counter": 366
1191
+ }
1192
+ },
1193
+ {
1194
+ "step": 29,
1195
+ "epoch": 1,
1196
+ "dataset": "Madras1/corpus-ptbr-v2",
1197
+ "quality": {
1198
+ "1.1_train_loss": -1.0,
1199
+ "1.2_train_acc": 1.0,
1200
+ "1.3_val_loss": -1.0,
1201
+ "1.4_val_acc": 1.0,
1202
+ "1.5_perplexity": 0.36787944123356736
1203
+ },
1204
+ "speed": {
1205
+ "2.1_throughput_sps": 6.678104497695096,
1206
+ "2.2_step_time_ms": 2395.889433224996,
1207
+ "2.3_epoch_progress": 1.0,
1208
+ "2.4_rss_mb": 1355.56640625,
1209
+ "2.5_xeon_tflops": 1.7564614108881937
1210
+ },
1211
+ "kohonen": {
1212
+ "sigma_t": 0.9097959895689501,
1213
+ "alpha_t": 0.0778800783071405,
1214
+ "t": 500,
1215
+ "n_neurons": 864,
1216
+ "fisher_w_mean": 0.0,
1217
+ "fisher_w_max": 0.0,
1218
+ "fisher_accum_count": 0,
1219
+ "has_ewc_reference": true,
1220
+ "weights_norm": 39.14575958251953,
1221
+ "weights_w_mean": -0.0014829144347459078
1222
+ },
1223
+ "hypothesis": {
1224
+ "classifier_trained": true,
1225
+ "punishment_count": 0,
1226
+ "success_count": 0,
1227
+ "training_ready": false,
1228
+ "buffer_size": 0,
1229
+ "required_new_samples": 10,
1230
+ "histogram_max": 0,
1231
+ "time_counter": 382
1232
+ }
1233
+ },
1234
+ {
1235
+ "step": 30,
1236
+ "epoch": 1,
1237
+ "dataset": "Madras1/corpus-ptbr-v2",
1238
+ "quality": {
1239
+ "1.1_train_loss": -1.0,
1240
+ "1.2_train_acc": 1.0,
1241
+ "1.3_val_loss": -1.0,
1242
+ "1.4_val_acc": 1.0,
1243
+ "1.5_perplexity": 0.36787944123356736
1244
+ },
1245
+ "speed": {
1246
+ "2.1_throughput_sps": 6.895147106551538,
1247
+ "2.2_step_time_ms": 2320.4726096122495,
1248
+ "2.3_epoch_progress": 1.0,
1249
+ "2.4_rss_mb": 1355.56640625,
1250
+ "2.5_xeon_tflops": 1.7564614108881937
1251
+ },
1252
+ "kohonen": {
1253
+ "sigma_t": 0.8398475498481031,
1254
+ "alpha_t": 0.07482635675785652,
1255
+ "t": 580,
1256
+ "n_neurons": 864,
1257
+ "fisher_w_mean": 0.0,
1258
+ "fisher_w_max": 0.0,
1259
+ "fisher_accum_count": 0,
1260
+ "has_ewc_reference": true,
1261
+ "weights_norm": 39.139549255371094,
1262
+ "weights_w_mean": -0.0007873232825659215
1263
+ },
1264
+ "hypothesis": {
1265
+ "classifier_trained": true,
1266
+ "punishment_count": 0,
1267
+ "success_count": 1,
1268
+ "training_ready": true,
1269
+ "buffer_size": 16,
1270
+ "required_new_samples": 10,
1271
+ "histogram_max": 16,
1272
+ "time_counter": 398
1273
+ }
1274
+ },
1275
+ {
1276
+ "step": 31,
1277
+ "epoch": 1,
1278
+ "dataset": "Madras1/corpus-ptbr-v2",
1279
+ "quality": {
1280
+ "1.1_train_loss": -0.97182531580755,
1281
+ "1.2_train_acc": 0.9444444444444444,
1282
+ "1.3_val_loss": -0.97182531580755,
1283
+ "1.4_val_acc": 0.9444444444444444,
1284
+ "1.5_perplexity": 0.3783917230298394
1285
+ },
1286
+ "speed": {
1287
+ "2.1_throughput_sps": 7.089719654239448,
1288
+ "2.2_step_time_ms": 2256.7888125777245,
1289
+ "2.3_epoch_progress": 1.0,
1290
+ "2.4_rss_mb": 1355.56640625,
1291
+ "2.5_xeon_tflops": 1.7564614108881937
1292
+ },
1293
+ "kohonen": {
1294
+ "sigma_t": 0.8398475498481031,
1295
+ "alpha_t": 0.07482635675785652,
1296
+ "t": 580,
1297
+ "n_neurons": 864,
1298
+ "fisher_w_mean": 0.0,
1299
+ "fisher_w_max": 0.0,
1300
+ "fisher_accum_count": 0,
1301
+ "has_ewc_reference": true,
1302
+ "weights_norm": 39.139549255371094,
1303
+ "weights_w_mean": -0.0007873232825659215
1304
+ },
1305
+ "hypothesis": {
1306
+ "classifier_trained": true,
1307
+ "punishment_count": 1,
1308
+ "success_count": 0,
1309
+ "training_ready": true,
1310
+ "buffer_size": 18,
1311
+ "required_new_samples": 10,
1312
+ "histogram_max": 18,
1313
+ "time_counter": 400
1314
+ }
1315
+ },
1316
+ {
1317
+ "step": 32,
1318
+ "epoch": 1,
1319
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
1320
+ "quality": {
1321
+ "1.1_train_loss": -1.0,
1322
+ "1.2_train_acc": 1.0,
1323
+ "1.3_val_loss": -1.0,
1324
+ "1.4_val_acc": 1.0,
1325
+ "1.5_perplexity": 0.36787944123356736
1326
+ },
1327
+ "speed": {
1328
+ "2.1_throughput_sps": 6.05238983408022,
1329
+ "2.2_step_time_ms": 2643.583846814705,
1330
+ "2.3_epoch_progress": 1.0,
1331
+ "2.4_rss_mb": 1361.140625,
1332
+ "2.5_xeon_tflops": 1.7564614108881937
1333
+ },
1334
+ "kohonen": {
1335
+ "sigma_t": 0.8398475498481031,
1336
+ "alpha_t": 0.07482635675785652,
1337
+ "t": 580,
1338
+ "n_neurons": 864,
1339
+ "fisher_w_mean": 0.0,
1340
+ "fisher_w_max": 0.0,
1341
+ "fisher_accum_count": 0,
1342
+ "has_ewc_reference": true,
1343
+ "weights_norm": 39.139549255371094,
1344
+ "weights_w_mean": -0.0007873232825659215
1345
+ },
1346
+ "hypothesis": {
1347
+ "classifier_trained": true,
1348
+ "punishment_count": 0,
1349
+ "success_count": 0,
1350
+ "training_ready": false,
1351
+ "buffer_size": 0,
1352
+ "required_new_samples": 10,
1353
+ "histogram_max": 0,
1354
+ "time_counter": 416
1355
+ }
1356
+ },
1357
+ {
1358
+ "step": 33,
1359
+ "epoch": 1,
1360
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
1361
+ "quality": {
1362
+ "1.1_train_loss": -1.0,
1363
+ "1.2_train_acc": 1.0,
1364
+ "1.3_val_loss": -1.0,
1365
+ "1.4_val_acc": 1.0,
1366
+ "1.5_perplexity": 0.36787944123356736
1367
+ },
1368
+ "speed": {
1369
+ "2.1_throughput_sps": 6.234089280159213,
1370
+ "2.2_step_time_ms": 2566.5336636935963,
1371
+ "2.3_epoch_progress": 1.0,
1372
+ "2.4_rss_mb": 1361.140625,
1373
+ "2.5_xeon_tflops": 1.7564614108881937
1374
+ },
1375
+ "kohonen": {
1376
+ "sigma_t": 0.7752770017375488,
1377
+ "alpha_t": 0.07189237334319262,
1378
+ "t": 660,
1379
+ "n_neurons": 864,
1380
+ "fisher_w_mean": 0.0,
1381
+ "fisher_w_max": 0.0,
1382
+ "fisher_accum_count": 0,
1383
+ "has_ewc_reference": true,
1384
+ "weights_norm": 39.1356201171875,
1385
+ "weights_w_mean": -0.000526978459674865
1386
+ },
1387
+ "hypothesis": {
1388
+ "classifier_trained": true,
1389
+ "punishment_count": 0,
1390
+ "success_count": 1,
1391
+ "training_ready": true,
1392
+ "buffer_size": 16,
1393
+ "required_new_samples": 10,
1394
+ "histogram_max": 16,
1395
+ "time_counter": 432
1396
+ }
1397
+ },
1398
+ {
1399
+ "step": 34,
1400
+ "epoch": 1,
1401
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
1402
+ "quality": {
1403
+ "1.1_train_loss": -1.0,
1404
+ "1.2_train_acc": 1.0,
1405
+ "1.3_val_loss": -1.0,
1406
+ "1.4_val_acc": 1.0,
1407
+ "1.5_perplexity": 0.36787944123356736
1408
+ },
1409
+ "speed": {
1410
+ "2.1_throughput_sps": 6.416003365677337,
1411
+ "2.2_step_time_ms": 2493.7642778669083,
1412
+ "2.3_epoch_progress": 1.0,
1413
+ "2.4_rss_mb": 1361.140625,
1414
+ "2.5_xeon_tflops": 1.7564614108881937
1415
+ },
1416
+ "kohonen": {
1417
+ "sigma_t": 0.7752770017375488,
1418
+ "alpha_t": 0.07189237334319262,
1419
+ "t": 660,
1420
+ "n_neurons": 864,
1421
+ "fisher_w_mean": 0.0,
1422
+ "fisher_w_max": 0.0,
1423
+ "fisher_accum_count": 0,
1424
+ "has_ewc_reference": true,
1425
+ "weights_norm": 39.1356201171875,
1426
+ "weights_w_mean": -0.000526978459674865
1427
+ },
1428
+ "hypothesis": {
1429
+ "classifier_trained": true,
1430
+ "punishment_count": 0,
1431
+ "success_count": 2,
1432
+ "training_ready": true,
1433
+ "buffer_size": 32,
1434
+ "required_new_samples": 10,
1435
+ "histogram_max": 32,
1436
+ "time_counter": 448
1437
+ }
1438
+ },
1439
+ {
1440
+ "step": 35,
1441
+ "epoch": 1,
1442
+ "dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
1443
+ "quality": {
1444
+ "1.1_train_loss": -1.0,
1445
+ "1.2_train_acc": 1.0,
1446
+ "1.3_val_loss": -1.0,
1447
+ "1.4_val_acc": 1.0,
1448
+ "1.5_perplexity": 0.36787944123356736
1449
+ },
1450
+ "speed": {
1451
+ "2.1_throughput_sps": 6.59676821040271,
1452
+ "2.2_step_time_ms": 2425.43007267846,
1453
+ "2.3_epoch_progress": 1.0,
1454
+ "2.4_rss_mb": 1361.140625,
1455
+ "2.5_xeon_tflops": 1.7564614108881937
1456
+ },
1457
+ "kohonen": {
1458
+ "sigma_t": 0.7752770017375488,
1459
+ "alpha_t": 0.07189237334319262,
1460
+ "t": 660,
1461
+ "n_neurons": 864,
1462
+ "fisher_w_mean": 0.0,
1463
+ "fisher_w_max": 0.0,
1464
+ "fisher_accum_count": 0,
1465
+ "has_ewc_reference": true,
1466
+ "weights_norm": 39.1356201171875,
1467
+ "weights_w_mean": -0.000526978459674865
1468
+ },
1469
+ "hypothesis": {
1470
+ "classifier_trained": true,
1471
+ "punishment_count": 0,
1472
+ "success_count": 3,
1473
+ "training_ready": true,
1474
+ "buffer_size": 34,
1475
+ "required_new_samples": 10,
1476
+ "histogram_max": 34,
1477
+ "time_counter": 450
1478
+ }
1479
+ },
1480
+ {
1481
+ "step": 36,
1482
+ "epoch": 1,
1483
+ "dataset": "nvidia/OpenMathInstruct-2",
1484
+ "quality": {
1485
+ "1.1_train_loss": -1.0,
1486
+ "1.2_train_acc": 1.0,
1487
+ "1.3_val_loss": -1.0,
1488
+ "1.4_val_acc": 1.0,
1489
+ "1.5_perplexity": 0.36787944123356736
1490
+ },
1491
+ "speed": {
1492
+ "2.1_throughput_sps": 6.205300501987162,
1493
+ "2.2_step_time_ms": 2578.4408015173835,
1494
+ "2.3_epoch_progress": 1.0,
1495
+ "2.4_rss_mb": 1400.0,
1496
+ "2.5_xeon_tflops": 1.7564614108881937
1497
+ },
1498
+ "kohonen": {
1499
+ "sigma_t": 0.7752770017375488,
1500
+ "alpha_t": 0.07189237334319262,
1501
+ "t": 660,
1502
+ "n_neurons": 864,
1503
+ "fisher_w_mean": 0.0,
1504
+ "fisher_w_max": 0.0,
1505
+ "fisher_accum_count": 0,
1506
+ "has_ewc_reference": true,
1507
+ "weights_norm": 39.1356201171875,
1508
+ "weights_w_mean": -0.000526978459674865
1509
+ },
1510
+ "hypothesis": {
1511
+ "classifier_trained": true,
1512
+ "punishment_count": 0,
1513
+ "success_count": 4,
1514
+ "training_ready": true,
1515
+ "buffer_size": 50,
1516
+ "required_new_samples": 10,
1517
+ "histogram_max": 50,
1518
+ "time_counter": 466
1519
+ }
1520
+ },
1521
+ {
1522
+ "step": 37,
1523
+ "epoch": 1,
1524
+ "dataset": "nvidia/OpenMathInstruct-2",
1525
+ "quality": {
1526
+ "1.1_train_loss": -1.0,
1527
+ "1.2_train_acc": 1.0,
1528
+ "1.3_val_loss": -1.0,
1529
+ "1.4_val_acc": 1.0,
1530
+ "1.5_perplexity": 0.36787944123356736
1531
+ },
1532
+ "speed": {
1533
+ "2.1_throughput_sps": 6.370995165925777,
1534
+ "2.2_step_time_ms": 2511.381594758285,
1535
+ "2.3_epoch_progress": 1.0,
1536
+ "2.4_rss_mb": 1400.0,
1537
+ "2.5_xeon_tflops": 1.7564614108881937
1538
+ },
1539
+ "kohonen": {
1540
+ "sigma_t": 0.7752770017375488,
1541
+ "alpha_t": 0.07189237334319262,
1542
+ "t": 660,
1543
+ "n_neurons": 864,
1544
+ "fisher_w_mean": 0.0,
1545
+ "fisher_w_max": 0.0,
1546
+ "fisher_accum_count": 0,
1547
+ "has_ewc_reference": true,
1548
+ "weights_norm": 39.1356201171875,
1549
+ "weights_w_mean": -0.000526978459674865
1550
+ },
1551
+ "hypothesis": {
1552
+ "classifier_trained": true,
1553
+ "punishment_count": 0,
1554
+ "success_count": 5,
1555
+ "training_ready": true,
1556
+ "buffer_size": 66,
1557
+ "required_new_samples": 10,
1558
+ "histogram_max": 66,
1559
+ "time_counter": 482
1560
+ }
1561
+ },
1562
+ {
1563
+ "step": 38,
1564
+ "epoch": 1,
1565
+ "dataset": "nvidia/OpenMathInstruct-2",
1566
+ "quality": {
1567
+ "1.1_train_loss": -0.9938837346736189,
1568
+ "1.2_train_acc": 0.9878048780487805,
1569
+ "1.3_val_loss": -0.9938837346736189,
1570
+ "1.4_val_acc": 0.9878048780487805,
1571
+ "1.5_perplexity": 0.37013638450004166
1572
+ },
1573
+ "speed": {
1574
+ "2.1_throughput_sps": 6.51479068261107,
1575
+ "2.2_step_time_ms": 2455.9499728373994,
1576
+ "2.3_epoch_progress": 1.0,
1577
+ "2.4_rss_mb": 1400.0,
1578
+ "2.5_xeon_tflops": 1.7564614108881937
1579
+ },
1580
+ "kohonen": {
1581
+ "sigma_t": 0.7752770017375488,
1582
+ "alpha_t": 0.07189237334319262,
1583
+ "t": 660,
1584
+ "n_neurons": 864,
1585
+ "fisher_w_mean": 0.0,
1586
+ "fisher_w_max": 0.0,
1587
+ "fisher_accum_count": 0,
1588
+ "has_ewc_reference": true,
1589
+ "weights_norm": 39.1356201171875,
1590
+ "weights_w_mean": -0.000526978459674865
1591
+ },
1592
+ "hypothesis": {
1593
+ "classifier_trained": true,
1594
+ "punishment_count": 1,
1595
+ "success_count": 0,
1596
+ "training_ready": true,
1597
+ "buffer_size": 82,
1598
+ "required_new_samples": 10,
1599
+ "histogram_max": 82,
1600
+ "time_counter": 498
1601
+ }
1602
+ },
1603
+ {
1604
+ "step": 39,
1605
+ "epoch": 1,
1606
+ "dataset": "nvidia/OpenMathInstruct-2",
1607
+ "quality": {
1608
+ "1.1_train_loss": -1.0,
1609
+ "1.2_train_acc": 1.0,
1610
+ "1.3_val_loss": -1.0,
1611
+ "1.4_val_acc": 1.0,
1612
+ "1.5_perplexity": 0.36787944123356736
1613
+ },
1614
+ "speed": {
1615
+ "2.1_throughput_sps": 6.678818935823154,
1616
+ "2.2_step_time_ms": 2395.633143186569,
1617
+ "2.3_epoch_progress": 1.0,
1618
+ "2.4_rss_mb": 1400.0,
1619
+ "2.5_xeon_tflops": 1.7564614108881937
1620
+ },
1621
+ "kohonen": {
1622
+ "sigma_t": 0.7752770017375488,
1623
+ "alpha_t": 0.07189237334319262,
1624
+ "t": 660,
1625
+ "n_neurons": 864,
1626
+ "fisher_w_mean": 0.0,
1627
+ "fisher_w_max": 0.0,
1628
+ "fisher_accum_count": 0,
1629
+ "has_ewc_reference": true,
1630
+ "weights_norm": 39.1356201171875,
1631
+ "weights_w_mean": -0.000526978459674865
1632
+ },
1633
+ "hypothesis": {
1634
+ "classifier_trained": true,
1635
+ "punishment_count": 0,
1636
+ "success_count": 0,
1637
+ "training_ready": false,
1638
+ "buffer_size": 0,
1639
+ "required_new_samples": 10,
1640
+ "histogram_max": 0,
1641
+ "time_counter": 500
1642
+ }
1643
+ }
1644
+ ],
1645
+ "summary": {
1646
+ "n_steps": 40,
1647
+ "final_loss": -1.0,
1648
+ "mean_loss": -0.9971289930033563,
1649
+ "min_loss": -1.0,
1650
+ "max_loss": -0.97182531580755,
1651
+ "final_acc": 1.0,
1652
+ "mean_acc": 0.9943146720070143,
1653
+ "sigma_start": 1.3846745195799537,
1654
+ "sigma_end": 0.7752770017375488,
1655
+ "alpha_start": 0.09607894391523232,
1656
+ "alpha_end": 0.07189237334319262,
1657
+ "rss_max_mb": 1400.0,
1658
+ "rss_final_mb": 1400.0,
1659
+ "rss_trend": "stable",
1660
+ "n_alerts": 39,
1661
+ "alerts": [
1662
+ {
1663
+ "type": "3.3_loss_vanishing",
1664
+ "step": 1,
1665
+ "value": -0.9842509842514764
1666
+ },
1667
+ {
1668
+ "type": "3.3_loss_vanishing",
1669
+ "step": 2,
1670
+ "value": -1.0
1671
+ },
1672
+ {
1673
+ "type": "3.3_loss_vanishing",
1674
+ "step": 3,
1675
+ "value": -1.0
1676
+ },
1677
+ {
1678
+ "type": "3.3_loss_vanishing",
1679
+ "step": 4,
1680
+ "value": -1.0
1681
+ },
1682
+ {
1683
+ "type": "3.3_loss_vanishing",
1684
+ "step": 5,
1685
+ "value": -1.0
1686
+ },
1687
+ {
1688
+ "type": "3.3_loss_vanishing",
1689
+ "step": 6,
1690
+ "value": -1.0
1691
+ },
1692
+ {
1693
+ "type": "3.3_loss_vanishing",
1694
+ "step": 7,
1695
+ "value": -1.0
1696
+ },
1697
+ {
1698
+ "type": "3.3_loss_vanishing",
1699
+ "step": 8,
1700
+ "value": -0.9926198253344827
1701
+ },
1702
+ {
1703
+ "type": "3.3_loss_vanishing",
1704
+ "step": 9,
1705
+ "value": -1.0
1706
+ },
1707
+ {
1708
+ "type": "3.3_loss_vanishing",
1709
+ "step": 10,
1710
+ "value": -1.0
1711
+ },
1712
+ {
1713
+ "type": "3.3_loss_vanishing",
1714
+ "step": 11,
1715
+ "value": -0.97182531580755
1716
+ },
1717
+ {
1718
+ "type": "3.3_loss_vanishing",
1719
+ "step": 12,
1720
+ "value": -1.0
1721
+ },
1722
+ {
1723
+ "type": "3.3_loss_vanishing",
1724
+ "step": 13,
1725
+ "value": -1.0
1726
+ },
1727
+ {
1728
+ "type": "3.3_loss_vanishing",
1729
+ "step": 14,
1730
+ "value": -1.0
1731
+ },
1732
+ {
1733
+ "type": "3.3_loss_vanishing",
1734
+ "step": 15,
1735
+ "value": -1.0
1736
+ },
1737
+ {
1738
+ "type": "3.3_loss_vanishing",
1739
+ "step": 16,
1740
+ "value": -1.0
1741
+ },
1742
+ {
1743
+ "type": "3.3_loss_vanishing",
1744
+ "step": 17,
1745
+ "value": -1.0
1746
+ },
1747
+ {
1748
+ "type": "3.3_loss_vanishing",
1749
+ "step": 18,
1750
+ "value": -0.9938837346736189
1751
+ },
1752
+ {
1753
+ "type": "3.3_loss_vanishing",
1754
+ "step": 19,
1755
+ "value": -1.0
1756
+ },
1757
+ {
1758
+ "type": "3.3_loss_vanishing",
1759
+ "step": 20,
1760
+ "value": -1.0
1761
+ }
1762
+ ],
1763
+ "kohonen_final": {
1764
+ "sigma_t": 0.7752770017375488,
1765
+ "alpha_t": 0.07189237334319262,
1766
+ "t": 660,
1767
+ "n_neurons": 864,
1768
+ "fisher_w_mean": 0.0,
1769
+ "fisher_w_max": 0.0,
1770
+ "fisher_accum_count": 0,
1771
+ "has_ewc_reference": true,
1772
+ "weights_norm": 39.1356201171875,
1773
+ "weights_w_mean": -0.000526978459674865
1774
+ },
1775
+ "hypothesis_final": {
1776
+ "classifier_trained": true,
1777
+ "punishment_count": 0,
1778
+ "success_count": 0,
1779
+ "training_ready": false,
1780
+ "buffer_size": 0,
1781
+ "required_new_samples": 10,
1782
+ "histogram_max": 0,
1783
+ "time_counter": 500
1784
+ }
1785
+ },
1786
+ "alerts": [
1787
+ {
1788
+ "type": "3.3_loss_vanishing",
1789
+ "step": 1,
1790
+ "value": -0.9842509842514764
1791
+ },
1792
+ {
1793
+ "type": "3.3_loss_vanishing",
1794
+ "step": 2,
1795
+ "value": -1.0
1796
+ },
1797
+ {
1798
+ "type": "3.3_loss_vanishing",
1799
+ "step": 3,
1800
+ "value": -1.0
1801
+ },
1802
+ {
1803
+ "type": "3.3_loss_vanishing",
1804
+ "step": 4,
1805
+ "value": -1.0
1806
+ },
1807
+ {
1808
+ "type": "3.3_loss_vanishing",
1809
+ "step": 5,
1810
+ "value": -1.0
1811
+ },
1812
+ {
1813
+ "type": "3.3_loss_vanishing",
1814
+ "step": 6,
1815
+ "value": -1.0
1816
+ },
1817
+ {
1818
+ "type": "3.3_loss_vanishing",
1819
+ "step": 7,
1820
+ "value": -1.0
1821
+ },
1822
+ {
1823
+ "type": "3.3_loss_vanishing",
1824
+ "step": 8,
1825
+ "value": -0.9926198253344827
1826
+ },
1827
+ {
1828
+ "type": "3.3_loss_vanishing",
1829
+ "step": 9,
1830
+ "value": -1.0
1831
+ },
1832
+ {
1833
+ "type": "3.3_loss_vanishing",
1834
+ "step": 10,
1835
+ "value": -1.0
1836
+ },
1837
+ {
1838
+ "type": "3.3_loss_vanishing",
1839
+ "step": 11,
1840
+ "value": -0.97182531580755
1841
+ },
1842
+ {
1843
+ "type": "3.3_loss_vanishing",
1844
+ "step": 12,
1845
+ "value": -1.0
1846
+ },
1847
+ {
1848
+ "type": "3.3_loss_vanishing",
1849
+ "step": 13,
1850
+ "value": -1.0
1851
+ },
1852
+ {
1853
+ "type": "3.3_loss_vanishing",
1854
+ "step": 14,
1855
+ "value": -1.0
1856
+ },
1857
+ {
1858
+ "type": "3.3_loss_vanishing",
1859
+ "step": 15,
1860
+ "value": -1.0
1861
+ },
1862
+ {
1863
+ "type": "3.3_loss_vanishing",
1864
+ "step": 16,
1865
+ "value": -1.0
1866
+ },
1867
+ {
1868
+ "type": "3.3_loss_vanishing",
1869
+ "step": 17,
1870
+ "value": -1.0
1871
+ },
1872
+ {
1873
+ "type": "3.3_loss_vanishing",
1874
+ "step": 18,
1875
+ "value": -0.9938837346736189
1876
+ },
1877
+ {
1878
+ "type": "3.3_loss_vanishing",
1879
+ "step": 19,
1880
+ "value": -1.0
1881
+ },
1882
+ {
1883
+ "type": "3.3_loss_vanishing",
1884
+ "step": 20,
1885
+ "value": -1.0
1886
+ },
1887
+ {
1888
+ "type": "3.3_loss_vanishing",
1889
+ "step": 21,
1890
+ "value": -0.9842509842514764
1891
+ },
1892
+ {
1893
+ "type": "3.3_loss_vanishing",
1894
+ "step": 22,
1895
+ "value": -1.0
1896
+ },
1897
+ {
1898
+ "type": "3.3_loss_vanishing",
1899
+ "step": 23,
1900
+ "value": -1.0
1901
+ },
1902
+ {
1903
+ "type": "3.3_loss_vanishing",
1904
+ "step": 24,
1905
+ "value": -1.0
1906
+ },
1907
+ {
1908
+ "type": "3.3_loss_vanishing",
1909
+ "step": 25,
1910
+ "value": -1.0
1911
+ },
1912
+ {
1913
+ "type": "3.3_loss_vanishing",
1914
+ "step": 26,
1915
+ "value": -1.0
1916
+ },
1917
+ {
1918
+ "type": "3.3_loss_vanishing",
1919
+ "step": 27,
1920
+ "value": -1.0
1921
+ },
1922
+ {
1923
+ "type": "3.3_loss_vanishing",
1924
+ "step": 28,
1925
+ "value": -0.9926198253344827
1926
+ },
1927
+ {
1928
+ "type": "3.3_loss_vanishing",
1929
+ "step": 29,
1930
+ "value": -1.0
1931
+ },
1932
+ {
1933
+ "type": "3.3_loss_vanishing",
1934
+ "step": 30,
1935
+ "value": -1.0
1936
+ },
1937
+ {
1938
+ "type": "3.3_loss_vanishing",
1939
+ "step": 31,
1940
+ "value": -0.97182531580755
1941
+ },
1942
+ {
1943
+ "type": "3.3_loss_vanishing",
1944
+ "step": 32,
1945
+ "value": -1.0
1946
+ },
1947
+ {
1948
+ "type": "3.3_loss_vanishing",
1949
+ "step": 33,
1950
+ "value": -1.0
1951
+ },
1952
+ {
1953
+ "type": "3.3_loss_vanishing",
1954
+ "step": 34,
1955
+ "value": -1.0
1956
+ },
1957
+ {
1958
+ "type": "3.3_loss_vanishing",
1959
+ "step": 35,
1960
+ "value": -1.0
1961
+ },
1962
+ {
1963
+ "type": "3.3_loss_vanishing",
1964
+ "step": 36,
1965
+ "value": -1.0
1966
+ },
1967
+ {
1968
+ "type": "3.3_loss_vanishing",
1969
+ "step": 37,
1970
+ "value": -1.0
1971
+ },
1972
+ {
1973
+ "type": "3.3_loss_vanishing",
1974
+ "step": 38,
1975
+ "value": -0.9938837346736189
1976
+ },
1977
+ {
1978
+ "type": "3.3_loss_vanishing",
1979
+ "step": 39,
1980
+ "value": -1.0
1981
+ }
1982
+ ]
1983
+ }