메뉴 건너뛰기

개발강좌/정보

  • 텐서플로우로 이미지인식 모바일앱 만들어보기 - 4 (모바일사용을 위한 그래프 변환) [머신러닝/딥러닝]
  • 공돌이
    조회 수: 2568, 2017.05.02 14:54:25
  • 2017.05.12: 앞부분 수정사항과 맞추기 위해 폴더명을 data, train 에서 input, output으로 변경했습니다.

    =====================

    이번에는 좀 짧습니다 ㅎ

     

    지난시간 까지 이미지를 학습시켜서 결과물로 .pb 확장자의 그래프파일(protobuf라고 하네요)과 텍스트파일(라벨)을 만들었습니다.

    하지만, 이렇게 만들어진 파일을 바로 모바일에서 읽을수가 없습니다. 모바일에서는 적용할 수 없는 op (operation) 가 일부 들어가 있기 때문이라고 하네요.

     

    그래서 모바일에서 지원하지 않는 op들을 제거해주는 (예를들면 DecodeJpeg 같은거) 작업을 해줘야 하는데 그게 바로 optimize_for_inference 라는 툴이 하는 역할입니다.

     

    2번째 강좌(https://meisteruser.net/devflow/2241) 에서 몇개의 툴들을 빌드 했었는데요...그중에 하나가 바로 optimize_for_inference 입니다.

     

    얘를 이용해서 아래와 같은 포맷으로 변환을 해보겠습니다.

     

    1) 학습된 그래프파일을 최적화하기

    우선, 터미널을 닫으셨다면...다시 터미널을 열고

     

    $ cd tensorflow

    $ source bin/activate 

     

    해서 가상환경을 활성화 한 다음

     

    아래의 명령을 실행해 줍니다.

     

    tensorflow/bazel-bin/tensorflow/python/tools/optimize_for_inference \
    --input=train/output/flower_photos/retrained_graph.pb \
    --output=train/output/flower_photos/optimized_graph.pb \
    --input_names=Mul \
    --output_names=final_result

     

    --input 은 지난시간에 ratrain 툴을 이용해서 만든 결과 그래프를 입력으로 넣어주고요

    --output 은 변환해서 생성할 그래프파일의 위치와 파일명을 지정해주시면 됩니다.

    --input_names 와 output_names 는 입출력 노드명인데, 우리는 스크래치부터 학습시킨게 아니니까, 예제에서 쓰는 노드명을 그대로 입력해주시면 됩니다. (Mul, final_result)

     

    그러면 잠시 시간이 흐른 후 파일이 생성됩니다.

     

    이거 잘 변환됐는지 함 확인해봐야겠죠?

     

     bazel-bin/tensorflow/examples/label_image/label_image \

             --input_layer=Mul \

             --output_layer=final_result \

             --labels=train/output/flower_photos/retrained_labels.txt \

             --image=test.jpg \

             --graph=train/output/flower_photos/optimized_graph.pb

     

    --graph  부분에 retrained_graph.pb 대신에 방금 생성한 optimized_graph를 지정해주시고 나머지는 동일하게 해서 돌려보시면 prediction값이 나옵니다.

     

    2017-05-02 11:43:38.480719: I tensorflow/examples/label_image/main.cc:206] dandelion (1): 0.999632

    2017-05-02 11:43:38.481233: I tensorflow/examples/label_image/main.cc:206] sunflowers (3): 0.000169071

    2017-05-02 11:43:38.481238: I tensorflow/examples/label_image/main.cc:206] tulips (4): 9.32354e-05

    2017-05-02 11:43:38.481242: I tensorflow/examples/label_image/main.cc:206] daisy (0): 7.80553e-05

    2017-05-02 11:43:38.481245: I tensorflow/examples/label_image/main.cc:206] roses (2): 2.74587e-05

     

    dandelion 일 확률 99.9% 나왔네요 ㅎㅎ 잘 변환된것 같습니다.

     

     

    2) Quantize 하기

    지금 파일을 바로 아이폰이나 안드로이드에서 사용할 수도 있지만, 아직 모바일에 최적화되어있는건 아닙니다. optimized_graph.pb 파일의 사이즈를 한번 보시면 거의 90MB전후가 되지요.  이 파일을 zip 으로 압축해보면 거의 압축이 안되는걸 아실 수 있을겁니다.  

    이것은 모델에서 사용된 가중치값들이 전부 조금조금씩 다른 float 값들로 이루어져 있어서 압축이 안되기 때문인데요, 그래서 반올림등의 작업을 통해 비슷한 float 값들을 압축이 가능한 동일한 값으로 변경시키는 작업을 해주는 것이 좋습니다.  (이 float 값들은 주로 가중치 -  weights - 라는 요소로, 텐서플로우 등의 머신러닝의 선형회귀분석을 통한 예측모델 구현에 대단히 중요한 값입니다...만 이 글의 범위를 벗어나니 이정도로만...) 

     

    이게 quantize 과정인데요, 이 과정을 통해서 변환된 결과물은 얼핏보기엔 크기가 비슷해 보이지만 압축해보면 크기가 거의 20MB중반대로 작아지는걸 알 수 있습니다.

     

    나중에 아이폰이나 안드로이드에서 사용하게 되면, 해당 실행파일(.ipa , .apk) 들이 자체적으로 압축되는 형태이므로, 줄어든 형태가 된다고 합니다.

     

    bazel-bin/tensorflow/tools/quantization/quantize_graph \
    --input=train/output/flower_photos/optimized_graph.pb \
    --output=train/output/flower_photos/rounded_graph.pb \
    --output_node_names=final_result \
    --mode=weights_rounded

     

    이렇게 만든 rounded_graph 를 한번 테스트해보겠습니다.

     

     bazel-bin/tensorflow/examples/label_image/label_image \

             --input_layer=Mul \

             --output_layer=final_result \

             --labels=train/output/flower_photos/retrained_labels.txt \

             --image=test.jpg \

             --graph=train/output/flower_photos/rounded_graph.pb

     

    2017-05-02 11:43:39.107280: I tensorflow/examples/label_image/main.cc:206] dandelion (1): 0.999289

    2017-05-02 11:43:39.107830: I tensorflow/examples/label_image/main.cc:206] sunflowers (3): 0.000307598

    2017-05-02 11:43:39.107836: I tensorflow/examples/label_image/main.cc:206] tulips (4): 0.000232983

    2017-05-02 11:43:39.107840: I tensorflow/examples/label_image/main.cc:206] daisy (0): 9.28887e-05

    2017-05-02 11:43:39.107843: I tensorflow/examples/label_image/main.cc:206] roses (2): 7.76977e-05

     

    보시는 바와 같이 살짝 예측치가 내려가긴 했으나 크게 차이가 나지 않으므로 괜찮은것 같습니다.

    (훈련횟수나 이미지소스, classify 방법 등에 따라 차이가 좀 날 수도 있습니다)

     

     

    3) Memory Mapping하기 (옵션)

    이렇게 quantize 된 그래프도 모바일에서 사용하는데에 문제 없지만,

     

    모바일에서는 이 그래프파일을 메모리에 로드해서 예측하는 과정에서 계속 사용해야 하므로, 자칫하면 메모리관련 크래쉬(메모리 오버플로우 등) 가 날 확률이 높아집니다...라고설명을 하네요. 그래서 모바일 상의 메모리 구조에 맞게 memory mapping 해주는 과정이 하나 더 들어가는데...

     

    문제는 안드로이드에서 이렇게 매핑된 그래프파일을 불러들이는 방법을 아직 못찾았습니다...ㅠㅜ

    iOS는 Graph load 하면서 옵션을 줘서 memory mapping된 파일을 불러들일 수 있는데, 안드로이드는 그 옵션을 못찾겠네요...쩝

     

    그래서 아래 내용은 예시만 보여드리고, 다음 회차에서 보여드릴 모바일에서 불러서 사용하는 부분은 quantize 된걸로 하겠습니다(rounded_graph.pb)

    방법을 찾으면 매핑된 그래프로 demo를 동작하는 것을 보여드리는 것으로 하고, 일단은 이렇게 한다 정도만 우선 참고해주세요...

     

     tensorflow/bazel-bin/tensorflow/contrib/util/convert_graphdef_memmapped_format \

             --in_graph=train/output/flower_photos/rounded_graph.pb \

             --out_graph=train/output/flower_photos/mmapped_graph.pb

     

    여기서는 노드명을 줄 필요는 없고, 입력받을 그래프명과 저장할 최종결과물파일명만 지정해주시면 됩니다.

     

    그리고, 매핑된 그래프파일은 모바일에 맞게 재구성된 그래프이므로, PC에서는 읽을수가 없다고 합니다. 그래서 테스트도 어렵네요...-_-;;

     

     

    여기까지 하시면 다음회차에 실제로 사용해 볼 rounded_graph.pb 파일과 retrained_graph.txt(라벨) 파일이 준비되었습니다.

     

    다음회차에서는 android의 경우는 안드로이드스튜디오 사용기준으로 설명을 드릴 예정이니 참고해주시고,

    iOS는 Xcode 를 사용하는 것으로 알려드립니다. 

     

     

    다음 튜토리얼에서 뵈요!

댓글 9 ...

  • 와웅

    2017.05.05 02:22

    다음 튜토리얼 기다리고 있어요:) 좋은 글 올려주셔서 감사합니다
  • 공돌이

    2017.05.05 03:41

    지금 조금씩 작성하고 있는데, 연휴동안 여행을 다녀오기로 해서 진도가 좀 더딜듯 하네요 ㅠㅜ. 틈틈이 만들어 다음주 초반에 올릴수 있도록 노력하겠습니다. 궁금하신거 있으면게시판에 글 남겨주세요...^^

  • 감사합니다

    2017.05.05 17:04

    모바일 환경에서 동작하는 방법 찾고있었는데... 드디어!! 찾았네요!ㅠㅠ 정말 감사드립니다! 다음 글도 기다릴게요~~!!!ㅎㅎ
  • 제자

    2017.05.24 10:09

    안녕하세요. 선생님~
    올려주신 글 보고 도움이 많이 되었습니다~ 감사합니다^^
    5월초 연휴 끝나고 다음 강좌 진행해 주신다고 하셔서 기다리고 있는데
    여전히 유효한건지 궁금하네요..ㅎㅎ
    선생님 강좌를 끝까지 잘 마무리하고 싶습니다!
  • 공돌이

    2017.05.24 11:12

    아 안녕하세요...^^ 도움되셨다니 뿌듯하네요. 강좌는 당연히 유효합니다. 다른업무 핑계로 차일피일 미루다보니 시간이 많이 흘렀네요 ㅠㅜ... 아마 종류에 따라 몇개로 쪼개야 할것 같은데 가능하면 이번주말까지 안드로이드 기본 데모를 활용한 버전은 꼭 올리도록 하겠습니다.

    참고로, 현재 텐서플로1.2.0프리뷰버전이 나왔는데, 앞으로는 훨씬 간단해지겠더라구요...^^ 튜토리얼을 1.2버전에 맞춰서 고친버전도 올려야 할듯...

  • 제자

    2017.05.26 13:34

    감사합니다 ^^ 저는 iOS 기본 데모를 테스트 중인데 잘 안되네요 ㅠ
    iOS도 부탁드립니다!
  • 공돌이

    2017.05.26 15:20

    넵 안드로이드 다 끝나면 하려고 생각중이예요... 안되는부분 질문게시판에 올려주시면 제가 살펴볼수 있을듯해요
  • 드린

    2017.08.25 16:15

    2) Quantize 하기를 진행하던 중에 이런 오류가 발생하더군요.

    Input graph file 'train/output/trademark/optimized_graph.pb' does not exist!

    (trademarkLearn) baegui-MacBook-Pro:trademark baeg$ ls
    bottlenecks optimized_graph.pb retrained_labels.txt
    inception retrained_graph.pb

    파일은 잘 생성되었는데도 말이죠.
    optimized_graph 파일로 테스트도 잘 되었습니다.
  • 공돌이

    2017.08.25 16:53

    크... 이것만으로는 저도 잘 모르겠네요...

    파일이 있다면 돌아가는게 정상인데요...ㅠㅜ 혹시 프로그램을 실행한 디렉토리 기준으로 디렉토리 상대경로가 잘못되어있는건 아닌지 한번 확인해보시구요, 아니면 절대경로로 지정해보시지요. 맥에서 하시는것이니 앞부분 글자만 치고 탭키를 눌러서 자동완성으로 하시면 혹시라도 있을수있는 오타를 줄일수있습니다 (이미 아시는거겠지만...^^)

     

https://meisteruser.net/devflow/2294
번호
제목
닉네임
11 프레임워크/기타 공돌이 3 2018.09.20
10 머신러닝/딥러닝 공돌이 2233 2017.07.05
9 머신러닝/딥러닝 공돌이 2397 2017.06.05
8 머신러닝/딥러닝 공돌이 7540 2017.05.26
머신러닝/딥러닝 공돌이 2568 2017.05.02
6 머신러닝/딥러닝 공돌이 8610 2017.04.27
5 머신러닝/딥러닝 공돌이 3877 2017.04.24
4 머신러닝/딥러닝 공돌이 2998 2017.04.23
3 머신러닝/딥러닝 공돌이 6099 2017.04.19
2 머신러닝/딥러닝 공돌이 23421 2017.03.22
1 공지 공돌이 700 2017.03.21
태그
위로