Darknet-53 Structure. ❘ Download Scientific Diagram
Darknet 53
- 객체 탐지 모델의 backbone network이다.
- 주요 특징
- 1. 깊이와 효율성
- 53개의 convolution layer로 구성되어 있다.
- 2. residual connections 잔차 연결
- 기울기 소실과 정보 손실을 해결 및 줄여줌
- 각 층의 입력값과 출력값이 덧셈 연산으로 연결된다.
이를 통해서 입력값이 network를 통과하며 변형된 출력값이 더해지니, 네트워크는 변형된 정보와 원본 정보를 동시에 보존함.
- 즉, layer가 입력과 출력의 차이만 학습함.
- 3. 다중 스케일 특징 추출가능
- 기본적 구성 요소
- 1. convolution layer
- 주로 3x3의 커널을 사용하며, 일부는 1x1로 채널수를 조절
- 2. residual block
- 3. down sampling
- stride 2의 convolution으로 feature map의 크기를 절반으로 줄인다.
- 4. batch normalization
- 5. leaky relu
- 장점.
# darknet53의 잔차 블록 생성 함수
# input 입력텐서
# filters 기준 필터 수
# training 배치 정규화의 학습/추론 모드 결정 플래그
# return 잔차 블록 처리 결과 텐서
def darknet53_residual_block( inputs , filters , training , data_format , strides=1 ):
# 1. 잔차 연결을 위해서 원본 입력을 보존
shortcut = inputs
# 2. 1번째 conv layer : 1x1커널로 채널수를 조정
inputs = conv2d_fixed_padding( inputs , filters=filters , kernel_size=1 , strides=strides , data_format=data_format )
inputs = batch_norm( inputs , training=training , data_format=data_format )
inputs = tf.nn.leaky_relu( inputs , alpha=0.1 )
# 3. 2번째 conv layer : 3x3 커널로 특징 추출
inputs = conv2d_fixed_padding( inputs , filters=2*filters , kernel_size=3 , strides=strides , data_format=data_format )
inputs = batch_norm( inputs , training=training , data_format=data_format )
inputs = tf.nn.leaky_relu( inputs , alpha=0.1 )
# 4. 잔차 연결
inputs += shortcut
return inputs
# darknet 53 특징 추출기 생성 함수
# route1은 중간층 특징 맵 52 x 52 x 256
# route2는 중간층 특징 맵 26 x 26 x 512
# inputs는 최종 출력층 특징 맵 13 x 14 x 1024
def darknet53( inputs , training , data_format ):
# 1. 초기 conv layer. 3x3커널 , 32필터 , 초기 특징을 추출
inputs = conv2d_fixed_padding( inputs , filters=32 , kernel_size=3 , data_format=data_format )
inputs = batch_norm( inputs , training=training , data_format=data_format )
inputs = tf.nn.leaky_relu( inputs , alpha=0.1 )
# 2. 첫번째 다운샘플링 레이어. 필터수는 64로 증가시킴.
inputs = conv2d_fixed_padding( inputs, filters=64 , kernel_size=3 , strides=2 , data_format=data_format )
inputs = batch_norm( inputs , training=training , data_format=data_format )
inputs = tf.nn.leaky_relu( inputs , alpha=0.1 )
# 3. 첫번째 잔차 블록
inputs = darknet53_residual_block( inputs , filters=32 , training=training , data_format=data_format )
# 4. 2번째 다운샘플링
inputs = conv2d_fixed_padding( inputs , filters=128 , kernel_size=3 , strides=2 , data_format=data_format )
inputs = batch_norm( inputs , training=training , data_format=data_format )
inputs = tf.nn.leaky_relu( inputs , alpha=0.1 )
# 5. 2번째 잔차 블록이며 2회 반복
for _ in range(2):
inputs = darknet53_residual_block( inputs , filters=64 , training=training , data_format=data_format )
# 6. 세번째 다운샘플링
inputs = conv2d_fixed_padding(inputs, filters=256, kernel_size=3, strides=2, data_format=data_format)
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=0.1 )
# 7. 3번째 잔차블록이며 8회 반복
for _ in range(8):
inputs = darknet53_residual_block(inputs, filters=128 , training=training , data_format=data_format)
route1 = inputs # route1 저장: 52x52x256 특징 맵
# 8. 4번째 다운 샘플링
inputs = conv2d_fixed_padding(inputs, filters=512 , kernel_size=3 , strides=2 , data_format=data_format )
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=0.1)
# 9. 4번째 잔차 블록이며 8회 반복
for _ in range(8):
inputs = darknet53_residual_block(inputs, filters=256 , training=training , data_format=data_format)
route2 = inputs # route2 저장: 26x26x512 특징 맵
# 10. 다섯 번째 다운샘플링 (26x26 → 13x13)
inputs = conv2d_fixed_padding(inputs, filters=1024, kernel_size=3 , strides=2 , data_format=data_format )
inputs = batch_norm(inputs, training=training, data_format=data_format)
inputs = tf.nn.leaky_relu(inputs, alpha=0.1)
# 11. 다섯 번째 잔차 블록 4회 반복 (필터 수 512)
# 최종 feature 맵: 13x13x1024
for _ in range(4):
inputs = darknet53_residual_block(inputs , filters=512 , training=training , data_format=data_format)
return route1, route2, inputs