Tensorflow Object Detection API를 이용한 물체 인식 #3-얼굴은 학습시켜보자
Object Detection API를 이용하여 커스텀 데이타 학습하기
얼굴인식 모델 만들기
조대협 (http://bcho.tistory.com)
이번글에서는 Tensorflow Object Detection API를 이용하여 직접 이미지를 인식할 수 있는 방법에 대해서 알아보자. 이미 가지고 있는 데이타를 가지고 다양한 상품에 대한 인식이나, 사람 얼굴에 대한 인식 모델을 머신러닝에 대한 전문적인 지식 없이도 손쉽게 만들 수 있다.
Object Detection API 설치
Object Detection API 설치는 http://bcho.tistory.com/1193 와 http://bcho.tistory.com/1192 에서 이미 다뤘기 때문에 별도로 언급하지 않는다.
학습용 데이타 데이타 생성 및 준비
Object Detection API를 학습 시키기 위해서는 http://bcho.tistory.com/1193 예제와 같이 TFRecord 형태로 학습용 파일과 테스트용 파일이 필요하다. TFRecord 파일 포맷에 대한 설명은 http://bcho.tistory.com/1190 를 참고하면 된다.
이미지 파일을 TFRecord로 컨버팅하는 전체 소스 코드는 https://github.com/bwcho75/objectdetection/blob/master/custom/create_face_data.py 를 참고하기 바란다.
구글 클라우드 VISION API를 이용하여,얼굴이 있는지 여부를 파악하고, 얼굴 각도가 너무 많이 틀어진 경우에는 필터링 해낸후에, 얼굴의 위치 좌표를 추출하여 TFRecord 파일에 쓰는 흐름이다.
VISION API를 사용하기 때문에 반드시 서비스 어카운트 (Service Account/JSON 파일)를 구글 클라우드 콘솔에서 만들어서 설치하고 실행하기 바란다.
사용 방법은
python create_face_data.py {이미지 소스 디렉토리} {이미지 아웃풋 디렉토리} {TFRECORD 파일명}
형태로 사용하면 된다.
예) python ./custom/create_face_data.py /Users/terrycho/trainingdata_source /Users/terrycho/trainingdata_out
{이미지 소스 디렉토리} 구조는 다음과 같다.
{이미지 소스 디렉토리}/{라벨1}
{이미지 소스 디렉토리}/{라벨2}
{이미지 소스 디렉토리}/{라벨3}
:
예를 들어
/Users/terrycho/trainingdata_source/Alba
/Users/terrycho/trainingdata_source/Jessica
/Users/terrycho/trainingdata_source/Victoria
:
이런식이 된다.
명령을 실행하면, {이미지 아웃풋 디렉토리} 아래
학습 파일은 face_training.record
테스트 파일은 face_evaluation.record
라벨맵은 face_label_map.pbtxt
로 생성된다. 이 세가지 파일이 Object Detection API를 이용한 학습에 필요하고 부가적으로 생성되는 csv 파일이 있는데
all_files.csv : 소스 디렉토리에 있는 모든 이미지 파일 목록
filtered_files.csv : 각 이미지명과, 라벨, 얼굴 위치 좌표 (사각형), 이미지 전체 폭과 높이
converted_result_files.csv : filtered_files에 있는 이미지중, 얼굴의 각도등이 이상한 이미지를 제외하고 학습과 테스트용 데이타 파일에 들어간 이미지 목록으로, 이미지 파일명, 라벨 (텍스트), 라벨 (숫자), 얼굴 좌표 (사각형) 을 저장한다.
여기서 사용한 코드는 간단한 테스트용 코드로, 싱글 쓰레드에 싱글 프로세스 모델로 대규모의 이미지를 처리하기에는 적절하지 않기 때문에, 운영환경으로 올리려면, Apache Beam등 분산 프레임웍을 이용하여 병렬 처리를 하는 것을 권장한다. http://bcho.tistory.com/1177 를 참고하기 바란다.
여기서는 학습하고자 하는 이미지의 바운드리(사각형 경계)를 추출하는 것을 VISION API를 이용해서 자동으로 했지만, 일반적인 경우는 이미지에서 각 경계를 수동으로 추출해서 학습데이타로 생성해야 한다
이런 용도로 사용되는 툴은 https://medium.com/towards-data-science/how-to-train-your-own-object-detector-with-tensorflows-object-detector-api-bec72ecfe1d9 문서에 따르면 FastAnnotationTool이나 ImageMagick 과 같은 툴을 추천하고 있다.
http://imagemagick.org/script/index.php#
이렇게 학습용 파일을 생성하였으면 다음 과정은 앞의 http://bcho.tistory.com/1193 에서 언급한 절차와 크게 다르지 않다.
체크포인트 업로드
학습 데이타가 준비 되었으면 학습을 위한 준비를 하는데, 트랜스퍼 러닝 (Transfer learning)을 위해서 기존의 학습된 체크포인트 데이타를 다운 받아서 이를 기반으로 학습을 한다.
Tensorflow Object Detection API는 경량이고 단순한 모델에서 부터 정확도가 비교적 높은 복잡한 모델까지 지원하고 있지만, 복잡도가 높다고 해서 정확도가 꼭 높지는 않을 수 있다. 복잡한 모델일 수 록 학습 데이타가 충분해야 하기 때문에, 학습하고자 하는 데이타의 양과 클래스의 종류에 따라서 적절한 모델을 선택하기를 권장한다.
여기서는 faster_rcnn_inception_resnet_v2 모델을 이용했기 때문에 아래와 같이 해당 모델의 체크포인트 데이타를 다운로드 받는다.
파일의 압축을 푼 다음 체크 포인트 파일을 학습 데이타용 Google Cloud Storage (GCS) 버킷으로 업로드 한다.
gsutil cp faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017/model.ckpt.* gs://${YOUR_GCS_BUCKET}/data/
설정 파일 편집 및 업로드
다음 학습에 사용할 모델의 설정을 해야 하는데, object_detection/samples/configs/ 디렉토리에 각 모델별 설정 파일이 들어 있으며, 여기서는 faster_rcnn_inception_resnet_v2_atrous_pets.config 파일을 사용한다.
이 파일에서 수정해야 하는 부분은 다음과 같다.
클래스의 수
클래스 수를 정의한다. 이 예제에서는 총 5개의 클래스로 분류를 하기 때문에 아래와 같이 5로 변경하였다.
8 model {
9 faster_rcnn {
10 num_classes: 5
11 image_resizer {
학습 데이타 파일 명 및 라벨명
학습에 사용할 학습데이타 파일 (tfrecord)와 라벨 파일명을 지정한다.
126 train_input_reader: {
127 tf_record_input_reader {
128 input_path: "gs://terrycho-facedetection/data/face_training.record"
129 }
130 label_map_path: "gs://terrycho-facedetection/data/face_label_map.pbtxt"
131 }
테스트 데이타 파일명 및 라벨 파일명
학습후 테스트에 사용할 테스트 파일 (tfrecord)과 라벨 파일명을 지정한다
140 eval_input_reader: {
141 tf_record_input_reader {
142 input_path: "gs://terrycho-facedetection/data/face_evaluation.record"
143 }
144 label_map_path: "gs://terrycho-facedetection/data/face_label_map.pbtxt"
145 shuffle: false
146 num_readers: 1
만약에 학습 횟수(스탭)을 조정하고 싶으면 num_steps 값을 조정한다. 디폴트 설정은 20만회인데, 여기서는 5만회로 수정하였다.
117 # never decay). Remove the below line to train indefinitely.
118 # num_steps: 200000
119 num_steps: 50000
120 data_augmentation_options {
121 random_horizontal_flip {
122 }
설정 파일 수정이 끝났으면 gsutil cp 명령을 이용하여 해당 파일을 GCS 버킷에 다음과 같이 업로드 한다.
gsutil cp object_detection/samples/configs/faster_rcnn_inception_resnet_v2_atrous_pets.config gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_inception_resnet_v2_atrous_pets.config
코드 패키징
models/ 디렉토리에서 다음 명령을 수행하여, 모델 코드를 패키징한다.
python setup.py sdist
(cd slim && python setup.py sdist)
학습
gcloud ml-engine jobs submit training `whoami`_object_detection_`date +%s` \
--job-dir=gs://${YOUR_GCS_BUCKET}/train \
--packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz \
--module-name object_detection.train \
--region asia-east1 \
--config object_detection/samples/cloud/cloud.yml \
-- \
--train_dir=gs://${YOUR_GCS_BUCKET}/train \
--pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_resnet101_pets.config
모니터링
학습이 진행되면 텐서보드를 이용하여 학습 진행 상황을 모니터링할 수 있고, 또한 테스트 트레이닝을 수행하여, 모델에 대한 테스트를 동시 진행할 수 있다. http://bcho.tistory.com/1193 와 방법이 동일하니 참고하기 바란다.
학습을 시작하면 텐서보드를 통해서, Loss 값이 수렴하는 것을 확인할 수 있다.
결과
학습이 끝나면 텐서보드에서 테스트된 결과를 볼 수 있다. 이 예제의 경우 모델을 가장 복잡한 모델을 사용했는데 반하여, 총 5개의 클래스에 대해서 클래스당 약 40개정도의 학습 데이타를 사용했는데, 상대적으로 정확도가 낮았다. 실 서비스에서는 더 많은 데이타를 사용하기를 권장한다.
활용
학습된 모델을 활용하는 방법은 학습된 모델을 export 한후에, (Export 하는 방법은 http://bcho.tistory.com/1193 참고) export 된 모델을 로딩하여, 코드에서 불러서 사용하면 된다.
http://bcho.tistory.com/1192 참고