[LAB 02 · 参数迁移:冻结、局部与全量微调](/course/notebooks/4bd450d54870432db91c80a4df563b8e.html) # 准备:本实验的固定材料 · 实现代码 [独立阅读](/course/notebook-blocks/cb2b6dec25874e6a9654f27808e15529.html) 按问题继续 同源参数的冻结/局部/全量/scratch与BN模式辨析 展开完整实现代码 ``` MODEL_PATH=ROOT/'results/cnn-plain-state.pt' REPORT_PATH=ROOT/'results/lab02-results.json' DATA=ROOT/'data' files={ 'train-images-idx3-ubyte.gz':'440fcabf73cc546fa21475e81ea370265605f56be210a4024d2ca8f203523609', 'train-labels-idx1-ubyte.gz':'3552534a0a558bbed6aed32b30c495cca23d567ec52cac8be1a0730e8010255c'} missing=[str(p) for p in [MODEL_PATH,REPORT_PATH,*[DATA/n for n in files]] if not p.is_file()] if missing: raise RuntimeError('独立材料包不完整,请重新解压 data/ 与 results/:'+', '.join(missing)) report=json.loads(REPORT_PATH.read_text()) protocol=report['protocol'] assert protocol['split_seed']==20260908 and protocol['train_n']==12000, '本练习要求 LAB 02 默认源训练划分;改变划分后需要重新检查源/目标重叠。' raw={} for name,sha in files.items(): raw[name]=(DATA/name).read_bytes() assert hashlib.sha256(raw[name]).hexdigest()==sha, 'MNIST 文件不匹配:'+name images=np.frombuffer(gzip.decompress(raw['train-images-idx3-ubyte.gz']),dtype=np.uint8,offset=16).reshape(60000,1,28,28) digit_labels=np.frombuffer(gzip.decompress(raw['train-labels-idx1-ubyte.gz']),dtype=np.uint8,offset=8) partition=np.random.default_rng(20260908).permutation(60000) expected_partition_sha=hashlib.sha256(partition.tobytes()).hexdigest() expected_train_sha=hashlib.sha256(partition[:12000].tobytes()).hexdigest() expected_val_sha=hashlib.sha256(partition[50000:].tobytes()).hexdigest() assert protocol['train_ids_sha256']==expected_train_sha assert protocol['partition_sha256']==expected_partition_sha and protocol['validation_n']==10000 state_bytes=MODEL_PATH.read_bytes() model_sha256=hashlib.sha256(state_bytes).hexdigest() COURSE_MODEL_SHA256='ba8b738cc67d4ec3cd83d75a5dbe8a70ec548377335ba0abaaa7c23cd14eeba3' identity=report.get('checkpoint_provenance',{}).get('cnn-plain-state.pt') if identity is not None: assert identity['sha256']==model_sha256, '模型与 LAB 02 报告不是同一轮保存的文件;请重新运行 LAB 02 第4节和保存结果单元。' source=identity['source_protocol'] assert source['split_seed']==20260908 and source['train_n']==12000 and source['validation_n']==10000 assert source['partition_sha256']==expected_partition_sha assert source['train_ids_sha256']==expected_train_sha and source['validation_ids_sha256']==expected_val_sha source_files={item['file']:item['sha256'] for item in source['files']} assert all(source_files.get(name)==sha for name,sha in files.items()), '源训练数据身份与本练习不一致。' identity_basis='LAB02 training-time checkpoint hash and source protocol' elif model_sha256==COURSE_MODEL_SHA256: # 已追溯的课程旧模型兼容旧报告;此分支仅接受这一份确切文件。 identity_basis='known course checkpoint SHA-256 with verified default source split' else: raise RuntimeError('当前模型缺少与报告绑定的训练来源。请重新运行更新后的 LAB 02 第4节及保存结果单元;不要给旧文件补写哈希。') target_ids=partition[12000:12640] assert not set(target_ids)&set(partition[:12000]) assert not set(target_ids)&set(partition[50000:]) target_buffer=io.BytesIO() np.savez_compressed(target_buffer,images=images[target_ids],digit_labels=digit_labels[target_ids], official_train_ids=target_ids,split=np.array([0]*256+[1]*128+[2]*256,dtype=np.uint8)) provenance={'dataset':'MNIST official training set','source_task':'ten-class digit classification', 'source_checkpoint_sha256':model_sha256,'source_identity_basis':identity_basis,'source_origin':'bundled original LAB02 protected checkpoint; cross-project independent package', 'target_task':'digit >= 5 (binary)','source_split_seed':20260908, 'source_train_permutation_positions':[0,12000],'source_validation_permutation_positions':[50000,60000], 'target_permutation_positions':[12000,12640],'target_split_sizes':{'train':256,'validation':128,'heldout':256}, 'target_ids_sha256':hashlib.sha256(target_ids.tobytes()).hexdigest(), 'limitations':['single small digit task','source/target sample indices disjoint; writer groups unavailable','not a leaf experiment']} asset_bytes={'cnn-plain-state.pt':state_bytes,'target.npz':target_buffer.getvalue(), 'target-provenance.json':json.dumps(provenance).encode()} print('使用包内已核验模型;目标样本与默认源训练/验证索引不重叠。') ```