
๊ธฐ๋ณธ ์์
VGGNet

ResNet

์ถ๊ฐ ์์
AlexNet ๊ตฌ์กฐ
๐ผ๏ธAlexNet
2012๋ ImageNet ILSVRC์์ ์ฐ์นํ ๋ชจ๋ธ.
LeNet์ด ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง ๊ฐ๋ ์ ์ ์ํ๊ธฐ๋ ํ์ง๋ง, ๊ณง๋ฐ๋ก ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ถ์ผ์ ์ฃผ๋ฅ๋ก ์๋ฆฌ๋งค๊นํ์ง๋ ๋ชปํ๋ค. ๊ทธ๋ฌ๋ ์ค AlexNet์ด ์๋์ ์ธ ์ฑ๋ฅ์ ๋ณด์ฌ์ฃผ๋ฉด์, CNN ๊ธฐ๋ฐ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ ํจ์ฉ์ฑ์ ์ ์ฆํด๋๋ค.
๊ตฌ์กฐ ์์ฝ
- ์ ๋ ฅ: 224x224x3 ์ด๋ฏธ์ง
- ์ด 8๊ฐ์ ์ธต(5๊ฐ Conv, 3๊ฐ FC)
- ReLU
- ๋๋กญ์์
- ๋ฐ์ดํฐ ์ฆ๊ฐ(ํฌ๋กญ, ํ๋ฆฝ ๋ฑ)
- ๋ ๊ฐ์ GPU๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ
AlexNet vs LeNet-5
- AlexNet ๋ชจ๋ธ์ LeNet-5 ๋ชจ๋ธ๋ณด๋ค ๋ง์ ์ธต์ ์ฌ์ฉํ๋ค.
- AlexNet ๋ชจ๋ธ์ LeNet-5 ๋ชจ๋ธ์์ ์ฌ์ฉํ ํ์ฑํ ํจ์์ธ ์๊ทธ๋ชจ์ด๋ ํจ์ ๋์ ๋ ๋ฃจ ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
- gradient vanishing problem ํด๊ฒฐ
- ํ๊ท ํ๋ง ๋์ ์ต๋ ํ๋ง์ ์ฌ์ฉํ๋ค.
- AlexNet ๋ชจ๋ธ์ ๋ฐ์ง์ธต์ ๊ณผ๋ ์ ํฉ์ ๋ง๊ธฐ ์ํด ์ ๋์ ์ถ๋ ฅ์ ๋๋คํ๊ฒ ๋๋ ๋๋กญ์์์ ์ฌ์ฉํ๋ค.
AlexNet ๋ชจ๋ธ ์ค์ต
import keras
from keras import layers
alexnet = keras.Sequential()
alexnet.add(layers.Input(shape=(227, 227, 3)))
alexnet.add(layers.Conv2D(filters=96, kernel_size=11, strides=4,
activation='relu'))
alexnet.add(layers.MaxPooling2D(pool_size=3, strides=2))
alexnet.add(layers.Conv2D(filters=256, kernel_size=5, padding='same',
activation='relu'))
alexnet.add(layers.MaxPooling2D(pool_size=3, strides=2))
alexnet.add(layers.Conv2D(filters=384, kernel_size=3, padding='same',
activation='relu'))
alexnet.add(layers.Conv2D(filters=384, kernel_size=3, padding='same',
activation='relu'))
alexnet.add(layers.Conv2D(filters=256, kernel_size=3, padding='same',
activation='relu'))
alexnet.add(layers.MaxPooling2D(pool_size=3, strides=2))
alexnet.add(layers.Flatten())
alexnet.add(layers.Dense(4096, activation='relu'))
alexnet.add(layers.Dropout(0.5))
alexnet.add(layers.Dense(4096, activation='relu'))
alexnet.add(layers.Dropout(0.5))
alexnet.add(layers.Dense(1000, activation='softmax'))
alexnet.summary()

๐งฉVGGNet
์ฅ์คํฌ๋ ๋ํ์ Visual Geometry Group์์ ๋ง๋ CNN ๋ชจ๋ธ, 2024๋ ์ด๋ฏธ์ง๋ท ๋ํ ์ฐ์น
VGGNet์ 3x3 Conv์ 2x2 Max pooling๋ง์ผ๋ก ์ ์ฒด ๋ชจ๋ธ์ ๊ตฌ์ฑํ๋ค. 3x3์ ๋ ๋ฒ ์์ผ๋ฉด 5x5, ์ธ ๋ฒ ์์ผ๋ฉด 7x7๊ณผ ๋์ผํ ์์ฉ ์์ญ์ ํ๋ณดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋น์ ํ์ฑ ์ฆ๊ฐ + ํ๋ผ๋ฏธํฐ ๊ฐ์๋ผ๋ ์ด์ ์ ์ป์ ์ ์๋ค.
๊ตฌ์กฐ ์์ฝ
- Conv: ๋ชจ๋ 3x3, stride=1, padding=same
- Pooling: ๋ชจ๋ 2x2 max pooling
- ๊น์ด: VGG-16 ๊ธฐ์ค Conv 13๊ฐ + FC 1๊ฐ
- ํ๋ผ๋ฏธํฐ ์๊ฐ ๋ง์์ ๋ฌด๊ฒ๊ณ ๋๋ฆผ
VGGNet ํน์ง
- ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ๊ต๋๋ก ๋ฐ๋ณตํ๋ ๋์ , ์ฌ๋ฌ ๋ฒ์ ํฉ์ฑ๊ณฑ์ธต์ ์ ์ฉํ ๋ค์ ํ๋ง์ธต์ ์ ์ฉํ๋ค.
- ๋์ผํ ์ฌ๋ฌ ๊ฐ์ ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ณตํ๋ ๋ธ๋ก์ ์ ์ฉํ๋ค.
- ํฐ ํํฐ๋ฅผ ์ฌ์ฉํ๋ ํ๋์ ํฉ์ฑ๊ณฑ์ธต ๋์ , 3x3 ํฌ๊ธฐ์ ์์ ํํฐ๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋ฌ ๊ฐ์ ํฉ์ฑ๊ณฑ์ธต์ ์ ์ฉํ๋ค.
VGGNet ์ค์ต
vggnet = keras.Sequential()
vggnet.add(layers.Input(shape=(224, 224, 3)))
# 1, 2๋ฒ์งธ ๋ธ๋ก
for n_filters in [64, 128]:
for _ in range(2):
vggnet.add(layers.Conv2D(filters=n_filters, kernel_size=3,
padding='same', activation='relu'))
vggnet.add(layers.MaxPooling2D(pool_size=2))
# 3, 4, 5๋ฒ์งธ ๋ธ๋ก
for n_filters in [256, 512, 512]:
for _ in range(3):
vggnet.add(layers.Conv2D(filters=n_filters, kernel_size=3,
padding='same', activation='relu'))
vggnet.add(layers.MaxPooling2D(pool_size=2))
vggnet.add(layers.Flatten())
vggnet.add(layers.Dense(4096, activation='relu'))
vggnet.add(layers.Dense(4096, activation='relu'))
vggnet.add(layers.Dense(1000, activation='softmax'))
vggnet.summary()

๐ AlexNet์ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ ์ฌ์ฉํด ์ปดํจํฐ ๋น์ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ํ์ ์ ๋ง๋ จํ๋ค. VGGNet์ ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ํ๋์ ๋ธ๋ก์ผ๋ก ๊ตฌ์ฑํ์ฌ ์ฌ๋ฌ ์ฐจ๋ก ๋ฐ๋ณตํ๋ ๊ธฐ๋ฒ์ ๋์ ํ๊ณ , ์ด๋ฐ ๋ฐ๋ณต ๊ตฌ์กฐ๋ ์ดํ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง๊ณผ ํธ๋์คํฌ๋จธ๋ฅผ ๋น๋กฏํ ๋ง์ ์ ๊ฒฝ๋ง ๊ตฌ์กฐ์ ์ํฅ์ ๋ฏธ์ณค๋ค.
ResNet
Degradation ๋ฌธ์ ํด๊ฒฐ์ ์ํ ์์ฐจ ๋ธ๋ก์ ๋์ ํ ๋ชจ๋ธ
ResNet์ ๋ฅ๋ฌ๋ ๊ตฌ์กฐ๊ฐ ๊น์ด์ง์๋ก ์คํ๋ ค ์ฑ๋ฅ์ด ๋๋น ์ง๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฑ์ฅํ๋ค. gradient vanishing, degradation gํ์ ๋ฌธ์ ๋ฅผ ์์ฐจ ์ฐ๊ฒฐ๋ก ํด๊ฒฐํ๋ค.
์ ๊ฒฝ๋ง์ด ํ์ตํ ํจ์ H(x) ๋์ , ์ ๋ ฅ์ ๊ทธ๋๋ก ๋๊ณ ์์ฐจ ํจ์ F(x) = H(x) - x ๋ง ํ์ต์ํค๋ฉด ๋ ์ฝ๋ค.
Output = F(x) + x
์์ฐจ ๋ธ๋ก
์ ๋ ฅ์ ์ถ๋ ฅ์ ์ง์ ์ฐ๊ฒฐํ๋ ์คํต ์ฐ๊ฒฐ์ ์ถ๊ฐํด ๊ธฐ์ธ๊ธฐ ์์ค ๋ฌธ์ ๋ฅผ ์ํ
Input x
↓
Conv → BN → ReLU → Conv → BN
↓ โ
←โโโโโโโ(+x)โโโโโโโ
↓
ReLU
- Conv ๋ค์ ํญ์ BatchNorm + ReLU
- ๋ธ๋ก์ ์ถ๋ ฅ์ F(x) + x
- ์คํต ์ฐ๊ฒฐ์ ํ ์ป ๊ธฐ์ธ๊ธฐ ํ๋ฆ์ ์ ์งํ๊ณ , ํ์ต ์์ ์ฑ์ ํ๋ณดํ๋ค.
๋ณ๋ชฉ ๋ธ๋ก
ResNet-50, ResNet-101 ๋ฑ์์๋ ํ๋ผ๋ฏธํฐ ์๋ฅผ ์ค์ด๊ธฐ ์ํด 1x1 -> 3x3 -> 1x1 ๊ตฌ์กฐ์ ๋ณ๋ชฉ ๋ธ๋ก์ ์ฌ์ฉํ๋ค.
1x1 Conv (์ฑ๋ ๊ฐ์)
↓
3x3 Conv
↓
1x1 Conv (์ฑ๋ ๋ณต์)
↓
+ ์
๋ ฅ x (skip)
์ด๋ ๊ฒ ์ฐ์ฐ๋์ ์ค์ด๋ฉด์, ์์ฐจ ์ฐ๊ฒฐ ๊ตฌ์กฐ๋ฅผ ์ ์งํ ์ ์๋ค.
๋ฐฐ์น ์ ๊ทํ
์์ฐจ ๋ธ๋ก ๋ด์์ ํ์ต์ ์๋๋ฅผ ๋์ด๊ณ ๋ชจ๋ธ์ ์์ ์ฑ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ธฐ๋ฒ
๊ฐ ๋ฏธ๋ ๋ฐฐ์น์ ๋ํด ํ๊ท 0, ๋ถ์ฐ 1๋ก ์ ๊ทํํ ๋ค, ์ค์ผ์ผ๊ณผ ์ํํธ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ ์กฐ์ ํ๋ ๋ฐฉ์์ด๋ค.

์ด๋ฅผ Conv ๋๋ FC ๋ ์ด์ด ๋ค์ ๋ฃ์ผ๋ฉด ํ์ต ์๋ ์ฆ๊ฐ + ์ด๊ธฐ๊ฐ ๋ฏผ๊ฐ๋ ๊ฐ์ ๊ฐ์ ์ด์ ์ ์ป์ ์ ์๋ค.
๐๐๊ฐ์์ง, ๊ณ ์์ด ์ฌ์ง ๋ถ๋ฅํ๊ธฐ
๋๋์ด ๊ฐ์์ง, ๊ณ ์์ด ์ฌ์ง ๋ถ๋ฅํ๊ธฐ ์ค์ต!
VGGNet์ผ๋ก ๋ถ๋ฅ
import keras
vggnet = keras.applications.VGG16()
!gdown 1xGkTT3uwYt4myj6eJJeYtdEFgTi2Sj8C
!unzip cat-dog-images.zip
from PIL import Image
dog_png = Image.open('images/dog.png')
display(dog_png)
import numpy as np
dog_array = np.array(dog_png)
dog_array.shape
from keras.applications import vgg16
vgg_prep_dog = vgg16.preprocess_input(dog_array)
predictions =vggnet.predict(vgg_prep_dog[np.newaxis, :])
max_index = np.argmax(predictions[0])
print(max_index, predictions[0][max_index])
import requests
url = "https://storage.googleapis.com/download.tensorflow.org/" + \
"data/imagenet_class_index.json"
json_data = requests.get(url).json()
print(json_data[str(max_index)])
vgg16.decode_predictions(predictions)
vgg16.decode_predictions(predictions, top=1)
cat_png = Image.open('images/cat.png')
display(cat_png)
vgg_prep_cat = vgg16.preprocess_input(np.array(cat_png))
predictions = vggnet.predict(vgg_prep_cat[np.newaxis,:])
vgg16.decode_predictions(predictions)
๊ฒฐ๊ณผ:
- 43.3% tabby, 31.1% egyption_cat


ResNet์ผ๋ก ๋ถ๋ฅ
!gdown 1xGkTT3uwYt4myj6eJJeYtdEFgTi2Sj8C
!unzip cat-dog-images.zip
from PIL import Image
import numpy as np
from keras.applications import resnet
dog_png = Image.open('images/dog.png')
resnet_prep_dog = resnet.preprocess_input(np.array(dog_png))
resnet50 = keras.applications.ResNet50()
predictions = resnet50.predict(resnet_prep_dog[np.newaxis,:])
resnet.decode_predictions(predictions)
cat_png = Image.open('images/cat.png')
resnet_prep_cat = resnet.preprocess_input(np.array(cat_png))
predictions = resnet50.predict(resnet_prep_cat[np.newaxis,:])
resnet.decode_predictions(predictions)
๊ฒฐ๊ณผ:
- 86.8%% tabby

VGG16 ๋ชจ๋ธ๋ณด๋ค ๋ ๋์ ์์ค์ ์์ธก์ ์ํํ๋ค!
์ด๋ฒ ์ค์ต์ ํตํด AlexNet, VGGNet, ResNet 3๊ฐ์ ๋ํ์ ์ธ CNN ๋ชจ๋ธ์ ์ฌ์ฉํด๋ณด๋ฉด์, ๊ฐ ๋ชจ๋ธ์ด ๊ฐ๋ ๊ตฌ์กฐ์ ํน์ง๊ณผ ํ๊ณ๋ฅผ ์ฒด๊ฐํ ์ ์์๋ค.
AlexNet์ ๊น์ด๊ฐ ์๊ณ ๊ตฌ์กฐ๋ ๋น๊ต์ ๋จ์ํ ํธ์ด์ง๋ง, ๋น์๋ก์๋ ํ์ ์ ์ด์๋ ์ฌ๋ฌ ๊ธฐ์ ์ด ์ง์ฝ๋์ด ์์๋ค. ReLU ํ์ฑํ ํจ์ ๋์ ์ด๋ ๋๋กญ์์, ๋ฐ์ดํฐ ์ฆ๊ฐ์ ํ์ฉ ๋ฑ์ ์ดํ ๋ง์ ๋ชจ๋ธ๋ค์๊ฒ ์ํฅ์ ์ฃผ์๋ค. ๋ค๋ง ์ปค๋ ํฌ๊ธฐ๊ฐ ํฌ๊ณ , ํ๋ผ๋ฏธํฐ ์๊ฐ ๋ง์ ๊ณ์ฐ๋์ด ๋ถํ์ํ๊ฒ ํฐ ๋ถ๋ถ์ ํ๊ณ๋ก ๋๊ปด์ก๋ค.
VGGNet์ AlexNet์ ๋จ์ ์ ๊ฐ์ ํ๋ฉฐ, ๋์ผํ 3x3 ์ปค๋์ ๋ฐ๋ณต์ ์ผ๋ก ์์ ๊น์ด๋ฅผ ๋๋ฆฌ๋ ๊ตฌ์กฐ๋ก ์ค๊ณ๋์๋ค. ์ด๋ก ์ธํด ๋ชจ๋ธ ๊ตฌ์กฐ๊ฐ ํจ์ฌ ๋ ์ผ๊ด๋๊ณ ๋จ์ํด์ก๊ณ , ์ฑ๋ฅ๋ ํฅ์๋์๋ค. ํ์ง๋ง ๊น์ด๊ฐ ๊น์ด์ง๋ฉด์ ํ๋ผ๋ฏธํฐ ์๊ฐ ๊ธ๊ฒฉํ ๋์ด๋๊ณ , ๊ณ์ฐ๋ ์ญ์ ๋งค์ฐ ์ปค์ง๋ค๋ ์ ์ ์ค์ฉ์ ์ธ ์ธก๋ฉด์์ ๋ถ๋ด์ด ๋์๋ค.
ResNet์ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํ ์๋๋ก, ์์ฐจ ํ์ต์ด๋ผ๋ ๊ฐ๋ ์ ๋์ ํ๋ค. ์ด๋ ๋คํธ์ํฌ๊ฐ ๊น์ด์ง์๋ก ๋ฐ์ํ๋ ์ฑ๋ฅ ์ ํ๋ฅผ ํด๊ฒฐํ๋ฉฐ, ์ค์ง์ ์ผ๋ก ๋ ๊น์ ๋คํธ์ํฌ๋ฅผ ์์ ์ ์ผ๋ก ํ์ตํ ์ ์๋๋ก ํด์ฃผ์๋ค. ๊ตฌํ ๊ด์ ์์๋ skip connection๋ง ์ ์ ์ฉํ๋ฉด, ๋น๊ต์ ๋ณต์กํ์ง ์๊ฒ ํ์ฅ ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ผ๋ ์ ์ด ์ธ์ ๊น์๋ค.
์ธ ๋ชจ๋ธ์ ๋น๊ตํด ๋ณด๋ฉด, ๊น์ด์ ๋ฐ๋ผ ์ฑ๋ฅ์ด ํฅ์๋์ง๋ง ๋จ์ํ ์ธต์ ๋ง์ด ์๋๋ค๊ณ ํด์ ๋ฌด์กฐ๊ฑด ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์๋ ์๋ค๋ ์ ์ ์ ์ ์์๋ค. ํ์ต ์์ ์ฑ๊ณผ ๊ณ์ฐ ํจ์จ์ฑ๋ ํจ๊ป ๊ณ ๋ คํด์ผ ํ๋ค๋ ๊ตํ์ ์ป์
'๐book' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [npm deep dive] ์๋ ์ฑ๋ฆฐ์ง-์๋ ๋ชปํ ํ๊ธฐ (12) | 2025.07.23 |
|---|---|
| [Luvit ํ๋ฌ ์คํฐ๋] ์๋ก์ด ์น ๊ฐ๋ฐ์ ์์ ์ค๋ฒจํธ #3 (1) | 2025.07.20 |
| [ํผ๊ณตํ์ต๋จ 14๊ธฐ] LeNet ์ค์ต-Fashoin MNIST ๋ถ๋ฅ ์ค์ต (3) | 2025.07.13 |
| [Luvit ํ๋ฌ ์คํฐ๋] ์๋ก์ด ์น ๊ฐ๋ฐ์ ์์ ์ค๋ฒจํธ #2 (8) | 2025.07.13 |
| [ํผ๊ณตํ์ต๋จ 14๊ธฐ] CNN ๊ตฌ์กฐ์ ๋์ ์๋ฆฌ์ ์ดํด (4) | 2025.07.06 |
