Files

65 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Report Phase 4S gates without selecting new parameters or checkpoints."""
from pathlib import Path
import json
import sys
import numpy as np
import pandas as pd
root=Path('/data/digital-drosophila/experiments/phase4s-timing-credit')
r=json.loads((root/'audit/results.json').read_text())
report={'status':r['status'],'timing':r['calibration'],'heldout':r['heldout'],'formal':r['formal'],
'isolated_endpoint':r['isolated']['endpoint'] if r['isolated'] else None,
'isolated_pass':r['isolated']['gate_pass'] if r['isolated'] else None,
'whole':r['whole'],'timing_gate_pass':r['timing_candidate'],'credit_gate_pass':r['credit_candidate'],
'regression_pass':r['regression_pass'],'performance':json.loads((root/'performance/summary.json').read_text()),
'scope':'Open-loop credit accumulation and replay; no learned weights fed back into trial generation; no associative memory claim.'}
if (root/'formal/group-trajectory.parquet').exists():
f=pd.read_parquet(root/'formal/group-trajectory.parquet')
endpoint=f[f.pairing==100].groupby(['arm','group'],as_index=False).agg(
mean_updated_edges=('updated_edges','mean'),mean_delta_E=('mean_delta_E','mean'),
mean_total_abs_delta_E=('total_abs_delta_E','mean'),mean_weighted_delta_mv=('total_weighted_delta_mv','mean'))
report['group_endpoints']=endpoint.to_dict('records')
c=pd.read_parquet(root/'formal/B-contamination.parquet')
report['B_contamination_unique_edges']=c.groupby('arm').edge_id.nunique().to_dict() if len(c) else {}
trajectory=pd.DataFrame(r['isolated']['trajectory']).groupby('pairing',as_index=False).agg(
A_L1=('A','mean'),B_L1=('B','mean'),random_A_L1=('random_A','mean'),
A_specific_seeds=('A_specific','sum'),random_specific_seeds=('random_specific','sum'))
report['isolated_trajectory']=trajectory.to_dict('records')
sys.path.insert(0,'/tmp/malecns-phase4r-plot-20260929/lib/python3.10/site-packages')
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig,axes=plt.subplots(1,3,figsize=(15,4.5),layout='constrained')
for ax,group in zip(axes[:2],['A-specific','B-specific']):
for arm in ('v2_same_US','v2_90ms','v3_matched','v3_random'):
z=f[(f.group==group)&(f.arm==arm)].groupby('pairing').total_abs_delta_E.mean()
ax.plot(z.index,z.values,marker='.',label=arm)
ax.set(title=group+' credit',xlabel='Pairings',ylabel='Mean sum |delta E|');ax.legend(fontsize=8)
for name in ('A_L1','B_L1','random_A_L1'):
axes[2].plot(trajectory.pairing,trajectory[name],marker='.',label=name)
axes[2].set(title='Isolated MBON output change',xlabel='Pairings',ylabel='Mean spike-count L1');axes[2].legend(fontsize=8)
(root/'figures').mkdir(exist_ok=True);fig.savefig(root/'figures/credit-and-transfer.png',dpi=180);plt.close(fig)
(root/'audit/mechanism-summary.json').write_text(json.dumps(report,indent=2,sort_keys=True)+'\n')
lines=['# Phase 4S:时序修复与 credit 特异性验证','',f"状态:`{r['status']}`",'',
'本轮只改变外部 US 时序及预注册的局部 eligibility 窗口。全脑动力学、APL、嗅觉 encoder、学习幅度和 14,232 条 plastic mask 保持冻结。',
'', '比较采用同一批真实 KC 事件,累积实验性 E overlay;事件采集始终使用未学习的 base brain。结果不构成在线关联记忆声明。','']
if r['calibration']:
t=r['calibration'];lines+=[f"校准选择:US={t['US_ms']} ms,window={t['window_ms']} ms,tau={t['tau_ms']:.6f} ms。",'']
if r['heldout']:
lines+=['独立 seeds 验证:','', '| 气味 | matched/random credit 比值 | 达标 seeds |','|---|---:|---:|']
for x in r['heldout']['odors']:lines.append(f"| {x['label']} | {x['ratio']:.4f} | {x['qualifying_seeds']}/5 |")
lines+=['',f"独立 timing gate:{r['heldout']['pass']}。",'']
if r['formal']:
lines+=[f"正式 A/B credit gate:{r['formal']['gate_pass']}(预注册 100-pairing 终点)。",'']
else:
lines+=['独立 timing gate 未通过,正式累积权重实验、isolated replay 和 whole-brain 传递实验均未执行。未生成学习产物;不能据此判断这些未执行实验的结果。','']
if r['isolated']:
lines+=[f"Isolated gate:{r['isolated']['gate_pass']}。",'', '| Seed | A L1 | B L1 | random A L1 | random B L1 |','|---|---:|---:|---:|---:|']
for x in r['isolated']['endpoint']:lines.append(f"| {x['seed']} | {x['A']} | {x['B']} | {x['random_A']} | {x['random_B']} |")
lines+=['','![Credit 与功能传递](../figures/credit-and-transfer.png)','']
lines += [f"Whole-brain:{json.dumps(r['whole'],ensure_ascii=False)}",'',
f"冻结参考回归:{r['regression_pass']}。完整 frozen integrity 结果见 `frozen-integrity.json`。",'',
'限制:只有两个 calibration odors 和五个独立验证 seeds;credit 改善与刺激特异 MBON 功能变化分别判定。没有根据正式 A/B 或 heldout 结果重新挑参数,没有提前停止在最有利 checkpoint。']
(root/'audit/REPORT.md').write_text('\n'.join(lines)+'\n',encoding='utf-8')
print(json.dumps({k:v for k,v in report.items() if k not in ('group_endpoints','isolated_trajectory')},indent=2))