Deep Learning
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Deep Learning
๋ฅ ๋ฌ๋์ ์ฌ๋ฌ ์ธต(๋ฅ ์ ๊ฒฝ๋ง)์ ๊ฐ์ง ์ ๊ฒฝ๋ง์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ณต์กํ ํจํด์ ๋ชจ๋ธ๋งํ๋ ๋จธ์ ๋ฌ๋์ ํ์ ์งํฉ์ ๋๋ค. ์ปดํจํฐ ๋น์ , ์์ฐ์ด ์ฒ๋ฆฌ ๋ฐ ์์ฑ ์ธ์ ๋ฑ ๋ค์ํ ๋ถ์ผ์์ ๋๋ผ์ด ์ฑ๊ณต์ ๊ฑฐ๋์์ต๋๋ค.
Neural Networks
์ ๊ฒฝ๋ง์ ๋ฅ ๋ฌ๋์ ๊ธฐ๋ณธ ๊ตฌ์ฑ ์์์ ๋๋ค. ์ด๋ค์ ์ธต์ผ๋ก ๊ตฌ์ฑ๋ ์ํธ ์ฐ๊ฒฐ๋ ๋ ธ๋(๋ด๋ฐ)๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค. ๊ฐ ๋ด๋ฐ์ ์ ๋ ฅ์ ๋ฐ๊ณ , ๊ฐ์ค์น ํฉ์ ์ ์ฉํ ํ, ํ์ฑํ ํจ์๋ฅผ ํตํด ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅ์ผ๋ก ์ ๋ฌํฉ๋๋ค. ์ธต์ ๋ค์๊ณผ ๊ฐ์ด ๋ถ๋ฅํ ์ ์์ต๋๋ค:
- Input Layer: ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ์ฒซ ๋ฒ์งธ ์ธต.
- Hidden Layers: ์ ๋ ฅ ๋ฐ์ดํฐ์ ๋ณํ์ ์ํํ๋ ์ค๊ฐ ์ธต. ์จ๊ฒจ์ง ์ธต๊ณผ ๊ฐ ์ธต์ ๋ด๋ฐ ์๋ ๋ค์ํ ์ ์์ผ๋ฉฐ, ์ด๋ ์๋ก ๋ค๋ฅธ ์ํคํ ์ฒ๋ก ์ด์ด์ง๋๋ค.
- Output Layer: ๋คํธ์ํฌ์ ์ถ๋ ฅ์ ์์ฑํ๋ ์ต์ข ์ธต์ผ๋ก, ๋ถ๋ฅ ์์ ์์ ํด๋์ค ํ๋ฅ ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Activation Functions
๋ด๋ฐ์ ์ธต์ด ์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋, ๊ฐ ๋ด๋ฐ์ ์
๋ ฅ์ ๊ฐ์ค์น์ ํธํฅ์ ์ ์ฉํฉ๋๋ค(z = w * x + b), ์ฌ๊ธฐ์ w๋ ๊ฐ์ค์น, x๋ ์
๋ ฅ, b๋ ํธํฅ์
๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ด๋ฐ์ ์ถ๋ ฅ์ ๋ชจ๋ธ์ ๋น์ ํ์ฑ์ ๋์
ํ๊ธฐ ์ํด ํ์ฑํ ํจ์๋ฅผ ํต๊ณผํฉ๋๋ค. ์ด ํ์ฑํ ํจ์๋ ๋ค์ ๋ด๋ฐ์ด โํ์ฑํ๋์ด์ผ ํ๋์ง์ ์ผ๋ง๋โ๋ฅผ ๋ํ๋
๋๋ค. ์ด๋ฅผ ํตํด ๋คํธ์ํฌ๋ ๋ฐ์ดํฐ์ ๋ณต์กํ ํจํด๊ณผ ๊ด๊ณ๋ฅผ ํ์ตํ ์ ์์ผ๋ฉฐ, ๋ชจ๋ ์ฐ์ ํจ์๋ฅผ ๊ทผ์ฌํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ํ์ฑํ ํจ์๋ ์ ๊ฒฝ๋ง์ ๋น์ ํ์ฑ์ ๋์ ํ์ฌ ๋ฐ์ดํฐ์ ๋ณต์กํ ๊ด๊ณ๋ฅผ ํ์ตํ ์ ์๊ฒ ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ํ์ฑํ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Sigmoid: ์ ๋ ฅ ๊ฐ์ 0๊ณผ 1 ์ฌ์ด์ ๋ฒ์๋ก ๋งคํํ๋ฉฐ, ์ด์ง ๋ถ๋ฅ์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
- ReLU (Rectified Linear Unit): ์ ๋ ฅ์ด ์์์ผ ๊ฒฝ์ฐ ์ ๋ ฅ์ ์ง์ ์ถ๋ ฅํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด 0์ ์ถ๋ ฅํฉ๋๋ค. ์ด๋ ๋จ์์ฑ๊ณผ ๋ฅ ๋คํธ์ํฌ ํ๋ จ์ ํจ๊ณผ์ฑ ๋๋ถ์ ๋๋ฆฌ ์ฌ์ฉ๋ฉ๋๋ค.
- Tanh: ์ ๋ ฅ ๊ฐ์ -1๊ณผ 1 ์ฌ์ด์ ๋ฒ์๋ก ๋งคํํ๋ฉฐ, ์ฃผ๋ก ์จ๊ฒจ์ง ์ธต์์ ์ฌ์ฉ๋ฉ๋๋ค.
- Softmax: ์์ ์ ์๋ฅผ ํ๋ฅ ๋ก ๋ณํํ๋ฉฐ, ๋ค์ค ํด๋์ค ๋ถ๋ฅ๋ฅผ ์ํ ์ถ๋ ฅ ์ธต์์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
Backpropagation
์ญ์ ํ๋ ๋ด๋ฐ ๊ฐ์ ์ฐ๊ฒฐ ๊ฐ์ค์น๋ฅผ ์กฐ์ ํ์ฌ ์ ๊ฒฝ๋ง์ ํ๋ จ์ํค๋ ๋ฐ ์ฌ์ฉ๋๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ด๋ ์์ค ํจ์์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๊ฐ ๊ฐ์ค์น์ ๋ํด ๊ณ์ฐํ๊ณ , ์์ค์ ์ต์ํํ๊ธฐ ์ํด ๊ธฐ์ธ๊ธฐ์ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค. ์ญ์ ํ์ ํฌํจ๋ ๋จ๊ณ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Forward Pass: ์ ๋ ฅ์ ์ธต์ ํตํด ์ ๋ฌํ๊ณ ํ์ฑํ ํจ์๋ฅผ ์ ์ฉํ์ฌ ๋คํธ์ํฌ์ ์ถ๋ ฅ์ ๊ณ์ฐํฉ๋๋ค.
- Loss Calculation: ์์ธก๋ ์ถ๋ ฅ๊ณผ ์ค์ ๋ชฉํ ๊ฐ์ ์์ค(์ค๋ฅ)์ ์์ค ํจ์(์: ํ๊ท์ ๊ฒฝ์ฐ ํ๊ท ์ ๊ณฑ ์ค์ฐจ, ๋ถ๋ฅ์ ๊ฒฝ์ฐ ๊ต์ฐจ ์ํธ๋กํผ)๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ์ฐํฉ๋๋ค.
- Backward Pass: ๋ฏธ๋ถ ๋ฒ์น์ ์ฌ์ฉํ์ฌ ๊ฐ ๊ฐ์ค์น์ ๋ํ ์์ค์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค.
- Weight Update: ์์ค์ ์ต์ํํ๊ธฐ ์ํด ์ต์ ํ ์๊ณ ๋ฆฌ์ฆ(์: ํ๋ฅ ์ ๊ฒฝ๋ ํ๊ฐ๋ฒ, Adam)์ ์ฌ์ฉํ์ฌ ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
Convolutional Neural Networks (CNNs)
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง(CNN)์ ์ด๋ฏธ์ง์ ๊ฐ์ ๊ฒฉ์ ํํ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๊ณ๋ ํน์ํ ์ ํ์ ์ ๊ฒฝ๋ง์ ๋๋ค. ์ด๋ค์ ๊ณต๊ฐ์ ํน์ง์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์๋์ผ๋ก ํ์ตํ ์ ์๋ ๋ฅ๋ ฅ ๋๋ถ์ ์ปดํจํฐ ๋น์ ์์ ์์ ํนํ ํจ๊ณผ์ ์ ๋๋ค.
CNN์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Convolutional Layers: ์ ๋ ฅ ๋ฐ์ดํฐ์ ๋ํด ํ์ต ๊ฐ๋ฅํ ํํฐ(์ปค๋)๋ฅผ ์ฌ์ฉํ์ฌ ํฉ์ฑ๊ณฑ ์ฐ์ฐ์ ์ ์ฉํ์ฌ ์ง์ญ ํน์ง์ ์ถ์ถํฉ๋๋ค. ๊ฐ ํํฐ๋ ์ ๋ ฅ ์๋ฅผ ์ฌ๋ผ์ด๋ํ๋ฉฐ ์ ๊ณฑ์ ๊ณ์ฐํ์ฌ ํน์ง ๋งต์ ์์ฑํฉ๋๋ค.
- Pooling Layers: ์ค์ํ ํน์ง์ ์ ์งํ๋ฉด์ ํน์ง ๋งต์ ๊ณต๊ฐ ์ฐจ์์ ์ค์ ๋๋ค. ์ผ๋ฐ์ ์ธ ํ๋ง ์ฐ์ฐ์๋ ์ต๋ ํ๋ง๊ณผ ํ๊ท ํ๋ง์ด ํฌํจ๋ฉ๋๋ค.
- Fully Connected Layers: ํ ์ธต์ ๋ชจ๋ ๋ด๋ฐ์ ๋ค์ ์ธต์ ๋ชจ๋ ๋ด๋ฐ์ ์ฐ๊ฒฐํ๋ฉฐ, ์ ํต์ ์ธ ์ ๊ฒฝ๋ง๊ณผ ์ ์ฌํฉ๋๋ค. ์ด๋ฌํ ์ธต์ ์ผ๋ฐ์ ์ผ๋ก ๋ถ๋ฅ ์์ ์ ์ํด ๋คํธ์ํฌ์ ๋์์ ์ฌ์ฉ๋ฉ๋๋ค.
CNN์ Convolutional Layers ๋ด๋ถ์์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ๋ถ๋ ๊ฐ๋ฅํฉ๋๋ค:
- Initial Convolutional Layer: ์์ ์ ๋ ฅ ๋ฐ์ดํฐ(์: ์ด๋ฏธ์ง)๋ฅผ ์ฒ๋ฆฌํ๋ ์ฒซ ๋ฒ์งธ ํฉ์ฑ๊ณฑ ์ธต์ผ๋ก, ์ฃ์ง ๋ฐ ํ ์ค์ฒ์ ๊ฐ์ ๊ธฐ๋ณธ ํน์ง์ ์๋ณํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
- Intermediate Convolutional Layers: ์ด๊ธฐ ์ธต์์ ํ์ตํ ํน์ง์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ํ์ ํฉ์ฑ๊ณฑ ์ธต์ผ๋ก, ๋คํธ์ํฌ๊ฐ ๋ ๋ณต์กํ ํจํด๊ณผ ํํ์ ํ์ตํ ์ ์๊ฒ ํฉ๋๋ค.
- Final Convolutional Layer: ์์ ์ฐ๊ฒฐ ์ธต ์ด์ ์ ๋ง์ง๋ง ํฉ์ฑ๊ณฑ ์ธต์ผ๋ก, ๊ณ ์์ค์ ํน์ง์ ์บก์ฒํ๊ณ ๋ถ๋ฅ๋ฅผ ์ํด ๋ฐ์ดํฐ๋ฅผ ์ค๋นํฉ๋๋ค.
Tip
CNN์ ๊ฒฉ์ ํํ์ ๋ฐ์ดํฐ์์ ํน์ง์ ๊ณต๊ฐ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ตํ๊ณ ๊ฐ์ค์น ๊ณต์ ๋ฅผ ํตํด ๋งค๊ฐ๋ณ์ ์๋ฅผ ์ค์ผ ์ ์๋ ๋ฅ๋ ฅ ๋๋ถ์ ์ด๋ฏธ์ง ๋ถ๋ฅ, ๊ฐ์ฒด ํ์ง ๋ฐ ์ด๋ฏธ์ง ๋ถํ ์์ ์ ํนํ ํจ๊ณผ์ ์ ๋๋ค. ๋ํ, ์ด๋ค์ ์ด์ ๋ฐ์ดํฐ(ํฝ์ )๊ฐ ๋จผ ํฝ์ ๋ณด๋ค ๋ ๊ด๋ จ์ฑ์ด ๋์ ๊ฐ๋ฅ์ฑ์ด ์๋ ํน์ง ์ง์ญ์ฑ ์์น์ ์ง์ํ๋ ๋ฐ์ดํฐ์์ ๋ ์ ์๋ํฉ๋๋ค. ์ด๋ ํ ์คํธ์ ๊ฐ์ ๋ค๋ฅธ ์ ํ์ ๋ฐ์ดํฐ์์๋ ํด๋น๋์ง ์์ ์ ์์ต๋๋ค. ๋ํ, CNN์ด ๋ณต์กํ ํน์ง์ ์๋ณํ ์ ์์ง๋ง ๊ณต๊ฐ์ ๋งฅ๋ฝ์ ์ ์ฉํ ์ ์๋ค๋ ์ ์ ์ ์ํ์ญ์์ค. ์ฆ, ์ด๋ฏธ์ง์ ์๋ก ๋ค๋ฅธ ๋ถ๋ถ์์ ๋ฐ๊ฒฌ๋ ๋์ผํ ํน์ง์ ๋์ผํ ๊ฒ์ ๋๋ค.
Example defining a CNN
์ฌ๊ธฐ์์๋ 48x48 ํฌ๊ธฐ์ RGB ์ด๋ฏธ์ง ๋ฐฐ์น๋ฅผ ๋ฐ์ดํฐ์ ์ผ๋ก ์ฌ์ฉํ๊ณ , ํน์ง์ ์ถ์ถํ๊ธฐ ์ํด ํฉ์ฑ๊ณฑ ์ธต๊ณผ ์ต๋ ํ๋ง์ ์ฌ์ฉํ๋ฉฐ, ๋ถ๋ฅ๋ฅผ ์ํด ์์ ์ฐ๊ฒฐ ์ธต์ ์ฌ์ฉํ๋ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง(CNN)์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ค๋ช ์ ์ฐพ์ ์ ์์ต๋๋ค.
๋ค์์ PyTorch์์ 1๊ฐ์ ํฉ์ฑ๊ณฑ ์ธต์ ์ ์ํ๋ ๋ฐฉ๋ฒ์
๋๋ค: self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1).
-
in_channels: ์ ๋ ฅ ์ฑ๋ ์. RGB ์ด๋ฏธ์ง์ ๊ฒฝ์ฐ, ์ด๋ 3(๊ฐ ์์ ์ฑ๋๋ง๋ค ํ๋)์ ๋๋ค. ๊ทธ๋ ์ด์ค์ผ์ผ ์ด๋ฏธ์ง์ ๊ฒฝ์ฐ, ์ด๋ 1์ด ๋ฉ๋๋ค. -
out_channels: ํฉ์ฑ๊ณฑ ์ธต์ด ํ์ตํ ์ถ๋ ฅ ์ฑ๋(ํํฐ) ์์ ๋๋ค. ์ด๋ ๋ชจ๋ธ ์ํคํ ์ฒ์ ๋ฐ๋ผ ์กฐ์ ํ ์ ์๋ ํ์ดํผํ๋ผ๋ฏธํฐ์ ๋๋ค. -
kernel_size: ํฉ์ฑ๊ณฑ ํํฐ์ ํฌ๊ธฐ์ ๋๋ค. ์ผ๋ฐ์ ์ธ ์ ํ์ 3x3์ด๋ฉฐ, ์ด๋ ํํฐ๊ฐ ์ ๋ ฅ ์ด๋ฏธ์ง์ 3x3 ์์ญ์ ์ปค๋ฒํจ์ ์๋ฏธํฉ๋๋ค. ์ด๋ in_channels์์ out_channels๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉ๋๋ 3ร3ร3 ์์ ์คํฌํ์ ๊ฐ์ต๋๋ค:
- ๊ทธ 3ร3ร3 ์คํฌํ๋ฅผ ์ด๋ฏธ์ง ํ๋ธ์ ์ผ์ชฝ ์๋จ ๋ชจ์๋ฆฌ์ ๋์ต๋๋ค.
- ๊ฐ ๊ฐ์ค์น๋ฅผ ๊ทธ ์๋์ ํฝ์ ์ ๊ณฑํ๊ณ ๋ชจ๋ ๋ํ ํ, ํธํฅ์ ์ถ๊ฐํ์ฌ ํ๋์ ์ซ์๋ฅผ ์ป์ต๋๋ค.
- ๊ทธ ์ซ์๋ฅผ ๋น ๋งต์ ์์น(0, 0)์ ๊ธฐ๋กํฉ๋๋ค.
- ์คํฌํ๋ฅผ ์ค๋ฅธ์ชฝ์ผ๋ก ํ ํฝ์ ์ฌ๋ผ์ด๋(์คํธ๋ผ์ด๋ = 1)ํ๊ณ ์ ์ฒด 48ร48 ๊ทธ๋ฆฌ๋๋ฅผ ์ฑ์ธ ๋๊น์ง ๋ฐ๋ณตํฉ๋๋ค.
padding: ์ ๋ ฅ์ ๊ฐ ์ธก๋ฉด์ ์ถ๊ฐ๋๋ ํฝ์ ์์ ๋๋ค. ํจ๋ฉ์ ์ ๋ ฅ์ ๊ณต๊ฐ ์ฐจ์์ ๋ณด์กดํ๋ ๋ฐ ๋์์ด ๋์ด ์ถ๋ ฅ ํฌ๊ธฐ๋ฅผ ๋ ์ ์ ์ดํ ์ ์๊ฒ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, 3x3 ์ปค๋์ ๊ฐ์ง 48x48 ํฝ์ ์ ๋ ฅ์ ๊ฒฝ์ฐ, ํจ๋ฉ 1์ ํฉ์ฑ๊ณฑ ์ฐ์ฐ ํ ์ถ๋ ฅ ํฌ๊ธฐ๋ฅผ ๋์ผํ๊ฒ ์ ์งํฉ๋๋ค(48x48). ์ด๋ ํจ๋ฉ์ด ์ ๋ ฅ ์ด๋ฏธ์ง ์ฃผ์์ 1ํฝ์ ์ ๊ฒฝ๊ณ๋ฅผ ์ถ๊ฐํ์ฌ ์ปค๋์ด ๊ฐ์ฅ์๋ฆฌ๋ฅผ ์ฌ๋ผ์ด๋ํ ์ ์๊ฒ ํ์ฌ ๊ณต๊ฐ ์ฐจ์์ ์ค์ด์ง ์๋๋ก ํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์ด ์ธต์ ํ์ต ๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- (3x3x3 (์ปค๋ ํฌ๊ธฐ) + 1 (ํธํฅ)) x 32 (out_channels) = 896 ํ์ต ๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์.
๊ฐ ํฉ์ฑ๊ณฑ ์ธต์ ๊ธฐ๋ฅ์ ์ ๋ ฅ์ ์ ํ ๋ณํ์ ํ์ตํ๋ ๊ฒ์ด๋ฏ๋ก ์ฌ์ฉ๋ ๊ฐ ์ปค๋๋ง๋ค ํธํฅ(+1)์ด ์ถ๊ฐ๋ฉ๋๋ค. ์ด๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์ ์์ผ๋ก ํํ๋ฉ๋๋ค:
Y = f(W * X + b)
W๋ ๊ฐ์ค์น ํ๋ ฌ(ํ์ต๋ ํํฐ, 3x3x3 = 27๊ฐ์ ๋งค๊ฐ๋ณ์)์ด๊ณ , b๋ ๊ฐ ์ถ๋ ฅ ์ฑ๋์ ๋ํด +1์ธ ๋ฐ์ด์ด์ค ๋ฒกํฐ์
๋๋ค.
self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1)์ ์ถ๋ ฅ์ (batch_size, 32, 48, 48) ํํ์ ํ
์๊ฐ ๋ ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์ 32๋ 48x48 ํฝ์
ํฌ๊ธฐ์ ์๋ก ์์ฑ๋ ์ฑ๋ ์์
๋๋ค.
๊ทธ๋ฐ ๋ค์, ์ด ํฉ์ฑ๊ณฑ ์ธต์ ๋ค๋ฅธ ํฉ์ฑ๊ณฑ ์ธต์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค: self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1).
์ด๊ฒ์ ๋ค์์ ์ถ๊ฐํฉ๋๋ค: (32x3x3 (์ปค๋ ํฌ๊ธฐ) + 1 (๋ฐ์ด์ด์ค)) x 64 (์ถ๋ ฅ ์ฑ๋) = 18,496๊ฐ์ ํ์ต ๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์์ (batch_size, 64, 48, 48) ํํ์ ์ถ๋ ฅ์ ์์ฑํฉ๋๋ค.
๋ณด์๋ค์ํผ ๋งค๊ฐ๋ณ์์ ์๋ ๊ฐ ์ถ๊ฐ ํฉ์ฑ๊ณฑ ์ธต๊ณผ ํจ๊ป ๋น ๋ฅด๊ฒ ์ฆ๊ฐํฉ๋๋ค, ํนํ ์ถ๋ ฅ ์ฑ๋ ์๊ฐ ์ฆ๊ฐํจ์ ๋ฐ๋ผ.
๋ฐ์ดํฐ ์ฌ์ฉ๋์ ์ ์ดํ๋ ํ ๊ฐ์ง ์ต์ ์ ๊ฐ ํฉ์ฑ๊ณฑ ์ธต ๋ค์ ์ต๋ ํ๋ง์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ต๋ ํ๋ง์ ํน์ง ๋งต์ ๊ณต๊ฐ ์ฐจ์์ ์ค์ฌ ๋งค๊ฐ๋ณ์ ์์ ๊ณ์ฐ ๋ณต์ก์ฑ์ ์ค์ด๋ ๋ฐ ๋์์ด ๋๋ฉฐ ์ค์ํ ํน์ง์ ์ ์งํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์ ์ธํ ์ ์์ต๋๋ค: self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2). ์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก 2x2 ํฝ์
๊ทธ๋ฆฌ๋๋ฅผ ์ฌ์ฉํ๊ณ ๊ฐ ๊ทธ๋ฆฌ๋์์ ์ต๋ ๊ฐ์ ์ทจํด ํน์ง ๋งต์ ํฌ๊ธฐ๋ฅผ ์ ๋ฐ์ผ๋ก ์ค์ด๋ ๊ฒ์ ๋ํ๋
๋๋ค. ๋ํ, stride=2๋ ํ๋ง ์์
์ด ํ ๋ฒ์ 2ํฝ์
์ฉ ์ด๋ํจ์ ์๋ฏธํ๋ฉฐ, ์ด ๊ฒฝ์ฐ ํ๋ง ์์ญ ๊ฐ์ ๊ฒน์นจ์ ๋ฐฉ์งํฉ๋๋ค.
์ด ํ๋ง ์ธต์ ์ฌ์ฉํ๋ฉด ์ฒซ ๋ฒ์งธ ํฉ์ฑ๊ณฑ ์ธต ์ดํ์ ์ถ๋ ฅ ํํ๋ self.conv2์ ์ถ๋ ฅ์ self.pool1์ ์ ์ฉํ ํ (batch_size, 64, 24, 24)๊ฐ ๋์ด ์ด์ ์ธต์ ํฌ๊ธฐ๋ฅผ 1/4๋ก ์ค์
๋๋ค.
Tip
ํฉ์ฑ๊ณฑ ์ธต ๋ค์ ํ๋ง์ ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ ํน์ง ๋งต์ ๊ณต๊ฐ ์ฐจ์์ ์ค์ฌ ๋งค๊ฐ๋ณ์ ์์ ๊ณ์ฐ ๋ณต์ก์ฑ์ ์ ์ดํ๋ ๋ฐ ๋์์ด ๋๋ฉฐ, ์ด๊ธฐ ๋งค๊ฐ๋ณ์๊ฐ ์ค์ํ ํน์ง์ ํ์ตํ๋๋ก ํฉ๋๋ค. ํ๋ง ์ธต ์์ ํฉ์ฑ๊ณฑ์ ์ ๋ ฅ ๋ฐ์ดํฐ์์ ํน์ง์ ์ถ์ถํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ณผ ์ ์์ต๋๋ค(์: ์ , ๋ชจ์๋ฆฌ). ์ด ์ ๋ณด๋ ์ฌ์ ํ ํ๋ง๋ ์ถ๋ ฅ์ ์กด์ฌํ์ง๋ง, ๋ค์ ํฉ์ฑ๊ณฑ ์ธต์ ์๋ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ณผ ์ ์๊ณ , ์ค์ง ํ๋ง๋ ์ถ๋ ฅ๋ง ๋ณผ ์ ์์ต๋๋ค. ์ด๋ ์ด์ ์ธต์ ์ ๋ณด๊ฐ ์ถ์๋ ๋ฒ์ ์ ๋๋ค. ์ผ๋ฐ์ ์ธ ์์:
Conv โ ReLU โ Pool์์ ๊ฐ 2ร2 ํ๋ง ์ฐฝ์ ์ด์ ํน์ง ํ์ฑํ(โ๋ชจ์๋ฆฌ ์กด์ฌ / ์์โ)์ ๊ฒฝ์ํ๋ฉฐ, ์์ ํฝ์ ๊ฐ๋์๋ ๋ค๋ฆ ๋๋ค. ๊ฐ์ฅ ๊ฐํ ํ์ฑํ๋ฅผ ์ ์งํ๋ ๊ฒ์ ์ ๋ง๋ก ๊ฐ์ฅ ๋๋๋ฌ์ง ์ฆ๊ฑฐ๋ฅผ ์ ์งํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ํ์ํ ๋งํผ์ ํฉ์ฑ๊ณฑ ๋ฐ ํ๋ง ์ธต์ ์ถ๊ฐํ ํ, ์ถ๋ ฅ์ ํํํํ์ฌ ์์ ์ฐ๊ฒฐ ์ธต์ ๊ณต๊ธํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐฐ์น์ ๊ฐ ์ํ์ ๋ํด ํ ์๋ฅผ 1D ๋ฒกํฐ๋ก ์ฌ๊ตฌ์ฑํ์ฌ ์ํ๋ฉ๋๋ค:
x = x.view(-1, 64*24*24)
๊ทธ๋ฆฌ๊ณ ์ด์ ์ ํฉ์ฑ๊ณฑ ๋ฐ ํ๋ง ๋ ์ด์ด์์ ์์ฑ๋ ๋ชจ๋ ํ๋ จ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์ด 1D ๋ฒกํฐ๋ก, ๋ค์๊ณผ ๊ฐ์ด ์์ ์ฐ๊ฒฐ ๋ ์ด์ด๋ฅผ ์ ์ํ ์ ์์ต๋๋ค:
self.fc1 = nn.Linear(64 * 24 * 24, 512)
์ด ๋ ์ด์ด๋ ์ด์ ๋ ์ด์ด์ ํํํ๋ ์ถ๋ ฅ์ ๊ฐ์ ธ์ 512๊ฐ์ ์จ๊ฒจ์ง ์ ๋์ ๋งคํํฉ๋๋ค.
์ด ๋ ์ด์ด๊ฐ ์ถ๊ฐํ (64 * 24 * 24 + 1 (bias)) * 512 = 3,221,504 ๊ฐ์ ํ์ต ๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์๋ฅผ ์ฃผ๋ชฉํ์ธ์. ์ด๋ ํฉ์ฑ๊ณฑ ๋ ์ด์ด์ ๋นํด ์๋นํ ์ฆ๊ฐ์
๋๋ค. ์ด๋ ์์ ์ฐ๊ฒฐ ๋ ์ด์ด๊ฐ ํ ๋ ์ด์ด์ ๋ชจ๋ ๋ด๋ฐ์ ๋ค์ ๋ ์ด์ด์ ๋ชจ๋ ๋ด๋ฐ์ ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ ๋งค๊ฐ๋ณ์์ ์๊ฐ ๋ง์์ง๋๋ค.
๋ง์ง๋ง์ผ๋ก, ์ต์ข ํด๋์ค ๋ก์ง์ ์์ฑํ๊ธฐ ์ํด ์ถ๋ ฅ ๋ ์ด์ด๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค:
self.fc2 = nn.Linear(512, num_classes)
์ด๊ฒ์ (512 + 1 (bias)) * num_classes์ ํ์ต ๊ฐ๋ฅํ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ฌ๊ธฐ์ num_classes๋ ๋ถ๋ฅ ์์
์ ํด๋์ค ์์
๋๋ค (์: GTSRB ๋ฐ์ดํฐ์
์ ๊ฒฝ์ฐ 43).
๋ ๋ค๋ฅธ ์ผ๋ฐ์ ์ธ ๊ดํ์ ๊ณผ์ ํฉ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์์ ์ฐ๊ฒฐ ๊ณ์ธต ์ ์ ๋๋กญ์์ ๋ ์ด์ด๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ํํ ์ ์์ต๋๋ค:
self.dropout = nn.Dropout(0.5)
์ด ๋ ์ด์ด๋ ํ๋ จ ์ค ์ ๋ ฅ ์ ๋์ ์ผ๋ถ๋ฅผ ๋ฌด์์๋ก 0์ผ๋ก ์ค์ ํ์ฌ ํน์ ๋ด๋ฐ์ ๋ํ ์์กด๋๋ฅผ ์ค์์ผ๋ก์จ ๊ณผ์ ํฉ์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ ์ค๋๋ค.
CNN ์ฝ๋ ์์
import torch
import torch.nn as nn
import torch.nn.functional as F
class MY_NET(nn.Module):
def __init__(self, num_classes=32):
super(MY_NET, self).__init__()
# Initial conv layer: 3 input channels (RGB), 32 output channels, 3x3 kernel, padding 1
# This layer will learn basic features like edges and textures
self.conv1 = nn.Conv2d(
in_channels=3, out_channels=32, kernel_size=3, padding=1
)
# Output: (Batch Size, 32, 48, 48)
# Conv Layer 2: 32 input channels, 64 output channels, 3x3 kernel, padding 1
# This layer will learn more complex features based on the output of conv1
self.conv2 = nn.Conv2d(
in_channels=32, out_channels=64, kernel_size=3, padding=1
)
# Output: (Batch Size, 64, 48, 48)
# Max Pooling 1: Kernel 2x2, Stride 2. Reduces spatial dimensions by half (1/4th of the previous layer).
self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
# Output: (Batch Size, 64, 24, 24)
# Conv Layer 3: 64 input channels, 128 output channels, 3x3 kernel, padding 1
# This layer will learn even more complex features based on the output of conv2
# Note that the number of output channels can be adjusted based on the complexity of the task
self.conv3 = nn.Conv2d(
in_channels=64, out_channels=128, kernel_size=3, padding=1
)
# Output: (Batch Size, 128, 24, 24)
# Max Pooling 2: Kernel 2x2, Stride 2. Reduces spatial dimensions by half again.
# Reducing the dimensions further helps to control the number of parameters and computational complexity.
self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
# Output: (Batch Size, 128, 12, 12)
# From the second pooling layer, we will flatten the output to feed it into fully connected layers.
# The feature size is calculated as follows:
# Feature size = Number of output channels * Height * Width
self._feature_size = 128 * 12 * 12
# Fully Connected Layer 1 (Hidden): Maps flattened features to hidden units.
# This layer will learn to combine the features extracted by the convolutional layers.
self.fc1 = nn.Linear(self._feature_size, 512)
# Fully Connected Layer 2 (Output): Maps hidden units to class logits.
# Output size MUST match num_classes
self.fc2 = nn.Linear(512, num_classes)
# Dropout layer configuration with a dropout rate of 0.5.
# This layer is used to prevent overfitting by randomly setting a fraction of the input units to zero during training.
self.dropout = nn.Dropout(0.5)
def forward(self, x):
"""
The forward method defines the forward pass of the network.
It takes an input tensor `x` and applies the convolutional layers, pooling layers, and fully connected layers in sequence.
The input tensor `x` is expected to have the shape (Batch Size, Channels, Height, Width), where:
- Batch Size: Number of samples in the batch
- Channels: Number of input channels (e.g., 3 for RGB images)
- Height: Height of the input image (e.g., 48 for 48x48 images)
- Width: Width of the input image (e.g., 48 for 48x48 images)
The output of the forward method is the logits for each class, which can be used for classification tasks.
Args:
x (torch.Tensor): Input tensor of shape (Batch Size, Channels, Height, Width)
Returns:
torch.Tensor: Output tensor of shape (Batch Size, num_classes) containing the class logits.
"""
# Conv1 -> ReLU -> Conv2 -> ReLU -> Pool1 -> Conv3 -> ReLU -> Pool2
x = self.conv1(x)
x = F.relu(x)
x = self.conv2(x)
x = F.relu(x)
x = self.pool1(x)
x = self.conv3(x)
x = F.relu(x)
x = self.pool2(x)
# At this point, x has shape (Batch Size, 128, 12, 12)
# Flatten the output to feed it into fully connected layers
x = torch.flatten(x, 1)
# Apply dropout to prevent overfitting
x = self.dropout(x)
# First FC layer with ReLU activation
x = F.relu(self.fc1(x))
# Apply Dropout again
x = self.dropout(x)
# Final FC layer to get logits
x = self.fc2(x)
# Output shape will be (Batch Size, num_classes)
# Note that the output is not passed through a softmax activation here, as it is typically done in the loss function (e.g., CrossEntropyLoss)
return x
CNN ์ฝ๋ ํ๋ จ ์์
๋ค์ ์ฝ๋๋ ์ผ๋ถ ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ณ ์์์ ์ ์ํ MY_NET ๋ชจ๋ธ์ ํ๋ จํฉ๋๋ค. ์ฃผ๋ชฉํ ๋งํ ๋ช ๊ฐ์ง ํฅ๋ฏธ๋ก์ด ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
EPOCHS๋ ๋ชจ๋ธ์ด ํ๋ จ ์ค ์ ์ฒด ๋ฐ์ดํฐ์ ์ ๋ณด๋ ํ์์ ๋๋ค. EPOCH์ด ๋๋ฌด ์์ผ๋ฉด ๋ชจ๋ธ์ด ์ถฉ๋ถํ ํ์ตํ์ง ๋ชปํ ์ ์๊ณ , ๋๋ฌด ํฌ๋ฉด ๊ณผ์ ํฉ๋ ์ ์์ต๋๋ค.LEARNING_RATE๋ ์ต์ ํ๊ธฐ์ ๋จ๊ณ ํฌ๊ธฐ์ ๋๋ค. ์์ ํ์ต๋ฅ ์ ๋๋ฆฐ ์๋ ด์ผ๋ก ์ด์ด์ง ์ ์๊ณ , ํฐ ํ์ต๋ฅ ์ ์ต์ ์๋ฃจ์ ์ ์ด๊ณผํ์ฌ ์๋ ด์ ๋ฐฉํดํ ์ ์์ต๋๋ค.WEIGHT_DECAY๋ ํฐ ๊ฐ์ค์น์ ๋ํด ํจ๋ํฐ๋ฅผ ๋ถ์ฌํ์ฌ ๊ณผ์ ํฉ์ ๋ฐฉ์งํ๋ ์ ๊ทํ ํญ์ ๋๋ค.
ํ๋ จ ๋ฃจํ์ ๊ด๋ จํ์ฌ ์์๋๋ฉด ์ข์ ํฅ๋ฏธ๋ก์ด ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
criterion = nn.CrossEntropyLoss()๋ ๋ค์ค ํด๋์ค ๋ถ๋ฅ ์์ ์ ์ฌ์ฉ๋๋ ์์ค ํจ์์ ๋๋ค. ์ํํธ๋งฅ์ค ํ์ฑํ์ ๊ต์ฐจ ์ํธ๋กํผ ์์ค์ ๋จ์ผ ํจ์๋ก ๊ฒฐํฉํ์ฌ ํด๋์ค ๋ก์ง์ ์ถ๋ ฅํ๋ ๋ชจ๋ธ ํ๋ จ์ ์ ํฉํฉ๋๋ค.- ๋ชจ๋ธ์ด ์ด์ง ๋ถ๋ฅ๋ ํ๊ท์ ๊ฐ์ ๋ค๋ฅธ ์ ํ์ ์ถ๋ ฅ์ ์์ํ๋ ๊ฒฝ์ฐ, ์ด์ง ๋ถ๋ฅ์๋
nn.BCEWithLogitsLoss(), ํ๊ท์๋nn.MSELoss()์ ๊ฐ์ ๋ค๋ฅธ ์์ค ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE, weight_decay=WEIGHT_DECAY)๋ ๋ฅ ๋ฌ๋ ๋ชจ๋ธ ํ๋ จ์ ์ธ๊ธฐ ์๋ ์ ํ์ธ Adam ์ต์ ํ๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ์ด๋ ๊ธฐ์ธ๊ธฐ์ ์ฒซ ๋ฒ์งธ ๋ฐ ๋ ๋ฒ์งธ ๋ชจ๋ฉํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ ๋งค๊ฐ๋ณ์์ ๋ํ ํ์ต๋ฅ ์ ์กฐ์ ํฉ๋๋ค.optim.SGD(ํ๋ฅ ์ ๊ฒฝ์ฌ ํ๊ฐ๋ฒ) ๋๋optim.RMSprop์ ๊ฐ์ ๋ค๋ฅธ ์ต์ ํ๊ธฐ๋ ํ๋ จ ์์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.model.train()๋ฉ์๋๋ ๋ชจ๋ธ์ ํ๋ จ ๋ชจ๋๋ก ์ค์ ํ์ฌ ๋๋กญ์์ ๋ฐ ๋ฐฐ์น ์ ๊ทํ์ ๊ฐ์ ๋ ์ด์ด๊ฐ ํ๊ฐ์ ๋น๊ตํ์ฌ ํ๋ จ ์ค์ ๋ค๋ฅด๊ฒ ๋์ํ๋๋ก ํฉ๋๋ค.optimizer.zero_grad()๋ ์ญ์ ํ ์ด์ ์ ๋ชจ๋ ์ต์ ํ๋ ํ ์์ ๊ธฐ์ธ๊ธฐ๋ฅผ ์ง์๋๋ค. ์ด๋ PyTorch์์ ๊ธฐ์ธ๊ธฐ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ ๋๊ธฐ ๋๋ฌธ์ ํ์ํฉ๋๋ค. ์ง์ฐ์ง ์์ผ๋ฉด ์ด์ ๋ฐ๋ณต์ ๊ธฐ์ธ๊ธฐ๊ฐ ํ์ฌ ๊ธฐ์ธ๊ธฐ์ ์ถ๊ฐ๋์ด ์๋ชป๋ ์ ๋ฐ์ดํธ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.loss.backward()๋ ๋ชจ๋ธ ๋งค๊ฐ๋ณ์์ ๋ํ ์์ค์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๊ณ์ฐํ๋ฉฐ, ์ด๋ ์ดํ ์ต์ ํ๊ธฐ๊ฐ ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.optimizer.step()์ ๊ณ์ฐ๋ ๊ธฐ์ธ๊ธฐ์ ํ์ต๋ฅ ์ ๋ฐ๋ผ ๋ชจ๋ธ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
import torch, torch.nn.functional as F
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
from tqdm import tqdm
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np
# ---------------------------------------------------------------------------
# 1. Globals
# ---------------------------------------------------------------------------
IMG_SIZE = 48 # model expects 48ร48
NUM_CLASSES = 10 # MNIST has 10 digits
BATCH_SIZE = 64 # batch size for training and validation
EPOCHS = 5 # number of training epochs
LEARNING_RATE = 1e-3 # initial learning rate for Adam optimiser
WEIGHT_DECAY = 1e-4 # L2 regularisation to prevent overfitting
# Channel-wise mean / std for MNIST (grayscale โ repeat for 3-channel input)
MNIST_MEAN = (0.1307, 0.1307, 0.1307)
MNIST_STD = (0.3081, 0.3081, 0.3081)
# ---------------------------------------------------------------------------
# 2. Transforms
# ---------------------------------------------------------------------------
# 1) Baseline transform: resize + tensor (no colour/aug/no normalise)
transform_base = transforms.Compose([
transforms.Resize((IMG_SIZE, IMG_SIZE)), # ๐น Resize โ force all images to 48 ร 48 so the CNN sees a fixed geometry
transforms.Grayscale(num_output_channels=3), # ๐น GrayscaleโRGB โ MNIST is 1-channel; duplicate into 3 channels for convnet
transforms.ToTensor(), # ๐น ToTensor โ convert PIL image [0โ255] โ float tensor [0.0โ1.0]
])
# 2) Training transform: augment + normalise
transform_norm = transforms.Compose([
transforms.Resize((IMG_SIZE, IMG_SIZE)), # keep 48 ร 48 input size
transforms.Grayscale(num_output_channels=3), # still need 3 channels
transforms.RandomRotation(10), # ๐น RandomRotation(ยฑ10ยฐ) โ small tilt โข rotation-invariance, combats overfitting
transforms.ColorJitter(brightness=0.2,
contrast=0.2), # ๐น ColorJitter โ pseudo-RGB brightness/contrast noise; extra variety
transforms.ToTensor(), # convert to tensor before numeric ops
transforms.Normalize(mean=MNIST_MEAN,
std=MNIST_STD), # ๐น Normalize โ zero-centre & scale so every channel โ N(0,1)
])
# 3) Test/validation transform: only resize + normalise (no aug)
transform_test = transforms.Compose([
transforms.Resize((IMG_SIZE, IMG_SIZE)), # same spatial size as train
transforms.Grayscale(num_output_channels=3), # match channel count
transforms.ToTensor(), # tensor conversion
transforms.Normalize(mean=MNIST_MEAN,
std=MNIST_STD), # ๐น keep test data on same scale as training data
])
# ---------------------------------------------------------------------------
# 3. Datasets & loaders
# ---------------------------------------------------------------------------
train_set = datasets.MNIST("data", train=True, download=True, transform=transform_norm)
test_set = datasets.MNIST("data", train=False, download=True, transform=transform_test)
train_loader = DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_set, batch_size=256, shuffle=False)
print(f"Training on {len(train_set)} samples, validating on {len(test_set)} samples.")
# ---------------------------------------------------------------------------
# 4. Model / loss / optimiser
# ---------------------------------------------------------------------------
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MY_NET(num_classes=NUM_CLASSES).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE, weight_decay=WEIGHT_DECAY)
# ---------------------------------------------------------------------------
# 5. Training loop
# ---------------------------------------------------------------------------
for epoch in range(1, EPOCHS + 1):
model.train() # Set model to training mode enabling dropout and batch norm
running_loss = 0.0 # sums batch losses to compute epoch average
correct = 0 # number of correct predictions
total = 0 # number of samples seen
# tqdm wraps the loader to show a live progress-bar per epoch
for X_batch, y_batch in tqdm(train_loader, desc=f"Epoch {epoch}", leave=False):
# 3-a) Move data to GPU (if available) ----------------------------------
X_batch, y_batch = X_batch.to(device), y_batch.to(device)
# 3-b) Forward pass -----------------------------------------------------
logits = model(X_batch) # raw class scores (shape: [B, NUM_CLASSES])
loss = criterion(logits, y_batch)
# 3-c) Backward pass & parameter update --------------------------------
optimizer.zero_grad() # clear old gradients
loss.backward() # compute new gradients
optimizer.step() # gradient โ weight update
# 3-d) Statistics -------------------------------------------------------
running_loss += loss.item() * X_batch.size(0) # sum of (batch loss ร batch size)
preds = logits.argmax(dim=1) # predicted class labels
correct += (preds == y_batch).sum().item() # correct predictions in this batch
total += y_batch.size(0) # samples processed so far
# 3-e) Epoch-level metrics --------------------------------------------------
epoch_loss = running_loss / total
epoch_acc = 100.0 * correct / total
print(f"[Epoch {epoch}] loss = {epoch_loss:.4f} | accuracy = {epoch_acc:.2f}%")
print("\nโ
Training finished.\n")
# ---------------------------------------------------------------------------
# 6. Evaluation on test set
# ---------------------------------------------------------------------------
model.eval() # Set model to evaluation mode (disables dropout and batch norm)
with torch.no_grad():
logits_all, labels_all = [], []
for X, y in test_loader:
logits_all.append(model(X.to(device)).cpu())
labels_all.append(y)
logits_all = torch.cat(logits_all)
labels_all = torch.cat(labels_all)
preds_all = logits_all.argmax(1)
test_loss = criterion(logits_all, labels_all).item()
test_acc = (preds_all == labels_all).float().mean().item() * 100
print(f"Test loss: {test_loss:.4f}")
print(f"Test accuracy: {test_acc:.2f}%\n")
print("Classification report (precision / recall / F1):")
print(classification_report(labels_all, preds_all, zero_division=0))
print("Confusion matrix (rows = true, cols = pred):")
print(confusion_matrix(labels_all, preds_all))
์ํ ์ ๊ฒฝ๋ง (RNNs)
์ํ ์ ๊ฒฝ๋ง (RNNs)์ ์๊ณ์ด ๋ฐ์ดํฐ๋ ์์ฐ์ด์ ๊ฐ์ ์์ฐจ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๊ณ๋ ์ ๊ฒฝ๋ง์ ํ ์ข ๋ฅ์ ๋๋ค. ์ ํต์ ์ธ ํผ๋ํฌ์๋ ์ ๊ฒฝ๋ง๊ณผ ๋ฌ๋ฆฌ, RNNs๋ ์์ ์๊ฒ ๋ค์ ์ฐ๊ฒฐ๋๋ ์ฐ๊ฒฐ์ ๊ฐ์ง๊ณ ์์ด, ์ํ์ค์ ์ด์ ์ ๋ ฅ์ ๋ํ ์ ๋ณด๋ฅผ ์บก์ฒํ๋ ์จ๊ฒจ์ง ์ํ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค.
RNNs์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ํ ๋ ์ด์ด: ์ด ๋ ์ด์ด๋ ์ ๋ ฅ ์ํ์ค๋ฅผ ํ ๋ฒ์ ํ ์๊ฐ ๋จ๊ณ์ฉ ์ฒ๋ฆฌํ๋ฉฐ, ํ์ฌ ์ ๋ ฅ๊ณผ ์ด์ ์จ๊ฒจ์ง ์ํ์ ๋ฐ๋ผ ์จ๊ฒจ์ง ์ํ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. ์ด๋ฅผ ํตํด RNNs๋ ๋ฐ์ดํฐ์ ์๊ฐ์ ์์กด์ฑ์ ํ์ตํ ์ ์์ต๋๋ค.
- ์จ๊ฒจ์ง ์ํ: ์จ๊ฒจ์ง ์ํ๋ ์ด์ ์๊ฐ ๋จ๊ณ์ ์ ๋ณด๋ฅผ ์์ฝํ ๋ฒกํฐ์ ๋๋ค. ๊ฐ ์๊ฐ ๋จ๊ณ์์ ์ ๋ฐ์ดํธ๋๋ฉฐ, ํ์ฌ ์ ๋ ฅ์ ๋ํ ์์ธก์ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์ถ๋ ฅ ๋ ์ด์ด: ์ถ๋ ฅ ๋ ์ด์ด๋ ์จ๊ฒจ์ง ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ต์ข ์์ธก์ ์์ฑํฉ๋๋ค. ๋ง์ ๊ฒฝ์ฐ, RNNs๋ ์ธ์ด ๋ชจ๋ธ๋ง๊ณผ ๊ฐ์ ์์ ์ ์ฌ์ฉ๋๋ฉฐ, ์ด ๊ฒฝ์ฐ ์ถ๋ ฅ์ ์ํ์ค์ ๋ค์ ๋จ์ด์ ๋ํ ํ๋ฅ ๋ถํฌ์ ๋๋ค.
์๋ฅผ ๋ค์ด, ์ธ์ด ๋ชจ๋ธ์์ RNN์ โThe cat sat on theโ์ ๊ฐ์ ๋จ์ด ์ํ์ค๋ฅผ ์ฒ๋ฆฌํ๊ณ , ์ด์ ๋จ์ด๋ค์ด ์ ๊ณตํ๋ ๋งฅ๋ฝ์ ๋ฐ๋ผ ๋ค์ ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค. ์ด ๊ฒฝ์ฐ โmatโ์ ๋๋ค.
์ฅ๊ธฐ ๋จ๊ธฐ ๊ธฐ์ต (LSTM) ๋ฐ ๊ฒ์ดํฐ๋ ์ํ ์ ๋ (GRU)
RNNs๋ ์ธ์ด ๋ชจ๋ธ๋ง, ๊ธฐ๊ณ ๋ฒ์ญ ๋ฐ ์์ฑ ์ธ์๊ณผ ๊ฐ์ ์์ฐจ์ ๋ฐ์ดํฐ์ ๊ด๋ จ๋ ์์ ์ ํนํ ํจ๊ณผ์ ์ ๋๋ค. ๊ทธ๋ฌ๋ ์์ค ๊ธฐ์ธ๊ธฐ์ ๊ฐ์ ๋ฌธ์ ๋ก ์ธํด ์ฅ๊ธฐ ์์กด์ฑ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ์ ์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฅ๊ธฐ ๋จ๊ธฐ ๊ธฐ์ต (LSTM) ๋ฐ ๊ฒ์ดํฐ๋ ์ํ ์ ๋ (GRU)๊ณผ ๊ฐ์ ํน์ ์ํคํ ์ฒ๊ฐ ๊ฐ๋ฐ๋์์ต๋๋ค. ์ด๋ฌํ ์ํคํ ์ฒ๋ ์ ๋ณด๋ฅผ ํ๋ฅด๊ฒ ํ๋ ๊ฒ์ดํ ๋ฉ์ปค๋์ฆ์ ๋์ ํ์ฌ ์ฅ๊ธฐ ์์กด์ฑ์ ๋ณด๋ค ํจ๊ณผ์ ์ผ๋ก ์บก์ฒํ ์ ์๊ฒ ํฉ๋๋ค.
- LSTM: LSTM ๋คํธ์ํฌ๋ ์ ์ํ์ ์ ๋ณด ํ๋ฆ์ ์กฐ์ ํ๊ธฐ ์ํด ์ธ ๊ฐ์ ๊ฒ์ดํธ(์ ๋ ฅ ๊ฒ์ดํธ, ๋ง๊ฐ ๊ฒ์ดํธ ๋ฐ ์ถ๋ ฅ ๊ฒ์ดํธ)๋ฅผ ์ฌ์ฉํ์ฌ ๊ธด ์ํ์ค์์ ์ ๋ณด๋ฅผ ๊ธฐ์ตํ๊ฑฐ๋ ์์ ์ ์๊ฒ ํฉ๋๋ค. ์ ๋ ฅ ๊ฒ์ดํธ๋ ์ ๋ ฅ๊ณผ ์ด์ ์จ๊ฒจ์ง ์ํ์ ๋ฐ๋ผ ์ผ๋ง๋ ๋ง์ ์๋ก์ด ์ ๋ณด๋ฅผ ์ถ๊ฐํ ์ง๋ฅผ ์กฐ์ ํ๊ณ , ๋ง๊ฐ ๊ฒ์ดํธ๋ ์ผ๋ง๋ ๋ง์ ์ ๋ณด๋ฅผ ๋ฒ๋ฆด์ง๋ฅผ ์กฐ์ ํฉ๋๋ค. ์ ๋ ฅ ๊ฒ์ดํธ์ ๋ง๊ฐ ๊ฒ์ดํธ๋ฅผ ๊ฒฐํฉํ์ฌ ์๋ก์ด ์ํ๋ฅผ ์ป์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก, ์๋ก์ด ์ ์ํ์ ์ ๋ ฅ ๋ฐ ์ด์ ์จ๊ฒจ์ง ์ํ๋ฅผ ๊ฒฐํฉํ์ฌ ์๋ก์ด ์จ๊ฒจ์ง ์ํ๋ฅผ ์ป์ต๋๋ค.
- GRU: GRU ๋คํธ์ํฌ๋ ์ ๋ ฅ ๊ฒ์ดํธ์ ๋ง๊ฐ ๊ฒ์ดํธ๋ฅผ ๋จ์ผ ์ ๋ฐ์ดํธ ๊ฒ์ดํธ๋ก ๊ฒฐํฉํ์ฌ LSTM ์ํคํ ์ฒ๋ฅผ ๋จ์ํํ์ฌ ๊ณ์ฐ์ ์ผ๋ก ๋ ํจ์จ์ ์ด๋ฉด์๋ ์ฌ์ ํ ์ฅ๊ธฐ ์์กด์ฑ์ ์บก์ฒํ ์ ์๊ฒ ํฉ๋๋ค.
LLMs (๋ํ ์ธ์ด ๋ชจ๋ธ)
๋ํ ์ธ์ด ๋ชจ๋ธ (LLMs)์ ์์ฐ์ด ์ฒ๋ฆฌ ์์ ์ ์ํด ํน๋ณํ ์ค๊ณ๋ ๋ฅ ๋ฌ๋ ๋ชจ๋ธ์ ํ ์ข ๋ฅ์ ๋๋ค. ์ด๋ค์ ๋ฐฉ๋ํ ์์ ํ ์คํธ ๋ฐ์ดํฐ๋ก ํ๋ จ๋์ด ์ธ๊ฐ๊ณผ ์ ์ฌํ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ , ์ง๋ฌธ์ ๋ตํ๊ณ , ์ธ์ด๋ฅผ ๋ฒ์ญํ๋ฉฐ, ๋ค์ํ ์ธ์ด ๊ด๋ จ ์์ ์ ์ํํ ์ ์์ต๋๋ค. LLMs๋ ์ผ๋ฐ์ ์ผ๋ก ๋ณํ๊ธฐ ์ํคํ ์ฒ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ์ด๋ ์ํ์ค ๋ด ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ์บก์ฒํ๊ธฐ ์ํด ์๊ธฐ ์ฃผ์ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ฌ ๋งฅ๋ฝ์ ์ดํดํ๊ณ ์ผ๊ด๋ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์๊ฒ ํฉ๋๋ค.
๋ณํ๊ธฐ ์ํคํ ์ฒ
๋ณํ๊ธฐ ์ํคํ ์ฒ๋ ๋ง์ LLMs์ ๊ธฐ์ด์ ๋๋ค. ์ด๋ ์ธ์ฝ๋-๋์ฝ๋ ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ์ธ์ฝ๋๋ ์ ๋ ฅ ์ํ์ค๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋์ฝ๋๋ ์ถ๋ ฅ ์ํ์ค๋ฅผ ์์ฑํฉ๋๋ค. ๋ณํ๊ธฐ ์ํคํ ์ฒ์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์๊ธฐ ์ฃผ์ ๋ฉ์ปค๋์ฆ: ์ด ๋ฉ์ปค๋์ฆ์ ๋ชจ๋ธ์ด ํํ์ ์์ฑํ ๋ ์ํ์ค ๋ด์ ๋ค์ํ ๋จ์ด์ ์ค์์ฑ์ ๊ฐ์ค์น๋ก ๋ถ์ฌํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฃผ์ ์ ์๋ฅผ ๊ณ์ฐํ์ฌ ๋ชจ๋ธ์ด ๊ด๋ จ ๋งฅ๋ฝ์ ์ง์คํ ์ ์๊ฒ ํฉ๋๋ค.
- ๋ค์ค ํค๋ ์ฃผ์: ์ด ๊ตฌ์ฑ ์์๋ ๋ชจ๋ธ์ด ์ฌ๋ฌ ์ฃผ์ ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ด ๊ฐ์ ์ฌ๋ฌ ๊ด๊ณ๋ฅผ ์บก์ฒํ ์ ์๊ฒ ํ๋ฉฐ, ๊ฐ ํค๋๋ ์ ๋ ฅ์ ๋ค์ํ ์ธก๋ฉด์ ์ง์คํฉ๋๋ค.
- ์์น ์ธ์ฝ๋ฉ: ๋ณํ๊ธฐ๋ ๋จ์ด ์์์ ๋ํ ๋ด์ฅ ๊ฐ๋ ์ด ์๊ธฐ ๋๋ฌธ์, ์์น ์ธ์ฝ๋ฉ์ด ์ ๋ ฅ ์๋ฒ ๋ฉ์ ์ถ๊ฐ๋์ด ์ํ์ค ๋ด ๋จ์ด์ ์์น์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํ์ฐ ๋ชจ๋ธ
ํ์ฐ ๋ชจ๋ธ์ ํ์ฐ ๊ณผ์ ์ ์๋ฎฌ๋ ์ด์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ํ์ตํ๋ ์์ฑ ๋ชจ๋ธ์ ํ ์ข ๋ฅ์ ๋๋ค. ์ด๋ค์ ์ด๋ฏธ์ง ์์ฑ๊ณผ ๊ฐ์ ์์ ์ ํนํ ํจ๊ณผ์ ์ด๋ฉฐ ์ต๊ทผ ๋ช ๋ ๋์ ์ธ๊ธฐ๋ฅผ ์ป๊ณ ์์ต๋๋ค. ํ์ฐ ๋ชจ๋ธ์ ๊ฐ๋จํ ๋ ธ์ด์ฆ ๋ถํฌ๋ฅผ ๋ณต์กํ ๋ฐ์ดํฐ ๋ถํฌ๋ก ์ ์ง์ ์ผ๋ก ๋ณํํ๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค. ํ์ฐ ๋ชจ๋ธ์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ ๋ฐฉํฅ ํ์ฐ ๊ณผ์ : ์ด ๊ณผ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ง์ ์ผ๋ก ๋ ธ์ด์ฆ๋ฅผ ์ถ๊ฐํ์ฌ ๊ฐ๋จํ ๋ ธ์ด์ฆ ๋ถํฌ๋ก ๋ณํํฉ๋๋ค. ์ ๋ฐฉํฅ ํ์ฐ ๊ณผ์ ์ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ ์์ค์ด ๋ฐ์ดํฐ์ ์ถ๊ฐ๋ ํน์ ์์ ๋ ธ์ด์ฆ์ ํด๋นํ๋ ์ผ๋ จ์ ๋ ธ์ด์ฆ ์์ค์ผ๋ก ์ ์๋ฉ๋๋ค.
- ์ญ๋ฐฉํฅ ํ์ฐ ๊ณผ์ : ์ด ๊ณผ์ ์ ์ ๋ฐฉํฅ ํ์ฐ ๊ณผ์ ์ ์ญ์ ์ํค๋ ๋ฐฉ๋ฒ์ ํ์ตํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ง์ ์ผ๋ก ๋๋ ธ์ด์ฆํ์ฌ ๋ชฉํ ๋ถํฌ์์ ์ํ์ ์์ฑํฉ๋๋ค. ์ญ๋ฐฉํฅ ํ์ฐ ๊ณผ์ ์ ๋ชจ๋ธ์ด ๋ ธ์ด์ฆ ์ํ์์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ตฌ์ฑํ๋๋ก ์ ๋ํ๋ ์์ค ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ จ๋ฉ๋๋ค.
๋ํ, ํ ์คํธ ํ๋กฌํํธ์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๊ธฐ ์ํด ํ์ฐ ๋ชจ๋ธ์ ์ผ๋ฐ์ ์ผ๋ก ๋ค์ ๋จ๊ณ๋ฅผ ๋ฐ๋ฆ ๋๋ค:
- ํ ์คํธ ์ธ์ฝ๋ฉ: ํ ์คํธ ํ๋กฌํํธ๋ ํ ์คํธ ์ธ์ฝ๋(์: ๋ณํ๊ธฐ ๊ธฐ๋ฐ ๋ชจ๋ธ)๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฌ ํํ์ผ๋ก ์ธ์ฝ๋ฉ๋ฉ๋๋ค. ์ด ํํ์ ํ ์คํธ์ ์๋ฏธ๋ฅผ ์บก์ฒํฉ๋๋ค.
- ๋ ธ์ด์ฆ ์ํ๋ง: ๊ฐ์ฐ์์ ๋ถํฌ์์ ๋ฌด์์ ๋ ธ์ด์ฆ ๋ฒกํฐ๊ฐ ์ํ๋ง๋ฉ๋๋ค.
- ํ์ฐ ๋จ๊ณ: ๋ชจ๋ธ์ ์ผ๋ จ์ ํ์ฐ ๋จ๊ณ๋ฅผ ์ ์ฉํ์ฌ ๋ ธ์ด์ฆ ๋ฒกํฐ๋ฅผ ํ ์คํธ ํ๋กฌํํธ์ ํด๋นํ๋ ์ด๋ฏธ์ง๋ก ์ ์ง์ ์ผ๋ก ๋ณํํฉ๋๋ค. ๊ฐ ๋จ๊ณ๋ ์ด๋ฏธ์ง๋ฅผ ๋๋ ธ์ด์ฆํ๊ธฐ ์ํด ํ์ต๋ ๋ณํ์ ์ ์ฉํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


