TensorFlow 2.2.0에서 아직 지원되지 않는 EfficientNet을 플라게하여 Food101에 도전합니다.

EfficientNet이란?



2019년에 등장과 동시에 각 방면에서 State Of the Art의 달성에 이용된, 이미지 인식의 최강 모델의 하나가 EfficientNet입니다. Omiita씨의 기사, 2019년 최강의 이미지 인식 모델 EfficientNet 해설  를 봐 주세요.

이하가 논문에서도 게재되고 있던 정밀도와 파라미터수의 그림입니다. 머리 하나 빠진 것을 알 수 있습니다.



EfficientNet을 TensorFlow로 사용하는 방법?



그런 EfficientNet입니다만, TensorFlow에서 ResNet등의 각종 저명 모델을 제공하고 있는 tf.keras.applications에는 아직 들어 있지 않은 것 같습니다. 2020년 6월 현재 TensorFlow의 최신 버전은 2.2.0입니다. EfficientNet은 이미 TensorFlow 소스 코드에 캡처되어 존재합니다 하지만 API 문서에서도 언급이 없고 API도 내보내지지 않았습니다. 아직 공식적으로는 이용할 수 없는 상태가 되어 있는 것 같습니다. 그래서 본고에서는, 플라잉 겟이라고 하는 것으로, Keras Applications로부터 EfficientNet를 받아들여 움직여 봅시다.

또한 모처럼 소스 코드를 만지는 기회이므로 활성화 함수도 EfficientNet에서 이용되고 있는 swish

Mish

Keras Applications에서 TensorFlow에서만 작동하도록 가져온 소스 코드는 tftk입니다.

Food101 데이터 세트로 사용해 보세요.



이제 EffiientNetB3 (개)를 사용하여 Food101 데이터 세트에서 학습해 보겠습니다. Food101의 데이터 세트나 학습 정밀도 벤치마크에 대해서는, 이쪽의 koshian2씨가 Inception v3로 시험한 실례, 을 참고로 하는 것이 좋을 것 같습니다.

우선은 학습 전에 목표로 하는 정밀도를 결정해 둡니다. 방금의 링크를 읽으면, 아무래도 특별한 신경망을 짜면 90%를 넘는 모델이 생겨, Inception V3로 상당히 노력하면 86.97%정도에 도착하는 것 같네요. 과연 스페셜한 일품 정도의 정밀도는 아니라고 생각하므로, 이쪽의 86.97%를 목표로 합시다. 그럼 바로 시도해 봅시다. 이번에는 적은 데이터 수에서도 정밀도가 나기 쉬운, ImageNet 데이터를 학습 끝난 가중치를 활용한 전이 학습을 실시해 보겠습니다. 그렇다면 EfficientNet에서는 어떻게 될까요? 최강 모델을 사용하여 학습을 진행합시다.

우선 구현을 합시다. 이번 학습의 구현은 다음과 같이 할 수 있습니다.

우선 라이브러리 설치.
> !pip install tftk -U

그리고 다음 코드를 실행합니다. (이것뿐입니다)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' 
import tensorflow as tf
import tftk
from tftk.image.dataset import Food101
from tftk.image.dataset import ImageDatasetUtil
from tftk.image.model import KerasEfficientNetB3

from tftk.train.image import ImageTrain
from tftk.image.augument import ImageAugument
from tftk.callback import CallbackBuilder
from tftk.optimizer import OptimizerBuilder

tftk.ENABLE_MIXED_PRECISION()
BATCH_SIZE = 40
CLASS_NUM = 101
IMAGE_SIZE = 224
CHANNELS = 3
EPOCHS = 150
SHUFFLE_SIZE = 1000

train, train_len = Food101.get_train_dataset()
validation, validation_len = Food101.get_validation_dataset()

train = train.map(ImageDatasetUtil.resize_and_max_square_crop(IMAGE_SIZE,IMAGE_SIZE),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageAugument.randaugment_map(1,4))
train = train.map(ImageDatasetUtil.image_reguralization(),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageDatasetUtil.one_hot(CLASS_NUM),num_parallel_calls=tf.data.experimental.AUTOTUNE).apply(ImageAugument.mixup_apply(200,0.1))
validation = validation.map(ImageDatasetUtil.resize_and_max_square_crop(IMAGE_SIZE,IMAGE_SIZE),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageDatasetUtil.image_reguralization(),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageDatasetUtil.one_hot(CLASS_NUM),num_parallel_calls=tf.data.experimental.AUTOTUNE)

optimizer = OptimizerBuilder.get_optimizer()
model = KerasEfficientNetB3.get_model(input_shape=(IMAGE_SIZE,IMAGE_SIZE,CHANNELS),classes=CLASS_NUM,weights="imagenet")
callbacks = CallbackBuilder.get_callbacks(tensorboard=True, consine_annealing=False, reduce_lr_on_plateau=True,reduce_patience=6,reduce_factor=0.25,early_stopping_patience=10)
ImageTrain.train_image_classification(train_data=train,train_size=train_len,batch_size=BATCH_SIZE,validation_data=validation,validation_size=validation_len,shuffle_size=SHUFFLE_SIZE,model=model,callbacks=callbacks,optimizer=optimizer,loss="categorical_crossentropy",max_epoch=EPOCHS)

위의 코드는 다음 두 줄로 데이터 확장을 수행합니다. RandAugument(확장수 1, 크기 4), Mixup을 사용해 봅니다.
train = train.map(ImageDatasetUtil.resize_and_max_square_crop(IMAGE_SIZE,IMAGE_SIZE),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageAugument.randaugment_map(1,4))
train.map(ImageDatasetUtil.image_reguralization(),num_parallel_calls=tf.data.experimental.AUTOTUNE).map(ImageDatasetUtil.one_hot(CLASS_NUM),num_parallel_calls=tf.data.experimental.AUTOTUNE).apply(ImageAugument.mixup_apply(200,0.1))

모델은 Keras Applications에서 가져온 모델이므로 사전 학습된 가중치가 있습니다. ImageNet을 사용하여 학습한 가중치를 사용하여 전이 학습을 해 봅니다.
model = KerasEfficientNetB0.get_model(input_shape=(IMAGE_SIZE,IMAGE_SIZE,CHANNELS),classes=CLASS_NUM,weights="imagenet")

실행을 시작하면 10분 정도 Food101 다운로드 시간이 걸립니다. 그러면 학습이 시작됩니다. 다음은 학습 로그입니다.
Epoch 70/150
1893/1893 [==============================] - 563s 297ms/step - loss: 0.5034 - acc: 0.9558 - val_loss: 0.5993 - val_acc: 0.8561 - lr: 0.0025


여기

그리고 검증 데이터에서의 val_acc는 85.61%에 도달하고 있어 그다지 궁리하고 있지 않지만, 목표의 86.97%까지는 단번에 나머지 한숨까지 도달할 수 있었습니다. 유석에 최강이라고하는 모델입니다. 과연 강합니다.

좋은 웹페이지 즐겨찾기