File size: 4,814 Bytes
547ac30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""Create plain Markdown, JSON and CSV per-operation evaluation after training.
Never fabricate metrics for missing stages. No checkpoint required to run this reporter.
"""
from pathlib import Path
import argparse,csv,json,sys
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/'src'))
from config import VARIANT
from architecture import count_all

def main():
 p=argparse.ArgumentParser();p.add_argument('--quick',action='store_true');a=p.parse_args()
 out=ROOT/'reports';out.mkdir(exist_ok=True)
 counts=count_all()
 rows=[];missing=[]
 def add(family,split,target,m,source):
  if not isinstance(m,dict):return
  rows.append({'variant':VARIANT,'family':family,'split':split,'target':target,'count':m.get('count',m.get('n',m.get('program_count',''))),
    'MAPE_pct':m.get('MAPE_pct',''),'WAPE_pct':m.get('WAPE_pct',''),'MSE':m.get('MSE',''),
    'R2':m.get('R2',''),'MAE':m.get('MAE',''),'source':source})
 src=out/'trained'/'metrics.json'
 if src.exists():
  d=json.loads(src.read_text());sm={'fdm':'FDM','cnc_milling':'Milling','cnc_turning':'Turning','cnc_drilling':'Drilling/Boring/Reaming/Tapping',
    'cnc_grinding':'Grinding','cnc_sawing':'Sawing','cnc_laser':'Laser','cnc_plasma':'Plasma'}
  for sp,modes in d.get('scores',{}).items():
   for k,targets in modes.items():
    for target,mm in targets.items():
     if isinstance(mm,dict) and target in ('time_s','energy_Wh','material_g'):
      add(sm.get(k,k),sp,target,mm,'manufacturing')
  for sp,groups in d.get('grouped_scores',{}).items():
   for k,targets in groups.items():
    for target,mm in targets.items():
     if isinstance(mm,dict) and target in ('time_s','energy_Wh','material_g'):
      add(k,sp,target,mm,'manufacturing_group')
 else:missing.append(str(src.relative_to(ROOT)))
 src=out/'robotics'/'metrics.json'
 if src.exists():
  d=json.loads(src.read_text());
  for sp,targets in d.get('results',{}).items():
   for k in ('duration_s','energy_Wh','cold_energy_Wh'):
    if k in targets:add('General Robotics',sp,k,targets[k],'robotics')
 else:missing.append(str(src.relative_to(ROOT)))
 src=out/'gmaw'/'metrics.json'
 if src.exists():
  d=json.loads(src.read_text());
  for sp,targets in d.get('results',{}).items():
   for k,mm in targets.items():
    if isinstance(mm,dict) and 'MAPE_pct' in mm:add('GMAW',sp,k,mm,'gmaw')
 else:missing.append(str(src.relative_to(ROOT)))
 for family,sub in [('RSW','rsw'),('TIG','tig')]:
  src=out/sub/'metrics.json'
  if src.exists():
   d=json.loads(src.read_text())
   for sp,targets in d.get('splits',{}).items():
    for k,mm in targets.items():
     if isinstance(mm,dict) and 'MAPE_pct' in mm:add(family,sp,k,mm,family.lower())
  else:missing.append(str(src.relative_to(ROOT)))
 fields=['variant','family','split','target','count','MAPE_pct','WAPE_pct','MSE','R2','MAE','source']
 with (out/'metrics.csv').open('w',newline='',encoding='utf-8') as f:
  w=csv.DictWriter(f,fieldnames=fields);w.writeheader();w.writerows(rows)
 report={'version':'1.0','variant':VARIANT,'synthetic_simulator_warning':True,'quick_undertrained':a.quick,
  'architecture_parameters':counts,'metrics_rows':len(rows),'incomplete_stage_reports':missing,
  'validation_model_selection':'train scripts use validation; test/OOD are audits only',
  'no_pretrained_checkpoint':'training initializes from random weights only',
  'weights_not_shared_between_general_robot_gmaw_rsw_tig':True}
 (out/'training_report.json').write_text(json.dumps(report,indent=2,ensure_ascii=False),encoding='utf-8')
 ls=[f'# Manufacturing-MoE Normal {VARIANT.upper()} — eğitim raporu', '',
     '**UYARI:** Sentetik fizik simülasyonu; gerçek makine doğruluğu değildir. '+('QUICK deneme sonuçları üretim metriği değildir.' if a.quick else ''),
     '',f"**Öğrenilebilir parametre:** {counts['total_parameters']:,}",
     f"**Model parametreleri:** {json.dumps(counts['parts'],ensure_ascii=False)}",'',
     'Kriterler: MAPE, WAPE, MSE, R², MAE. Eğitim raporu validation checkpoint seçimi sonrası üretilir.',
     'Ağırlık paylaşımı yok: genel robot, GMAW, RSW ve TIG ayrı ağlar.',
     'Eksik raporlar: '+(', '.join(missing) if missing else 'Yok'),'',
     '| Operasyon | Bölüm | Çıktı | MAPE (%) | WAPE (%) | MSE | R² | MAE |',
     '|---|---|---|---:|---:|---:|---:|---:|']
 for r in rows:
  if r['source']=='manufacturing_group' and r['target']!='energy_Wh':continue
  def fmt(v):return f'{v:.5g}' if isinstance(v,(int,float)) else ('—' if v is None or v=='' else str(v))
  ls.append('| '+' | '.join(fmt(r[k]) for k in ('family','split','target','MAPE_pct','WAPE_pct','MSE','R2','MAE'))+' |')
 (out/'training_report.md').write_text('\n'.join(ls)+'\n',encoding='utf-8')
 print('Created',out/'training_report.md','metrics rows',len(rows),'missing',missing)
if __name__=='__main__':main()