{"version":2,"relationshipURLBase":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html","relationshipResolution":"Resolve relative relationship URLs against relationshipURLBase; complete records and absolute URLs are in blocks.","title":"PCA、均值基线与冻结评价 · 实现代码","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html","markdown":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.md","pages":[{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","unit":"PCA、均值基线与冻结评价 · 实现代码","unitId":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","chapter":"course","number":1}],"aliases":[{"oldId":"b-d25d3043aad4885f018b7663","targetId":"b-d25d3043aad4885f018b7663","page":"reading-opening","operation":"move","beforeSHA256":"4730e90285e279b2564c179018b9df76aafd9db5dd2729f0f687ac380af591ed","afterSHA256":"4730e90285e279b2564c179018b9df76aafd9db5dd2729f0f687ac380af591ed","reason":"Same source body in authored semantic page"},{"oldId":"b-1170390d2c90676ceeeae282","targetId":"b-1170390d2c90676ceeeae282","page":"reading-opening","operation":"move","beforeSHA256":"04f786aee23e7932efda6d8496a2c2c8c2e35fdb55e9e309b949cd5fc23c08c9","afterSHA256":"04f786aee23e7932efda6d8496a2c2c8c2e35fdb55e9e309b949cd5fc23c08c9","reason":"Same source body in authored semantic page"},{"oldId":"b-eac6e42ce500ec64cbe49728","targetId":"b-eac6e42ce500ec64cbe49728","page":"reading-opening","operation":"move","beforeSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","afterSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","reason":"Same source body in authored semantic page"},{"oldId":"b-596282ae5b8179d05a536cf5","targetId":"b-596282ae5b8179d05a536cf5","page":"reading-opening","operation":"move","beforeSHA256":"0f845ef31b98ed8c96f689fea3088b0a7482be32b2d5510c83f9fcbb05da4c9d","afterSHA256":"0f845ef31b98ed8c96f689fea3088b0a7482be32b2d5510c83f9fcbb05da4c9d","reason":"Same source body in authored semantic page"},{"oldId":"b-40cec310e97b5daed07e853f","targetId":"b-40cec310e97b5daed07e853f","page":"reading-opening","operation":"move","beforeSHA256":"346501991ef9efbc297a06f21a942a08d19a2941f1cd91dc0ee0f9ad87b2aec4","afterSHA256":"346501991ef9efbc297a06f21a942a08d19a2941f1cd91dc0ee0f9ad87b2aec4","reason":"Same source body in authored semantic page"}],"blocks":[{"id":"b-d25d3043aad4885f018b7663","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html#b-d25d3043aad4885f018b7663","content":"[LAB 08 · 图像重建：遮挡损失与表示评价](/course/notebooks/b5ba27f2c5ba4ec0922208a7d5dc80a4.html)","sha256":"4730e90285e279b2564c179018b9df76aafd9db5dd2729f0f687ac380af591ed","chapter":{"id":"course","title":"PCA、均值基线与冻结评价 · 实现代码"},"unit":{"id":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","title":"PCA、均值基线与冻结评价 · 实现代码"},"page":{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","number":1},"sectionTitle":"PCA、均值基线与冻结评价 · 实现代码","currentQuestion":"PCA、均值基线与冻结评价 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":null,"nextBlock":"b-1170390d2c90676ceeeae282","prerequisites":[],"relatedBlocks":[]},{"id":"b-1170390d2c90676ceeeae282","type":"h1","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html#b-1170390d2c90676ceeeae282","content":"# PCA、均值基线与冻结评价 · 实现代码","sha256":"04f786aee23e7932efda6d8496a2c2c8c2e35fdb55e9e309b949cd5fc23c08c9","chapter":{"id":"course","title":"PCA、均值基线与冻结评价 · 实现代码"},"unit":{"id":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","title":"PCA、均值基线与冻结评价 · 实现代码"},"page":{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","number":1},"sectionTitle":"PCA、均值基线与冻结评价 · 实现代码","currentQuestion":"PCA、均值基线与冻结评价 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-d25d3043aad4885f018b7663","nextBlock":"b-eac6e42ce500ec64cbe49728","prerequisites":[{"id":"b-d25d3043aad4885f018b7663","url":"#b-d25d3043aad4885f018b7663","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-eac6e42ce500ec64cbe49728","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html#b-eac6e42ce500ec64cbe49728","content":"按问题继续","sha256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","chapter":{"id":"course","title":"PCA、均值基线与冻结评价 · 实现代码"},"unit":{"id":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","title":"PCA、均值基线与冻结评价 · 实现代码"},"page":{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","number":1},"sectionTitle":"PCA、均值基线与冻结评价 · 实现代码","currentQuestion":"PCA、均值基线与冻结评价 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-1170390d2c90676ceeeae282","nextBlock":"b-596282ae5b8179d05a536cf5","prerequisites":[{"id":"b-1170390d2c90676ceeeae282","url":"#b-1170390d2c90676ceeeae282","role":"section-title"},{"id":"b-d25d3043aad4885f018b7663","url":"#b-d25d3043aad4885f018b7663","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-596282ae5b8179d05a536cf5","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html#b-596282ae5b8179d05a536cf5","content":"索引恢复、去噪/遮挡ConvAE训练、PCA基线、独立冻结评价","sha256":"0f845ef31b98ed8c96f689fea3088b0a7482be32b2d5510c83f9fcbb05da4c9d","chapter":{"id":"course","title":"PCA、均值基线与冻结评价 · 实现代码"},"unit":{"id":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","title":"PCA、均值基线与冻结评价 · 实现代码"},"page":{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","number":1},"sectionTitle":"PCA、均值基线与冻结评价 · 实现代码","currentQuestion":"PCA、均值基线与冻结评价 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-eac6e42ce500ec64cbe49728","nextBlock":"b-40cec310e97b5daed07e853f","prerequisites":[{"id":"b-1170390d2c90676ceeeae282","url":"#b-1170390d2c90676ceeeae282","role":"section-title"},{"id":"b-d25d3043aad4885f018b7663","url":"#b-d25d3043aad4885f018b7663","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-40cec310e97b5daed07e853f","type":"pre","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f.html#b-40cec310e97b5daed07e853f","content":"```\ndef run_reconstruction(out_dir='lab08-output'):\n    started=time.time();out=Path(out_dir);out.mkdir(parents=True,exist_ok=True)\n    x,y,train,test=digit_data()\n    np.savez_compressed(out/'inputs.npz',images=x.numpy(),labels=y,train_ids=train,test_ids=test)\n    denoise,random_d,hist_d,delta_d=train_ae(x,train,'denoise',40)\n    masked,random_m,hist_m,delta_m=train_ae(x,train,'masked',50)\n    torch.save(denoise.state_dict(),out/'denoise.pt');torch.save(masked.state_dict(),out/'masked-conv-ae.pt')\n    torch.save({'denoise':random_d.state_dict(),'masked':random_m.state_dict()},out/'random-init.pt')\n    denoise.eval();masked.eval();torch.manual_seed(SEED+19)\n    clean=x[test];corrupted=noise_corrupt(clean)\n    with torch.no_grad():recon=denoise(corrupted)[0]\n    mean_image=x[train].mean(0,keepdim=True)\n    # PCA fits clean training images only. It is a rank-16 linear projection baseline.\n    a=x[train].flatten(1).numpy();mu=a.mean(0);_,_,vt=np.linalg.svd(a-mu,full_matrices=False)\n    v=vt[:16];noisy=corrupted.flatten(1).numpy();pca=np.clip((noisy-mu)@v.T@v+mu,0,1)\n    metrics={'denoise':{'corrupted_input_mse':float(F.mse_loss(corrupted,clean)),\n      'train_mean_mse':float(((clean-mean_image)**2).mean()),\n      'rank16_pca_noisy_mse':float(np.mean((pca-clean.flatten(1).numpy())**2)),\n      'learned_conv_ae_mse':float(F.mse_loss(recon,clean))}}\n    masked_outputs={}\n    for ratio in [.25,.5,.75]:\n        torch.manual_seed(SEED+25)  # Same permutation at all ratios: nested hidden sets.\n        mask=patch_mask(len(clean),ratio)\n        inp=torch.cat([clean*(1-mask),mask],1)\n        with torch.no_grad():pred=masked(inp)[0]\n        loss=(((pred-clean)**2)*mask).sum()/mask.sum()\n        mean_loss=(((mean_image-clean)**2)*mask).sum()/mask.sum()\n        zero_loss=((clean**2)*mask).sum()/mask.sum()\n        metrics[f'mask_{ratio}']={'hidden_pixels_mse':float(loss),'train_mean_hidden_mse':float(mean_loss),\n          'zero_fill_hidden_mse':float(zero_loss),'visible_patches':int(16*(1-ratio)),\n          'conv_encoder_grid_pixels':64}\n        masked_outputs[ratio]=(mask,pred)\n    probes={}\n    for name,model,is_masked in [('random-denoise',random_d,False),('trained-denoise',denoise,False),('random-masked',random_m,True),('trained-masked',masked,True)]:\n        probes[name]=frozen_probe(model,x,y,train,test,is_masked)\n    # Save complete inference evidence, including corruption and masks.\n    output_arrays={'clean':clean.numpy(),'corrupted':corrupted.numpy(),'denoised':recon.numpy(),'pca':pca.reshape(-1,1,8,8)}\n    for ratio,(mask,pred) in masked_outputs.items():output_arrays[f'mask_{ratio}']=mask.numpy();output_arrays[f'pred_{ratio}']=pred.numpy()\n    np.savez_compressed(out/'predictions.npz',**output_arrays)\n    # Examples selected BEFORE seeing predictions: first eight test IDs, never cherry-picked.\n    mask,pred=masked_outputs[.5]\n    fig,axes=plt.subplots(8,6,figsize=(9,12))\n    titles=['clean','corrupted','denoised','50% masked','predicted hidden','absolute error']\n    for i in range(8):\n        completed=clean[i]*(1-mask[i])+pred[i]*mask[i]\n        ims=[clean[i],corrupted[i],recon[i],clean[i]*(1-mask[i]),completed,abs(completed-clean[i])]\n        for j,im in enumerate(ims):\n            axes[i,j].imshow(im[0],cmap='magma' if j==5 else 'gray',vmin=0,vmax=1,interpolation='nearest')\n            axes[i,j].set_xticks([]);axes[i,j].set_yticks([])\n            if i==0:axes[i,j].set_title(titles[j],fontsize=9)\n        axes[i,0].set_ylabel(f'id {test[i]}\\ny={y[test[i]]}',fontsize=8)\n    fig.tight_layout();fig.savefig(out/'reconstruction-grid.png',dpi=150);plt.close(fig)\n    fig,axes=plt.subplots(1,3,figsize=(14,4))\n    axes[0].plot(hist_d,label='denoise: all pixels');axes[0].plot(hist_m,label='masked: hidden only');axes[0].legend(fontsize=8)\n    axes[0].set(xlabel='epoch (0-based)',ylabel='train MSE',title='Objectives have different pixel sets')\n    ratios=[.25,.5,.75]\n    axes[1].plot(ratios,[metrics[f'mask_{r}']['hidden_pixels_mse'] for r in ratios],'o-',label='trained at 50%')\n    axes[1].plot(ratios,[metrics[f'mask_{r}']['train_mean_hidden_mse'] for r in ratios],'o--',label='train mean')\n    axes[1].set(xlabel='evaluation mask ratio',ylabel='held-out hidden MSE');axes[1].legend()\n    axes[2].bar(list(probes),list(probes.values()));axes[2].tick_params(axis='x',rotation=25)\n    axes[2].set(ylim=(0,1),ylabel='held-out accuracy',title='Frozen clean h: cosine 5-NN')\n    fig.tight_layout();fig.savefig(out/'loss-mask-probe.png',dpi=140);plt.close(fig)\n    config={'seed':SEED,'dataset':'sklearn load_digits, 1797 grayscale 8x8, pixels divided by16','train_n':len(train),'test_n':len(test),'split':'stratified random source-image split before corruption','denoise_epochs':40,'masked_epochs':50,'batch_size':64,'adam_lr':.003,'latent_dim':16,'denoise_corruption':{'pixel_drop':.25,'gaussian_sigma':.15,'clip':[0,1]},'mask_training_ratio':.5,'mask_patch_pixels':[2,2],'labels_used':'stratify/probe only; never AE loss','mask_encoder':'dense two-channel convolutional autoencoder; NOT ViT MAE','test_tuning':'none; predetermined epochs/mask ratios'}\n    (out/'config.json').write_text(json.dumps(config,indent=2))\n    payload={'code_sha256':globals().get('SOURCE_SHA256') or hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),'kind':'local CPU full training and held-out evaluation','utc':time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime()),'seconds':time.time()-started,'torch':torch.__version__,'numpy':np.__version__,'python':platform.python_version(),'metrics':metrics,'frozen_clean_5nn':probes,'loss_history':{'denoise':hist_d,'masked':hist_m},'encoder_weight_l2_change':{'denoise':delta_d,'masked':delta_m},'index_warmup':mask_index_warmup(),'inputs_sha256':hashlib.sha256((out/'inputs.npz').read_bytes()).hexdigest()}\n    (out/'results.json').write_text(json.dumps(payload,indent=2))\n    print(json.dumps({'metrics':metrics,'frozen_clean_5nn':probes,'seconds':payload['seconds']},indent=2))\n    return payload\n```","sha256":"346501991ef9efbc297a06f21a942a08d19a2941f1cd91dc0ee0f9ad87b2aec4","chapter":{"id":"course","title":"PCA、均值基线与冻结评价 · 实现代码"},"unit":{"id":"notebook-blocks/41ffe8f7d5284c27aec5c2474b234a1f","title":"PCA、均值基线与冻结评价 · 实现代码"},"page":{"id":"reading-opening","title":"PCA、均值基线与冻结评价 · 实现代码","number":1},"sectionTitle":"PCA、均值基线与冻结评价 · 实现代码","currentQuestion":"PCA、均值基线与冻结评价 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-596282ae5b8179d05a536cf5","nextBlock":null,"prerequisites":[{"id":"b-1170390d2c90676ceeeae282","url":"#b-1170390d2c90676ceeeae282","role":"section-title"},{"id":"b-d25d3043aad4885f018b7663","url":"#b-d25d3043aad4885f018b7663","role":"problem-context"}],"relatedBlocks":[]}]}
