Manufacturing-MoE / src /make_report.py
rasitcesur's picture
Sync from rasitcesur/Manufacturing-MoE via hub-sync
547ac30 verified
Raw History Blame Contribute Delete
4.81 kB
"""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()