Career/Barrier Free Application Development

기능: 볼라드 탐지하기 (Bollard Detector) - Tiny YOLO 앱에 탑재하기(2단계)

김 정 환 2020. 2. 19. 19:42
반응형

이 포스트는 YOLO 포스트와 이어지는 부분입니다. 이전 포스트에서 YOLO를 어떻게 학습시키는 알아보았습니다. 그리고 Tiny-YOLO로 학습을 시키시면, 결과물로 tiny-yolo-obj_final.weights 파일을 얻을 수 있습니다. 이 파일을 그대로 어플에 탑재할 수 없습니다. protobuff file(.pb) 형식으로 바꿔주어야 합니다. 

 

 

 

Darkflow 프로그램을 이용해서 weights를 pb로 변형시키겠습니다. 여기서 다운로드 합니다. Windows에서 cmd를 실행합니다. darkflow파일로 이동합니다. python flow --model cfg/tiny-yolo-obj.cfg --load weights/tiny-yolo-obj_final.weights --savepb 를 입력합니다. 이 명령어의 의미를 아래와 같습니다.

 

--train : 학습 시킬때
--load : weights 파일 Load, -1을 주면 ckpt/checkpoint에서 가장 최근걸 불러온다.
--model : cfg 파일 경로
--annotation : xml 파일 경로
--dataset : 학습 image 파일 경로
--demo : video test시 video 파일 경로 입력
--imgdir : image test시 image 파일 경로 입력

(위 명령어를 보시면 학습도 가능하다는 것을 알 수 있습니다. Darkflow로 학습이 가능합니다.)

 

 

명령어를 실행하면 아마도 오류가 발생할 것입니다. 

Parsing cfg/tiny-yolo-obj.cfgLoading weights/tiny-yolo-obj_final.weights ...Traceback (most recent call last): File "./flow", line 6, in <module> cliHandler(sys.argv) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/cli.py", line 26, in cliHandler tfnet = TFNet(FLAGS) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/net/build.py", line 58, in __init__ darknet = Darknet(FLAGS) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/dark/darknet.py", line 27, in __init__ self.load_weights() File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/dark/darknet.py", line 82, in load_weights wgts_loader = loader.create_loader(*args) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/utils/loader.py", line 105, in create_loader return load_type(path, cfg) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/utils/loader.py", line 19, in __init__ self.load(*args) File "/home/ubbcluj/Documents/Egyetem/FinalExam/Darknet/Darknet/darkflow/darkflow/utils/loader.py", line 77, in load walker.offset, walker.size)AssertionError: expect 63102554 bytes, found 63102560

 

 

./darkflow/utils/loader.py 파일 열어서 self.offset = 16을 self.offset = 20으로 바꿔줍니다. 그리고 다시 이전 명령어를 실행합니다. 그러면 ./built_graph directory에 tiny-yolo-obj.meta와 tiny-yolo-obj.pb가 생성되어 있을 것 입니다.

 

방법은 공식 홈페이지에 있습니다. 

 

 

다른 방법도 있습니다. DW2TF를 이용합니다. 마찬가지로 Windows에서 cmd를 실행합니다. DW2TF파일로 이동해서 python main.py --cfg 'cfg/tiny-yolo-obj.cfg' --weights 'weights/tiny-yolo-obj_final.wieghts' --output 'data/' --prefix 'tiny-yolo/' --gpu 0 를 입력합니다. 

 

 

 

이제 tensorflow 앱을 다운 받아서 pb 파일을 탑재할 시간입니다. Android 앱에서 YOLO를 사용하기 위해서 tensorflow demo 프로그램을 만들었습니다. 여기서 다운로드 합니다. 안드로이드 프로젝트는 tensorflow/tensorflow/examples/android에 있습니다. Android Studio로 실행합니다. 여러가지 업데이트를 합니다. 그리고 build.gradle 파일에서 nativeBuildSystem 값을 none으로 바꿉니다. 

 

 

이 프로젝트에서는 4가지 기능이 있습니다.

  • TF Classify: Google Inception 모델을 이용해서 물체를 실시간으로 분류합니다.
  • TF Detect: Tensorflow Object Detection API로 학습된 모델이 물체의 위치를 나타내고 추적합니다. 80가지 물체가 가능합니다.)
  • TF Stylize: A Learned Representation For Artistic Style를 기초로한 모델이 카메라에 담긴 이미지를 다양한 스타일로 변형해 줍니다.
  • TF Speech: 간단한 음성 인식 모델입니다. 

저희에게는 TF Detect 만 필요했습니다. 그래서 AndroidManifest.xml에서 DetectorActivity를 제외하고 주석처리 합니다. 또는 삭제하셔도 됩니다. 

여기까지 하시고 그냥 빌드하고 핸드폰에 설치하면서 80개을 물체를 탐지할 수 있습니다. 그러면 이제 우리가 원하는 물체를 탐지할 수 있게 바꿔보도록 하겠습니다. 

 

 

darkflow/build_graph에서 생성된 tiny-yolo-obj.pb를 tensorflow/tensorflow/examples/android/assets에 추가합니다. 이제 프로젝트에서 2개의 .java 파일을 수정하겠습니다. DetectorActivity.java로 가겠습니다. 

  • YOLO_MODEL_FILE = 학습시킨 파일, 저는 tiny-yolo-obj.pb
  • MODE = DetectorMode.YOLO
  • MINIMUM_CONFIDENCE_YOLO = threshold, 탐지된 물체에서 bounding box를 그리기 위한 confidence
  • MAINTAIN_ASPECT = MODE == DectorMode.YOLO

 

 

이제 TensorFlowYoloDetector.java로 이동합니다. 

  • NUM_CLASSES = 탐지할 물체 수, 저는 1
  • LABLES = {""} 물체 이름, 저는 Bollard

 

 

이제 빌드하시고 어플을 설치하면 정상적으로 작동할 것입니다. 

 

 

[문제해결]

버전 호환 문제가 발생해서 많은 시간 고생했습니다. 아래와 같은 오류 메시지가 나타났습니다.

The name tf.train.RMSPropOptimizer is deprecated. Please use tf.compat.v1.train.RMSPropOptimizer instead.
The name tf.variable_scope is deprecated. Please use tf.compat.v1.variable_scope instead.
The name tf.get_variable is deprecated. Please use tf.compat.v1.get_variable instead.
The name tf.placeholder_with_default is deprecated. Please use tf.compat.v1.placeholder_with_default instead.

...

 

저를 엄청 고생시킨 오류였습니다. 거의 2주 이상을 소비했습니다. 원인은 tensorflow 버전이 달랐기 때문이었습니다. 다음과 같은 상황이었습니다. GTX 1070Ti로 학습시킨 컴퓨터는 데스크탑이었습니다. 그리고 데스크탑에서 얻어진 pb파일을 랩탑으로 옮겨서 안드로이드 스튜디오를 실행했습니다. 문제는 데스트탑과 랩탑의 tensorflow버전이 달랐습니다. 데스크탑은 1.12였고 랩탑은 1.14였습니다. 그래서 어플을 설치하고 실행시키면 오류가 발생해서 바로 종료되었습니다. 그러니 tensorflow 버전을 동일하게 유지해주세요. tensorflow버전을 확인하는 방법은 cmd를 켜서 아래와 같이 입력하면 됩니다:

python
>>> import tensorflow as tf
>>>tf.__version__

 

 

 

다음 포스트에서는 detect의 정확도가 현저하게 낮았던 이유와 이것을 해결한 방법에 대해서 작성하겠습니다.

반응형