학습된 디렉토리 확인

일반적으로 TF OD API로 객체 감지 네트워크 모델을 학습했을 때에 대한 상황을 먼저 확인한다. 앞선 포스팅 TF1 객체감지 모델 학습의 내용처럼 학습을 했다면 학습이 완료되고 나서의 디렉토리 모습은 다음과 같다.

학습결과 디렉토리

train/tf1/<my_network_model>
├─ eval_0/
├─ export/
│  └─ servo
├─ checkpoint
├─ events.out.tfevents......
├─ graph.pbtxt
├─ model.ckpt-N.data
├─ model.ckpt-N.index
├─ model.ckpt-N.meta
├─ ...
├─ ...
└─ pipeline.txt

해당 디렉토리 구조의 내용은 다음과 같다.

  • eval_0: 텐서보드 용 학습 중간에 실행된 evaluation의 이벤트 로그.
  • export: 학습이 끝날 때 체크포인트에서 saved_pb를 생성.
  • checkpoint: 생성된 ckeckpoint 들에 대한 목록
  • events.out.tfevents: 텐서보드 train 로그
  • graph.pbtxt: 네트워크 모델에 대한 텍스트 정의
  • pipeline.txt: 객체 감지 모델을 학습 하기 위한 사전 정의 파일
  • model.ckpt.*: 학습된 체크포인트

여기서 우리가 몇 번째 체크포인트를 Frozen graph로 변환할 지 확인을 한다. 일반적으로는 Evaluation 과정에서 mAPLoss가 가장 좋게나온 체크포인트를 뽑거나 혹은 가장 마지막 체크포인트로 설정하기도 한다.

Frozen Graph 추출

파라미터 확인

우리가 사용할 코드는 models 리포지토리의 <repo_path>/research/object_detection/export_inference_graph.py이다. 우선 해당 파이썬 코드에 --help 명령어를 같이 입력하여 파라미터들의 용법을 확인한다.

$ python export_inference_graph.py --help

...
...
...

export_inference_graph.py:
  --config_override: pipeline_pb2.TrainEvalPipelineConfig text proto to override pipeline_config_path.
    (default: '')
  --input_shape: If input_type is `image_tensor`, this can explicitly set the shape of this input tensor to a
    fixed size. The dimensions are to be provided as a comma-separated list of integers. A value of -1 can be
    used for unknown dimensions. If not specified, for an `image_tensor, the default shape will be partially
    specified as `[None, None, None, 3]`.
  --input_type: Type of input node. Can be one of [`image_tensor`, `encoded_image_string_tensor`, `tf_example`]
    (default: 'image_tensor')
  --output_directory: Path to write outputs.
  --pipeline_config_path: Path to a pipeline_pb2.TrainEvalPipelineConfig config file.
  --trained_checkpoint_prefix: Path to trained checkpoint, typically of the form path/to/model.ckpt
  --[no]write_inference_graph: If true, writes inference graph to disk.
    (default: 'false')

중간에 출력되는 내용이 많은데 일단은 필요한 파라미터부터 파악해본다.

  • input_shape: 체크포인트를 frozen_graph로 변환 할 때 해당 그래프의 네트워크 입력 크기를 지정할 수 있다. None은 가변적인 동적입력 크기를 의미하고 명시적인 값을 적어주면 해당 크기의 shape으로만 입력을 받을 수 있다.
  • output_directory: saved_pbfrozen_graph가 저장될 위치이다. 본인은 일반적으로 모델 학습 경로와 동일하게 준다.
  • pipeline_config_path: 학습 때 사용한 pipeline.config 파일 경로를 입력해준다.
  • trained_checkpoint_prefix: 변환할 체크포인트 이름을 입력해준다. 일반적으로 model.ckpt-xxxxx 형식을 가지며 xxxxx 자리에 학습 횟수가 들어간다.

추가적으로 출력되는 내용들에 대해서 이야기를 해보자면 다음과 같다.

  • input_tpye은 3가지가 있는데 대부분이 image_tensor를 사용한다.(기본값) 그 외의 encoded_image_string_tensor는 1차원의 이미지 텐서로 3차원의 이미지 배열을 1차원으로 바꿔서 네트워크에 직접 넣어줄 때 사용하는 것 같다.
  • 추출한 frozen graph의 output은 num_detections, detection_boxes, detection_scores, detection_classes, detection_masks의 5가지가 있는데 마스크는 제하더라도 앞의 4개는 추론코드에서 사용하니 잘 기억하자.

또한 해당 코드를 실행하면 결과는 다음과 같을 것이라고 출력 된다. 텍스트 형식의 inference_graph 와 해당 체크포인트(이름 리셋), frozen graph, saved model까지 나온다.

The expected output would be in the directory
path/to/exported_model_directory (which is created if it does not exist)
with contents:
 - inference_graph.pbtxt
 - model.ckpt.data-00000-of-00001
 - model.ckpt.info
 - model.ckpt.meta
 - frozen_inference_graph.pb
 + saved_model (a directory)

실행 후 확인

코드 실행은 다음과 같이 하였다.

python export_inference_graph.py \
--output_directory=/data/tensorflow/train/tf1/my_model/ \
--pipeline_config_path=/data/tensorflow/train/tf1/my_model/pipeline.config \
--trained_checkpoint_prefix=/data/tensorflow/train/tf1/my_model/model.ckpt-200000

trained_checkpoint_prefix에는 학습의 결과로 생성된 여러개의 체크포인트 중 내가 변환할 20만번째 스텝의 체크포인트 이름을 지정하였다. input_shape은 기존의 [None, None, None, 3]을 그대로 사용할 것이기에 따로 명시해 주지 않았다.

결과 출력은 다음과 같다.

...
...
...
INFO:tensorflow:SavedModel written to: /data/tensorflow/train/tf1/211230_ssd_mobilenet_v2_helmet/saved_model/saved_model.pb
I0104 17:11:26.238900 140170646153088 builder_impl.py:425] SavedModel written to: /data/tensorflow/train/tf1/211230_ssd_mobilenet_v2_helmet/saved_model/saved_model.pb
WARNING:tensorflow:From /data/tensorflow/models-r1.13/research/object_detection/utils/config_util.py:180: The name tf.gfile.Open is deprecated. Please use tf.io.gfile.GFile instead.

W0104 17:11:26.249929 140170646153088 module_wrapper.py:139] From /data/tensorflow/models-r1.13/research/object_detection/utils/config_util.py:180: The name tf.gfile.Open is deprecated. Please use tf.io.gfile.GFile instead.

INFO:tensorflow:Writing pipeline config file to /data/tensorflow/train/tf1/211230_ssd_mobilenet_v2_helmet/pipeline.config
I0104 17:11:26.250065 140170646153088 config_util.py:182] Writing pipeline config file to /data/tensorflow/train/tf1/211230_ssd_mobilenet_v2_helmet/pipeline.config

대충 SavedModel도 써지고 pipeline config file에 관한 결과도 볼 수 있다. 해당 결과 디렉토리를 보면 아래 이미지와 같이 frozen graph가 생성된 것을 알 수 있다.

변환결과 디렉토리

Leave a comment