model = tf.keras.Model(input_, x)
VGGNet (2014)
- 16~19개의 깊은 층을 쌓아 네트워크의 깊이와 성능 간의 관계를 조사
- 3x3 Convolution Layer 를 여러 개 쌓는 단순하고 일관된 구조를 사용
K. Simonyan and A. Zisserman, "Very Deep Convolutional Networks for Large-Scale Image Recognition," in International Conference on Learning Representations (ICLR), 2015.
- 주요 특징
- 단순한 구조:
- VGGNet의 구조는 매우 단순합니다. 3x3 크기의 작은 필터를 사용하는 합성곱 층(convolutional layer)과 최대 풀링 층(max pooling layer)을 깊게 쌓아 올린 형태로 설계되었습니다.
- 합성곱 층의 필터 크기를 3x3으로 고정하고, 스트라이드(stride)와 패딩(padding)을 적절히 조정하여 출력 크기가 유지되도록 설계했습니다.
- 모델의 깊이는 VGG-11, VGG-13, VGG-16, VGG-19와 같이 11개에서 19개 층으로 구성됩니다(숫자는 가중치 층의 개수).
- 작은 필터의 장점:
- 3x3 필터를 여러 층 쌓으면, 같은 수의 매개변수로도 더 큰 receptive field를 커버할 수 있습니다. 예를 들어, 3x3 필터를 3개 쌓으면 7x7 필터와 같은 리셉티브 필드를 얻을 수 있습니다.
- 작은 필터를 사용하면 매개변수 수를 줄이면서 비선형성(activation)을 추가하여 모델의 표현력을 증가시킬 수 있습니다.
- 레이어의 깊이:
- VGGNet은 이전 모델(AlexNet, ZFNet)에 비해 매우 깊은 네트워크 구조를 가지고 있습니다.
- 깊은 네트워크는 더 복잡한 특징을 학습할 수 있으며, 특히 대규모 데이터셋(ImageNet)에서 뛰어난 성능을 보였습니다.
- Dense Layer:
- 네트워크의 마지막 부분에는 완전연결 층(Fully Connected Layer, FC)과 소프트맥스(softmax) 층이 추가되어 이미지의 클래스 확률을 예측합니다.
- 전이 학습(Transfer Learning):
- VGGNet은 이미지넷(ImageNet)에서 학습된 가중치를 기반으로 전이 학습에 자주 사용됩니다.
- 특히 컴퓨터 비전 작업에서 특정 도메인의 데이터를 학습시키는 데 유용합니다.
VGGNet의 구조- 입력: 224x224 RGB 이미지
- 합성곱 층: 3x3 필터, ReLU 활성화 함수 사용
- 풀링 층: 2x2 최대 풀링
- 완전연결 층: 3개의 FC 층
- 출력: 1000개의 클래스 (ImageNet 기준)
- 입력: 224x224x3 이미지
- Conv3-64 → Conv3-64 → MaxPool
- Conv3-128 → Conv3-128 → MaxPool
- Conv3-256 → Conv3-256 → Conv3-256 → MaxPool
- Conv3-512 → Conv3-512 → Conv3-512 → MaxPool
- Conv3-512 → Conv3-512 → Conv3-512 → MaxPool
- FC4096 → FC4096 → FC1000 → Softmax
장점- 성능:
- 이미지 분류(ImageNet)에서 매우 높은 정확도를 달성했습니다.
- 전이 학습에 적합한 구조를 가짐.
- 단순성:
- 구조가 간단하여 이해 및 구현이 용이.
- 딥러닝 연구에서 기본 모델로 자주 사용됨.
- 모듈화:
- 작은 3x3 필터를 사용해 모듈화된 설계를 제공, 다양한 변형을 쉽게 생성 가능.
단점- 많은 매개변수:
- 깊은 구조로 인해 모델이 매우 크고(수백 MB 이상), 많은 메모리가 필요.
- 학습과 추론 속도가 느림.
- 과적합:
- 작은 데이터셋에 사용하면 과적합 가능성이 큼.
실제 응용- 이미지 분류
- 객체 탐지
- 특징 추출
- 전이 학습
- 단순한 구조:
- VGGNet은 이후의 딥러닝 모델(ResNet, Inception 등)에 비해 효율성은 떨어지지만, 그 단순한 설계와 뛰어난 성능 덕분에 딥러닝 연구의 기초를 닦은 모델로 여전히 중요하게 사용되고 있습니다.
VGGNet 구현
import tensorflow as tf
비교를 위한 tf.keras.applications.VGG16
vgg16 = tf.keras.applications.VGG16(include_top=True)
vgg16.summary()
Model: "vgg16"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ input_layer (InputLayer) │ (None, 224, 224, 3) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_conv1 (Conv2D) │ (None, 224, 224, 64) │ 1,792 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_conv2 (Conv2D) │ (None, 224, 224, 64) │ 36,928 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_pool (MaxPooling2D) │ (None, 112, 112, 64) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_conv1 (Conv2D) │ (None, 112, 112, 128) │ 73,856 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_conv2 (Conv2D) │ (None, 112, 112, 128) │ 147,584 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_pool (MaxPooling2D) │ (None, 56, 56, 128) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv1 (Conv2D) │ (None, 56, 56, 256) │ 295,168 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv2 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv3 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_pool (MaxPooling2D) │ (None, 28, 28, 256) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv1 (Conv2D) │ (None, 28, 28, 512) │ 1,180,160 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv2 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv3 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_pool (MaxPooling2D) │ (None, 14, 14, 512) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv1 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv2 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv3 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_pool (MaxPooling2D) │ (None, 7, 7, 512) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten) │ (None, 25088) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ fc1 (Dense) │ (None, 4096) │ 102,764,544 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ fc2 (Dense) │ (None, 4096) │ 16,781,312 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ predictions (Dense) │ (None, 1000) │ 4,097,000 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 138,357,544 (527.79 MB)
Trainable params: 138,357,544 (527.79 MB)
Non-trainable params: 0 (0.00 B)
VGGNet16 input layer
input_ = tf.keras.Input((224,224,3))
VGGNet16 model
x = tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu', name='block1_conv1')(input_)
x = tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu', name='block1_conv2')(x)
x = tf.keras.layers.MaxPool2D(2,2,name='block1_pool')(x)
x = tf.keras.layers.Conv2D(128, 3, padding='same', activation='relu', name='block2_conv1')(x)
x = tf.keras.layers.Conv2D(128, 3, padding='same', activation='relu', name='block2_conv2')(x)
x = tf.keras.layers.MaxPool2D(2, 2,name='block2_pool')(x)
x = tf.keras.layers.Conv2D(256, 3, padding='same', activation='relu', name='block3_conv1')(x)
x = tf.keras.layers.Conv2D(256, 3, padding='same', activation='relu', name='block3_conv2')(x)
x = tf.keras.layers.Conv2D(256, 3, padding='same', activation='relu', name='block3_conv3')(x)
x = tf.keras.layers.MaxPool2D(2, 2,name='block3_pool')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block4_conv1')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block4_conv2')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block4_conv3')(x)
x = tf.keras.layers.MaxPool2D(2, 2,name='block4_pool')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block5_conv1')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block5_conv2')(x)
x = tf.keras.layers.Conv2D(512, 3, padding='same', activation='relu', name='block5_conv3')(x)
x = tf.keras.layers.MaxPool2D(2, 2,name='block5_pool')(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(4096, name='fc1')(x)
x = tf.keras.layers.Dense(4096, name='fc2')(x)
x = tf.keras.layers.Dense(1000, activation='softmax', name='predictions')(x)
model = tf.keras.Model(input_, x)
구현한 모델 summary 확인
model.summary()
tf.keras.applications.VGG16 와 비교 확인
Model: "functional"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ input_layer_1 (InputLayer) │ (None, 224, 224, 3) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_conv1 (Conv2D) │ (None, 224, 224, 64) │ 1,792 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_conv2 (Conv2D) │ (None, 224, 224, 64) │ 36,928 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block1_pool (MaxPooling2D) │ (None, 112, 112, 64) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_conv1 (Conv2D) │ (None, 112, 112, 128) │ 73,856 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_conv2 (Conv2D) │ (None, 112, 112, 128) │ 147,584 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block2_pool (MaxPooling2D) │ (None, 56, 56, 128) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv1 (Conv2D) │ (None, 56, 56, 256) │ 295,168 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv2 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_conv3 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block3_pool (MaxPooling2D) │ (None, 28, 28, 256) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv1 (Conv2D) │ (None, 28, 28, 512) │ 1,180,160 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv2 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_conv3 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block4_pool (MaxPooling2D) │ (None, 14, 14, 512) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv1 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv2 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_conv3 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ block5_pool (MaxPooling2D) │ (None, 7, 7, 512) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten_1 (Flatten) │ (None, 25088) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ fc1 (Dense) │ (None, 4096) │ 102,764,544 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ fc2 (Dense) │ (None, 4096) │ 16,781,312 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ predictions (Dense) │ (None, 1000) │ 4,097,000 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 138,357,544 (527.79 MB)
Trainable params: 138,357,544 (527.79 MB)
Non-trainable params: 0 (0.00 B)
'AI' 카테고리의 다른 글
Residual Network 구현 및 학습 (0) | 2024.11.24 |
---|---|
DenseNet 구현 및 학습 (1) | 2024.11.22 |
TensorFlow 함수형 API 로 AlexNet 논문 구현 (0) | 2024.11.18 |
Colab 에서 Kaggle 데이터 API 로 받기 (3) | 2024.11.15 |
ViT 에서 언급한 CNN 의 Inductive bias 에 대해 알아보자 (3) | 2024.11.13 |