딥러닝은 최근 몇 년 동안 컴퓨터 비전, 자연어 처리 및 음성 인식과 같은 다양한 분야에서 뛰어난 성능을 보여주었습니다. 이러한 성능은 크게 신경망 아키텍처의 발전과 관련이 있습니다. 딥러닝의 핵심 요소인 변형된 신경망 아키텍처들은 기존의 신경망 아키텍처를 개선하거나 새로운 개념을 도입하여 성능을 향상시킨 것입니다.
이번 포스트에서는 가장 유명한 변형된 신경망 아키텍처인 VGG와 ResNet을 소개하고, 각각의 특징과 장단점을 살펴보겠습니다.
VGG (Visual Geometry Group)
VGG는 옥스퍼드 대학교의 Visual Geometry Group에서 개발한 신경망 아키텍처입니다. VGGNet은 간단하고 일관된 구조로 이루어져 있으며, 주로 이미지 분류에 사용됩니다. VGGNet은 소규모 필터를 사용하여 깊은 네트워크를 구축합니다. 이는 신경망의 깊이에 따라 성능이 향상되는 것을 의미합니다.
VGGNet의 특징은 다음과 같습니다:
- 모든 컨볼루션 레이어는 3x3 크기의 필터로 구성됩니다.
- 풀링 레이어는 2x2 크기의 필터로 구성되고, 스트라이드(stride)는 2로 설정됩니다.
- VGGNet은 16 또는 19개의 레이어로 구성됩니다. VGG16과 VGG19라고 불리는 이유는 레이어의 수에 따른 것입니다.
아래는 VGGNet의 간단한 구현 예제입니다:
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
model = Sequential([
Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(224, 224, 3)),
Conv2D(64, (3, 3), activation='relu', padding='same'),
MaxPooling2D((2, 2)),
Conv2D(128, (3, 3), activation='relu', padding='same'),
Conv2D(128, (3, 3), activation='relu', padding='same'),
MaxPooling2D((2, 2)),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
MaxPooling2D((2, 2)),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D((2, 2)),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D((2, 2)),
Flatten(),
Dense(4096, activation='relu'),
Dense(4096, activation='relu'),
Dense(1000, activation='softmax')
])
model.summary()
ResNet (Residual Network)
ResNet은 마이크로소프트에서 개발된 신경망 아키텍처로, 매우 깊은 신경망을 구축하는 데 사용됩니다. ResNet의 핵심 개념은 잔차 연결(residual connection)입니다. 잔차 연결은 이전 층에서의 입력 데이터를 현재 층의 출력에 직접 추가하는 것을 의미합니다. 이를 통해 깊은 네트워크에서 발생할 수 있는 기울기 소실(gradient vanishing) 문제를 해결할 수 있습니다.
ResNet의 특징은 다음과 같습니다:
- 잔차 블록(residual block)이라고 불리는 구조로 이루어져 있습니다. 이 블록은 하나 이상의 컨볼루션 레이어와 스킵 연결(skip connection)로 구성됩니다.
- 잔차 블록에서는 층의 개수에 따라 다양한 종류의 구조를 사용합니다. 일반적으로 18, 34, 50, 101, 152개의 층으로 구성된 ResNet이 사용됩니다.
- ResNet은 이미지 분류, 객체 탐지, 세그멘테이션 등에 널리 사용됩니다.
아래는 ResNet의 간단한 구현 예제입니다:
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, Add, GlobalAveragePooling2D, Dense
def resnet_block(x, filters, strides=1, activation='relu'):
shortcut = x
strides1x1 = (strides, strides)
# 첫 번째 블록
x = Conv2D(filters, (3, 3), strides=strides1x1, padding='same')(x)
x = BatchNormalization()(x)
x = Activation(activation)(x)
# 두 번째 블록
x = Conv2D(filters, (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
# 스킵 연결
if strides > 1:
shortcut = Conv2D(filters, (1, 1), strides=strides1x1, padding='same')(shortcut)
shortcut = BatchNormalization()(shortcut)
x = Add()([x, shortcut])
x = Activation(activation)(x)
return x
input_shape = (224, 224, 3)
num_classes = 1000
inputs = tf.keras.Input(shape=input_shape)
x = Conv2D(64, (7, 7), strides=(2, 2), padding='same')(inputs)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = tf.keras.layers.MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
# 잔차 연결 블록 3개
x = resnet_block(x, 64)
x = resnet_block(x, 64)
x = resnet_block(x, 64)
x = GlobalAveragePooling2D()(x)
outputs = Dense(num_classes, activation='softmax')(x)
model = Model(inputs, outputs)
model.summary()
딥러닝 아키텍처는 계속해서 발전하고 있으며, 이번 포스트에서는 VGG와 ResNet과 같은 변형된 신경망 아키텍처를 소개했습니다. 다른 신경망 아키텍처들도 많이 있으며, 각각의 특징과 적용 분야를 공부하고 활용할 수 있습니다.