{"version":2,"relationshipURLBase":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html","relationshipResolution":"Resolve relative relationship URLs against relationshipURLBase; complete records and absolute URLs are in blocks.","title":"图像、两视图与同源正例 · 实现代码","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html","markdown":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.md","pages":[{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","unit":"图像、两视图与同源正例 · 实现代码","unitId":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","chapter":"course","number":1}],"aliases":[{"oldId":"b-3de58d08726ba70ecf74a154","targetId":"b-3de58d08726ba70ecf74a154","page":"reading-opening","operation":"move","beforeSHA256":"88a04c9ecb442ccaa48afb715979a4f7ec256d11b69e583a238c98ab9d60e977","afterSHA256":"88a04c9ecb442ccaa48afb715979a4f7ec256d11b69e583a238c98ab9d60e977","reason":"Same source body in authored semantic page"},{"oldId":"b-7bb76eb1a189af2a343b2cf1","targetId":"b-7bb76eb1a189af2a343b2cf1","page":"reading-opening","operation":"move","beforeSHA256":"e190f8427bbe7865c3954e640dfb7916a7b7fa2997b2aead045fe97bf5744dcd","afterSHA256":"e190f8427bbe7865c3954e640dfb7916a7b7fa2997b2aead045fe97bf5744dcd","reason":"Same source body in authored semantic page"},{"oldId":"b-3f25eff47bbc9491fc527285","targetId":"b-3f25eff47bbc9491fc527285","page":"reading-opening","operation":"move","beforeSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","afterSHA256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","reason":"Same source body in authored semantic page"},{"oldId":"b-8f60ed1afa4a8c76c4ca0917","targetId":"b-8f60ed1afa4a8c76c4ca0917","page":"reading-opening","operation":"move","beforeSHA256":"2a269d38480454fbc554b17f926927738416555e36045ec5fe468ba056454f5d","afterSHA256":"2a269d38480454fbc554b17f926927738416555e36045ec5fe468ba056454f5d","reason":"Same source body in authored semantic page"},{"oldId":"b-2059c27ef6b94a483b4b5217","targetId":"b-2059c27ef6b94a483b4b5217","page":"reading-opening","operation":"move","beforeSHA256":"2124e4f903ef5e5b292d389935649c6cb9905e73f45aefd3d46b7687db7f6f73","afterSHA256":"2124e4f903ef5e5b292d389935649c6cb9905e73f45aefd3d46b7687db7f6f73","reason":"Same source body in authored semantic page"}],"blocks":[{"id":"b-3de58d08726ba70ecf74a154","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html#b-3de58d08726ba70ecf74a154","content":"[LAB 07 · MoCo：历史 key、队列与两种更新](/course/notebooks/0d1b8f6fbf6a476c93ffcc169f2ec1f4.html)","sha256":"88a04c9ecb442ccaa48afb715979a4f7ec256d11b69e583a238c98ab9d60e977","chapter":{"id":"course","title":"图像、两视图与同源正例 · 实现代码"},"unit":{"id":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","title":"图像、两视图与同源正例 · 实现代码"},"page":{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","number":1},"sectionTitle":"图像、两视图与同源正例 · 实现代码","currentQuestion":"图像、两视图与同源正例 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":null,"nextBlock":"b-7bb76eb1a189af2a343b2cf1","prerequisites":[],"relatedBlocks":[]},{"id":"b-7bb76eb1a189af2a343b2cf1","type":"h1","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html#b-7bb76eb1a189af2a343b2cf1","content":"# 图像、两视图与同源正例 · 实现代码","sha256":"e190f8427bbe7865c3954e640dfb7916a7b7fa2997b2aead045fe97bf5744dcd","chapter":{"id":"course","title":"图像、两视图与同源正例 · 实现代码"},"unit":{"id":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","title":"图像、两视图与同源正例 · 实现代码"},"page":{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","number":1},"sectionTitle":"图像、两视图与同源正例 · 实现代码","currentQuestion":"图像、两视图与同源正例 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-3de58d08726ba70ecf74a154","nextBlock":"b-3f25eff47bbc9491fc527285","prerequisites":[{"id":"b-3de58d08726ba70ecf74a154","url":"#b-3de58d08726ba70ecf74a154","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-3f25eff47bbc9491fc527285","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html#b-3f25eff47bbc9491fc527285","content":"按问题继续","sha256":"e91f24e4e4ca40e2099a0d81d30db6568f4bf2074b499eeee6e3959617bd97ac","chapter":{"id":"course","title":"图像、两视图与同源正例 · 实现代码"},"unit":{"id":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","title":"图像、两视图与同源正例 · 实现代码"},"page":{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","number":1},"sectionTitle":"图像、两视图与同源正例 · 实现代码","currentQuestion":"图像、两视图与同源正例 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-7bb76eb1a189af2a343b2cf1","nextBlock":"b-8f60ed1afa4a8c76c4ca0917","prerequisites":[{"id":"b-7bb76eb1a189af2a343b2cf1","url":"#b-7bb76eb1a189af2a343b2cf1","role":"section-title"},{"id":"b-3de58d08726ba70ecf74a154","url":"#b-3de58d08726ba70ecf74a154","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-8f60ed1afa4a8c76c4ca0917","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html#b-8f60ed1afa4a8c76c4ca0917","content":"真实FIFO键、EMA、梯度更新及低于随机基线的保留结果","sha256":"2a269d38480454fbc554b17f926927738416555e36045ec5fe468ba056454f5d","chapter":{"id":"course","title":"图像、两视图与同源正例 · 实现代码"},"unit":{"id":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","title":"图像、两视图与同源正例 · 实现代码"},"page":{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","number":1},"sectionTitle":"图像、两视图与同源正例 · 实现代码","currentQuestion":"图像、两视图与同源正例 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-3f25eff47bbc9491fc527285","nextBlock":"b-2059c27ef6b94a483b4b5217","prerequisites":[{"id":"b-7bb76eb1a189af2a343b2cf1","url":"#b-7bb76eb1a189af2a343b2cf1","role":"section-title"},{"id":"b-3de58d08726ba70ecf74a154","url":"#b-3de58d08726ba70ecf74a154","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-2059c27ef6b94a483b4b5217","type":"pre","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/b4c113869cc04e4a9753038a5858a879.html#b-2059c27ef6b94a483b4b5217","content":"```\ndef make_data(seed=SEED):\n    rng=np.random.default_rng(seed)\n    yy,xx=np.mgrid[:16,:16]\n    images=[]; shape=[]; color=[]; split=[]\n    # Stratified before view construction. One independently generated source per ID.\n    for s in range(3):\n        for c in range(2):\n            for i in range(140):\n                cx,cy=rng.uniform(6,10,2); r=rng.uniform(3.0,4.7)\n                dx,dy=xx-cx,yy-cy\n                if s==0: mask=dx*dx+dy*dy<=r*r\n                elif s==1: mask=np.maximum(abs(dx),abs(dy))<=r\n                else: mask=abs(dx)+abs(dy)<=r*1.35\n                # Red and blue have equal channel sums: grayscale erases hue by design.\n                rgb=np.array([.9,.15,.15] if c==0 else [.15,.15,.9])\n                bg=rng.uniform(.015,.075,(16,16,1))\n                im=np.where(mask[...,None],rgb*rng.uniform(.8,1),bg)\n                im+=rng.normal(0,.012,im.shape)\n                images.append(np.clip(im,0,1).transpose(2,0,1))\n                shape.append(s); color.append(c); split.append(0 if i<100 else 1)\n    x=np.asarray(images,dtype='float32'); split=np.asarray(split)\n    ids=np.arange(len(x)); train=ids[split==0]; test=ids[split==1]\n    assert set(train).isdisjoint(test)\n    assert len({hashlib.sha256(v.tobytes()).hexdigest() for v in x})==len(x)\n    return torch.from_numpy(x),np.asarray(shape),np.asarray(color),train,test\n\ndef views(x, destroy_color=False):\n    # Independent transforms of each source; no labels/scene attributes are read.\n    a=x.clone(); n=len(a)\n    shifts=torch.randint(-1,2,(n,2))\n    for i,(dy,dx) in enumerate(shifts.tolist()):\n        a[i]=torch.roll(a[i],(dy,dx),(-2,-1))\n    a=a*torch.empty(n,1,1,1).uniform_(.8,1.2)\n    a=a+torch.randn_like(a)*.025\n    # The ablation changes only the hue swap. Every run consumes this RNG draw.\n    swap=torch.rand(n)<.5\n    if destroy_color: a[swap]=a[swap][:,[2,1,0]]\n    return a.clamp(0,1)\n\nclass ImageEncoder(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.conv=nn.Sequential(nn.Conv2d(3,12,3,padding=1),nn.ReLU(),\n          nn.Conv2d(12,24,3,stride=2,padding=1),nn.ReLU(),\n          nn.Conv2d(24,24,3,stride=2,padding=1),nn.ReLU())\n        self.readout=nn.Linear(24*4*4,48)\n    def forward(self,x): return self.readout(self.conv(x).flatten(1))\n\nclass ContrastiveModel(nn.Module):\n    def __init__(self):\n        super().__init__(); self.encoder=ImageEncoder()\n        self.projector=nn.Sequential(nn.Linear(48,48),nn.ReLU(),nn.Linear(48,24))\n    def forward(self,x):\n        h=self.encoder(x); z=self.projector(h)\n        return h,z\n\ndef info_nce(z1,z2,tau=.2):\n    z=F.normalize(torch.cat([z1,z2]),dim=1); n=len(z1)\n    logits=z@z.T/tau\n    logits=logits.masked_fill(torch.eye(2*n,dtype=torch.bool),-1e9)\n    positive=(torch.arange(2*n)+n)%(2*n)\n    return F.cross_entropy(logits,positive)\n\ndef train_simclr(initial,x,train,destroy_color,epochs=40):\n    # Equal initialization, minibatch ordering, optimizer, steps, and RNG streams.\n    torch.manual_seed(SEED+1)\n    model=copy.deepcopy(initial); opt=torch.optim.Adam(model.parameters(),lr=.002)\n    history=[]; before=next(model.encoder.parameters()).detach().clone()\n    for epoch in range(epochs):\n        model.train(); losses=[]\n        for ids in torch.as_tensor(train)[torch.randperm(len(train))].split(60):\n            batch=x[ids]; a,b=views(batch,destroy_color),views(batch,destroy_color)\n            loss=info_nce(model(a)[1],model(b)[1])\n            opt.zero_grad(); loss.backward(); opt.step(); losses.append(float(loss.detach()))\n        history.append(float(np.mean(losses)))\n    delta=float((next(model.encoder.parameters()).detach()-before).norm())\n    assert delta>0\n    return model,history,delta\n```","sha256":"2124e4f903ef5e5b292d389935649c6cb9905e73f45aefd3d46b7687db7f6f73","chapter":{"id":"course","title":"图像、两视图与同源正例 · 实现代码"},"unit":{"id":"notebook-blocks/b4c113869cc04e4a9753038a5858a879","title":"图像、两视图与同源正例 · 实现代码"},"page":{"id":"reading-opening","title":"图像、两视图与同源正例 · 实现代码","number":1},"sectionTitle":"图像、两视图与同源正例 · 实现代码","currentQuestion":"图像、两视图与同源正例 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-8f60ed1afa4a8c76c4ca0917","nextBlock":null,"prerequisites":[{"id":"b-7bb76eb1a189af2a343b2cf1","url":"#b-7bb76eb1a189af2a343b2cf1","role":"section-title"},{"id":"b-3de58d08726ba70ecf74a154","url":"#b-3de58d08726ba70ecf74a154","role":"problem-context"}],"relatedBlocks":[]}]}
