GYUMIN DEV LOG

이전에는 FloydHub를 이용하여 모델을 학습하였다.


이제 학습된 모델을 TensorFlow Lite형식의 모델로 변환 후 Android에 올려 Image Classfication을 해보려고 한다.


https://codelabs.developers.google.com/codelabs/tensorflow-for-poets-2-tflite/index.html#0

구글 코드랩에서 tflite로 변환하는 부분을 참고 하였고 구글링을 통해서 필요한 변환 과정, 스크립트, 도구 정보를 습득 하였습니다.


이 게시글에서 필요한 파일들은 모두 제 github에 올려놓았습니다.

현재 글과 해당 github에 있는 모델 구조가 상이하므로 참고해주세요.

Link : https://github.com/GyuminDev/CNN_Classification_N


필요한 파일 및 환경

- python 3.6, tensorflow 1.6
- 위 구글 코드랩 github repo를 local에 clone(스크립트와 안드로이드 예제 사용할 예정)
- toco 라이브러리
- 각 단계에 필요한 스크립트 파일



전체 과정은 크게 보면 이렇다.


1. TensorFlow를 이용해 학습된 모델 파일 -> .pb

   - .pb파일을 tensorboard를 이용해 시각화 해보며 Graph에서 input node, ouput node의 이름을 파악해야함.

2. .pb파일을 optimize 한다.

3. optimize한 .pb파일도 역시 tensorboard를 이용해서 graph의 변화가 없는지 check

4. 마지막으로 .pb파일을 .tflite형태로 변환한다.

5. .tflite파일을 Android Project의 올려서 Run!!



1. .pb파일 확인 및 Tensorboard를 이용하여 시각화


학습을 진행한 후 output을 보면 이렇다 

1. step별 checkpoint파일

2. 모델 파일 - cifar.pb

3. tensorboard event파일 - train, validate 폴더로 구성되어 있음


먼저 Script/pb_tensorboard.py를 이용해서 학습된 모델인 cifar.pb를 시각화 해보자.

pb_tensorboard.py가 있는 위치로 이동 후 아래처럼 스크립트 실행을 한다.

model_dir=pb파일이 있는 경로

log_dir=tensorboard 이벤트파일을 저장할 경로

1
2
3
python pb_tensorboard.py \ 
model_dir=./cifar10.pb \ 
log_dir=./pb_logs
cs


이렇게 작성하면 pb_logs 하위에 tensorboard Event파일이 생성된다.




다음과 같이 cifar10.pb를 시각화하여 그래프의 형태를 볼 수 있다. 

여기서 input과 output 노드의 이름을 메모해 놓아야 한다.


input node = input_node -> shape = [?, 32, 32, 3] 

output = output -> shape = [?, 10]


input은 32x32 사이즈의 RGB(3채널)이미지를 받으며 Output으로는 softmax 함수를 취하여 10가지 Label(클래스)에 대한 예측점수가 나오게 된다.


중요한 점은 TensorFlow Code를 작성 할 때 Tensorboard 시각화가 잘되도록 scope 부분과 name을 잘 지정해 주어야 한다.



2. .pb파일을 optimize

모바일에서 동작하려면 모델의 복잡도가 낮아야지 빠르게 동작한다. 그렇기 때문에 추론(Inference)과정에 필요하지 않는 node들을 제거해서 최적화 하는 작업이 필요한데 이 작업 최적화에 해당된다.
Script 폴더에서 해당 명령어를 실행한다.
1
2
3
4
5
python optimize_for_inference.py \
  --input=./cifar.pb \
  --output=./opt_cifar10.pb \
  --input_names="input_node" \
  --output_names="output"
cs

input, output node name을 제대로 입력한 경우 무리없이 동작할 것이다. 이로써 나온 opt_cifar10.pb를 1번 과정처럼 다시 시각화하여 최적화 하기전 모델과 달라진 점이 있는지 비교해 본다.

나는 비교해 보았을 때 .pb파일의 용량도 달라지지 않았고 그래프의 노드도 변화가 없었다. 그냥 이과정을 생략하고 tflite로 변환해봐도 될 듯하다. 물론 현재 이 모델에만 해당 될 수 도있고 정확하지는 않으니 참고바람.

 

3. .pb convert to .tflite

1
2
3
4
5
6
7
8
9
10
11
IMAGE_SIZE=32
toco \
--input_file=./opt_cifar10.pb \            
--output_file=./cifar10.tflite \
--input_format=TENSORFLOW_GRAPHDEF \ 
--output_format=TFLITE \ 
--input_shape=1,${IMAGE_SIZE},${IMAGE_SIZE},3 \ 
--input_array=input_node \
--output_array=output \       
--inference_type=FLOAT \ 
--input_type=FLOAT 
cs

input_file : .pb
output_file : 변환될 .tflite 파일
input_format : TensorFlow Graph
output_fromat : tensorflow Lite 파일
input_shpate : 1번에서 확인 했던 것처럼 [1, 32, 32, 3] shape를 명시해 줌. 맨 앞을 1로 한다는 것은 1장의 32x32 RGB(3채널)이미지를 input으로 한다는 의미
intput_array : 1번에서 확인한 input node 이름
output_array : 1번에서 확인한 output node 이름
inference_type : FLOAT과 Quantize 방식이 있는데 TensorFlow Lite 공식 문서에서 확인 가능하다.
input_type :  FLOAT Array형태로 이미지를 입력하므로 float으로 설정

이렇게 하면 cifar10.tflite가 만들어진다.


4. example에 내가 만든 cifar10.tflite로 대체하기



google codelab github Repo에 들어가면 Android 예제 프로젝트가 있다. 

cifar10.tflitelabel.txt를 app/src/main/assets폴더에 넣어주고 
ImageClassifier.java 파일을 알맞게 수정해주고 빌드해보면 작동이 잘 되는 것을 확인 할 수 있다.


추후에는 2017년에 공개된 DenseNet을 TensorFlow로 구현하여 포스팅을 진행하겠습니다.


'ML_DL' 카테고리의 다른 글

FloydHub 이용 TensorFlow CNN CIFAR10 예제 학습  (1) 2018.04.09