[LAB 01 · 固定表示:标签预算与读出](/course/notebooks/4dd8605ed9904820919ea9e13d9e7d7c.html) # 0 · 固定输入、来源与数据职责 · 实现代码 [独立阅读](/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html) 按问题继续 固定CNN与缓存特征、标签预算、kNN/linear和独立评价 展开完整实现代码 ``` # 当前项目中的独立材料:已存在则复用,缺失才从本讲原站准备。 from pathlib import Path import io, zipfile, urllib.request _base = Path.cwd() _folder = 'lab10-readout' _sentinel = 'assets/target.npz' _choices = [_base/_folder, _base/'lecture03-labs'/_folder, _base] _ready = next((p for p in _choices if (p/_sentinel).is_file()), None) if _ready is None: _url = 'https://codingai-lec03.pages.dev/course/materials/' + _folder + '.zip' _payload = urllib.request.urlopen(_url, timeout=60).read() with zipfile.ZipFile(io.BytesIO(_payload)) as _archive: _names = [i.filename for i in _archive.infolist() if not i.is_dir()] _prefix = _folder + '/' _prefixed = all(n.startswith(_prefix) for n in _names) _destination = _base if _prefixed else _base/_folder for _item in _archive.infolist(): _target = (_destination/_item.filename).resolve() if not _target.is_relative_to(_destination.resolve()): raise ValueError('材料包中有越界路径,停止解压。') if _item.is_dir(): _target.mkdir(parents=True, exist_ok=True) elif not _target.exists(): _target.parent.mkdir(parents=True, exist_ok=True) _target.write_bytes(_archive.read(_item)) _ready = next((p for p in _choices if (p/_sentinel).is_file()), None) assert _ready is not None, '请将本讲完整材料包解压到当前项目的 ' + _folder + '/;保留文件结构。' LAB_ROOT = _ready print('材料目录已就绪:', LAB_ROOT) import json, hashlib, platform, sys, time from pathlib import Path from collections import OrderedDict import numpy as np import matplotlib.pyplot as plt import torch from torch import nn from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score import sklearn ROOT=LAB_ROOT if not (ROOT/'assets/target.npz').exists() and (ROOT/'lab10-readout/assets/target.npz').exists(): ROOT=ROOT/'lab10-readout' assert (ROOT/'assets/target.npz').exists(), '请下载完整材料包并解压为项目中的 lab10-readout/;单独 ipynb 只供读取保存输出。' OUT=ROOT/'runs/current'; OUT.mkdir(parents=True,exist_ok=True) FIG=OUT/'figures'; FIG.mkdir(exist_ok=True) torch.set_num_threads(2); torch.manual_seed(20260918) torch.use_deterministic_algorithms(True) plt.rcParams.update({'figure.dpi':120,'font.size':10,'axes.spines.top':False,'axes.spines.right':False}) BLUE,GOLD,GREEN,PURPLE='#002676','#E6A500','#00856A','#69458D' def sha_file(path): return hashlib.sha256(Path(path).read_bytes()).hexdigest() def savefig(name): if not plt.gcf().get_constrained_layout(): plt.tight_layout() plt.savefig(FIG/name,dpi=140,bbox_inches='tight'); plt.show() provenance=json.loads((ROOT/'assets/provenance.json').read_text()) assert sha_file(ROOT/'assets/cnn-plain-state.pt')==provenance['source_checkpoint_sha256'] assert sha_file(ROOT/'assets/target.npz')==provenance['target_asset_sha256'] assert provenance['source_checkpoint_sha256']=='ba8b738cc67d4ec3cd83d75a5dbe8a70ec548377335ba0abaaa7c23cd14eeba3' z=np.load(ROOT/'assets/target.npz',allow_pickle=False) images=z['images']; digits=z['digit_labels']; sample_ids=z['official_train_ids']; split=z['split'] partition=np.random.default_rng(20260908).permutation(60000) assert np.array_equal(sample_ids,partition[12000:12640]) assert not set(sample_ids)&set(partition[:12000]) assert not set(sample_ids)&set(partition[50000:]) assert len(set(sample_ids))==640 train=np.flatnonzero(split==0); val=np.flatnonzero(split==1); heldout=np.flatnonzero(split==2) assert not set(train)&set(val) and not set(train)&set(heldout) and not set(val)&set(heldout) x=torch.tensor(images,dtype=torch.float32)/255 shifted=torch.zeros_like(x); shifted[:,:,:,2:]=x[:,:,:,:-2]; x=shifted y=(digits>=5).astype(np.int64) fig,axes=plt.subplots(1,8,figsize=(12,2.3)) for i,ax in enumerate(axes): ax.imshow(x[i,0],cmap='gray',vmin=0,vmax=1); ax.set_title(f'id {sample_ids[i]}\ndigit {digits[i]} → y={y[i]}',fontsize=9); ax.axis('off') savefig('01-fixed-inputs.png') print('Split sizes:',{'train':len(train),'validation':len(val),'heldout':len(heldout)}) print('SOURCE:',provenance['source_checkpoint_sha256']) print('Checks passed: file identity; sample separation; preprocessing.') ```