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


Archive»


 
 

CloudML을 이용하여 예측하기

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


지난글 (http://bcho.tistory.com/1189) 에서 학습된 모델을 *.pb 파일 포맷으로 Export 하였다. 그러면 이 Export 된 모델을 이용하여 예측 (prediction)을 하는 방법에 대해서 알아보겠다. 앞글에서도 언급했듯이, 예측은 Google CloudML을 이용한다.

전체 코드를 https://github.com/bwcho75/facerecognition/blob/master/CloudML%20Version/face_recog_model/%2528wwoo%2529%2BML%2BEngine%2Bprediction.ipynb 를 참고하기 바란다.

Export된 모델을 CloudML에 배포하기

학습된 모델을 CloudML에 배포하기 위해서는 export된 *.pb 파일과 variables 폴더를 구글 클라우드 스토리지 ( GCS / Google Cloud Storage) 에 업로드해야 한다.

아니면 학습때 모델 Export를 GCS로 시킬 수 도 있다.


아래는 terrycho-face-recog-export 라는 GCS 버킷아래 /export 디렉토리에, export 된 *.pb 파일과 variables 폴더가 저장된 모습이다.


다음 구글 클라우드 콘솔에서 ML Engine을 선택하여, Models 메뉴를 고른다. 이 메뉴는 모델을 배포하고 Prediction을 해주는 기능이다.



Models 화면으로 들어오면 Create Model 버튼이 나온다. 이 버튼을 이용해서 모델을 생성한다.





모델 생성시에 아래와 같이 단순하게 모델이름을 넣어주면된다.




모델 이름을 넣어준후에, 해당 모델에 실제 Export된 모델 파일을 배포해줘야 하는데, CloudML은 버전 기능을 제공한다. 그래서 아래 그림과 같이 Create Version 버튼을 눌러서 새로운 버전을 생성한다.





Create Version 메뉴에서는 Name에 버전명을 쓰고, Source에는 Export된 *.pb 파일과 variables 폴더가 저장된 GCS 경로를 선택한다.



아래는 terrycho-face-recog-export 버킷을 선택한 후, 그 버킷안에 export 폴더를 선택하는 화면이다.



선택을 해서 배포를 하면 아래와 같이 v7 버전이름을 모델이 배포가 된다.


배포된 모델로 예측 (Prediction)하기

그러면 배포된 모델을 사용해서 예측을 해보자. 아래가 전체코드이다.


from googleapiclient import discovery

from oauth2client.client import GoogleCredentials

import numpy

import base64

import logging


from IPython.display import display, Image


cropped_image = "croppedjolie.jpg"

display(Image(cropped_image))


PROJECT = 'terrycho-ml'

MODEL_NAME = 'face_recog'

MODEL_VERSION ='v7'



def call_ml_service(img_str):

   parent = 'projects/{}/models/{}/versions/{}'.format(PROJECT, MODEL_NAME,MODEL_VERSION)

   pred = None


   request_dict = {

       "instances": [

           {

               "image": {

                   "b64": img_str

               }

           }

       ]

   }


   try:

       credentials = GoogleCredentials.get_application_default()

       cloudml_svc = discovery.build('ml', 'v1', credentials=credentials)

       request = cloudml_svc.projects().predict(name=parent, body=request_dict)

       response = request.execute()

       print(response)

       #pred = response['predictions'][0]['scores']

       #pred = numpy.asarray(pred)


   except Exception, e:

       logging.exception("Something went wrong!")


   return pred



# base64 encode the same image

with open(cropped_image, 'rb') as image_file:

   encoded_string = base64.b64encode(image_file.read())


# See what ML Engine thinks

online_prediction = call_ml_service(encoded_string)


print online_prediction


코드를 살펴보면

       credentials = GoogleCredentials.get_application_default()

       cloudml_svc = discovery.build('ml', 'v1', credentials=credentials)


에서 discovery.build를 이용해서 구글 클라우드 API 중, ‘ML’ 이라는 API의 버전 ‘v1’을 불러왔다. CloudML 1.0 이다. 다음 credentials는 get_application_default()로 디폴트 credential을 사용하였다.

다음으로, CloudML에 request 를 보내야 하는데, 코드 윗쪽으로 이동해서 보면


def call_ml_service(img_str):

   parent = 'projects/{}/models/{}/versions/{}'.format(PROJECT, MODEL_NAME,MODEL_VERSION)

   pred = None


   request_dict = {

       "instances": [

           {

               "image": {

                   "b64": img_str

               }

           }

       ]

   }


를 보면 request body에 보낼 JSON을 request_dict로 정의하였다. 이때, 이미지를 “b64”라는 키로 img_str을 넘겼는데, 이 부분은 이미지 파일을 읽어서 base64 스트링으로 인코딩 한 값이다.

request = cloudml_svc.projects().predict(name=parent, body=request_dict)


다음 request 를 만드는데, 앞에서 선언한 cloudml_svc객체를 이용하여 prediction request 객체를 생성한다. 이때 parent 에는 모델의 경로가 들어가고 body에는 앞서 정의한 이미지가 들어있는 JSON 문자열이 된다.


   parent = 'projects/{}/models/{}/versions/{}'.format(PROJECT, MODEL_NAME,MODEL_VERSION)


Parent에는 모델의 경로를 나타내는데, projects/{프로젝트명}/models/{모델명}/versions/{버전명} 형태로 표현되며, 여기서는 projects/terrycho-ml/models/face_recog/versions/v7 의 경로를 사용하였다.


이렇게 request 객체가 만들어지면 이를 request.execute()로 이를 호출하고 결과를 받는다.

       response = request.execute()

       print(response)


결과를 받아서 출력해보면 다음과 같은 결과가 나온다.




2번째 라벨이 0.99% 확률로 유사한 결과가 나온것을 볼 수 있다. 라벨 순서 대로 첫번째가 제시카 알바, 두번째가 안젤리나 졸리, 세번째가 니콜 키드만, 네번째가 설현, 다섯번째가 빅토리아 베컴이다.


이제 까지 여러회에 걸쳐서 텐서플로우를 이용하여 CNN 모델을 구현하고, 이 모델을 기반으로 얼굴 인식을 학습 시키고 예측 시키는 모델 개발까지 모두 끝 맞췄다.


실제 운영 환경에서 사용하기에는 모델이 단순하지만, 여기에 CNN 네트워크만 고도화하면 충분히 사용할만한 모델을 개발할 수 있을 것이라고 본다. CNN 네트워크에 대한 이론 보다는 실제 구현하면서 데이타 전처리 및 학습과, 학습된 모델의 저장 및 이를 이용한 예측 까지 전체 흐름을 설명하기 위해서 노력하였다.


다음은 이 얼굴 인식 모델을 실제 운영환경에서 사용할만한 수준의 품질이 되는 모델을 사용하는 방법을 설명하고자 한다.

직접 CNN 모델을 만들어도 되지만, 얼마전에, 발표된 Tensorflow Object Detection API (https://github.com/tensorflow/models/tree/master/object_detection)는 높은 정확도를 제공하는 이미지 인식 모델을 라이브러리 형태로 제공하고 있다. 다음 글에서는 이 Object Detection API를 이용하여 연예인 얼굴을 학습 시키고 인식하는 모델을 개발하고 학습 및 예측 하는 방법에 대해서 알아보도록 하겠다.



Bazel 빌드툴


Tensorflow Serving을 살펴보다보니, Serving Server는 C++기반에 gRPC 인터페이스 기반이라는 것을 알았는데,

빌드 환경이 bazel이라는 것을 사용한다. 그래서 Bazel이 무엇인가 찾아봤는데. 쉽게 말하면 빌드 툴이다





위키에 설명이 가장 잘나와 있는데, 구글에서 만든 빌드 시스템으로, 구글의 경우 큰 소스코드를 빌드하기 때문에, 이를 위해서 만들어진 빌드 시스템을 오픈소스화 한것으로, 분산 빌드등을 제공하고 빠른 성능을 제공한다.


쉽게 말해서 make,ant,gradle,maven과 같은 빌드 시스템으로 보면 된다.

Java,C,C++,Python,Object C등의 언어를 지원한다.


https://en.wikipedia.org/wiki/Bazel_(software)

In software developmentBazel is an open source tool that allows for the automation of building and testing of software.[2] The company Google uses the build tool Blaze internally[3] and released and open-sourced part of the Blaze tool as Bazel, named as an anagram of Blaze.[4] Bazel was first released in March 2015 and achieved beta status by September 2015.[5]

Similar to build tools like MakeApache Ant, or Apache Maven,[2][4] Bazel builds software applications from source code using a set of rules. Rules and macros are created in the Skylark language, a subset of Python.[4] There are built-in rules for building software written in the programming languages of JavaCC++PythonObjective-C and Bourne shell scripts.[4][5] Bazel can produce software application packages suitable for deployment for the Android and iOS operating systems.[6]

In designing Bazel, emphasis has been placed on build speed, correctness, and reproducibility.[2][4] The tools uses parallelization to speed up parts of the build process.[4] It includes a Bazel Query language that can be used to analyze build dependencies in complex build graphs.[4]


아무래도 개발 환경 설정이 쉽지 않은 만큼, Bazel C++ 빌드 환경이 패키징된 도커 환경을 알아보는것이 더 좋겠다.