서울ICT이노베이션스퀘어 - 인공지능 고급과정(시각지능) 12일 차

※ Notification
본 포스팅은 작성자가 이해한 내용을 바탕으로 작성된 글이기 때문에 틀린 부분이 있을 수 있습니다.
잘못된 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다 :)

Intro

어제와 이어서 Transfer learning와 ImageDataAugmentation, ImageDataGenerator에 대해 배우고 실습을 진행했다.

Transfer learning

cats and dogs dataset에 다양한 pre-trained model을 적용하고, 결과를 비교 분석해보는 시간을 가졌다.
MobileNet, ResNet50, InceptionV3, Xception 모델을 돌려본 결과 아래와 같은 결과를 얻을 수 있었다.

MobileNetResNet50InceptionV3Xception
Total params4,031,73025,193,39422,622,03422,467,162
Trainable parmas4,009,84225,140,27422,587,60222,412,634
Non-trainable params21,88853,12034,43254,528
Elapsed time04:2509:2808:3116:28
Accuracy0.9840.9900.9900.990

각 모델은 비슷한 성능을 보여준다.
모델의 선택에 있어서 비슷하다는 말은 사람마다 받아들이는 기준이 다를 수 있으므로 회사마다 선택 기준을 정의해둬야 한다.
성능의 차이가 크게 나지 않는다면 소요시간이 적고 정확도와 overfitting이 적은 모델을 선택한다. 위 결과에서 하나를 선택한다고 한다면 MobileNet이 될 것이다.
언제나 그렇듯 Simple is Best.

Non-trainable params

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 mobilenet_1.00_224 (Functio  (None, 7, 7, 1024)       3228864   
 nal)                                                            
                                                                 
 flatten_2 (Flatten)         (None, 50176)             0         
                                                                 
 dense_4 (Dense)             (None, 16)                802832    
                                                                 
 dropout_2 (Dropout)         (None, 16)                0         
                                                                 
 dense_5 (Dense)             (None, 1)                 17        
                                                                 
=================================================================
Total params: 4,031,713
Trainable params: 4,009,825
Non-trainable params: 21,888
_________________________________________________________________

Model summary를 출력해보면 Total params, Trainable params, Non-trainable params가 출력된다.
Total params, Trainable params는 딱봐도 알 것 같은데 Non-trainable params는 무엇일까?


다음과 같이 모델이 3등분으로 나눠져있다면 Non trainable에 해당하는 부분은 어디일까?
가로나 세로, 대각성 같이 큰 특징은 바뀌지 않기 때문에 1번이 Non trainable이라고 하셨다.

수업을 들을 때는 '당연히 전이학습이니까 앞에서 최적화된 가중치 값은 변하지 않겠지'라고 생각했었는데 Model.summary()는 학습을 하기 전, 모델 선언만 하고 출력되는 부분이라는 것에 이해가 가지 않았다.

그래서 자료들을 찾아봤는데 역시나 한글로는 나오지도 않아서 Keras API Docs까지 가서 찾았다.
Transfer learning & fine-tuning 문서의 Freezing layers: understanding the trainable attribute part이다. (https://keras.io/guides/transfer_learning)

non_trainable_weights is the list of those that aren't meant to be trained. Typically they are updated by the model during the forward pass.

In general, all weights are trainable weights. The only built-in layer that has non-trainable weights is the BatchNormalization layer. It uses non-trainable weights to keep track of the mean and variance of its inputs during training.

일반적으로 모든 가중치는 훈련이 가능하지만, 특별히 BatchNormalization layer는 Non-trainable weight를 가진다고 한다. 또 다른 글에서 이야기하길 BatchNorm은 평균과 분산을 이용해 업데이트되지만, 역전파 과정에서는 훈련이 되지 않는다고 한다. 그래서 Non-trainable weight라고 하는 것 같다.

따라서 BatchNormalization layer가 있으면 Non-trainable weight를 가진다고 할 수 있을 것이다.
직접 확인해보기 위해 코드를 돌려봤다.

Model: "mobilenet_1.00_224"
						---- 중략 ----
=================================================================
Total params: 3,228,864
Trainable params: 3,206,976
Non-trainable params: 21,888
_________________________________________________________________

MobileNet을 불러와서 모델에 있는 BatchNormalization layer들을 모두 제거한 모델을 새로 만들어보았다.

model = Sequential()
for layer in mobilenet.layers:
    if 'bn' not in layer.name: 
        model.add(layer)

그리고 model.summary()는 다음과 같다.

Model: "sequential"
					---- 중략 ----
=================================================================
Total params: 3,185,088
Trainable params: 3,185,088
Non-trainable params: 0
_________________________________________________________________

예상한 것처럼 BatchNorm layer를 모두 제거하니 Non-trainable params가 0이 나왔다.

사실 간단하게 BatchNorm layer를 추가한 모델을 만들어서 확인은 했지만 뭔가 MobileNet에 적용해서 확인해보고 싶었다.

BatchNormalization에 대해서 깊이 알지 못해서 자세한 내용은 추후에 공부한 후 추가해야겠다.

Include_top

Feature를 가져다 쓸 것인지, 해당 모델을 가져다 쓸 것인지 결정하는 매개변수

  • include_top = Ture 모델 전체를 가져옴, Vector를 반환
  • include_top = False Tensor를 반환
model = Sequential()

# Pre-trained model
model.add(mobilenet) 

# 주어진 데이터를 분류하는 MLP
model.add(Flatten())
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(2, activation='softmax'))

model.compile(loss='sparse_categorical_crossentropy',
              optimizer=Adam(2e-5),
              metrics=['acc'])
model.summary()

Pre-trained model

pre-trained model은 224x224(MobileNet Default)와 같이 비교적으로 큰 이미지로 학습을 시켰기 때문에 pre-trained model에 작은 사이즈의 이미지를 사용하면 자동으로 확대한다.

때문에 모델을 구축할 때 어떤 사이즈의 이미지를 넣을 것인지 Default를 정의해줘야 한다.

Image Data Generator

tf.keras.preprocessing.image.ImageDataGenerator(
    featurewise_center=False, samplewise_center=False,
    featurewise_std_normalization=False, samplewise_std_normalization=False,
    zca_whitening=False, zca_epsilon=1e-06, rotation_range=0, width_shift_range=0.0,
    height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0,
    channel_shift_range=0.0, fill_mode='nearest', cval=0.0,
    horizontal_flip=False, vertical_flip=False, rescale=None,
    preprocessing_function=None, data_format=None, validation_split=0.0, dtype=None)

TF에서는 이미지 데이터 보강을 위해 ImageDataGenerator class를 제공하며 rescale, rotation, shift 등의 다양한 변화를 줄 수 있다.
flow_from_directory()를 사용해 train과 test로 나누어놓은 디렉토리를 통해 쉽게 train/test data에 변형을 적용할 수 있다.

Image Data Augmentation

그냥 Data Augmentation이라고 하면 되지 왜 굳이 앞에 Image를 붙이는 걸까?

Text data

hello I am good 이라는 문장이 있다고 하면 hello와 good을 바꾸기 위해서는 0번째 인덱스와 -1번 인덱스를 교환해야 한다. 이렇듯 source change가 발생하기 때문에 안된다고 하셨다. 물론 어떻게 어떻게 하면 가능은 하겠지만 그렇게 효율적이지 않다는 말씀 같았다.

좀 더 궁금해서 찾아보니 다른 블로그를 찾아보니 다음과 같은 내용을 발견할 수 있었다.

2019년 EMNLP에서 발표된 "Easy Data Augmentation Techniques for Boosting Performance on Text Classification Tasks" 논문에서는 자연어 처리에서 쉽게 떠올릴 수 있는 DA 테크닉들이 실제로 성능 향상에 유의미한 영향을 미칠 수 있으며, Augmentation 과정을 통해 생성된 문장들이 원 라벨의 성질을 잘 따른다는 연구 결과를 발표하였습니다.

NLP

그렇다면 자연어 처리는 어떨까?

  • I work at google
  • I google at work

똑같이 google이라는 단어가 쓰였지만 하나는 명사로, 하나는 동사로 쓰였다.
이처럼 같은 데이터라도 어느 순어에 위치하냐에 따라서 그 의미가 달라지며, 자연어 처리에서 데이터의 순서는 매우 중요한 역할을 한다.
이러한 이유 때문에 언어에 augmentation을 적용하는 것은 결코 쉽지 않다.

Image

하지만 이미지는 어떨까?
이미지는 뒤집거나 돌려도 정답이 달라지지 않는다.

때문에 Image에 대해 Data augmentation을 적용할 수 있다.

Object detection

하지만 object detection의 경우에는 약간 다른데 zoom과 같은 문제가 있다고 하셨다. 잘 이해가 가진 않지만 가능은 한데 굳이 하지 않는다고 한다.
object detection은 객체를 인식하는 것이라 돌리거나 뒤집어도 효과가 크지 않나보다.

이 내용도 궁금해서 좀 더 찾아봤는데 object detection에서는 이미지 뿐만 아니라 bounding box 또한 변화시켜야 된다고 한다.
이러한 이유 때문에 굳이 하지 않는다고 하신 것 같다.

Classification

하지만 Classification에서는 이야기가 다른데 이미지를 자르거나 돌려도 그 대상을 분류한다는 목적은 변하지 않는다. 즉, 강아지 사진을 180도 돌려도 강아지 사진이고, 반전해도 강아지 사진이라는 이야기다.

Class mode

ImageDataGenerator의 옵션중에는 class_mode라는 것이 있는데, 이전에 학습했던 내용과 연결된다.
이전 포스팅에서 다음과 같은 표를 그린 적이 있었는데 Image 데이터에는 실수는 없으므로 실수 내용은 삭제했다.

이항 분류다항분류다항분류
One hot encoding
Loss functionBinary Cross EntropySparse Cross EntropyCategorical Cross Entropy
Activation functionSigmoidSoftmaxSoftmax
class_modebinarysparsecategorical

class_mode는 주어진 문제에 따라 binary, sparse, categorical로 적용해야 한다. 참고로 TF의 Default는 categorical이다.

이전에 학습했던 Cats and Dogs dataset으로 binary, sparse, categorical 방식으로 실습하는 시간을 가졌다.

Image Data Generator 의 순서는 다음과 같다.

  • 어떤 효과를 줄지 definition.
  • 어디서 데이터를 가져올지, flow_from_directory()
  • 실제 데이터를 가져와서 내 메모리에 저장 next()

그러나 실제 모델을 돌릴때는 next() 부분은 찾아볼 수 없는데, 그 이유는 바로 model을 fit하는 model.fit() 자체가 batch size 만큼 반복하는 iterator이므로 next()의 의미를 내포하고 있다고 보면된다.

Note

  • image data generator를 쓸 때는 항상 class_indices와 num_classes는 출력해보자.

Outro

확실히 코딩하니까 시간이 훅훅 가는 것 같다.
원래라면 실습 코드도 첨부하려고 했지만 내용이 너무 길어질 것 같아서 생략하기로 했다.

좋은 웹페이지 즐겨찾기