# Conv2d tay

`Conv2d` của PyTorch thật ra tính tương quan chéo (cross-correlation): kernel trượt trên ảnh **không bị lật**. Bài này chạy một lớp conv với trọng số cho sẵn.

Ảnh `X` có shape `(1, 2, H, W)`: một ảnh, hai kênh. Trọng số `weight` có shape `(3, 2, 2, 2)`: ba kernel, mỗi kernel $2\times2$ trên cả hai kênh. Mỗi kernel có một bias. Ô đầu ra $(o, i, j)$ là

$$
b_o+\sum_{c}\sum_{u,v}W_{o,c,u,v}\,X_{c,\ i\cdot s+u\cdot d-p,\ j\cdot s+v\cdot d-p},
$$

với stride $s$, dilation $d$, padding $p$ (ô nằm ngoài ảnh tính bằng $0$).

## Dữ liệu vào

Mỗi tệp `input.json` gồm `X`, `weight`, `bias`, `stride`, `padding` và `dilation`.

## Kết quả

Một đối tượng JSON `{"output": [...]}` có shape `(1, 3, H_out, W_out)`.

## Chấm điểm

Có 20 test, mỗi test 5 điểm. Số thực được chấm với sai số khoảng $10^{-7}$.

## Ví dụ

```input
{
  "X": [
    [
      [
        [
          0.9941649847270383, 0.8714908410965864, 0.4778359318420114,
          -0.20362094367134093, 0.8034539093416588,
          -0.10027453719883658
        ],
        [
          -0.8648482046319442, -0.2130301157834983,
          -0.6578936361113877, 0.21772600459652044, 1.3850889084688136,
          1.8634260914104992
        ],
        [
          -1.2527331997986315, -0.4707816111094908,
          -0.7425036294286324, 0.6450882188831598,
          -0.29880416570218327, -1.0891469541920324
        ],
        [
          0.8033435534769493, -0.43478439722307866, 2.457454582730744,
          -0.6338210740064577, -0.7037795521940649, 0.7531111327089655
        ],
        [
          0.6263366991486764, -0.313342621950984, 1.3558802518118604,
          1.112885515204439, -1.3567707475615751, 0.3094659863268635
        ]
      ],
      [
        [
          0.7574717789521999, 1.105123118323312, 1.6236190880175154,
          -0.5761509831780386, 1.0722196283391285,
          -0.16145609361713362
        ],
        [
          -0.64338461600537, -0.9313659603090584, -0.1370129254299484,
          0.6511270684465356, 0.053839787449426926,
          -1.6471171249999417
        ],
        [
          0.2083156204451989, -0.7747172489119286, 2.823924984056371,
          -0.8487206457222503, 0.25661263805896567,
          0.32352377288020645
        ],
        [
          -0.3980148546181156, 0.07216566155558686, 0.5107334489314023,
          -0.9586381425138399, 0.6232986299065064, -1.2692790149342876
        ],
        [
          1.386728854325789, -0.21843193962922577, -0.832774545662875,
          0.7510103122104543, -1.1077306475074769, 1.4648801505380327
        ]
      ]
    ]
  ],
  "weight": [
    [
      [
        [-0.6656224886283981, -0.1864821966337601],
        [-0.1514703172479926, 0.37363081168314854]
      ],
      [
        [-1.0385591944125616, -0.3241147287416149],
        [0.3682096542710066, 0.8077865558183547]
      ]
    ],
    [
      [
        [0.29670538633665117, -0.8130354386403779],
        [0.8974657862190032, 1.2778490472464958]
      ],
      [
        [-1.3523799397398009, -0.5736624805112627],
        [1.523856789838555, -0.9977333998813952]
      ]
    ],
    [
      [
        [-0.230076087150105, 0.008629864788336928],
        [-0.7960030374661429, -0.25754399571856773]
      ],
      [
        [-1.288038371990468, -0.8996272217183028],
        [-0.8366453303762007, -0.1160305810858022]
      ]
    ]
  ],
  "bias": [0.5247383993976499, -0.062208514508075845, -1.0663812068072698],
  "stride": 1,
  "padding": 0,
  "dilation": 1
}
```

```output
{
  "output": [
    [
      [
        [
          -2.38222476995108, -2.4855847644766262, -0.5983110625955299,
          1.5290631510759474, -1.8768536239756517
        ],
        [
          1.5749405957397258, 3.5906655468621853, 1.56100474535285,
          -0.8867366761657783, -0.27261809752718286
        ],
        [
          1.1087373354756995, 2.289052364489781, -2.9544268740771185,
          0.9329133137681045, 0.14755473873677127
        ],
        [
          0.5832811376483922, -0.08368748701332762,
          -0.7020673548525129, 0.5776673526875621, 1.7133774746778758
        ]
      ],
      [
        [
          -3.2337077488793247, -4.932527690824646, -2.7907700210605375,
          2.292065245443437, 4.2499553837424
        ],
        [
          0.6233089817723445, -3.6217653998620474, 4.685346263683165,
          -3.3874331874570576, -1.885880653517321
        ],
        [
          -0.40156991980667, 2.179968254223109, -1.0088295518350647,
          -2.1781551185096415, 2.748982708180901
        ],
        [
          3.519335750001745, -0.6303690720382181, 1.6620981691971823,
          2.7754915264208067, -4.969915785377326
        ]
      ],
      [
        [
          -1.8678074126797433, -3.012729815532116, -2.2443477484648775,
          -2.316133965172847, -3.9242898509815003
        ],
        [
          1.831378518526195, 1.186322904046677, -3.161679952097028,
          -1.7478677229804596, 0.309587628126696
        ],
        [
          -0.5564457738335163, -2.9135382997682573, -5.872749310216174,
          1.0604459458662148, -1.6365637175646475
        ],
        [
          -2.3599491067264045, -1.3179618302766587, -2.188984852307358,
          -1.2888320897470753, 1.19818559529604
        ]
      ]
    ]
  ]
}
```

::: goal Nộp bài
Tải bộ kit ở nút **Dữ liệu** rồi giải nén. Viết hàm `solve` trong `starter.py` hoặc `starter.ipynb` rồi chạy. Chương trình tự đi qua các thư mục `inputs/01`, `inputs/02`, … và gói kết quả thành `output/submission.zip`, gồm các tệp `01.json`, `02.json`, …, `20.json`. Nộp tệp ZIP ấy, chọn **Output**.
:::
