MobileNetV1 본문
모바일넷은 standard conv, detphwise conv, pointwise conv의 3가지 컨볼루션 레이어를 사용하며 총 28개의 레이어로 구성되어 있다 첫번째 conv layer는 일반 convolutional layer를 사용하며 모든 컨볼루션 레이어 뒤에 Batch Normalization과 ReLU가 이어진다.
그냥 논문으로 보고 구현한 네트워크랑 케라스에서 제공하는 모바일넷 모델과 비교했을 때 파라미터 수나 텐서 size 차이가 있길래 좀 더 확인해봤더니 다음과 같은 사실을 알게 되었다.
케라스에서 제공하는 모바일넷 모델은
1. 모든 convolutional layer에서 bias를 사용하지 않는다.
-> Conv layer에서 use_bias 인자 값을 False로 주면 된다. 왜 bias를 사용하지 않았는지 잘 모르겠다. (논문에서 bias를 사용하지 않는다는 내용을 못 찾겠다.)
2. 모델의 json파일을 뜯어보고 ZeroPadding2D 레이어를 확인해보니 padding을 주는 방식이 조금 달랐다.
케라스의 ZeroPadding2D 레이어는 padding 인자 값을 int / tuple of 2ints / tuple of 2 tuples of 2 ints의 3가지 케이스로 받을 수 있다.
- padding=2로 주는 것은 width와 height의 크기를 2씩 늘린다. 100x100 -> 104x104가 됨
- padding=(2, 2)로 주는 것은 위의 케이스와 같다. 그렇지만 height, width에 주는 padding값을 다르게 지정해줄 수 있다.
- padding=((0,1), (0,1))과 같이 2개의 int를 가지고 있는 튜플을 2개 사용한다. ((top_pad, bottom_pad), (left_pad, right_pad))이기 때문에 내가 원하는 위치에만 패딩 값을 줄 수 있다.
3. 1차원으로 reshape할 때 Resphae((1000,))처럼 써야한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | from keras import models, layers from keras import Input from keras.models import Model, load_model from keras.preprocessing.image import ImageDataGenerator from keras import optimizers, initializers, regularizers, metrics from keras.callbacks import ModelCheckpoint, EarlyStopping from keras.layers import BatchNormalization, DepthwiseConv2D, Conv2D, Activation, Dense from keras.layers import GlobalAveragePooling2D, ZeroPadding2D, Reshape, Dropout import os import matplotlib.pyplot as plt import numpy as np import math train_datagen = ImageDataGenerator(rescale=1./255) val_datagen = ImageDataGenerator(rescale=1./255) train_dir = os.path.join('./dataset/1/images/train') val_dir = os.path.join('./dataset/1/images/val') train_generator = train_datagen.flow_from_directory(train_dir, batch_size=16, target_size=(224, 224), color_mode='rgb') val_generator = val_datagen.flow_from_directory(val_dir, batch_size=16, target_size=(224, 224), color_mode='rgb') def depthwise_bn_relu(x, s, padd): x = DepthwiseConv2D((3, 3), strides=(s, s), padding=padd, use_bias=False)(x) x = BatchNormalization()(x) x = Activation('relu')(x) return x def pointwise_bn_relu(x, number_of_filter): x = Conv2D(number_of_filter, (1, 1), strides=(1, 1), padding='same', use_bias=False)(x) x = BatchNormalization()(x) x = Activation('relu')(x) return x input_tensor = Input(shape=(224, 224, 3), dtype='float32', name='input') x = ZeroPadding2D(padding=((0, 1), (0, 1)))(input_tensor) x = Conv2D(32, (3, 3), strides=(2, 2), padding='valid', use_bias=False)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = depthwise_bn_relu(x, 1, 'same') x = pointwise_bn_relu(x, 64) x = ZeroPadding2D(padding=((0, 1), (0, 1)))(x) x = depthwise_bn_relu(x, 2, 'valid') x = pointwise_bn_relu(x, 128) x = depthwise_bn_relu(x, 1, 'same') x = pointwise_bn_relu(x, 128) x = ZeroPadding2D(padding=((0, 1), (0, 1)))(x) x = depthwise_bn_relu(x, 2, 'valid') x = pointwise_bn_relu(x, 256) x = depthwise_bn_relu(x, 1, 'same') x = pointwise_bn_relu(x, (256)) x = ZeroPadding2D(padding=((0, 1), (0, 1)))(x) x = depthwise_bn_relu(x, 2, 'valid') x = pointwise_bn_relu(x, 512) for _ in range(5): x = depthwise_bn_relu(x, 1, 'same') x = pointwise_bn_relu(x, 512) x = ZeroPadding2D(padding=((0, 1), (0, 1)))(x) x = depthwise_bn_relu(x, 2, 'valid') x = pointwise_bn_relu(x, 1024) x = depthwise_bn_relu(x, 2, 'same') x = pointwise_bn_relu(x, 1024) x = GlobalAveragePooling2D()(x) x = Reshape((1, 1, 1024))(x) x = Dropout(0.001)(x) x = Conv2D(1000, (1, 1), strides=(1, 1), padding='same')(x) x = Activation('softmax')(x) output_tensor = Reshape((1000,))(x) my_mobile = Model(input_tensor, output_tensor) my_mobile.summary() | cs |
'ML & DL > 이것저것..' 카테고리의 다른 글
Keras에서 tensorflow 함수 사용하기 (0) | 2019.02.26 |
---|---|
ResNet50 구현해보기 (4) | 2019.01.23 |
difference between SeparableConv and DepthwiseConv (0) | 2019.01.15 |
pre-trained VGG를 사용한 blood cell classification (2) (1) | 2019.01.08 |
pre-trained VGG를 사용한 blood cell classification (1) (0) | 2019.01.04 |