본문 바로가기
  • 우당탕탕속의 잔잔함
Programming/Deep Learning Network

[Code] MobileNet v1

by zpstls 2023. 3. 8.
반응형

이전, MobileNet v1에 대해서 알아보았습니다.

이번 포스트에서는 MobileNet v1을 코드로 구현하는 부분을 다룰 것입니다.

 

 

우선, MobileNet v1의 이론적인 부분에 대한 내용은 다음과 같습니다.

 

[Model] MobileNet v1

개발자로서 스트레스를 많이 받는 것 중 하나는 수행 속도입니다. 특히, AI 그리고 Deep Learning에서의 처리 속도 개선은 어려운 작업 중 하나입니다. 이와 관련된 고민들을 통해 만들어진 MobileNet에

mj-thump-thump-story.tistory.com

 

위 페이지에서도 언급되었지만, 코드 생성을 위해 다시 언급해 봅니다. ㅎㅎ

MobileNet v1은 다음과 같은 Architecture를 갖습니다.

위 표에서 몇가지 단어(?)들이 의미하는 것에 대해 짚고 넘어가도록 하겠습니다.

s는 Stride Size를 의미합니다. 예를 들면, s2는 Stride Size가 2 임을 의미합니다. Conv dw는 Depthwise Convolution을 의미하고 Conv / s1은 Pointwise Convolution을 의미합니다.

그리고 MobileNet v1의 핵심 구조인 Depthwise Separable Convolution은 다음과 같습니다.

3x3 Depthwise Convolution을 통과한 후에 Batch Normalization을 수행하고 ReLU를 통과시킵니다. 그리고 Pointwise Convolution 연산을 수행하게 되는데, 이 Pointwise Convolution은 1x1 Convolution을 통과하고 Batch Normalization, ReLU를 차례로 통과하는 구조입니다.

 

각각의 요소에 따른 Code 부분은 다음과 같습니다.

_Standard_Conv와 _Depthwise_Separable_Conv, GlobalAveragePooling2D, Dropout, Dense로 간단하게 구현할 수 있습니다. 각 Layer마다의 Stride, Padding, Filter Size 등은 왼쪽 표에 맞게 넣어주면 됩니다.

 

앞서 언급한 _Standard_Conv와 _Depthwise_Separable, Pointwise 부분에 대한 코드는 다음과 같습니다.

TensorFlow에서 제공하는 Conv2D, DepthwiseConv2D, BatchNormalization, ReLU를 통해 간단하게 구현할 수 있습니다. 참고로 앞서 언급하였듯이 Depthwise Separable Convolution은 Depthwise→Pointwise의 순으로 수행되는 것을 의미합니다.

 

 

 

 

이제 모두 구현하였다고 생각해도 무방합니다!

다음은 위 내용을 토대로 구현한 Model의 전반적인 코드입니다.

 

  • Main 부분
# Initializing models
MobilenetV1 = Mobilenet_V1(classes= 5, alpha= 1.0, rho= 1.0, droppout= 0.3, img_size= (150, 150)).build()

# Complie optimizer and loss function into model
MobilenetV1.compile(optimizer='adam', loss= CategoricalCrossentropy(label_smoothing=0.01, metrics= ['acc'])

# Callback
checkpoint = callbacks.ModelCheckpoint(args.Mobilenetv1_folder, monitor= 'val_acc', save_best_only=  True, verbose = 1)
lr_R = callbacks.ReduceLROnPlateau(monitor= 'acc', patience= 4, verbose= 1 , factor= 0.5, min_lr= 0.00001)

# Training model 
MobilenetV1.fit(train_data, validation_data= val_data, epochs= 100, verbose= 1, callbacks= [checkpoint, lr_R])

 

  • Model 부분
from tensorflow.keras.layers import *
from tensorflow.keras import *

class Mobilenet_V1():
    def __init__(self,*, classes, alpha = 1.0, rho = 1.0, droppout = 0.001, img_size = (224,224)):
        self._alpha = alpha
        self._rho = rho
        self._num_classes = classes
        self.model = None 
        self._droppout = droppout
        self.img_size = img_size

    def __Standard_Conv(self):
        return models.Sequential([
            Conv2D(filters= 32, kernel_size=(3,3), strides= (2,2), padding= 'valid'),
            BatchNormalization(),
            ReLU(max_value= 6)
        ])
    
    def __Depthwise_Conv(self, strides, padding):
        return models.Sequential([
            DepthwiseConv2D(kernel_size= (3,3), strides= strides, padding= padding),
            BatchNormalization(),
            ReLU(max_value= 6)
        ])
    
    def __Pointwise_Conv(self, filters):
        return models.Sequential([
            Conv2D(filters= int(filters * self._alpha), kernel_size= (1,1), strides= 1),
            BatchNormalization(),
            ReLU(max_value= 6)
            
        ])

    def __Depthwise_Separable_Conv(self, *, strides_depthwise, padding_depthwise, filters_pointwise):
        return models.Sequential([
            self.__Depthwise_Conv(strides= strides_depthwise, padding= padding_depthwise),
            self.__Pointwise_Conv(filters= filters_pointwise)
        ])

    def build(self):

        featur_map_size = int(self.img_size[0] * self._rho) 

        self.model = Sequential([
            InputLayer(input_shape= (featur_map_size,featur_map_size,3)),

            self.__Standard_Conv(),

        # Depth_Separable_Conv 1
            self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same',filters_pointwise= 64),
        # Depth_Separable_Conv 2
            self.__Depthwise_Separable_Conv(strides_depthwise= (2,2), padding_depthwise= 'valid', filters_pointwise= 128),
        # Depth_Separable_Conv 3
            self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 128),
        # Depth_Separable_Conv 4
            self.__Depthwise_Separable_Conv(strides_depthwise= (2,2), padding_depthwise= 'valid', filters_pointwise= 256),
        # Depth_Separable_Conv 5
            self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 256),
        # Depth_Separable_Conv 6
            self.__Depthwise_Separable_Conv(strides_depthwise= (2,2), padding_depthwise= 'valid', filters_pointwise= 512),
        # Depth_Separable_Conv 7 - > 11
                self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 512),
                self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 512),
                self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 512),
                self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 512),
                self.__Depthwise_Separable_Conv(strides_depthwise= (1,1), padding_depthwise= 'same', filters_pointwise= 512),
        # Depth_Separable_Conv 12
             self.__Depthwise_Separable_Conv(strides_depthwise= (2,2), padding_depthwise= 'valid', filters_pointwise= 1024),

        # Depth_Separable_Conv 13
            self.__Depthwise_Separable_Conv(strides_depthwise= (2,2), padding_depthwise= 'same', filters_pointwise= 1024),
            GlobalAveragePooling2D(),
    
        # FC
            Dropout(self._droppout),
            Dense(self._num_classes, activation= 'softmax')
        ])
        return self.model

 

 

생각보다 정말 간단하게 구현할 수 있었습니다.

물론, TensorFlow를 사용하여 기본적인 연산(ex. Conv2D, Batch Normalization 등)은 구현할 필요가 없었기에 간단할 수도 있겠지만, 그래도 기본 요소들을 활용하여 어떠한 모델을 구현함에 있어 짧은 코드만으로 구현할 수 있다는 것은 의외라고 생각할 수도 있을 것입니다.

 

이번 포스트는 이렇게 간단하게 마무리하도록 하겠습니다!

반응형

'Programming > Deep Learning Network' 카테고리의 다른 글

[Code] VNect  (0) 2023.03.13
[Model] VNect과 XNect  (0) 2023.03.13
[Model] RefineDet  (0) 2023.03.06
[Model] SSD (Single Shot Detector)  (0) 2023.03.02
[Model] YOLO v1  (0) 2023.02.23

댓글