데이터사이언스/딥러닝

Object Detection Tensorflow API (Colab) #2_모델학습

Zero Coding 2022. 7. 18. 18:10

10. Pre-Trained 된 모델 불러오기 (Detection Model Zoo)

# CenterNet HourGlass104 512x512 (70ms / 41.9 COCO mAP)
!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/centernet_hg104_512x512_kpts_coco17_tpu-32.tar.gz
!tar -xzvf centernet_hg104_512x512_kpts_coco17_tpu-32.tar.gz

# CenterNet Resnet50 V1 FPN 512x512 (27ms / 31.2 COCO mAP)
!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/centernet_resnet50_v1_fpn_512x512_coco17_tpu-8.tar.gz
!tar -xzvf centernet_resnet50_v1_fpn_512x512_coco17_tpu-8.tar.gz

# SSD MobileNet V2 FPNLite 320x320 (22ms / 22.2 COCO mAP)
!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8.tar.gz
!tar -xzvf ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8.tar.gz

# SSD ResNet152 V1 FPN 640x640 [RetinaNet152] (80ms / 35.4 COCO mAP)
!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/ssd_resnet152_v1_fpn_640x640_coco17_tpu-8.tar.gz
!tar -xzvf ssd_resnet152_v1_fpn_640x640_coco17_tpu-8.tar.gz

# Mask R-CNN Inception ResNet V2 1024x1024 (301ms / 39.0 COCO mAP)
!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/mask_rcnn_inception_resnet_v2_1024x1024_coco17_gpu-8.tar.gz
!tar -xzvf mask_rcnn_inception_resnet_v2_1024x1024_coco17_gpu-8.tar.gz

11. config file을 가지고와서 model pipeline 구성

11-1. config file 준비

  • /content/models/research/object_detection/configs/tf2 폴더에 모델별 Config파일들 위치해 있음
  • 10번에서 선택한 모델에 맞게  현재 작업폴더(/content/gdrive/MyDrive/customTF2/data)로 copy해옴
  • 본 예제에서는 ssd_mobilenet_v2_fpnlite_320x320 모델을 사용
!cp /content/models/research/object_detection/configs/tf2/ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8.config /mydrive/customTF2/data

11-2. config 파일을 열어서 아래 부분 수정 (모델마다 다르므로 잘 찾아서 바꿔주면 됨)

  • num_classes : classification 몇 개인지 지정 해줌. 본 예제에서는 4개로 지정했으므로 4 입력

  • 앞의 8번/9번에서 만든 label_map, test.record, train.record의 경로를 입력해줌

  • train_config 에서 batch_size, num_steps 적절히 조절.
  • fine_tune_checkpoint는 10번에서 만들어진 모델 폴더의 ../checkpoint/cpkt-0 경로 지정
  • fine_tune_checkpoint_type 을 detection으로 변경

12. 모델 전이 학습 (Transfer Learning)

12-1. 학습을 수행할 models/research/object_detection 폴더로 먼저 이동

%cd /content/models/research/object_detection

12-2. TroubleShooting

  • 바로 학습진행시 openCV관련 버전 호환 문제 발생하게 됨. 학습에 앞서 opencv 관련 라이브러리들의 버전을 반드시 맞춰줘야함.
  • 아래에서는 headless 패키지 버전이 혼자 높아서 지우고 다른버전하고 동일하게 맞춰주는 작업을 진행하였음

!pip uninstall opencv-python-headless --y
!pip install opencv-python-headless==4.1.2.30
!pip list|grep opencv

12-3. ★ 모델 학습 시작

  • --pipeline_config_path=/content/.. 부분을 앞에서 수정한 모델명.config 파일로 변경후 진행
!python model_main_tf2.py --pipeline_config_path=/content/models/research/object_detection/configs/tf2/ssd_mobilenet_v2_fpnlite_320x320_coco17_tpu-8.config --model_dir=/mydrive/customTF2/training --alsologtostderr
  • 아래 그림처럼 step별 시간, loss등이 순차적으로 출력되면 정상 작동 하는 것임

13.  모델 내보내기  (.pb 파일 저장)

  • --pipeline_config_path=/content/.. 부분을 앞에서 수정한 모델명.config 파일로 변경후 진행
!python exporter_main_v2.py --trained_checkpoint_dir=/mydrive/customTF2/training --pipeline_config_path=/content/gdrive/MyDrive/customTF2/data/ssd_resnet152_v1_fpn_640x640_coco17_tpu-8.config --output_directory /mydrive/customTF2/data/inference_graph
  • 아래와 같이 inference_graph > saved_model 폴더에 pb파일 생성 확인

14. Custom Image를 활용한 결과 테스트

14-1 폰트 타입 지정

!wget https://freefontsdownload.net/download/160187/arial.zip
!unzip arial.zip -d .
%cd utils/
!sed -i "s/font = ImageFont.truetype('arial.ttf', 30)/font = ImageFont.truetype('arial.ttf', 30)/" visualization_utils.py
%cd ..

14-2. 테스트할 사진 가지고와서 확인

  • PATH_TO_SAVED_MODEL: .pb 모델이 저장되어있는 경로 지정
  • create_category_index_from_labelmap("...") : labelmap 파일 경로 지정
  • image_path: 테스트할 사진 경로
#Loading the saved_model
import tensorflow as tf
import time
import numpy as np
import warnings
warnings.filterwarnings('ignore')
from PIL import Image
from google.colab.patches import cv2_imshow
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as viz_utils

IMAGE_SIZE = (6, 6) # Output display size as you want
import matplotlib.pyplot as plt
PATH_TO_SAVED_MODEL="/mydrive/customTF2/data/inference_graph/saved_model"
print('Loading model...', end='')

# Load saved model and build the detection function
detect_fn=tf.saved_model.load(PATH_TO_SAVED_MODEL)
print('Done!')

#Loading the label_map
category_index=label_map_util.create_category_index_from_labelmap("/mydrive/customTF2/data/label_map.pbtxt",use_display_name=True)


def load_image_into_numpy_array(path):

    return np.array(Image.open(path))

image_path = "/content/gdrive/MyDrive/customTF2/data/test/009.jpg"
#print('Running inference for {}... '.format(image_path), end='')

image_np = load_image_into_numpy_array(image_path)

# The input needs to be a tensor, convert it using `tf.convert_to_tensor`.
input_tensor = tf.convert_to_tensor(image_np)
# The model expects a batch of images, so add an axis with `tf.newaxis`.
input_tensor = input_tensor[tf.newaxis, ...]

detections = detect_fn(input_tensor)

# All outputs are batches tensors.
# Convert to numpy arrays, and take index [0] to remove the batch dimension.
# We're only interested in the first num_detections.
num_detections = int(detections.pop('num_detections'))
detections = {key: value[0, :num_detections].numpy()
              for key, value in detections.items()}
detections['num_detections'] = num_detections

# detection_classes should be ints.
detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

image_np_with_detections = image_np.copy()

viz_utils.visualize_boxes_and_labels_on_image_array(
      image_np_with_detections,
      detections['detection_boxes'],
      detections['detection_classes'],
      detections['detection_scores'],
      category_index,
      use_normalized_coordinates=True,
      max_boxes_to_draw=100,
      min_score_thresh=.4, # Adjust this value to set the minimum probability boxes to be classified as True
      agnostic_mode=False)
%matplotlib inline
plt.figure(figsize=IMAGE_SIZE, dpi=100)
plt.axis("off")
plt.imshow(image_np_with_detections)
plt.show()

※ 아래와 같이 Bounding Box와 함께 Class로 구분되는 것을 확인할 수 있음