1. ํ์ดํ ์น ํธ๋์คํฌ๋จธ๋ฅผ ํ์ฉํ ์์ฐ์ด ์ฒ๋ฆฌ์ ์ปดํจํฐ๋น์ ์ฌ์ธตํ์ต p601~623
2. Shusen Wang - Vision Transformer for Image Classification (์ ํ๋ธ)
3. ๊ณ ๋ ค๋ํ๊ต DSBA - [Paper Review] ViT
์์ฐ์ด ์ฒ๋ฆฌ์์์ ํธ๋์คํฌ๋จธ๋ ์ปดํจํฐ ๋น์ ์์๋ ๋ง์ ์ํฅ์ ์ฃผ์๋๋ฐ,
์ด์ ์ปดํจํฐ๋น์ ๊ด๋ จ ์ฐ๊ตฌ๋ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์ ์ ํ ์ดํ ์ ๋ชจ๋์ ์ฐฉ์ฉํ ๋ชจ๋ธ์ด ๋ง์์ง๋ง,
ViT(Vision Transformer)๋ ํธ๋์คํฌ๋จธ ๊ตฌ์กฐ ์์ฒด๋ฅผ ์ปดํจํฐ๋น์ ๋ถ์ผ์ ์ ์ฉํ ์ฒซ ๋ฒ์งธ ์ฐ๊ตฌ๋ค.
CNN ๋ชจ๋ธ์ ํฉ์ฑ๊ณฑ ๊ณ์ธต ๋ฐฉ๋ฒ์ ์ด๋ฏธ์ง ๋ถ๋ฅ๋ฅผ ์ํด์ ์ง์ญ ํน์ง์ ์ถ์ถํ๋ค๋ฉด
ViT๋ ์ ํ ์ดํ ์ ์ ์ฌ์ฉํด ์ ์ฒด ์ด๋ฏธ์ง๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
BERT์ ViT ๋ชจ๋ธ์ ๋ชจ๋ ํธ๋์คํฌ๋จธ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ฐ, ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ์๋ก ๋ค๋ฅด๋ค.
ViT ๋ชจ๋ธ์ ์ด๋ฏธ์ง๊ฐ ๊ฒฉ์๋ก ์์ ๋จ์์ ์ด๋ฏธ์ง ํจ์น๋ก ๋๋์ด ์์ฐจ์ ์ผ๋ก ์ ๋ ฅ๋๋ค.
ViT ๋ชจ๋ธ์ ์ฌ์ฉ๋๋ ์ ๋ ฅ ์ด๋ฏธ์ง ํจ์น๋ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ, ์์์ ์๋๋ก ํํ๋ ์ํ์ ๋ฐฐ์ด์ ๊ฐ์ ํ๋ค
ํฉ์ฑ๊ณฑ ๋ชจ๋ธ๊ณผ ViT ๋ชจ๋ธ ๋น๊ต
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง๊ณผ ํธ๋์คํฌ๋จธ๋ ์ด๋ฏธ์ง ํน์ง์ ์ ํํํ๋ ์๋ฒ ๋ฉ์ ๋ง๋ค๊ณ ์ ํ๋ ๋ชฉ์ ์ ๊ฐ์
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ ์๋ฒ ๋ฉ์ ์ด๋ฏธ์ง ํจ์น ์ค ์ผ๋ถ๋ง ์ ํํ์ฌ ํ์ตํ๋ฉฐ, ์ด๋ฅผ ํตํด ์ด๋ฏธ์ง ์ ์ฒด์ ํน์ง์ ์ถ์ถํจ
๋ฐ๋ฉด ViT ์๋ฒ ๋ฉ์ ์ด๋ฏธ์ง๋ฅผ ์์ ํจ์น๋ค๋ก ๋๋ ๊ฐ ํจ์น ๊ฐ์ ์๊ด๊ด๊ณ๋ฅผ ํ์ตํจ.
์ด๋ฅผ ์ํด ์ ํ ์ดํ ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด
๋ชจ๋ ์ด๋ฏธ์ง ํจ์น๊ฐ ์๋ก์๊ฒ ์ฃผ๋ ์ํฅ์ ๊ณ ๋ คํด
์ด๋ฏธ์ง์ ์ ์ฒด ํน์ง์ ์ถ์ถํจ.
๊ทธ๋ฌ๋ฏ๋ก ViT๋ ๋ชจ๋ ์ด๋ฏธ์ง ํจ์น๊ฐ ํ์ต์ ๊ด์ฌํ๋ฉฐ ๋์ ์์กด์ ์ด๋ฏธ์ง ํํ์ ์ ๊ณตํจ
์ข์ ์์ฉ ์์ญ(Receptive Field, RF)์ ๊ฐ์ง ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์
์ ์ฒด ์ด๋ฏธ์ง ์ ๋ณด๋ฅผ ํํํ๋ ๋ฐ ์๋ง์ ๊ณ์ธต์ด ํ์ํ์ง๋ง,
ํธ๋์คํฌ๋จธ ๋ชจ๋ธ์ ์ดํ ์ ๊ฑฐ๋ฆฌ(Attention Distance)๋ฅผ ๊ณ์ฐํ์ฌ
์ค์ง ํ ๊ฐ์ ViT ๋ ์ด์ด๋ก ์ ์ฒด ์ด๋ฏธ์ง ์ ๋ณด๋ฅผ ์ฝ๊ฒ ํํํ ์ ์๋ค.
ViT๋ ํฝ์ ๋จ์๋ก ์ฒ๋ฆฌํ๋ ํฉ์ฑ๊ณฑ ๋ชจ๋ธ๊ณผ ๋ฌ๋ฆฌ ํจ์น ๋จ์๋ก ์ด๋ฏธ์ง๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์
๋ ์์ ๋ชจ๋ธ๋ก๋ ๋์ ์ฑ๋ฅ์ ์ป์ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
ViT ๋ชจ๋ธ์ ์ ๋ ฅ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด ์์ด
ํฌ๊ธฐ๊ฐ ๋ค๋ฅธ ์ด๋ฏธ์ง๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ๋ง์ถ๋ ์ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ฉฐ,
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ด ์ด๋ฏธ์ง์ ๊ณต๊ฐ์ ์ธ ์์น ์ ๋ณด๋ฅผ ๊ณ ๋ คํ๋ ๋ฐ ๋นํด
ViT๋ ํจ์น ๊ฐ์ ์๋์ ์ธ ์์น ์ ๋ณด๋ง ๊ณ ๋ คํ๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ์ง ๋ณํ์ ์ทจ์ฝํ ์ ์๋ค
ViT์ ๊ท๋ฉ์ ํธํฅ
ํธํฅ์ ๊ฐ๋
์ด ์์ํจ..
ViT ๋ชจ๋ธ
์ ๋ ฅ ์ด๋ฏธ์ง๋ฅผ
ํธ๋์คํฌ๋จธ ๊ตฌ์กฐ์ ๋ง๊ฒ ์ผ์ ํ ํฌ๊ธฐ์ ํจ์น๋ก ๋๋ ๋ค์
๊ฐ ํจ์น๋ฅผ ๋ฒกํฐ ํํ๋ก ๋ณํํ๋
ํจ์น ์๋ฒ ๋ฉ(Patch Embedding)๊ณผ
๊ฐ ํจ์น์์ ๊ด๊ณ๋ฅผ ํ์ตํ๋ ์ธ์ฝ๋(Encoder) ๊ณ์ธต์ผ๋ก ๊ตฌ์ฑ๋จ
ํจ์น ์๋ฒ ๋ฉ๊ณผ ์ธ์ฝ๋ ๊ณ์ธต์ ํตํด
์ด๋ฏธ์ง์ ํน์ง์ ์ถ์ถํ๊ณ ๋ถ๋ฅ๋ ํ๊ท์ ๊ฐ์ ์์ ์ ๋ง๋ ์ถ๋ ฅ๊ฐ์ผ๋ก ๋ณํํด ์ฌ์ฉํจ
ํจ์น ์๋ฒ ๋ฉ
ํจ์น ์๋ฒ ๋ฉ(Patch Embedding)์ ์ ๋ ฅ ์ด๋ฏธ์ง๋ฅผ ์์ ํจ์น๋ก ๋ถํ ํ๋ ๊ณผ์ ์ ๋งํจ
์์ ํจ์น๋ก ๋ถํ ํ๊ธฐ ์ํด์๋ ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ๋ง์ถ๋ ์ ์ฒ๋ฆฌ๊ฐ ์ํ๋ผ์ผ ํจ
ํฌ๊ธฐ์ ๋ง๊ฒ ์ ๋ฐฉํฅ ํฌ๊ธฐ๋ก ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์กฐ์ ํจ
์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์ผ์ ํ ํฌ๊ธฐ๋ก ๋ณ๊ฒฝํ๋ค๋ฉด
์ ์ฒด ์ด๋ฏธ์ง๋ฅผ ํจ์น ํฌ๊ธฐ๋ก ๋ถํ ํด ์ํ์ ๋ฐฐ์ด์ ๋ง๋ฆ
์ด๋ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ ๊ณ์ธต์ ํ์ฉํจ
์ธ์ฝ๋ ๊ณ์ธต
๋ชจ๋ธ ์ค์ต
ํ๊น ํ์ด์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ FashionMNIST ๋ฐ์ดํฐ์ธํธ๋ฅผ ํ์ฉํด
ViT ๋ชจ๋ธ์ ๋ฏธ์ธ ์กฐ์ ํด๋ณธ๋ค
FashionMNIST ๋ฐ์ดํฐ์ธํธ๋ ๊ธฐ์กด์ MNIST ๋ฐ์ดํฐ์ธํธ๋ณด๋ค ๋ ๋ณต์กํ ์ด๋ฏธ์ง ๋ถ๋ฅ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง๋ค์ด์ง
FashionMNIST ๋ฐ์ดํฐ์ธํธ๋ ์๋ฅ ์ด๋ฏธ์ง๋ฅผ ๋ด๊ณ ์๋ ๋ฐ์ดํฐ์ธํธ๋ก
์ด 10๊ฐ์ ํด๋์ค์ 60000๊ฐ์ ํ๋ จ ๋ฐ์ดํฐ์ธํธ, 10000๊ฐ์ ํ ์คํธ ๋ฐ์ดํฐ์ธํธ๋ก ๊ตฌ์ฑ๋๋ค
๊ฐ๋จํ ์ค์ต์ ์ํด ํ์ต ๋ฐ์ดํฐ๋ฅผ 10000๊ฐ, ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ 1000๊ฐ๋ก ์ํ๋งํ๋ค
itertools ๋ชจ๋์์ chain ํจ์๋ฅผ ๊ฐ์ ธ์ต๋๋ค. chain ํจ์๋ ์ฌ๋ฌ ๊ฐ์ iterable์ ํ๋์ iterable๋ก ๊ฒฐํฉํฉ๋๋ค.
from collections import defaultdict
collections ๋ชจ๋์์ defaultdict๋ฅผ ๊ฐ์ ธ์ต๋๋ค. defaultdict๋ ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ง ๋์
๋๋ฆฌ๋ฅผ ์์ฑํ๋ ํด๋์ค์
๋๋ค.
from torch.utils.data import Subset
PyTorch์ ๋ฐ์ดํฐ์
์ ์ฌ์ฉํ๊ธฐ ์ํด Subset ํด๋์ค๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ด ํด๋์ค๋ ๋ฐ์ดํฐ์
์ ์ผ๋ถ๋ฅผ ๋ํ๋ด๋ ์๋ธ์
์ ๋ง๋ค์ด์ค๋๋ค.
๋ ผ๋ฌธ ๊ด๋ จ ๊ฐ์ ๋ด์ฉ
๊ฐ์์ง์ ์ฌ์ง์ Neural Network์ ๋ฃ์ผ๋ฉด ๋ฒกํฐ p๊ฐ์ ๋ด๋์๋ค.
์ด ๋ฒกํฐ p๊ฐ์ ์ด๋ฏธ์ง ๋ถ๋ฅ(image classification)์ ๊ฒฐ๊ณผ๋ค.
๋ฒกํฐ p์ ๊ฐ๊ฐ์ ์์(element)๋ class์ ์ฐ๊ด ๋์ด ์๋ค.
๊ทธ๋์ ๋ง์ฝ์ 8๊ฐ์ class๊ฐ ์์ผ๋ฉด ๋ฒกํฐ p๋ 8์ฐจ์์ด๋ค.
๋ฐ์ ๊ทธ๋ํ์ฒ๋ผ ๊ฐ๊ฐ์ ์์๋ค์ 0~1์ฌ์ด์ ๊ฐ์ ๊ฐ์ง๋ฉฐ
์ดํฉ์ 1๋ก ์๋ ดํ๋ค.
๋ฐ์ดํฐ์ ์ด ํด์๋ก ResNet๋ณด๋ค ๋ ํจ์จ์ ์ธ ์ฑ๋ฅ์ ๋ณด์
ViT is based on Transformer (for NLP)
์ผ๋จ ์ฒ์์ ViT ๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฅผ ๋๋ฆฌ๊ธฐ ์ํด์๋ ์ด๋ฏธ์ง๋ฅผ partitionํด์ผํจ (into Patches)
์ด๋ฏธ์ง๋ฅผ partitionํ ๋ sliding window๋ฅผ ์ด์ฉํ์ฌ ๋งค๋ฒ ๋ช ํฝ์ ์ฉ ์์ง์ธ๋ค
์ฌ๊ธฐ์ stride๋ how many pixels the sliding window moves each time
์์ ๊ฐ์ ์ํ์์ User Specifies ์กฐ๊ฑด์ patch size๊ฐ 16x16์ธ๋ฐ
stride๋ฅผ 1x1๋ก ํ๋ฉด patch๊ฐ ๋๋ฌด ๋ง์์ ธ์ ๊ณ์ฐ๋์ด ๋ง์์ง ๊ฒ์ (heavy computation)
9๊ฐ์ patch๋ก ๋๋ ์ก๋ค๊ณ ์๊ฐํด๋ณด์.
๋ชจ๋ patch๋ค์ ๋ ๊ฐ๊ฐ์ rgb ์ฑ๋์ด ์๋ ์ด๋ฏธ์ง๋ฅผ ํ์ฑํ๋ค
a patch is an order 3 tensor
์ด๋ ๊ฒ 9๊ฐ์ patch๋ค๋ก ์ชผ๊ฐฐ์ผ๋ฉด patch๋ค์ vectorizeํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค
vectorization์ด๋ tensor๋ฅผ ๋ฒกํฐ๋ก reshape ํ๋ ๊ฒ์ ์๋ฏธํ๋ค
์ patches ๋ถ๋ถ ์ดํด ๋ชปํจ..
n๊ฐ์ patches๋ค๋ก ๋๋ ์ง๊ณ ์ด patches๋ค์ด n๊ฐ์ ๋ฒกํฐ๋ก ๋๋ ์ก๋ค๊ณ ์๊ฐ์ ํด๋ณด์
์ด๋ ๊ฐ๊ฐ์ vector์์ dense layer์ ์ ์ฉํ๋ฉด
์ด๋ฌํ output์ด ๋์ค๋๋ฐ
์ด๋ linear activation function์ด ์ ์ฉ๋ ๊ฒ์ด ์๋๋ฏ๋ก
dense layer์ ์ ํํจ์์์ ์ ์ ์๋ค. (linear functions)
W๋ ํ๋ ฌ์ด๊ณ b๋ ๋ฒกํฐ์ธ๋ฐ ์ด๋ training data๋ฅผ ํตํด์ ์ ์ ์๋ ๊ฐ๋ค์ด๋ค
๊ทธ๋ฆฌ๊ณ ์ด dense layer์ ๋ชจ๋ ๋ฒกํฐ์์ ๋์ผํ parameter W, b๋ฅผ ๊ฐ๋๋ค
We need to add positional encoding to vector z1 to zn
the input image is split into n patches
each patch has a position which is an integer between 1 and n
positional encoding maps that integer into a vector
the shape of the vector is the same as z
Add the positional encoding vectors to the z vectors
This way, a z vector captures both the content and the position of a patch
The ViT paper empirically demonstrated the benefit of using positional encoding
Without position encoding the accuracy decreases by three percent
The paper tried several positional encoding methods
Those methods lead to almost the same accuracy
so it is okay to use any kind of positional encoding
์ positional encoding์ ์ค์ํ ๊น?
๋ ๋ฒ์งธ ์ด๋ฏธ์ง๋ patch๋ค์ ์ฌ๋ฐฐ์ดํ์ฌ ๊ทธ๋ฆผ์ ๋ํ๋๋ค. ๊ทธ๋์ ๋น์ฐํ ๊ฐ์์ง ๊ทธ๋ฆผ์ ๋ ๊ฐ๊ฐ ์๋ก ๋ค๋ฅด๊ฒ ๋๋๋ฐ
z๋ฒกํฐ๋ฅผ swapping ํ๋ ๊ฒ์ final output of transformer์ ์ํฅ์ ์ฃผ์ง ์์ ๊ฒ์
if the z vectors do not contain the positional encoding
๊ทธ๋ฌ๋ฉด transformer ์ ์ฅ์์๋ ๋ ์ด๋ฏธ์ง๊ฐ ๋๊ฐ๋ค๊ณ ํ๋จํ ๊ฒ์
๋น์ฐํ ์ด๊ฒ์ ์ฌ๋ฐ๋ฅด์ง ์์ ํ๋จ์ด๊ธฐ ๋๋ฌธ์
positional information์ patches์ ๋ถํ๊ณ z vectors์ positional encoding ์ ๋ถํ๋ ๊ฒ์
์ด๋ ๊ฒ ๋๋ฉด ๋ง์ฝ์ ์ด๋ฏธ์ง๊ฐ ๋ค์ฃฝ ๋ฐ์ฃฝ ๋์ ๋
positional encoding ์ด ๋ฐ๋ํ ๋๊น
๊ทธ๋ฌ๋ฉด transformer์ output์ด ๋ฌ๋ผ์ง ๊ฒ์ด๋ค
(๋ณต์ต : ์ฌ๊ธฐ์์ z1~zn ๋ฒกํฐ์ ๊ฒฐ๊ณผ๋ linear transformation๊ณผ positional encoding ์ ๊ฒฐ๊ณผ๋ค
they are the representations of the n patches
they capture both the content and the positions of the patches)
We use the CLS token for classification
Then the embedding layer takes the input of the CLS token and outputs vector z0
์ด๋ z0 has the same shape as the other z vectors
We use this CLS token because the output of transformer in this position will be used for classification
(BERT ๋ชจ๋ธ์ CLS ๊ด๋ จ๋ ๋ด์ฉ์ด ๋์ค๋๋ด!)
the output of this multi-head self-attention layer are sequence of n plus 1 vectors
the output of the dense layer are sequence of n plus 1 vectors
you can add many self attention layers and dense layers one by one if you want
besides from the layers
transformer actually uses skip connection and normalization
there are standard tricks for improving performance
๋ฉํฐํค๋ ์ ํ ์ดํ ์ ๋ ์ด์ด์ ๋ด์ค ๋ ์ด์ด๋ ํธ๋์คํฌ๋จธ์ encoder ๋คํธ์ํฌ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
์ด์ ๋ํ output์ n+1 ๋ฒกํฐ์ ์ํ์ค๋ค์ด๋ค
c0~cn์ transformer์ output์.
classification task๋ฅผ ์ํํ๊ธฐ ์ํด์๋ ์ฐ๋ฆฌ๋ c1~cn์ ๋ฒกํฐ๋ ํ์ ์์ด์ ๋ฌด์ํด๋ ์ข๋ค
์ฐ๋ฆฌ๊ฐ ํ์ํ ๊ฒ์ vector c0์ด๋ค
vector c0๋ feature vector extracted from the image
the classification is based on c0
๊ทธ๋์ ๋ฒกํฐ c0๋ฅผ softmax classifier์ ์ง์ด ๋ฃ์ผ๋ฉด ๋ฒกํฐ p๊ฐ ๋์ค๊ฒ ๋๊ณ
์ด ๋ฒกํฐ์ shape์ class์ ์์ ๊ฐ๋ค
๋ง์ฝ์ data set์ด 8๊ฐ์ class๋ฅผ ๊ฐ์ง๋ฉด
p๋ 8์ฐจ์์ด๋ค
p์ ๊ฐ์ ๋ํ๋ธ ๊ทธ๋ํ์
during training we compute the cross entropy of vector p and the ground truth
then compute the gradient of the cross entropy loss with respect to the model parameters
and perform gradient descent to update the parameters
์ด์ ViT์ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ดค์ผ๋
dataset์ train ์์ผ๋ด์ผํ๋ค
(Next step is to train the model on image data)
์ผ๋จ ๋ชจ๋ธ์ random intialize(์ด๊ธฐํ)ํ ํ
train the model on data set A
์ด๋ ์ด ๋ฐ์ดํฐ์ธํธ๋ large scale data set์ด์ฌ์ผ ํ๋ค
์ด๊ฒ์ pretraining ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค
๊ทธ๋์ ์์ pretrainํ ๋ชจ๋ธ์ ๊ฐ์ง๊ณ
dataset B๋ก training์ ๋ ์ํจ๋ค
๋ณดํต์ ๊ฒฝ์ฐ dataset A๋ณด๋ค๋ ํฌ๊ธฐ๊ฐ ์๊ณ
์ด๋ฌํ ๊ณผ์ ์ fine tuning์ด๋ผ๊ณ ํ๋ค
dataset B๋ ImageNet์ด ๋ ์ ์์
Dataset B is the target data set
๊ทธ๋์ test accuracy๋ฅผ ๊ตฌํ๊ธฐ ์ํด์ data set b๋ฅผ evaluation matrix๋ก ์ฌ์ฉํจ
๋ฐ์ดํฐ์์ด ์์ฒญ ํด์๋ก resnet๋ณด๋ค ์ข์
transformer requires very large data for pretraining
the bigger the pre-training data set
the greater the advantage of transformer over resnet
300M ์ด์์ด ๋ ์ข์ ๋ฏํจ
๋ ์ฆ๋ท์ ๊ฒฝ์ฐ 100m์ด๋ 300m์ด๋ ์ฐจ์ด๊ฐ ์์
the accuracy of resnet does not improve
as the number of samples grows from 100m to 300m
in sum ViT requires huge data for pre-training
Transformer is an advantage over cnn only when the data set for pretuning is sufficiently large
300m ์ด๋ฏธ์ง๋ ๋ถ์กฑํจ (not enough)
https://www.youtube.com/watch?v=HZ4j_U3FC94
https://github.com/wangshusen/DeepLearning?tab=readme-ov-file