{"version":2,"relationshipURLBase":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html","relationshipResolution":"Resolve relative relationship URLs against relationshipURLBase; complete records and absolute URLs are in blocks.","title":"0 · 固定输入、来源与数据职责 · 实现代码","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html","markdown":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.md","pages":[{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","unit":"0 · 固定输入、来源与数据职责 · 实现代码","unitId":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","chapter":"course","number":1}],"aliases":[{"oldId":"b-d1d42614d9a7eef1069756cb","targetId":"b-d1d42614d9a7eef1069756cb","page":"reading-opening","operation":"move","beforeSHA256":"7d57f9e628741b07c2704a32d4b4c2e5ca44d512d696e3562c18003cb33df7d1","afterSHA256":"7d57f9e628741b07c2704a32d4b4c2e5ca44d512d696e3562c18003cb33df7d1","reason":"Same source body in authored semantic page"},{"oldId":"b-669934ee02829d22a58c433c","targetId":"b-669934ee02829d22a58c433c","page":"reading-opening","operation":"move","beforeSHA256":"3c71d41838ef4fb011caef549de3aeea08ca65f2549f35fbe2b59eaa981b3df8","afterSHA256":"3c71d41838ef4fb011caef549de3aeea08ca65f2549f35fbe2b59eaa981b3df8","reason":"Same source body in authored semantic page"},{"oldId":"b-d36454b9bfb3934632628a5c","targetId":"b-d36454b9bfb3934632628a5c","page":"reading-opening","operation":"move","beforeSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","afterSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","reason":"Same source body in authored semantic page"},{"oldId":"b-c41894befa3eadc4110dde15","targetId":"b-c41894befa3eadc4110dde15","page":"reading-opening","operation":"move","beforeSHA256":"75bc3d13109b5a891b82a4daefd668c001abde4ddf12e5ad4e20e6fe674663c6","afterSHA256":"75bc3d13109b5a891b82a4daefd668c001abde4ddf12e5ad4e20e6fe674663c6","reason":"Same source body in authored semantic page"},{"oldId":"b-541d8f6b27b7d6676d0d3e8b","targetId":"b-541d8f6b27b7d6676d0d3e8b","page":"reading-opening","operation":"move","beforeSHA256":"9c22fab644cfde4b4d33c46b459f7db5f0167ad64830741b63643a22dcdce06a","afterSHA256":"9c22fab644cfde4b4d33c46b459f7db5f0167ad64830741b63643a22dcdce06a","reason":"Same source body in authored semantic page"}],"blocks":[{"id":"b-d1d42614d9a7eef1069756cb","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html#b-d1d42614d9a7eef1069756cb","content":"[LAB 01 · 固定表示：标签预算与读出](/course/notebooks/4dd8605ed9904820919ea9e13d9e7d7c.html)","sha256":"7d57f9e628741b07c2704a32d4b4c2e5ca44d512d696e3562c18003cb33df7d1","chapter":{"id":"course","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"unit":{"id":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"page":{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","number":1},"sectionTitle":"0 · 固定输入、来源与数据职责 · 实现代码","currentQuestion":"0 · 固定输入、来源与数据职责 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":null,"nextBlock":"b-669934ee02829d22a58c433c","prerequisites":[],"relatedBlocks":[]},{"id":"b-669934ee02829d22a58c433c","type":"h1","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html#b-669934ee02829d22a58c433c","content":"# 0 · 固定输入、来源与数据职责 · 实现代码","sha256":"3c71d41838ef4fb011caef549de3aeea08ca65f2549f35fbe2b59eaa981b3df8","chapter":{"id":"course","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"unit":{"id":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"page":{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","number":1},"sectionTitle":"0 · 固定输入、来源与数据职责 · 实现代码","currentQuestion":"0 · 固定输入、来源与数据职责 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-d1d42614d9a7eef1069756cb","nextBlock":"b-d36454b9bfb3934632628a5c","prerequisites":[{"id":"b-d1d42614d9a7eef1069756cb","url":"#b-d1d42614d9a7eef1069756cb","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-d36454b9bfb3934632628a5c","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html#b-d36454b9bfb3934632628a5c","content":"按问题继续","sha256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","chapter":{"id":"course","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"unit":{"id":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"page":{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","number":1},"sectionTitle":"0 · 固定输入、来源与数据职责 · 实现代码","currentQuestion":"0 · 固定输入、来源与数据职责 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-669934ee02829d22a58c433c","nextBlock":"b-c41894befa3eadc4110dde15","prerequisites":[{"id":"b-669934ee02829d22a58c433c","url":"#b-669934ee02829d22a58c433c","role":"section-title"},{"id":"b-d1d42614d9a7eef1069756cb","url":"#b-d1d42614d9a7eef1069756cb","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-c41894befa3eadc4110dde15","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html#b-c41894befa3eadc4110dde15","content":"固定CNN与缓存特征、标签预算、kNN/linear和独立评价","sha256":"75bc3d13109b5a891b82a4daefd668c001abde4ddf12e5ad4e20e6fe674663c6","chapter":{"id":"course","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"unit":{"id":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"page":{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","number":1},"sectionTitle":"0 · 固定输入、来源与数据职责 · 实现代码","currentQuestion":"0 · 固定输入、来源与数据职责 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-d36454b9bfb3934632628a5c","nextBlock":"b-541d8f6b27b7d6676d0d3e8b","prerequisites":[{"id":"b-669934ee02829d22a58c433c","url":"#b-669934ee02829d22a58c433c","role":"section-title"},{"id":"b-d1d42614d9a7eef1069756cb","url":"#b-d1d42614d9a7eef1069756cb","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-541d8f6b27b7d6676d0d3e8b","type":"pre","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8.html#b-541d8f6b27b7d6676d0d3e8b","content":"```\n# 当前项目中的独立材料：已存在则复用，缺失才从本讲原站准备。\nfrom pathlib import Path\nimport io, zipfile, urllib.request\n_base = Path.cwd()\n_folder = 'lab10-readout'\n_sentinel = 'assets/target.npz'\n_choices = [_base/_folder, _base/'lecture03-labs'/_folder, _base]\n_ready = next((p for p in _choices if (p/_sentinel).is_file()), None)\nif _ready is None:\n    _url = 'https://codingai-lec03.pages.dev/course/materials/' + _folder + '.zip'\n    _payload = urllib.request.urlopen(_url, timeout=60).read()\n    with zipfile.ZipFile(io.BytesIO(_payload)) as _archive:\n        _names = [i.filename for i in _archive.infolist() if not i.is_dir()]\n        _prefix = _folder + '/'\n        _prefixed = all(n.startswith(_prefix) for n in _names)\n        _destination = _base if _prefixed else _base/_folder\n        for _item in _archive.infolist():\n            _target = (_destination/_item.filename).resolve()\n            if not _target.is_relative_to(_destination.resolve()):\n                raise ValueError('材料包中有越界路径，停止解压。')\n            if _item.is_dir():\n                _target.mkdir(parents=True, exist_ok=True)\n            elif not _target.exists():\n                _target.parent.mkdir(parents=True, exist_ok=True)\n                _target.write_bytes(_archive.read(_item))\n    _ready = next((p for p in _choices if (p/_sentinel).is_file()), None)\nassert _ready is not None, '请将本讲完整材料包解压到当前项目的 ' + _folder + '/；保留文件结构。'\nLAB_ROOT = _ready\nprint('材料目录已就绪：', LAB_ROOT)\n\nimport json, hashlib, platform, sys, time\nfrom pathlib import Path\nfrom collections import OrderedDict\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport torch\nfrom torch import nn\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.metrics import accuracy_score\nimport sklearn\n\nROOT=LAB_ROOT\nif not (ROOT/'assets/target.npz').exists() and (ROOT/'lab10-readout/assets/target.npz').exists():\n    ROOT=ROOT/'lab10-readout'\nassert (ROOT/'assets/target.npz').exists(), '请下载完整材料包并解压为项目中的 lab10-readout/；单独 ipynb 只供读取保存输出。'\nOUT=ROOT/'runs/current'; OUT.mkdir(parents=True,exist_ok=True)\nFIG=OUT/'figures'; FIG.mkdir(exist_ok=True)\ntorch.set_num_threads(2); torch.manual_seed(20260918)\ntorch.use_deterministic_algorithms(True)\nplt.rcParams.update({'figure.dpi':120,'font.size':10,'axes.spines.top':False,'axes.spines.right':False})\nBLUE,GOLD,GREEN,PURPLE='#002676','#E6A500','#00856A','#69458D'\ndef sha_file(path): return hashlib.sha256(Path(path).read_bytes()).hexdigest()\ndef savefig(name):\n    if not plt.gcf().get_constrained_layout(): plt.tight_layout()\n    plt.savefig(FIG/name,dpi=140,bbox_inches='tight'); plt.show()\nprovenance=json.loads((ROOT/'assets/provenance.json').read_text())\nassert sha_file(ROOT/'assets/cnn-plain-state.pt')==provenance['source_checkpoint_sha256']\nassert sha_file(ROOT/'assets/target.npz')==provenance['target_asset_sha256']\nassert provenance['source_checkpoint_sha256']=='ba8b738cc67d4ec3cd83d75a5dbe8a70ec548377335ba0abaaa7c23cd14eeba3'\nz=np.load(ROOT/'assets/target.npz',allow_pickle=False)\nimages=z['images']; digits=z['digit_labels']; sample_ids=z['official_train_ids']; split=z['split']\npartition=np.random.default_rng(20260908).permutation(60000)\nassert np.array_equal(sample_ids,partition[12000:12640])\nassert not set(sample_ids)&set(partition[:12000])\nassert not set(sample_ids)&set(partition[50000:])\nassert len(set(sample_ids))==640\ntrain=np.flatnonzero(split==0); val=np.flatnonzero(split==1); heldout=np.flatnonzero(split==2)\nassert not set(train)&set(val) and not set(train)&set(heldout) and not set(val)&set(heldout)\nx=torch.tensor(images,dtype=torch.float32)/255\nshifted=torch.zeros_like(x); shifted[:,:,:,2:]=x[:,:,:,:-2]; x=shifted\ny=(digits>=5).astype(np.int64)\nfig,axes=plt.subplots(1,8,figsize=(12,2.3))\nfor i,ax in enumerate(axes):\n    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')\nsavefig('01-fixed-inputs.png')\nprint('Split sizes:',{'train':len(train),'validation':len(val),'heldout':len(heldout)})\nprint('SOURCE:',provenance['source_checkpoint_sha256'])\nprint('Checks passed: file identity; sample separation; preprocessing.')\n```","sha256":"9c22fab644cfde4b4d33c46b459f7db5f0167ad64830741b63643a22dcdce06a","chapter":{"id":"course","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"unit":{"id":"notebook-blocks/c0a28317e0b94fe48d5680f6bc6d7fd8","title":"0 · 固定输入、来源与数据职责 · 实现代码"},"page":{"id":"reading-opening","title":"0 · 固定输入、来源与数据职责 · 实现代码","number":1},"sectionTitle":"0 · 固定输入、来源与数据职责 · 实现代码","currentQuestion":"0 · 固定输入、来源与数据职责 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-c41894befa3eadc4110dde15","nextBlock":null,"prerequisites":[{"id":"b-669934ee02829d22a58c433c","url":"#b-669934ee02829d22a58c433c","role":"section-title"},{"id":"b-d1d42614d9a7eef1069756cb","url":"#b-d1d42614d9a7eef1069756cb","role":"problem-context"}],"relatedBlocks":[]}]}
