DeepLab v1
- semantic segmentation문제를 해결하기 위해서 google에서 개발한 모델이다.
- 주요특징
- 1. atrous convolution 을 사용하여, pooling없이 receptive field를 확장할 수 있다.
- 2. Fully convolutional network 기반이다.
( 기존의 fully connected layer를 제거하고, 모든 레이어를 convolutional layer 바꾸어서 입력 크기에 상관없이 동작하게 함. )
- 3. Conditional Random Field ( 조건부 무작위장 )
- 위의 fully convolutonal network기반 출력은 간혹 경계가 부정확하거나 가장자리에서 세부 사항이 손실된다.
그래서 이를 해결하기 위해 CRF로 후처리를 하여, 세그멘테이션 결과를 정교화 시킴
- 4. Multi-Scale Feature Extraction
- deepLab v1에서는 고정된 단일 스케일의 receptive field만 사용하는 대신 여러 스케일에서의 특징을 학습해서 다양한 크기의 객체를 더 잘 처리할 수 있다.
- DeepLab v1의 한계
- atrous convolution은 해상도를 유지하며 학습이 가능하나 계산비용이 높다.
- 실시간 응용 어려움
- CRF는 경계를 세밀하게 보정하지만, 별도의 후처리 단계로 작동해서 시스템 전체가 느려질수 있다.
- deeplab v1의 구성요소
- backbone network
- 손실함수로 cross-entropy loss를 사용하여 segmentation 정확도를 향상
DeepLab v1의 동작 원리
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Input, Conv2DTranspose, Softmax, Concatenate
from tensorflow.keras.models import Model
from tensorflow.keras.utils import plot_model
# VGG-16 백본 모델을 구축하는 함수
# 입력: 이미지 입력 크기 (input_shape)
# 출력: VGG-16의 마지막 convolution layer (block5_conv3)
def build_vgg16_backbone(input_shape):
inputs = Input(shape=input_shape)
# Block 1
x = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 2
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 3
x = Conv2D(256, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 4
x = Conv2D(512, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 5
x = Conv2D(512, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
model = Model(inputs, x, name="VGG16_Backbone")
return model
# DeepLab v1 모델을 VGG-16 백본을 기반으로 구축하는 함수
# 입력: 이미지 크기 (input_shape), 클래스 수 (num_classes)
# 출력: DeepLab v1 모델
def build_deeplabv1_vgg16(input_shape=(512, 512, 3), num_classes=21):
base_model = build_vgg16_backbone(input_shape)
# VGG-16의 마지막 convolution layer (block5_conv3) 가져오기
x = base_model.get_layer("block5_conv3").output
# Atrous Convolution 적용 (다중 스케일 정보 추출)
atrous_rates = [6, 12, 18, 24]
atrous_layers = [Conv2D(512, (3, 3), padding='same', dilation_rate=rate, activation='relu')(x) for rate in atrous_rates]
# Atrous Convolution 결과 합치기
x = Concatenate()(atrous_layers)
x = Conv2D(512, (1, 1), activation='relu', padding='same')(x)
# Upsampling (16배 upsampling)
x = Conv2DTranspose(num_classes, kernel_size=16, strides=16, padding='same')(x)
x = Softmax()(x)
model = Model(inputs=base_model.input, outputs=x)
# 모델 구조 시각화 (Graphviz 사용)
plot_model(model, to_file='deeplabv1_vgg16.png', show_shapes=True, show_layer_names=True)
return model
# 모델 생성
model = build_deeplabv1_vgg16()
# 모델 구조 출력
model.summary()