블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

Object Detection API에 애완동물 사진을 학습 시켜 보자


조대협 (http://bcho.tistory.com)


Object Detection API에 이번에는 애완동물 사진 데이타를 학습시켜 보도록 한다.

애완 동물 학습 데이타의 원본은  Oxford-IIIT Pets lives  http://www.robots.ox.ac.uk/~vgg/data/pets/ 에 있다. 약 37개의 클래스에, 클래스당 200개 정도의 이미지를 가지고 있다.



이번 글에서는 이 애완동물 데이타를 다운 받아서, Object Detection API에 학습 시키는 것까지 진행을 한다.

데이타를 다운로드 받은 후, Object Detection API에 학습 시키기 위해서, 데이타 포맷을 TFRecord 형태로 변환한 후, 학습을 하는 과정을 설명한다.


주의할점 : 이 튜토리얼은 총 37개의 클래스 약 7000장의 이미지를 학습시키는데, 17시간 이상이 소요되며, 구글 클라우 CloudML의 텐서플로우 클러스터에서 분산 러닝을 하도록 설명하고 있는데, 많은 비용이 들 수 있다. 전체 흐름과 과정을 이해하기 위해서는 17시간을 풀 트레이닝 시키지 말고 학습 횟수를 줄이거나 아니면 중간에서 학습을 멈춰서 비용이 많이 나오지 않도록 하는 것을 권장한다.

학습 데이타 다운로드 받기

%curl -O http://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz

%curl -O http://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz

※ 맥이기 때문에, curl -O 를 사용했는데, Linux의 경우에는 wget을 사용하면 된다.

파일을 다운로드 받았으면 압축을 풀어보자

  • images.tar.gz에는 애완동물의 학습용 이미지가 들어가 있다.

  • annotations.tar.gz 는 각 이미지에 대한 메타 데이타가 들어있다. 이미지 마다 나타난 동물의 종류, 사진상 동물의 위치 (박스)

TFRecord 파일 포맷으로  컨버팅 하기

압축을 푼 메타데이타와 이미지 파일을 이용해서 tfrecord 파일 형태로 컨버팅을 해야 한다. Tfrecord 내에는 이미지 바이너리, 이미지에 대한 정보 (이미지 크기, 인식할 물체의 위치, 라벨)등이 들어간다. 상세 데이타 포맷에 대해서는 다음글에서 설명하도록 한다.

이 데이타를 가지고 tfrecord 타입으로 컨버팅 하는 코드는 object_detection/create_pet_tf_record.py

에 이미 작성되어 있다. 아래 코드를 이용해서 실행해주면 자동으로 pet_train.record에 학습용 데이타를 pet_val.record에 테스트용 데이타를 생성해준다.


python object_detection/create_pet_tf_record.py \
   --label_map_path=object_detection/data/pet_label_map.pbtxt \
   --data_dir=`pwd` \
   --output_dir=`pwd`

학습 환경 준비하기

데이타가 준비되었으면 학습을 위한 환경을 준비해야 한다.

학습은 구글 클라우드 플랫폼의 CloudML을 사용한다. CloudML은 구글 클라우드 플랫폼의 Tensorflow managed 서비스로, Tensorflow 클러스터 설치나 운영 필요 없이 간단하게 명령어 만으로 여러대의 머신에서 학습을 가능하게 해준다.

CloudML을 사용하기 위해서는 몇가지 환경 설정을 해줘야 한다.

  • 먼저 학습용 데이타 (tfrecord)파일을 구글 클라우드 스토리지 (GCS)로 업로드 해야 한다.

  • Object Detection API에서 사물 인식에 사용된 모델의 체크 포인트를 업로드 해야 한다.

  • 클라우드에서 학습을 하기 때문에, 텐서플로우 코드를 패키징해서 업로드해야 한다.

학습 데이타 업로드 하기

데이타를 업로드하기전에, 구글 클라우드 콘솔에서 구글 클라우드 스토리지 버킷을 생성한다.

생성된 버킷명을 YOUR_GCS_BUCKET 환경 변수에 저장한다.

export YOUR_GCS_BUCKET=${YOUR_GCS_BUCKET}


다음 gsutil 유틸리티를 이용하여 YOUR_GCS_BUCKET 버킷으로 학습용 데이타와, 라벨맵 데이타를 업로드 한다.


gsutil cp pet_train.record gs://${YOUR_GCS_BUCKET}/data/pet_train.record
gsutil cp pet_val.record gs://${YOUR_GCS_BUCKET}/data/pet_val.record
gsutil cp object_detection/data/pet_label_map.pbtxt gs://${YOUR_GCS_BUCKET}/data/pet_label_map.pbtxt


학습된 모델 다운로드 받아서 업로드 하기

다음은 학습된 모델을 받아서, 그중에서 체크포인트를  GCS에 올린다.


curl -O http://storage.googleapis.com/download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_coco_11_06_2017.tar.gz

tar -xvf faster_rcnn_resnet101_coco_11_06_2017.tar.gz
gsutil cp faster_rcnn_resnet101_coco_11_06_2017/model.ckpt.* gs://${YOUR_GCS_BUCKET}/data/


체크 포인트를 다운받아서 업로드 하는 이유는, 트랜스퍼 러닝 (Transfer Learning)을 하기 위함인데, 하나도 학습이 되지 않은 모델을 학습을 시키는데는 시간이 많이 들어간다. 트랜서퍼러닝은 이미 학습이 되어 있는 모델로 다른 데이타를 학습 시키는 방법인데, 사물을 인식하는 상태로 학습되어 있는 모델을 다른 물체 (여기서는 애완동물)를 학습하는데 사용하면 학습 시간을 많이 줄 일 수 있다. 이런 이유로, 사물 인식용으로 학습된 체크포인트를 로딩해서 이 체크포인트 부터 학습을 하기 위함이다.

설정 파일 변경하기

Object Detection API를 사용하기 위해서는 학습에 대한 설정 정보를 정의해야 한다.

이 설정 파일안에는 학습 데이타의 위치, 클래스의 수 및 각종 하이퍼 패러미터들이 정의되어 있다. 패러미터에 대한 자세한 설명은  https://github.com/tensorflow/models/blob/master/object_detection/g3doc/configuring_jobs.md를 참고하기 바란다. 이 예제에서는 설정 파일을 따로 만들지 않고 애완동물 사진 학습을 위해서 미리 정의되어 있는 템플릿 설정 파일을 이용하도록 한다.  설정 파일은 미리 정의된 모델에 따라 다른데, 여기서는 faster_rcnn_resnet101_pets 모델을 사용하기 때문에 object_detection/samples/configs/faster_rcnn_resnet101_pets.config 파일을 사용한다.


파일의 위치가 PATH_TO_BE_CONFIGURED 문자열로 정의되어 있는데, 이를 앞에서 만든 GCS 버킷명으로 변경해야 하기 때문에, 아래와 같이 sed 명령을 이용하여 해당 문자열을 변경하자


Linux : sed -i "s|PATH_TO_BE_CONFIGURED|"gs://${YOUR_GCS_BUCKET}"/data|g" object_detection/samples/configs/faster_rcnn_resnet101_pets.config


Max : sed -i ‘’ -e "s|PATH_TO_BE_CONFIGURED|"gs://${YOUR_GCS_BUCKET}"/data|g" object_detection/samples/configs/faster_rcnn_resnet101_pets.config


설정 파일 작성이 끝났으면 이를 GCS 버킷에 올린 후에, 학습시에 사용하도록 한다. 다음 명령어는 설정 파일을 GCS 버킷에 올리는 명령이다.

gsutil cp object_detection/samples/configs/faster_rcnn_resnet101_pets.config \
   gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_resnet101_pets.config


텐서플로우 코드 패키징 및 업로드

학습에 사용할 데이타와 체크포인트등을 업로드 했으면, 다음 텐서플로우 코드를 패키징 해야 한다. 이 글에서는 학습을 로컬 머신이 아니라 구글 클라우드의 텐서플로우 메니지드 서비스인 CloudML을 사용하는데, 이를 위해서는 텐서플로우코드와 코드에서 사용하는 파이썬 라이브러리들을 패키징해서 올려야 한다.


Object Detection API 모델 디렉토리에서 다음 명령어를 실행하면, model 디렉토리와 model/slim 디렉토리에 있는 텐서플로우 코드 및 관련 라이브러리를 같이 패키징하게된다.


# From tensorflow/models/
python setup.py sdist
(cd slim && python setup.py sdist)


명령을 실행하고 나면 패키징된 파일들은 dist/object_detection-0.1.tar.gzslim/dist/slim-0.1.tar.gz 에 저장되게 된다.

학습하기

구글 CloudML을 이용하여 학습하기. 그러면 학습을 시작해보자. 학습은 200,000 스탭에 총 17시간 정도가 소요되며, 비용이 3000$ 이상이 소요되니, 비용이 넉넉하지 않다면, 학습을 중간에 중단 시키기를 권장한다. 테스트 목적이라면 약 10~20분 정도면 충분하지 않을까 한다. 아니면 앞의 config 파일에서 trainning step을 작게 낮춰서 실행하기 바란다.


# From tensorflow/models/
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


학습을 시킬 텐서플로우 클러스터에 대한 정보는 object_detection/samples/cloud/cloud.yml 에 들어 있다. 내용을 보면,

trainingInput:

 runtimeVersion: "1.0"

 scaleTier: CUSTOM

 masterType: standard_gpu

 workerCount: 5

 workerType: standard_gpu

 parameterServerCount: 3

 parameterServerType: standard


scaleTier로 클러스터의 종류를 정의할 수 있는데, 서버 1대에서 부터 여러대의 클러스터까지 다양하게 적용이 가능하다. 여기서는 모델이 크기가 다소 크기 때문에, Custom으로 설정하였다.


역할

서버 타입

댓수

Master server

standard_gpu

1

Worker

standard_gpu

5

Parameter Server

standard

5


각 서버의 스펙은 상세 스펙은 나와있지 않고, 상대값으로 정의되어 있는데 대략 내용이 다음과 같다.



출처 https://cloud.google.com/ml-engine/docs/concepts/training-overview#machine_type_table




학습을 시작하고 나면 CloudML 콘솔에서 실행중인 Job을 볼 수 있고, Job을 클릭하면 자원의 사용 현황을 볼 수 있다. (CPU와 메모리 사용량)



학습을 시작한 후에, 학습된 모델을 Evaluate할 수 있는데, Object Detection API에서는 학습 말고 Evaluation 모델을 별도로 나눠서, 잡을 나눠서 수행하도록 하였다. 학습중에 생성되는 체크포인트 파일을 읽어서 Evaluation을 하는 형태이다.

다음을 Evaluation을 실행하는 명령어인데, 위의 학습 작업이 시작한 후에, 한시간 정도 후부터 실행해도 실행 상태를 볼 수 있다.


# From tensorflow/models/
gcloud ml-engine jobs submit training `whoami`_object_detection_eval_`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.eval \
   --region asia-east1 \
   --scale-tier BASIC_GPU \
   -- \
   --checkpoint_dir=gs://${YOUR_GCS_BUCKET}/train \
   --eval_dir=gs://${YOUR_GCS_BUCKET}/eval \
  --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_resnet101_pets.config


학습 진행 상황 확인하기

학습이 진행중에도, Evaluation을 시작했으면, Tensorboard를 이용하여 학습 진행 상황을 모니터링 할 수 있다. 학습 진행 데이타가 gs://${YOUR_GCS_BUCKET} 에 저장되기 때문에, 이 버킷에 있는 데이타를 Tensorboard로 모니터링 하면 된다.

실행 방법은 먼저 GCS 에 접속이 가능하도록 auth 정보를 설정하고, Tensorboard에 로그 파일 경로를

GCS 버킷으로 지정하면 된다.

gcloud auth application-default login
tensorboard --logdir=gs://${YOUR_GCS_BUCKET}


아래는 실제 실행 결과이다.



Evaluataion이 끝났으면, 테스트된 이미지도 IMAGES 탭에서 확인이 가능하다.



학습된 모델을 Export 하기

학습이 완료되었으면, 이 모델을 예측 (Prediction)에 사용하기 위해서 Export 할 수 있다. 이렇게 Export 된 이미지는 나중에 다시 로딩하여 예측(Prediction)코드에서 로딩을 하여 사용이 가능하다.

${YOUR_GCS_BUCKET}에 가면 체크 포인트 파일들이 저장되어 있는데, 이 체크 포인트를 이용하여 모델을 Export 한다.



GCS 버킷에서 Export 하고자 하는 Check Point 번호를 선택한 후에 Export 하면 된다, 여기서는 200006 Check Point를 Export 해보겠다.


${CHECKPOINT_NUMBER} 환경 변수를

export CHECKPOINT_NUMBER=200006

으로 설정한 다음에 다음 명령어를 실행한다.


# From tensorflow/models
gsutil cp gs://${YOUR_GCS_BUCKET}/train/model.ckpt-${CHECKPOINT_NUMBER}.* .
python object_detection/export_inference_graph.py \

   --input_type image_tensor \

   --pipeline_config_path object_detection/samples/configs/faster_rcnn_resnet101_pets.config \

   --trained_checkpoint_prefix model.ckpt-${CHECKPOINT_NUMBER} \

   --output_directory output_inference_graph.pb


명령을 실행하고 나면 output_inference_graph.pb 디렉토리에 모델이 Export 된것을 확인할 수 있다.

다음 글에서는 직접 자신의 사진 데이타만을 가지고 학습과 예측을 하는 방법에 대해서 알아보겠다.


참고 자료



저작자 표시 비영리
신고


Machine Learning Pipeline


조대협 (http://bcho.tistory.com)

대부분 모델 개발과 알고리즘에 집중

머신러닝을 공부하고 나서는 주로 통계학이나, 모델 자체에 많은 공부를 하는 노력을 드렸었다. 선형대수나 미적분 그리고 방정식에 까지 기본으로 돌아가려고 노력을 했었고, 그 중간에 많은 한계에도 부딪혔지만, 김성훈 교수님의 모두를 위한 딥러닝 강의를 접하고 나서, 수학적인 지식도 중요하지만 수학적인 깊은 지식이 없어도 모델 자체를 이해하고 근래에 발전된 머신러닝 개발 프레임웍을 이용하면 모델 개발이 가능하다는 것을 깨달았다.

 

계속해서 모델을 공부하고, 머신러닝을 공부하는 분들을 관심있게 지켜보고 실제 머신러닝을 사용하는 업무들을 살펴보니 재미있는 점이 모두 모델 자체 개발에만 집중한다는 것이다. 커뮤니티에 올라오는 글의 대부분은 어떻게 모델을 구현하는지 어떤 알고리즘을 사용하는지에 대한 내용들이 많았고, 실 업무에 적용하는 분들을 보면 많은 곳들이 R을 이용하여 데이타를 분석하고 모델링을 하는데, 데이타를 CSV 파일 형태로 다운 받아서 정재하고 데이타를 분석하고 모델을 개발하는 곳이 많은 것을 보았다. 데이타의 수집 및 전처리 및 개발된 모델에 대한 서비스에 대해서는 상대적으로 많은 정보를 접하지 못했는데, 예상하기로 대부분 모델 개발에 집중하기 때문이 아닌가 싶다.

 

엔지니어 백그라운드를 가진 나로써는 CSV로 데이타를 끌어다가 정재하고 분석하는 것이 매우 불편해 보이고 이해가 되지 않았다. 빅데이타 분석 시스템에 바로 연결을 하면, CSV로 덤프 받고 업로드 하는 시간등에 대한 고민이 없을텐데.” 왜 그렇게 할까 ?”라는 의문이 계속 생기기 시작하였다.

미니 프로젝트를 시작하다

이런 의문을 가지던중 CNN 네트워크 모델에 대한 대략적인 학습이 끝나고, 실제로 적용하면서 경험을 쌓아보기로 하였다. 그래서 얼굴 인식 모델 개발을 시작하였다. CNN 모델이라는 마법을 사용하면 쉽게 개발이 될줄 알았던 프로젝트가 벌써 몇달이 되어 간다. 학습용 데이타를 구하고, 이를 학습에 적절하도록 전처리 하는 과정에서 많은 실수가 있었고, 그 과정에서 많은 재시도가 있었다.

 

(자세한 내용은 http://bcho.tistory.com/1174 , https://www.slideshare.net/Byungwook/ss-76098082 를 참조)

 

특히나 데이타 자체를 다시 처리해야 하는 일이 많았기 때문에, 데이타 전처리 코드를 지속적으로 개선하였고 개선된 코드를 이용하여 데이타를 지속적으로 다시 처리해서 데이타의 품질을 높여나갔는데, 처리 시간이 계속해서 많이 걸렸다.

자동화와 스케일링의 필요성

특히 이미지 전처리 부분은 사진에서 얼굴이 하나만 있는 사진을 골라내고 얼굴의 각도와 선글라스 유무등을 확인한후 사용 가능한 사진에서 얼굴을 크롭핑하고 학습용 크기로 리사이즈 하는 코드였는데 (자세한 내용 http://bcho.tistory.com/1176) 싱글 쓰레드로 만들다 보니 아무래도 시간이 많이 걸렸다. 실제 운영환경에서는 멀티 쓰레드 또는 멀티 서버를 이용하여 스케일링을 할 필요가 있다고 느꼈다.

 

또한 이미지 수집에서 부터 필터링, 그리고 학습 및 학습된 모델의 배포와 서비스 까지 이 전 과정을 순차적으로 진행을 하되 반복적인 작업이기 때문에 자동화할 필요성이 있다고 생각했다.

아이 체중 예측 모델을 통한 파이프라인에 대한 이해

그러던 중에 팀 동료로 부터 좋은 예제 하나를 전달 받게 되었다.

미국 아기들의 환경에 따른 출생 체중을 예측하는 간단한 선형 회귀 모델을 구현한 파이썬 노트북인데 (https://github.com/GoogleCloudPlatform/training-data-analyst/blob/master/blogs/babyweight/babyweight.ipynb) 하나의 노트북에 전체 단계를 모두 구현해놓았다.

 


 

데이타에 대한 분석을 통한 데이타 특성 추출, 추출된 특성을 통한 모델 개발, 모델 학습을 위한 데이타 전처리 그리고 학습 및 학습된 모델을 통한 예측 서비스 까지 모든 과정을 하나의 노트북에 구현해놓았다.

(시간이 있으면 꼭 보기를 강력 추천한다.)

 

흥미로운 점이 데이타 전처리를 Apache Beam이라는 데이타 처리 플랫폼을 썼고, 그 전처리 코드를 파이썬 노트북에 하나로 다 정리한것이다. (실제로 수행은 로컬에서도 가능하지만, 클라우드에서도 실행이 가능해서 충분한 스케일링을 지원한다.)

 

Apache Beam의 구글의 빅데이타 분석 프레임웍으로 Apache Spark 과 같은 프레임웍이라고 보면된다. Google Dataflow라는 이름으로 구글 클라우드에서 서비스가 되는데, Apache Beam이라는 오픈소스로 공개가 되었다. ( http://bcho.tistory.com/1123 http://bcho.tistory.com/1122 http://bcho.tistory.com/1124 )

 

아 이렇게 하는구나 하는 생각이 들었고, 그즘 실무에서 이와 같은 흐름으로 실제로 머신러닝을 수행하는 것을 볼 기회가 있었다.

데이타 전처리를 스케일링하다.

서비스가 가능한 수준의 전체 머신러닝 서비스 파이프라인을 만들어보고 싶어졌다. 마침 또 Apache Beam의 경우에는 예전에 Java 코드로 실시간 분석을 해본 경험이 있고 이번에 2.0 버전이 릴리즈 되서 이번에는 2.0에서 파이썬을 공부해보기로 하고 개발에 들어갔다.

 

특히 기존의 데이타 전처리 코드는 싱글 쓰레드로 돌기 때문에 스케일링에 문제가 있었지만, Apache Beam을 사용할 경우 멀티 쓰레드 뿐만 아니라 동시에 여러대의 머신에서 돌릴 수 있고 이러한 병렬성에 대해서는 크게 고민을 하지 않아도 Apache Beam이 이 기능을 다 제공해준다. 또한 이 데이타 전처리 코드를 돌릴 런타임도 별도 설치할 필요가 없이 커멘드 하나로 구글 클라우드에서 돌릴 수 가 있다. (직업 특성상 클라우드 자원을 비교적 자유롭게 사용할 수 있었다.)

 

Apache Beam으로 전처리 코드를 컨버팅 한결과 기존 싱글 쓰레드 파이썬 코드가 400~500장의 이미지 전처리에 1~2시간이 걸렸던 반면, 전환후에 대략 15~17분이면 끝낼 수 있었다. 전처리 중에는 서버의 대수가 1대에서 시작해서 부하가 많아지자 자동으로 5대까지 늘어났다. 이제는 아무리 많은 데이타가 들어오더라도 서버의 대수만 단순하게 늘리면 수분~수십분내에 수십,수만장의 데이타 처리가 가능하게 되었다.


<그림. Apache Beam 기반의 이미지 전처리 시스템 실행 화면 >

 

Apache Beam 기반의 이미지 전처리 코드는 https://github.com/bwcho75/facerecognition/blob/master/Preprocess%2Bface%2Brecognition%2Bdata%2Band%2Bgenerate%2Btraining%2Bdata.ipynb 에 공개해 놨다.

 

머신러닝 파이프라인 아키텍쳐와 프로세스

이번 과정을 통해서 머신러닝의 학습 및 예측 시스템 개발이 어느 정도 정형화된 프로세스화가 가능하고 시스템 역시 비슷한 패턴의 아키텍쳐를 사용할 수 있지 않을까 하는 생각이 들었고, 그 내용을 아래와 같이 정리한다.

파이프라인 개발 프로세스

지금까지 경험한 머신러닝 개발 프로세스는 다음과 같다.

 

  1. 데이타 분석
    먼저 머신러닝에 사용할 전체 데이타셋을 분석한다. 그래프도 그려보고 각 변수간의 연관 관계나 분포도를 분석하여, 학습에 사용할 변수를 정의하고 어떤 모델을 사용할지 판단한다.

  2. 모델 정의
    분석된 데이타를 기반으로 모델을 정의하고, 일부 데이타를 샘플링하여 모델을 돌려보고 유효한 모델인지를 체크한다. 모델이 유효하지 않다면 변수와 모델을 바꿔 가면서 최적의 모델을 찾는다.

  3. 데이타 추출 및 전처리
    유효한 모델이 개발이 되면, 일부 데이타가 아니라 전체 데이타를 가지고 학습을 한다. 전체 데이타를 추출해서 모델에 넣어서 학습을 하려면 데이타의 크기가 크면 매번 매뉴얼로 하기가 어렵기 때문에 데이타 추출 및 전처리 부분을 자동화 한다.   

  4. 전체 데이타를 이용한 반복 학습 및 튜닝
    모델 자체가 유효하다고 하더라도 전체 데이타를 가지고 학습 및 검증을 한것이 아니기 때문에 의외의 데이타가 나오거나 전처리에 의해서 필터링되지 않은 데이타가 있을 수 있기 때문에 지속적으로 데이타 추출 및 전처리 모듈을 수정해야 하고, 마찬가지로 모델 역시 정확도를 높이기 위해서 지속적으로 튜닝을 한다. 이 과정에서 전체 데이타를 다루기 때문에 모델 역시 성능을 위해서 분산형 구조로 개선되어야 한다.

  5. 모델 배포
    학습 모델이 완성되었으면 학습된 모델을 가지고 예측을 할 수 있는 시스템을 개발하고 이를 배포한다.

  6. 파이프라인 연결 및 자동화
    머신러닝의 모델은 위의 과정을 통해서 만들었지만, 데이타가 앞으로도 지속적으로 들어올 것이고 지속적인 개선이 필요하기 때문에 이 전과정을 자동화 한다. 이때 중요한것은 데이타 전처리, 학습, 튜닝, 배포등의 각 과정을 물 흐르듯이 연결하고 자동화를 해야 하는데 이렇게 데이타를 흐르는 길을 데이타 플로우라고 한다. (흔히 Luigi, Rundeck, Airflow와 같은 데이타플로우 오케스트레이션 툴을 이용한다)

 

전체적인 프로세스에 대해서 좋은 영상이 있어서 공유한다.


아키텍쳐

위의 프로세스를 기반으로한 머신러닝 파이프라인 아키텍쳐 는 다음과 같다.


 

 

Inputs

머신 러닝 파이프라인의 가장 처음단은 데이타를 수집하고 이 수집된 데이타를 저장하는 부분이다.

데이타 수집은 시간,일,주,월과 같이 주기적으로 데이타를 수집하는 배치 프로세싱과, 실시간으로 데이타를 수집하는 리얼타임 프로세싱 두가지로 나뉘어 진다. 이 두 파이프라인을 통해서 데이타 소스로 부터 데이타를 수집하고 필터링하고 정재하여, 데이타 레이크에 저장한다. 이 구조는 일반적인 빅데이타 분석 시스템의 구조와 유사하다. (참고 자료 http://bcho.tistory.com/984 http://bcho.tistory.com/671 )

 

개인적으로 머신러닝을 위해서 중요한 부분 중 하나는 데이타 레이크를 얼마나 잘 구축하느냐이다. 데이타 레이크는 모든 데이타가 모여 있는 곳으로 보통 데이타 레이크를 구축할때는 많은 데이타를 모으는 데만 집중하는데, 데이타를 잘 모으는 것은 기본이고 가장 중요한 점은 이 모여 있는 데이타에 대한 접근성을 제공하는 것이다.

 

무슨 이야기인가 하면, 보통 머신러닝 학습을 위해서 학습 데이타를 받거나 또는 데이타에 대한 연관성 분석등을 하기 위해서는 데이타 레이크에서 데이타를 꺼내오는데, 데이타 레이크를 개발 운영 하는 사람과 데이타를 분석하고 머신러닝 모델을 만드는 사람은 보통 다르기 때문에, 모델을 만드는 사람이 데이타 레이크를 운영하는 사람에게 “무슨 무슨 데이타를 뽑아서 CSV로 전달해 주세요.” 라고 이야기 하는 것이 보통이다. 그런데 이 과정이 번거롭기도 하고 시간이 많이 걸린다.

가장 이상적인 방법은 데이타를 분석하고 모델링 하는 사람이 데이타 레이크 운영팀에 부탁하지 않고서도 손쉽고 빠르게 데이타에 접근해서 데이타를 읽어오고 분석을 할 수 있어야 한다.

직업 특성상 구글의 빅쿼리를 많이 접하게 되는데, 빅쿼리는 대용량 데이타를 저장할 수 있을 뿐만 아니라 파이썬 노트북이나 R 스튜디오 플러그인을 통해서 바로 데이타를 불러와서 분석할 수 있다.  


<그림 INPUT 계층의 빅데이타 저장 분석 아키텍쳐>

Pre processing & Asset creation

Pre processing은 수집한 데이타를 학습 시스템에 넣기 위해서 적절한 데이타만 필터링하고 맞는 포맷으로 바꾸는 작업을 한다. 작은 모델이나 개발등에서는 샘플링된 데이타를 로컬에서 내려 받아서 R이나 numpy/pandas등으로 작업이 가능하지만, 데이타가 수테라에서 수백테라이상이 되는 빅데이타라면 로컬에서는 작업이 불가능하기 때문에, 데이타 전처리 컴포넌트를 만들어야 한다.

일반적으로 빅데이타 분석에서 사용되는 기술을 사용하면 되는데, 배치성 전처리는 하둡이나 스파크와 같은 기술이 보편적으로 사용되고 실시간 스트리밍 분석은 스파크 스트리밍등이 사용된다.


Train

학습은 전처리된 데이타를 시스템에 넣어서 모델을 학습 시키는 단계이다. 이 부분에서 생각해야 할점은 첫번째는 성능 두번째는 튜닝이다. 성능 부분에서는 GPU등을 이용하여 학습속도를 늘리고 여러대의 머신을 연결하여 학습을 할 수 있는 병렬성이 필요하다. 작은 모델의 경우에는 수시간에서 하루 이틀 정도 소요되겠지만 모델이 크면 한달 이상이 걸리기 때문에 고성능 하드웨어와 병렬 처리를 통해서 학습 시간을 줄이는 접근이 필요하다. 작은 모델의 경우에는 NVIDIA GPU를 데스크탑에 장착해놓고 로컬에서 돌리는 것이 가성비 적으로 유리하고, 큰 모델을 돌리거나 동시에 여러 모델을 학습하고자 할때는 클라우드를 사용하는 것이 절대 적으로 유리하다 특히 구글 클라우드의 경우에는  알파고에서 사용된 GPU의 다음 세대인 TPU (텐서플로우 전용 딥러닝 CPU)를 제공한다. https://cloud.google.com/tpu/ CPU나 GPU대비 최대 15~30배 정도의 성능 차이가 난다.

 

 

학습 단계에서는 세부 변수를 튜닝할 필요가 있는데, 예를 들어 학습 속도나 뉴럴 네트워크의 폭이나 깊이, 드롭 아웃의 수, 컨볼루셔널 필터의 크기등등이 있다. 이러한 변수들을 하이퍼 패러미터라고 하는데, 학습 과정에서 모델의 정확도를 높이기 위해서 이러한 변수들을 자동으로 튜닝할 수 있는 아키텍쳐를 가지는 것이 좋다.

 

텐서플로우등과 같은 머신러닝 전용 프레임웍을 사용하여 직접 모델을 구현하는 방법도 있지만, 모델의 난이도가 그리 높지 않다면 SparkML등과 같이 미리 구현된 모델의 런타임을 사용하는 방법도 있다.

Predict

Predict에서는 학습된 모델을 이용하여 예측 기능을 서비스 하는데, 텐서플로우에서는  Tensorflow Serv를 사용하면 되지만, Tensorflow Serv의 경우에는 bazel 빌드를 이용하여 환경을 구축해야 하고, 대규모 서비를 이용한 분산 환경 서비스를 따로 개발해야 한다. 거기다가 인터페이스가 gRPC이다. (귀찮다.)

구글 CloudML의 경우에는 별도의 빌드등도 필요 없고 텐서 플로우 모델만 배포하면 대규모 서비스를 할 수 있는 런타임이 바로 제공되고 무엇보다 gRPC 인터페이스뿐만 아니라 HTTP/REST 인터페이스를 제공한다. 만약에 Production에서 머신러닝 모델을 서비스하고자 한다면 구글 CloudML을 고려해보기를 권장한다.

Dataflow Orchestration

이 전과정을 서로 유기적으로 묶어 주는 것을 Dataflow Orchestration이라고 한다.

예를 들어 하루에 한번씩 이 파이프라인을 실행하도록 하고, 파이프라인에서 데이타 전처리 과정을 수행하고, 이 과정이 끝나면 자동으로 학습을 진행하고 학습 정확도가 정해진 수준을 넘으면 자동으로 학습된 모델은 서비스 시스템에 배포하는 이 일련의 과정을 자동으로 순차적으로 수행할 수 있도록 엮어 주는 과정이다.

airbnb에서 개발한 Airflow나 luigi 등의 솔루션을 사용하면 된다.

아직도 갈길은 멀다.

얼굴 인식이라는 간단한 모델을 개발하고 있지만, 전체를 자동화 하고, 클라우드 컴퓨팅을 통해서 학습 시간을 단축 시키고 예측 서비스를 할 수 있는 컴포넌트를 개발해야 하고, 향후에는 하이퍼 패러미터 튜닝을 자동으로 할 수 있는 수준까지 가보려고 한다. 그 후에는 GAN을 통한 얼굴 합성들도 도전하려고 하는데, node.js 공부하는데도 1~2년을 투자한후에나 조금이나마 이해할 수 있게 되었는데, 머신러닝을 시작한지 이제 대략 8개월 정도. 길게 보고 해야 하겠다.

 



 

 

저작자 표시 비영리
신고

텐서플로우에서 이미지 데이타 처리 성능 향상방법


이미지 인식 모델을 만들다가 파일 포맷 성능 향상 관련해서 좋은 팁을 찾아서 메모


if you are working with >O(1000) JPEG images, keep in mind that it is extremely inefficient to individually ready 1000's of small files. This will slow down your training quite a bit.

A more robust and faster solution to convert a dataset of images to a sharded TFRecord of Example protos. Here is a fully worked script for converting the ImageNet data set to such a format. And here is a set of instructions for running a generic version of this preprocessing script on an arbitrary directory containing JPEG images.

http://stackoverflow.com/questions/37126108/how-to-read-data-into-tensorflow-batches-from-example-queue

1000개 이상의 JPEG나 PNG 이미지를 매번 읽어서 트레이닝을 시킬 경우, 트레이닝 성능이 낮아진다.

그래서 JPEG 포맷을 사용하지 말고 TFRecord 포맷을 사용하고, TFRecord 포맷에서 한 파일에 하나의 데이타를 넣지말고 여러 데이타를 넣는 방법을 사용해야 한다.


저작자 표시 비영리
신고