Tensorflow: [์งˆ๋ฌธ&์˜ค๋ฅ˜] tensorflow-lite์— SSD-Mobile-net๊ณผ ๊ฐ™์€ ๊ฐ์ง€ ๋ชจ๋ธ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2017๋…„ 12์›” 26์ผ  ยท  141์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: tensorflow/tensorflow

์•ˆ๋…•.

tensorflow-lite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ๋“œ๋กœ์ด๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ.

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/models.md
๊ฒ€์ƒ‰ ๋ชจ๋ธ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ tensorflow-lite-API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SSD-Inceptionv2๋ฅผ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ช…๋ น


bazel run --config=opt --copt=-msse4.1 --copt=-msse4.2 \
  //tensorflow/contrib/lite/toco:toco -- \
  --input_file=/home/danshin/tensorflow_lite/lite_model/fire_incpetion_v2.pb \
  --output_file=/home/danshin/tensorflow_lite/lite_model/fire_inception_v2.lite \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --inference_type=FLOAT \
  --input_shape=1,300,300,3 \
  --input_array=image_tensor \
  --output_array={detection_boxes,detection_scores,detection_classes,num_detections}

์—๋Ÿฌ ์ฝ”๋“œ


2017-12-26 14:59:25.159220: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before general graph transformations: 2029 operators, 3459 arrays (0 quantized)
2017-12-26 14:59:25.251633: F tensorflow/contrib/lite/toco/graph_transformations/resolve_tensorflow_switch.cc:95] Check failed: other_op->type == OperatorType::kTensorFlowMerge 

fire_inception_v2 ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜์ง€๋งŒ ํฌ๊ธฐ๋Š” 0๋ฐ”์ดํŠธ์ž…๋‹ˆ๋‹ค.
๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋˜ํ•œ,
๊ฐœ์ฒด ๊ฐ์ง€๋ฅผ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • ๋ชจ๋ธ์„ ๋ฐฐํฌํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋ˆ„๊ฐ€ ์ข€ ๋„์™€์ฃผ์„ธ์š”!.

๊ฐ์‚ฌ ํ•ด์š”.

lite feature

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

ํ˜„์žฌ tensorflow/contrib/lite/examples/android ์— ์žˆ์Šต๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ์›๋ณธ TF Android ๋ฐ๋ชจ์˜ ๋ณด๋‹ค ์™„์ „ํ•œ ํฌํŠธ์ด๋ฉฐ(Stylize ์˜ˆ์ œ๋งŒ ์—†์Œ) ์•ž์œผ๋กœ tensorflow/contrib/lite/java/demo์˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ๋ฅผ ๋Œ€์ฒดํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋ณ€ํ™˜๋œ TF Lite ํ”Œ๋žซ ๋ฒ„ํผ๋Š” mobilenet_ssd_tflite_v1.zip ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๊ณ  Java ์ถ”๋ก  ๊ตฌํ˜„์€ TFLiteObjectDetectionAPIModel.java ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒ์ž๋ฅผ Java์—์„œ ์ˆ˜๋™์œผ๋กœ ๋””์ฝ”๋”ฉํ•ด์•ผ ํ•˜๊ณ  ์ƒ์ž ์ด์ „ txt ํŒŒ์ผ์„ ์•ฑ ์ž์‚ฐ์— ํŒจํ‚ค์ง•ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์—์„œ ์›๋ž˜ TF ๊ตฌํ˜„๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”„).

TOCO ๋ณ€ํ™˜ ์ค‘์—๋Š” ๋‹ค๋ฅธ ์ž…๋ ฅ ๋…ธ๋“œ(Preprocessor/sub)์™€ ๋‹ค๋ฅธ ์ถœ๋ ฅ ๋…ธ๋“œ(concat,concat_1)๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ๋ž˜ํ”„๊ฐ€ ์žฌ๊ตฌ์„ฑ๋˜๊ฑฐ๋‚˜ TF Lite๊ฐ€ TF ํŒจ๋ฆฌํ‹ฐ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ tflite์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ๋ถ€๋ถ„์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ SSD MobileNet ๋ชจ๋ธ์„ tflite ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ๋ชจ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋น ๋ฅธ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

๋ชจ๋“  141 ๋Œ“๊ธ€

@aselle ์ด ๋ฌธ์ œ๋ฅผ ์ข€ ๋ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”.

์šฐ๋ฆฌ๋Š” ํ˜„์žฌ mobilenet SSD๋ฅผ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ดํ›„์—๋Š” inception ssd). ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์—๋Š” ์™„์ „ํžˆ ์ง€์›๋˜์ง€ ์•Š๋Š” ์ž‘์—…์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์™„๋ฃŒ๋˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ข‹์•„์š”, ์—ฌ๊ธฐ์— ๋น„์Šทํ•œ ์งˆ๋ฌธ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค: https://github.com/tensorflow/tensorflow/issues/14731

ssd-mobilenet์—์„œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๋•Œ๊นŒ์ง€ ์–ผ๋งˆ๋‚˜ ๊ฑธ๋ฆฝ๋‹ˆ๊นŒ?

๊ฐ์‚ฌ ํ•ด์š”,
๋งˆํ‹ด ํŽ˜๋‹ˆ์•…

TensorFlow ์กฐ์ง์˜ ๊ตฌ์„ฑ์›์ด stat:awaiting tensorflower ๋ ˆ์ด๋ธ”์ด ์ ์šฉ๋œ ํ›„ ์‘๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค.

?

์ž”์†Œ๋ฆฌํ•˜๋Š” ๋‹ด๋‹น์ž: 14์ผ ๋™์•ˆ ํ™œ๋™์ด ์—†์—ˆ์œผ๋ฉฐ ์ด ๋ฌธ์ œ์—๋Š” ๋‹ด๋‹น์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์— ๋”ฐ๋ผ ๋ ˆ์ด๋ธ” ๋ฐ/๋˜๋Š” ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค.

์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
์ €๋„ ๋น„์Šทํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

@yucheeling

ํ‹ฐ์…”์ธ , ์ฒญ๋ฐ”์ง€ ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์˜๋ฅ˜ ์‹๋ณ„์„ ์œ„ํ•ด ์†Œ๋งค์ ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” " ssd_mobilenet_v1_coco_2017_11_17.tar "์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ์ œ์•ˆํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@rana3579 , stackoverflow์—์„œ ๊ทธ๋Ÿฐ ์งˆ๋ฌธ์„ ํ•ด์ฃผ์„ธ์š”. mobilenet ssd์— ๋Œ€ํ•œ ๋น ๋ฅธ ์—…๋ฐ์ดํŠธ. ์ด๊ฒƒ์€ ์ง„ํ–‰ ์ค‘์ด๋ฉฐ ๊ณง ์˜ˆ์ œ๊ฐ€ ๋‚˜์˜ค๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@rana3579 ๋‚ด ๋น„๋””์˜ค๋ฅผ ํ™•์ธํ•˜๊ณ  ์ด๊ฒƒ์„ movidius, nvidia gpus ๋ฐ arm ํ”„๋กœ์„ธ์„œ์—์„œ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ํšŒ์‚ฌ์˜ ์ผ์›์ด๋ผ๋ฉด ์ž ์žฌ์ ์ธ ํ˜‘์—…์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://www.youtube.com/watch?v=3MinI9cCJrc

@aselle ์—…๋ฐ์ดํŠธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ด์— ๋Œ€ํ•œ ์•Œ๋ฆผ์€ ์–ด๋””์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ถœ์‹œ๋˜๋Š” ๋Œ€๋กœ ์•Œ๋ ค๋“œ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ๋…ธ๊ณ ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

@andrewharp ๋Š” ์ด ์ž‘์—…์„ ์ง„ํ–‰ ์ค‘์ด๋ฉฐ tflite๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก Java TF ๋ชจ๋ฐ”์ผ ์•ฑ์„ ์—…๋ฐ์ดํŠธํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ €์žฅ์†Œ์—์„œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ง€๊ธˆ์€ ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ๋‚˜ 2์ฃผ ์•ˆ์— ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@andrewharp ๊ต‰์žฅํ•ด!! iOS ์นด๋ฉ”๋ผ ์˜ˆ์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๊นŒ?
๋˜ํ•œ ๋ฌด๊ฒŒ์˜ ํฌ๊ธฐ์™€ ์„ฑ๋Šฅ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?
TFLite ๋ถ„๋ฅ˜ ๋ชจ๋ฐ”์ผ๋„ท์€ ์ž‘๊ณ  iOS์—์„œ์˜ ์„ฑ๋Šฅ์€ ๋งค์šฐ ๋ถ€๋“œ๋Ÿฝ๊ธฐ ๋•Œ๋ฌธ์— TFLite์— ๋Œ€ํ•ด ์ •๋ง ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค.

์ผ๋ถ€๋Š” ์ด๋ฏธ ๊ธฐ์กด SSD Mobilenet pb๋ฅผ coreml ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  Swift์—์„œ ๋ˆ„๋ฝ๋œ ์ถœ๋ ฅ ๋ ˆ์ด์–ด๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/vonholst/SSDMobileNet_CoreML

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ iPhone 7์—์„œ 8-12fps์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•,
์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ €๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค :)

ํ˜„์žฌ ๊ฒ€ํ†  ์ค‘์ธ tflite๋กœ Android TF ๋ฐ๋ชจ๋ฅผ ์ด์‹ํ•˜๋Š” ์ปค๋ฐ‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ์— github์— ํ‘œ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@madhavajay Android ์ „์šฉ์ด์ง€๋งŒ iOS์— ๋งž๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ ์ผํ•œ ๊ฒƒ์€ tflite๊ฐ€ MobileNet SSD์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ์—ฐ์‚ฐ์ž๋ฅผ ์™„์ „ํžˆ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€ ์‚ฌ์ „ ์ฒ˜๋ฆฌ(์ด๋ฏธ์ง€ ํฌ๊ธฐ ์กฐ์ •/์ •๊ทœํ™”) ๋ฐ ์‚ฌํ›„ ์ฒ˜๋ฆฌ(์ตœ๋Œ€๊ฐ€ ์•„๋‹Œ ์–ต์ œ ๋ฐ ์ƒ์ž ์‚ฌ์ „์— ์˜ํ•œ ์กฐ์ •)๊ฐ€ Java์—์„œ ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. .

@andrewharp ๊ต‰์žฅํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ TF lite์—์„œ ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋ฅผ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ผ๋ฐ˜ SSD์˜ tfcoreml ๋ณ€ํ™˜ ๋„๊ตฌ์™€ ๋™์ผํ•œ ๊ฒฝ์šฐ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๊ธฐ์ˆ ์ ์ธ ๊ด€์‹ฌ ๋•Œ๋ฌธ์— ๋ถˆํ‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋ฐ”์ผ ์Šคํƒ์—์„œ ๊ตฌํ˜„ํ•˜๊ธฐ ํŠนํžˆ ์–ด๋ ค์šด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๊นŒ?

Android ์ฝ”๋“œ์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์—„์ฒญ๋‚œ ๋…ธ๋ ฅ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค!!! ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ธฐ๋Œ€ํ•˜๋Š” ์œ ์ผํ•œ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!

@andrewharp ๋ฐ @aselle TFLite ์— ๋Œ€ํ•œ SSD ๊ธฐ๋ฐ˜ ๊ฐœ์ฒด ํ˜„์ง€ํ™” ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ๋ชจ ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ˜„์žฌ tensorflow/contrib/lite/examples/android ์— ์žˆ์Šต๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ์›๋ณธ TF Android ๋ฐ๋ชจ์˜ ๋ณด๋‹ค ์™„์ „ํ•œ ํฌํŠธ์ด๋ฉฐ(Stylize ์˜ˆ์ œ๋งŒ ์—†์Œ) ์•ž์œผ๋กœ tensorflow/contrib/lite/java/demo์˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ๋ฅผ ๋Œ€์ฒดํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋ณ€ํ™˜๋œ TF Lite ํ”Œ๋žซ ๋ฒ„ํผ๋Š” mobilenet_ssd_tflite_v1.zip ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๊ณ  Java ์ถ”๋ก  ๊ตฌํ˜„์€ TFLiteObjectDetectionAPIModel.java ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒ์ž๋ฅผ Java์—์„œ ์ˆ˜๋™์œผ๋กœ ๋””์ฝ”๋”ฉํ•ด์•ผ ํ•˜๊ณ  ์ƒ์ž ์ด์ „ txt ํŒŒ์ผ์„ ์•ฑ ์ž์‚ฐ์— ํŒจํ‚ค์ง•ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์—์„œ ์›๋ž˜ TF ๊ตฌํ˜„๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”„).

TOCO ๋ณ€ํ™˜ ์ค‘์—๋Š” ๋‹ค๋ฅธ ์ž…๋ ฅ ๋…ธ๋“œ(Preprocessor/sub)์™€ ๋‹ค๋ฅธ ์ถœ๋ ฅ ๋…ธ๋“œ(concat,concat_1)๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ๋ž˜ํ”„๊ฐ€ ์žฌ๊ตฌ์„ฑ๋˜๊ฑฐ๋‚˜ TF Lite๊ฐ€ TF ํŒจ๋ฆฌํ‹ฐ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ tflite์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ๋ถ€๋ถ„์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ SSD MobileNet ๋ชจ๋ธ์„ tflite ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ๋ชจ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋น ๋ฅธ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

@andrewharp ํ–‰๋ณตํ•œ ๋ถ€ํ™œ์ ˆ ๐Ÿฅš๐Ÿซ ๋‹น์‹ ์€ ๋ ˆ์ „๋“œ์ž…๋‹ˆ๋‹ค! :) ๋‚ด๊ฐ€ ์ด๊ฒƒ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ํ€€ํƒ€์ด์ฆˆ ๋ฒ„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์œ„์˜ ์ง€์นจ์— ๋”ฐ๋ผ ์ž‘๋™ํ–ˆ์ง€๋งŒ ๋‹ค์Œ์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋‚ด bazel ๋ฒ„์ „์œผ๋กœ ์ธํ•œ Android SDK 15
  • Android Studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค.

@andrewharp ๋Š” Gradle ๋Œ€์‹  bazel์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์ƒˆ๋กœ์šด Android Studio์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์ž‘๋™ํ•˜๋Š” ๋ฐ ์งง์€ ์‹œ๊ฐ„ ํ”„๋ ˆ์ž„ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์ผ๋ถ€ ํ”„๋กœ์ ํŠธ ์„ค์ •์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๋ฉด PR์„ ์ œ๊ณตํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์„ฑ๋Šฅ๊ณผ ๊ด€๋ จํ•˜์—ฌ Android 7์˜ LG G6์—์„œ๋Š” ๋Š๋ฆฐ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
NN API๊ฐ€ Android 8์—๋งŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ธ๊ฐ€์š”?

Android 8์—์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์•Œ์•„, ๋‚˜๋Š” ์ง€์นจ์ด ๋ณ€ํ™˜๋งŒ์„ ์œ„ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‹น์‹ ์ด ๋ชจ๋ธ์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ๋ฌธ์žฅ์˜ ์ฒซ ๋ถ€๋ถ„ ์ดํ›„ ์ฝ๊ธฐ๋ฅผ ์ค‘๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

๋„ค, ํ”ฝ์…€ xl์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ „ํ™”๊ธฐ์— ์ถ”๋ก ์„ ๊ฐ€์†ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜๋“œ์›จ์–ด๊ฐ€ ์—†๊ฑฐ๋‚˜ ํ•ด๋‹น ํ•˜๋“œ์›จ์–ด๊ฐ€ ์†Œํ”„ํŠธ์›จ์–ด์—์„œ ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋ณด๊ณ  ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค doh๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค ...

๋‚ด iPhone์—์„œ ๋ณด๋‚ธ

2018๋…„ 3์›” 31์ผ 20์‹œ 5๋ถ„์— Madhava Jay [email protected] ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์ง€์นจ์— ๋”ฐ๋ผ ์ž‘๋™ํ–ˆ์ง€๋งŒ ๋‹ค์Œ์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด bazel ๋ฒ„์ „์œผ๋กœ ์ธํ•œ Android SDK 15
Android Studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค.
@andrewharp ๋Š” Gradle ๋Œ€์‹  bazel์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์ƒˆ๋กœ์šด Android Studio์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์ž‘๋™ํ•˜๋Š” ๋ฐ ์งง์€ ์‹œ๊ฐ„ ํ”„๋ ˆ์ž„ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์ผ๋ถ€ ํ”„๋กœ์ ํŠธ ์„ค์ •์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๋ฉด PR์„ ์ œ๊ณตํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์„ฑ๋Šฅ๊ณผ ๊ด€๋ จํ•˜์—ฌ Android 7์˜ LG G6์—์„œ๋Š” ๋Š๋ฆฐ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
NN API๊ฐ€ Android 8์—๋งŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ธ๊ฐ€์š”?

Android 8์—์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ๋ณด๊ฑฐ๋‚˜ ์Šค๋ ˆ๋“œ๋ฅผ ์Œ์†Œ๊ฑฐํ•˜์„ธ์š”.

๋„ค, ์ €๋„ ๋˜‘๊ฐ™์ด ํ•˜๊ณ  ๋ฐ”๋กœ ์ฝ”๋“œ์™€ ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค๋กœ ๊ฐ”์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์˜ค๋Š˜ ์•„์นจ์— ๋‹น์‹ ์ด ํ•‘(ping)์„ ๋ณด๋‚ธ ํ›„ ๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๋‹ต์žฅํ•˜๋ ค๊ณ  ํ–ˆ๊ณ  ๋‹ค์‹œ RTFM์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿคฃ

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด LG G6์€ Pixel 1๊ณผ ๋™์ผํ•œ Qualcomm 821 SoC๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— NN API๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ถˆํ–‰ํžˆ๋„ LG๋Š” Android 8 ๋˜๋Š” 8.1์„ ์ถœ์‹œํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์ตœ์‹  LineageOS ๋นŒ๋“œ๋Š” ์•ฝ๊ฐ„ ๊ฐœ๋žต์ ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด Android 8.1์—์„œ ๋” ์ž˜ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•œ๋‹ค๋ฉด ๋ณด๋ฅ˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. Pixel์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ๋ฉ‹์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค! ๐Ÿ‘

๋‚˜๋Š” ์ด๊ฒƒ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ๋ฐ๋ชจ๋Š” ์ •๋ง ๋Š๋ฆฌ๊ฒŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์›๋ž˜ ๋ฒ„์ „๋ณด๋‹ค ๋” ๋Š๋ฆฝ๋‹ˆ๋‹ค.
์ €๋Š” Pixel XL(์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „)์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด์ „์— 64๋น„ํŠธ ์•„์น˜์šฉ ์ด์ „ ๋ฐ๋ชจ๋ฅผ ์ปดํŒŒ์ผํ–ˆ๋Š”๋ฐ, ์ด๋Š” tfLite ์—†์ด๋„ ๊ฑฐ์˜ 2๋ฐฐ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค... ์ด ๊ฒฝ์šฐ ์ถ”๋ก  ์‹œ๊ฐ„์€ ์•ฝ 450ms์ž…๋‹ˆ๋‹ค. ์ด ๋ฐ๋ชจ๋ฅผ ์‹œ๋„ํ•  ๋•Œ ์•ฝ 850ms์—์„œ ์‹คํ–‰๋˜๋ฉฐ ๋•Œ๋กœ๋Š” 1์ดˆ ์ด์ƒ ์‹คํ–‰๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ์ž˜๋ชป ํ–ˆ์Šต๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์ ์ ˆํ•œ ์†๋„ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•˜๊ธฐ ์œ„ํ•ด ์ง€๋‚˜์น˜๊ฒŒ ๋‚™๊ด€์ ์ด์—ˆ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”.

@mpeniak ๋””๋ฒ„๊ทธ ์ผœ๊ธฐ ๋˜๋Š” ๋„๊ธฐ๋กœ LG G6์—์„œ ๋™์ผํ•œ ์†๋„๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค(์ฒ˜์Œ์—๋Š” ๋””๋ฒ„๊ทธ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค). NNAPI๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. nnapi_lib ๋นŒ๋“œ๋กœ ๋ญ”๊ฐ€ ํŠน๋ณ„ํ•œ ๊ฒƒ์„ ํ•ด์•ผ ํ• ๊นŒ์š”?
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/BUILD

์ข…์†์„ฑ์ด ๋‚˜์—ด๋˜์–ด ์žˆ์ง€๋งŒ ํŠน์ • ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•œ ๋นŒ๋“œ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์•„๋งˆ๋„ ./configure์— ์žˆ๋Š” ๊ฒƒ
(btw ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ ์†๋„๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ./configure์—์„œ XLA๋ฅผ ํ™œ์„ฑํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค)

@andrewarp
NNAPI๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€๋ฐ ์‚ฌ์šฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด Neural Networks API๋Š” Android 8.1์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. >
8.1์ด์ƒ์ด๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉ๋˜๋‚˜์š”? ๋˜๋Š” ์ถ”๊ฐ€ NDK ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ๋ฌธ์„œ ๋งํฌ
์ข‹์€ ํ•˜๋ฃจ ๋˜์„ธ์š” XD

@andrewharp , tflite_demo์šฉ NNAPI๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  apk๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ apk๊ฐ€ ์ถฉ๋Œํ•œ ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.
AddOpsAndParams๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ tflite::BuiltinOperator_SQUEEZE ์ž‘์—…์€ ์ง€์›๋˜์ง€ ์•Š์œผ๋ฉฐ
nn_op_type์€ -1๋กœ ์„ค์ •๋˜์–ด FATAL์ด ํ˜ธ์ถœ๋˜๊ณ  exit(-1)์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค
๊ทผ๋ณธ ์›์ธ. ํ–ฅํ›„ ๋ฒ„์ „์—์„œ ์ง€์›๋  ๊ฒƒ์ธ์ง€ ๋ง์”€ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‹ค๋ฅธ ์ž‘์—… ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?
NNAPI ๊ฒฝ๋กœ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด? ๊ฐ์‚ฌ ํ•ด์š”.

@andrehentz
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=True \
--input_names=์ „์ฒ˜๋ฆฌ๊ธฐ/ํ•˜์œ„ --output_names=concat,concat_1 \
--๋˜ํ•œlogtostderr

input_names image_tensor๊ฐ€ ์•„๋‹Œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
์ด ๋ฐฉ๋ฒ•์„ ์‹œ๋„ํ–ˆ๋Š”๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

@๋‚˜๋‚˜๋งˆ๋ ˆ
frozen_inference_graph.pb ๋Œ€์‹  frozen_inference_graph_stripped.pb๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
"bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=frozen_inference_graph_stripped.pb" ์‹œ๋„
๋‹ค์Œ ์ถœ๋ ฅ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1๊ฐœ์˜ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค: (์ด๋ฆ„=์ „์ฒ˜๋ฆฌ๊ธฐ/ํ•˜์œ„, ์œ ํ˜•=float(1), ๋ชจ์–‘=์—†์Œ)
๋ณ€์ˆ˜๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
2๊ฐœ์˜ ๊ฐ€๋Šฅํ•œ ์ถœ๋ ฅ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. (name=concat, op=ConcatV2) (name=concat_1, op=ConcatV2)

์ž…๋ ฅ ์ด๋ฆ„์€ ์ „์ฒ˜๋ฆฌ๊ธฐ/ํ•˜์œ„ abd ์ถœ๋ ฅ ์ด๋ฆ„์€ concat์ž…๋‹ˆ๋‹ค.

@๋‚˜๋‚˜๋งˆ๋ ˆ
์ตœ์‹  tensorflow lite ์ฝ”๋“œ์—๋Š” NNAPI๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” Java ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ์ธํ„ฐํ”„๋ฆฌํ„ฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. setUseNNAPI(true);
์ด๋Ÿฌํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@zhangbo0325
์ด๋ฏธ setUserNNAPI(true);๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
NNAPI๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ฑฐ์˜ ์œ ์‚ฌํ•œ ์ถ”๋ก ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
์•ˆ๋“œ๋กœ์ด๋“œ ์‚ฌ์–‘: 8.1 ๋ฒ„์ „.

@nanamare , ์‹คํ–‰ ์ค‘์ธ ssd-mobilenet์ž…๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ๋„คํŠธ์›Œํฌ์—๋Š” Android NNAPI์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” SQUEEZE ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ ์งˆ๋ฌธ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. mobilenet-v1์˜ ๊ฒฝ์šฐ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

<strong i="5">@andrewharp</strong>  Hi, andrewharp. i just followed your quick steps for converting an SSD MobileNet model to tflite format, and then i tried to  build the demo to use it. But something accurred in apk.
for the tflite from mobilenet_ssd_tflite_v1.zip, everything is ok! i can use mobile to detecter things.
And then i tried to use pet data to fine tune the model from the checkpoint in mobilenet_ssd_tflite_v1.zip. this process is also ok. i check the generated frozen_inference_graph.pb with the object_detection_tutorial.ipynb(https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb). the result shown this pb can used to object detection. And then i followed the script to convert frozen pb to tflite. Then build demo with tflite, unfortunately something wrong ocurred. Then log is written below. 
It seems the Shape of output target [1, 1917, 4] does not match with the shape of the Tensor [1, 1917, 1, 4]. Because i am new to use object detection api, i donot know how to deal with the problem. 
Hope you can point out some solutions, Thx!

์—ฌ๊ธฐ์—์„œ ๋ชจ๋ฐ”์ผ ๋กœ๊ทธ:
04-04 19:46:36.099 28864-28882/org.tensorflow.lite.demo E/AndroidRuntime: ์น˜๋ช…์ ์ธ ์˜ˆ์™ธ: ์ถ”๋ก  ํ”„๋กœ์„ธ์Šค: org.tensorflow.lite.demo, PID: 28864 java.lang.IllegalArgumentException: ์ถœ๋ ฅ ๋Œ€์ƒ์˜ ๋ชจ์–‘ [1, 1917, 4]๋Š” Tensor [1, 1917, 1, 4]์˜ ๋ชจ์–‘๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. org.tensorflow.lite.Tensor.copyTo(Tensor.java:44) org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:139) org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java: ) org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:248) at android.os.Handler.handleCallback(Handler.java:761) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.HandlerThread.run(HandlerThread.java:61)์˜ android.os.Looper.loop(Looper.java:156)

๋†€๋ผ์šด! iOS์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. Tensor ์ถœ๋ ฅ์„ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ฉ๋‹ˆ๊นŒ?

interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);

DetectorActivity ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋‚ด ํ”„๋กœ์ ํŠธ์— ๊ฐ‡ํ˜”์Šต๋‹ˆ๋‹ค. ์กด์žฌํ•ฉ๋‹ˆ๊นŒ? ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@zhangbo0325 ์ž์„ธํ•œ ๋‚ด์šฉ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์Šคํ€ด์ฆˆ๊ฐ€ NNAPI์—์„œ ์ง€์›๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— NNAPI๊ฐ€ ์ „ํ˜€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์ถ”๋ก ์ด ๊ทธ๋Œ€๋กœ ๋Š๋ฆฐ ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๊นŒ? ์ด์ „ ๋Œ“๊ธ€์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด Pixel XL์—์„œ ์„ฑ๋Šฅ์ด ์ •๋ง ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€๋žต 80-120ms ์ •๋„์˜ ์ถ”๋ก  ์‹œ๊ฐ„์„ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

@mpeniak , ๋‚˜๋Š” andrewharp์—๊ฒŒ ๊ฐ™์€ ์งˆ๋ฌธ์„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐฉ๊ธˆ tensorflow-lite cpu ๊ตฌํ˜„์˜ ๋„์›€์œผ๋กœ ssd-mobilenet์„ ์‹คํ–‰ํ–ˆ์ง€๋งŒ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Dev Summit 2018์—์„œ TensorFlow Lite๋Š” MobileNet์—์„œ 3๋ฐฐ์˜ ์„ฑ๋Šฅ์„ ๋ณด์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
https://youtu.be/FAMfy7izB6A?t=530

SSD์šฉ์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋จผ์ € ๊ฐ€์ค‘์น˜ ์–‘์žํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” mobilnet์„ ์‹œ๋„ํ–ˆ๊ณ  ํ›จ์”ฌ ๋น ๋ฅด์ง€ ๋งŒ ์ด๊ฒƒ์€ mobilnet-ssd์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ...

์Šฌํ”ˆ ํŒ๋‹ค โ˜น๏ธ๐Ÿผ
@andrewharp ๊ณ ์„ฑ๋Šฅ SSD ๊ตฌํ˜„์ด ์–ธ์ œ ๊ฐ€๋Šฅํ• ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ€์ค‘์น˜ ์–‘์žํ™”์˜ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

๋˜ํ•œ TensorFlowLite์—์„œ ssd-mobilenet์˜ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ, ๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์˜ ์ ์ˆ˜๊ฐ€ 1์„ ์ดˆ๊ณผํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ํ™•๋ฅ  ์•„๋‹Œ๊ฐ€?

@a1103304122 ์ œ๊ฐ€ ์•Œ๊ธฐ๋กœ๋Š” ์ ์ˆ˜๋Š” softmax ์ด์ „์— ๋…ธ๋“œ "concat"์˜ ์ถœ๋ ฅ์ด๋ฏ€๋กœ ํ™•๋ฅ ์ด ์•„๋‹™๋‹ˆ๋‹ค.

TOCO ๋ณ€ํ™˜ ์ค‘์—๋Š” ๋‹ค๋ฅธ ์ž…๋ ฅ ๋…ธ๋“œ(Preprocessor/sub)์™€ ๋‹ค๋ฅธ ์ถœ๋ ฅ ๋…ธ๋“œ(concat,concat_1)๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ๋ž˜ํ”„๊ฐ€ ์žฌ๊ตฌ์„ฑ๋˜๊ฑฐ๋‚˜ TF Lite๊ฐ€ TF ํŒจ๋ฆฌํ‹ฐ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ tflite์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ๋ถ€๋ถ„์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

์ด ๋ชจ๋ธ์—์„œ TFlite๊ฐ€ TFmobile๋ณด๋‹ค ๋Š๋ฆฐ ์ด์œ ๋ฅผ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@andrewharp TF Lite SSD์˜ ์„ฑ๋Šฅ์— ๋Œ€ํ•ด ๋…ผํ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ ์–‘์žํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ / ์˜ค๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์—ฌ๋Ÿฌ๋ถ„์ด ์ด ๋ชจ๋“  ์ผ์ด ์ผ์–ด๋‚˜๋„๋ก ์—ด์‹ฌํžˆ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ๋‹จ๊ธฐ์ ์ธ ๋ฌธ์ œ์ธ์ง€ ์•„๋‹ˆ๋ฉด ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์†”๋ฃจ์…˜์ด ์žˆ๋Š”์ง€ ์•„๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๐Ÿ˜„

@andrewharp ์ข‹์€ ํฌ์ŠคํŒ… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ท€ํ•˜์˜ ๋‹จ๊ณ„์— ๋Œ€ํ•ด ํ•œ ๊ฐ€์ง€ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

TOCO์—์„œ graphdef๋ฅผ ๋ณด๊ธฐ ์ „์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค.

bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=True \
--input_names=์ „์ฒ˜๋ฆฌ๊ธฐ/ํ•˜์œ„ --output_names=concat,concat_1 \
--๋˜ํ•œlogtostderr

์ œ๊ฐ€ ์ž˜๋ชป ์ดํ•ดํ•œ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด ์—ฌ๊ธฐ์—์„œ STRIPPED_PB๋ฅผ ํ”„๋กœ๋“€์Šคํ•˜๊ณ  ์‹ถ์œผ์‹œ์ฃ ? ๊ทธ๋ ‡๋‹ค๋ฉด ํ˜„์žฌ ์ž…๋ ฅ ํŒŒ์ผ์˜ ์ž…๋ ฅ์€ image_tensor์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๊ฐ€ ์ „์ฒ˜๋ฆฌ๊ธฐ/์„œ๋ธŒ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋ฅผ ์ž˜ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋‘˜์งธ, ์—ฌ๊ธฐ์„œ optimize_for_inference๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. transform_graph ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ƒˆ๋กœ์šด tensorflow ๋ฌธ์„œ๋Š” optimize_for_inference ๋Œ€์‹  transform_graph๋ฅผ ๊ถŒ์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@mpeniak ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”? ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๋ง์”€ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

org.tensorflow.lite.demo E/AndroidRuntime: ์น˜๋ช…์  ์˜ˆ์™ธ: ์ถ”๋ก  ํ”„๋กœ์„ธ์Šค: org.tensorflow.lite.demo, PID: 28864 java.lang.IllegalArgumentException: ์ถœ๋ ฅ ๋Œ€์ƒ์˜ ๋ชจ์–‘[1, 1917, 4]์ด(๊ฐ€) ๋‹ค์Œ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ…์„œ์˜ ๋ชจ์–‘ [1, 1917, 1, 4].

@Haijunlv ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์…จ๋‚˜์š”? ์†”๋ฃจ์…˜์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

TF Lite ์ƒˆ Android ๋ฐ๋ชจ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ OS X์—์„œ Error:Plugin with id 'com.android.application' not found. ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

@csmith105 ์™€ ๊ฐ™์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค! bazel์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ๋ชจ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ Android Studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@Eddy-zheng ์ •์ง€๋œ ๊ทธ๋ž˜ํ”„์—์„œ "concat" ๋…ธ๋“œ๋ฅผ ๋ณธ ๊ฒฝ์šฐ concat op ๋‹ค์Œ์— squeeze op๊ฐ€ ์‹คํ–‰๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜•ํƒœ๊ฐ€ ์–ด์šธ๋ฆฌ์ง€ ์•Š๋Š” ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์Šคํ€ด์ฆˆ ์—ฐ์‚ฐ์˜ ์†๋„๋ฅผ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. ์••์ฐฉ ๋ฐ ์—ฐ๊ฒฐ ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ssd_meta_arch.py์—์„œ " box_encodings = tf.squeeze(tf.concat(prediction_dict['box_encodings'], axis=1), axis=2)"๋ฅผ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  2. ์ถ• 2์—์„œ ๋ชจ์–‘ 1์„ ์ง์ ‘ ์ฃฝ์ž…๋‹ˆ๋‹ค. box_predictor.py์—์„œ " box_encodings =tf.reshape(
    box_encodings, tf.stack([combined_feature_map_shape[0],
    Combined_feature_map_shape[1] *
    Combined_feature_map_shape[2] *
    num_predictions_per_location,
    1, self._box_code_size]))"

์‚ฌ์‹ค ๋‚˜๋Š” ์™œ ํ…์„œ๋ฅผ ์—ฌ๋ถ„์˜ "1"๋ชจ์–‘์œผ๋กœ ์žฌ๊ตฌ์„ฑํ•˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ค‘๋ณต์ผ์ˆ˜๋„
op.
๋‚˜๋Š” ๋ฐฉ๋ฒ• 1์„ ์‹œ๋„ํ•˜๊ณ  ๋ชจ๋ฐ”์ผ์—์„œ ๋ชจ๋ธ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์กฐ๊ธˆ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋” ๋‚˜์€ ์†๋„๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฉ๋ฒ• 2๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค

@Haijunlv ๊ฐ์ง€๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ข‹์€๊ฐ€์š”? @andrewharp ๋ฐ๋ชจ์˜ ๋ผ์ดํŠธ ๋ชจ๋ธ์€ ๊ทธ๋ž˜ํ”„์—์„œ ๋ชจ๋“  ์ „์ฒ˜๋ฆฌ ๋ฐ ํ›„์ฒ˜๋ฆฌ ๋…ธ๋“œ(์ˆ˜์ฒœ ๊ฐœ)๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์—ฌ๋Ÿฌ ์ค„์˜ ์ฝ”๋“œ๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”..

android studio์™€ gradle ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. (์ œ๊ฐ€ ํ‹€๋ ธ๊ฑฐ๋‚˜ ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋‹ค๋ฉด ์ €๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ์„ธ์š”):

  • ์ตœ์„ ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์•„๋‹ˆ์ง€๋งŒ Gradle์„ "๋Œ€์ฒด"ํ•˜๊ธฐ ์œ„ํ•ด Android Studio ๋‚ด๋ถ€์— ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š” Bazel ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ์œผ๋ฉฐ AS๋ฅผ ํ†ตํ•ด Bazel์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‚˜๋Š” Bazel์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ๊ธฐ์‚ฌ๋ฅผ ์ฝ์—ˆ๊ณ  Quora์—์„œ ์ด ์งˆ๋ฌธ ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ต๋ณ€์— ๋”ฐ๋ฅด๋ฉด tensorflow๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋” ์ž˜ ํ™œ์šฉํ•˜๊ณ  ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— Bazel์„ ๊ณ„์† ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํŠน์ • ๊ฒฝ์šฐ์˜ ๊ฐœ๋ฐœ์ž๋กœ์„œ ์šฐ๋ฆฌ๋Š” ์ ์‘ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค tensorflow๊ฐ€ ์™„์ „ํžˆ ์ง€์›ํ•  ๋•Œ๊นŒ์ง€ Gradle์„ ๊ทธ๋Œ€๋กœ ๋‘์‹ญ์‹œ์˜ค.

@davidfant
TensorFlow Lite C++์—์„œ ์—ฌ๋Ÿฌ ์ถœ๋ ฅ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ?

interpreter->Invoke();
???? output = interpreter->typed_output_tensor<?????>(0);

์ง„ํ–‰ ์ค‘์ด์ง€๋งŒ ์—ฌ์ „ํžˆ C++์—์„œ ์ถœ๋ ฅ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ํ˜„์žฌ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ ์ˆ˜๋ฅผ ์–ป์œผ๋ ค๋ฉด ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์— ์–ด๋–ป๊ฒŒ ์•ก์„ธ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

(fill inputs)
.......
intepreter->Invoke();
const std::vector<int>& results = interpreter->outputs();
TfLiteTensor* outputLocations = interpreter->tensor(results[0]);
TfLiteTensor* outputClasses   = interpreter->tensor(results[1]);
float *data = tflite::GetTensorData<float>(outputClasses);
for(int i=0;i<NUM_RESULTS;i++)
{
   for(int j=1;j<NUM_CLASSES;j++)
   {
      float score = expit(data[i*NUM_CLASSES+j]); // ยฟ?
    }
}

@JaviBonilla ๋‚˜๋Š” ๋น„์Šทํ•œ ์ผ์„ํ–ˆ๊ณ  ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. Android ๋ฐ๋ชจ ์•ฑ์˜ ์ปท์˜คํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋„ˆ๋ฌด ๋งŽ์€ ๋…ธ์ด์ฆˆ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ํ…์„œ๋ณด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๋ฅผ ์ฝ์œผ๋ฉด ๋ผ์ดํŠธ ๋ชจ๋ธ์ด ์ˆ˜์ฒœ ๊ฐœ์˜ ํ›„์ฒ˜๋ฆฌ ๋…ธ๋“œ๋ฅผ ํ”„๋ฃจ๋‹ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์˜ ๋ฐฉ์‹์ด ํ†ตํ•˜์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์•„์š”. ๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ํ•ดํ‚น์„ ์š”๊ตฌํ•˜๋Š” ๋Œ€์‹  tensorflow lite๊ฐ€ ๋ฏธ๋ž˜์— ์ด๋Ÿฌํ•œ ํ›„์ฒ˜๋ฆฌ ๋…ธ๋“œ๋ฅผ ์ง€์›ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@YijinLiu ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ €์žฅ์†Œ tf-cpu๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ๋‚ด ๊ตฌํ˜„์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜๊ณ  ์ข‹์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@JaviBonilla C++๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ฒŒ ๋˜๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”! ๐Ÿ™Œ

์•ˆ๋…•ํ•˜์„ธ์š” @davidfant ์ž…๋‹ˆ๋‹ค .

์•„์ง ํ…Œ์ŠคํŠธํ•ด์•ผํ•˜์ง€๋งŒ @YijinLiu๋Š” ์ด๋ฏธ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค!.

๊ทธ์˜ ์ €์žฅ์†Œ(https://github.com/YijinLiu/tf-cpu)๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค. ํŠนํžˆ Interpreter->Invoke() ๋‹ค์Œ์— ์‹คํ–‰๋˜๋Š” tf-cpu/benchmark/obj_detect_lite.cc ํŒŒ์ผ, AnnotateMat() ํ•จ์ˆ˜์—์„œ ์ถœ๋ ฅ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@JaviBonilla ๋‚˜๋Š” obj_detect_lite.cc๋ฅผ ๋๋‚ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ํƒ์ง€ ์ƒ์ž๋ฅผ ๋””์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์ „์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์ฐพ์€ ๊ฒƒ์€ ์ ์ˆ˜๊ฐ€ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ์†Œ์Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์ผ๋ถ€ ์ข‹์€ ๊ฐ์ง€ ๊ธฐ๋Šฅ์ด ์†์‹ค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ค‘๊ฐ„ ์ ์ˆ˜๋ฅผ ์ตœ์ข… ๊ฐ€๋Šฅ์„ฑ ์ ์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ˆ˜์ฒœ ๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ...

@YijinLiu ์ด๋ฅผ ๋ช…ํ™•ํžˆ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด TensorFlow Lite์— ๊ฐ์ฒด ๊ฐ์ง€๋ฅผ ์œ„ํ•ด ๋” ๋งŽ์€ ๊ฐœ์„  ์‚ฌํ•ญ์ด ํฌํ•จ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์‹œ๊ฐ„์ด ์žˆ์œผ๋ฉด C++๋กœ ํƒ์ง€ ์ƒ์ž๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @andrewharp ์ž…๋‹ˆ๋‹ค .

์ƒˆ๋กœ์šด Android ๋ฐ๋ชจ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ tensorflow lite๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก tensorflow/contrib/lite/examples/android ์— readme.md ๋˜๋Š” ์„ค๋ช… ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค~!

์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” ssd_mobilenet_v1_coco_2017_11_17 ๋ฐ๋ชจ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰ํ–ˆ๊ณ  ๋ฏธ์„ธ ์กฐ์ •๋œ ๋ชจ๋ธ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. @andrehentz ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
bazel run tensorflow/contrib/lite/toco:toco -- --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub --output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์—ฐ์‚ฐ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์ „: 586๊ฐœ์˜ ์—ฐ์‚ฐ์ž, 871๊ฐœ์˜ ๋ฐฐ์—ด(0๊ฐœ ์–‘์žํ™”)
2018-06-12 15:29:54.273221: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] ์ผ๋ฐ˜ ๊ทธ๋ž˜ํ”„ ๋ณ€ํ™˜ ์ด์ „: ์—ฐ์‚ฐ์ž 586๊ฐœ, ๋ฐฐ์—ด 871๊ฐœ(์–‘์žํ™” 0๊ฐœ)
2018-06-12 15:29:54.300213: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] ์ผ๋ฐ˜ ๊ทธ๋ž˜ํ”„ ๋ณ€ํ™˜ ํ†ต๊ณผ ํ›„ 1: 409 ์—ฐ์‚ฐ์ž, 688 ๋ฐฐ์—ด(0 ์–‘์žํ™”)
2018-06-12 15:29:54.309735: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] ์—ญ์–‘์žํ™” ์ „ ๊ทธ๋ž˜ํ”„ ๋ณ€ํ™˜: ์—ฐ์‚ฐ์ž 409๊ฐœ, ๋ฐฐ์—ด 688๊ฐœ(์–‘์žํ™” 0๊ฐœ)
2018-06-12 15:29:54.317395: I tensorflow/contrib/lite/toco/allocate_transient_arrays.cc:329] ์ „์ฒด ์ž„์‹œ ๋ฐฐ์—ด ํ• ๋‹น ํฌ๊ธฐ: 2880256๋ฐ”์ดํŠธ, ์ด๋ก ์ƒ ์ตœ์ ๊ฐ’: 2880128๋ฐ”์ดํŠธ.
2018-06-12 15:29:54.319173: F tensorflow/contrib/lite/toco/tflite/export.cc:330] ๋ชจ๋ธ์˜ ์ผ๋ถ€ ์—ฐ์‚ฐ์ž๋Š” ํ‘œ์ค€ TensorFlow Lite ๋Ÿฐํƒ€์ž„์—์„œ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ๊ตฌํ˜„์ด ์žˆ๋Š” ๊ฒฝ์šฐ --allow_custom_ops๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ tf.contrib.lite.toco_convert()๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ allow_custom_ops=True๋ฅผ ์„ค์ •ํ•˜์—ฌ ์ด ์˜ค๋ฅ˜๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ๊ตฌํ˜„์ด ํ•„์š”ํ•œ ์—ฐ์‚ฐ์ž ๋ชฉ๋ก์€ RSQRT, SquaredDifference, Stack, TensorFlowShape์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ๋‚ด ๋ชจ๋ธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. https://drive.google.com/open?id=1IxRSU4VSmVmhUtUpSQew_5anEfxTg3Ca

์•„๋ฌด๋„ ๋‚˜๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
@andrehentz

@JaviBonilla ๋ฐ @YijinLiu Google์˜ ๋ฏธ๋ฆฌ ํฌํ•จ๋œ SSD MobileNet V{1,2} ๋ฐ SSDLite MobileNet V2 ๋ชจ๋ธ๋กœ ํ…Œ์ŠคํŠธํ•œ Python ๊ตฌํ˜„ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๊ฐ„๋‹จํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

@freedomtan ์–ด๋–ค ๋ฒ„์ „์˜ tf๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ๋‹ˆ๊นŒ? tf 1.8?

tflite ์ธํ„ฐํ”„๋ฆฌํ„ฐ Python ๋ฐ”์ธ๋”ฉ ํ›„ @hengshanji ๋งˆ์Šคํ„ฐ ๋ถ„๊ธฐ(29c129c6). ๋‚˜๋Š” 1.8์— ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@freedomtan tf1.8์—๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ Python ๋ฐ”์ธ๋”ฉ์ด ์žˆ์ง€๋งŒ "nnapi ์˜ค๋ฅ˜: ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ libneuralnetworks.so๋ฅผ ์—ด ์ˆ˜ ์—†์Œ"๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด .so๋ฅผ ์–ด๋””์„œ ์–ป๊ฑฐ๋‚˜ ์–ด๋–ป๊ฒŒ ์ƒ์„ฑํ•ฉ๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”.

๋ฌด์‹œํ•˜์„ธ์š” :) ์•ˆ๋“œ๋กœ์ด๋“œ NNAPI์šฉ์ž…๋‹ˆ๋‹ค.

@freedomtan ์žฅ์น˜ ๋˜๋Š” PC์—์„œ ์˜ˆ์ œ๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๊นŒ? PC์—์„œ ํ…Œ์ŠคํŠธํ•  ๋•Œ android-28/x86 libneuralnetworks.so๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด "tflite์—์„œ ์‹คํŒจ๋ฅผ ๋ฐ˜ํ™˜ํ•œ ์ดํ›„ ์ค‘๋‹จ ์ค‘" ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด, ๊ทธ NNAPI ๋ฌธ์ œ๋ฅผ ๋ฌด์‹œํ•˜์‹ญ์‹œ์˜ค. libneuralnetwork.so ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. Ubuntu๋ฅผ ์‹คํ–‰ํ•˜๋Š” x86๊ณผ Debian์„ ์‹คํ–‰ํ•˜๋Š” ARMv8 ๋ณด๋“œ ๋ชจ๋‘์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

@freedomtan , ์ฝ”๋“œ์™€ ๋ฌธ์„œ๋ฅผ ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ €์žฅ์†Œ ๊ธฐ๋ฐ˜(https://github.com/YijinLiu/tf-cpu). ์ถœ๋ ฅ์„ ์–ป๊ธฐ ์œ„ํ•ด tf-cpu/benchmark/obj_detect_lite.cc๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. AnnotateMat() ํ•จ์ˆ˜์—์„œ output_locations๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด decodeCenterSizeBoxes ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด nm๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
๋™์‹œ์— https://github.com/tensorflow/tensorflow/issues/14688 ์„ ์‚ฌ์šฉํ•˜์—ฌ libtensorflow-lite.a๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Ubuntu๋ฅผ ์‹คํ–‰ํ•˜๋Š” x86๊ณผ ssdlite_mobilenet_v2_coco_2018_05_09์˜ tflite ๋ชจ๋ธ์ด ์žˆ๋Š” Android ์žฅ์น˜ ๋ชจ๋‘์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. tar.gz.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@WeiboXu ์—ฌ๊ธฐ์—์„œ ์ฝ”๋“œ์™€ ๋ชจ๋ธ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

obj_detect_lite.cc์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
obj_detect_lite.cc.zip

๋ชจ๋ธ์€ http://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz ์ž…๋‹ˆ๋‹ค.

@freedomtan ํŒŒ์ด์ฌ ๊ตฌํ˜„ ์ฝ”๋“œ์—๋Š” "/tmp/box_priors.txt" ํŒŒ์ผ์ด ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ์ด ํŒŒ์ผ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ณ„์‚ฐ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? 300X300 ์‚ฌ์ด์ฆˆ์˜ ์ด๋ฏธ์ง€๋Š” ์ถ”๋ก ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋‚˜, 224X224 ์‚ฌ์ด์ฆˆ์˜ ์ด๋ฏธ์ง€๋Š” ์ถ”๋ก ์„ ํ•˜๋ฉด ์ถ”๋ก  ์ •ํ™•๋„๊ฐ€ ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.

@freedomtan , @andrewharp , ์ตœ์‹  TFLite ๋ฐ๋ชจ์˜ tflite ๋ชจ๋ธ์—๋Š” 4๊ฐœ์˜ ์ถœ๋ ฅ์ด ํ•„์š”ํ•˜์ง€๋งŒ ์ด์ „ ๋ชจ๋ธ์—๋Š” 2๊ฐœ์˜ ์ถœ๋ ฅ๋งŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ง€์นจ ์„ ๋”ฐ๋ฅด๋Š” ์ด์ „ ๋ชจ๋ธ ์€ ์ตœ์‹  TFLite ๋ฐ๋ชจ ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ, ์—ฐ๊ฒฐ1).

๋„์™€์ฃผ์„ธ์š”, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ด ์ง€์นจ์€ ํ˜„์žฌ ์—…๋ฐ์ดํŠธ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ์— ์—…๋ฐ์ดํŠธ๋œ ์ง€์นจ์— ๋Œ€ํ•œ ๋งํฌ๋ฅผ ์ œ๊ณตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

@frontword /tmp/box_priors.txt ์— ์žˆ๋Š” ๊ฒƒ์€ ์‚ฌํ›„ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ƒ์ž์ž…๋‹ˆ๋‹ค. @WenguoLi ๊ฐ€ ์–ธ๊ธ‰ํ•œ ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ์ด๋Ÿฌํ•œ ํ›„์ฒ˜๋ฆฌ ์ž‘์—…์€ TF Lite ์‚ฌ์šฉ์ž ์ง€์ • ์ž‘์—…์œผ๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ๋…ธ๋ ฅ ์—†์ด๋Š” NNAPI ๊ฐ€์†๊ธฐ๋กœ ๊ฐ€์†ํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ํฌ๊ธฐ ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ ๋„ค, 224x224 ์ด๋ฏธ์ง€๋ฅผ SSD300(Google์—์„œ ์ถœ์‹œํ•œ ๋ชจ๋ธ์€ 300x300 ์ด๋ฏธ์ง€๋กœ ํ›ˆ๋ จ)์— ๊ณต๊ธ‰ํ•˜๊ณ  ์ •ํ™•๋„๊ฐ€ ๋” ๋‚˜๋น ์ง€๋Š” ๊ฒƒ์€ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ผ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@WenguoLi ๋ง์”€ํ•˜์‹  ์—…๋ฐ์ดํŠธ๋œ ๋ชจ๋ธ์€ ๋‹ค๋ฃจ๊ธฐ ๋งค์šฐ ์‰ฌ์šด ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด ์—…๋ฐ์ดํŠธ ์Šคํฌ๋ฆฝํŠธ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ๋‹ค์Œ ๊ทธ๋ฆผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

python  tensorflow/contrib/lite/examples/python/object_detection.py --image /tmp/image2.jpg  --show_image True

image

1์„ ์ดˆ๊ณผํ•˜๋Š” ์ถ”๋ก  ๊ฒฐ๊ณผ์˜ ์ ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด Java ๋ฉ”์„œ๋“œ TrackedObject.getCurrentCorrelation()์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•ญ์ƒ 1๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์ •ํ™•ํ•œ์ง€ ์—ฌ๋ถ€๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์Œ). TFLite Android ์˜ˆ์ œ๋Š” ํ•ญ์ƒ 1๋ณด๋‹ค ํฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” Recognition.getConfidence()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@mpeniak Movidius ์—์„œ ssd mobilenet tflite ๋ชจ๋ธ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €๋„ ๋น„์Šทํ•œ ์ผ์„ ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•˜์…จ๋Š”์ง€ ์•ˆ๋‚ด ์ข€ ๋ถ€ํƒ๋“œ๋ ค๋„ ๋ ๊นŒ์š”?

@achowdhery ์•ˆ๋…•ํ•˜์„ธ์š”, ์—ฌ๊ธฐ(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/examples/android/app)์—์„œ ์ตœ์‹  Android ๋ฐ๋ชจ์— ๋Œ€ํ•œ ๋นŒ๋“œ ์ง€์นจ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ณด์•˜์ง€๋งŒ ๊ณ ์ •๋œ pb ๋ชจ๋ธ์„ tflite ๋ชจ๋ธ(์ตœ์‹  ๋ฐ๋ชจ์—์„œ ์‚ฌ์šฉ๋œ ์–‘์žํ™”๋œ detect.tflite)๋กœ ์‹ค์ œ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์–‘์žํ™”๋œ ๋ชจ๋ธ ๋ณ€ํ™˜ ํ๋ฆ„์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ง€์นจ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ ์—ฌ๊ธฐ(https://www.tensorflow.org/performance/quantization)์—์„œ ์ง€์‹œํ•œ ๋Œ€๋กœ ๊ฐ€์งœ ์–‘์žํ™” ์—ฐ์‚ฐ์œผ๋กœ ์–‘์žํ™” ํ›ˆ๋ จ์„ ๋จผ์ € ์‹คํ–‰ํ•œ ๋‹ค์Œ ๋ชจ๋ธ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋งž๋‚˜์š”? ๋˜ํ•œ ์ตœ์‹  Android ๋ฐ๋ชจ์—์„œ NNAPI๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? TFLiteObjectDetectionAPIModel.java์—์„œ tfLite.setUseNNAPI(true)๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ Android 8.1์„ ์‹คํ–‰ํ•˜๋Š” Pixel 2์—์„œ ์ถฉ๋Œํ–ˆ์Šต๋‹ˆ๋‹ค(NNAPI ์—†์ด๋„ ์ž˜ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Œ). ์–ด๋–ค ์ œ์•ˆ? ๊ฐ์‚ฌ ํ•ด์š”!

@tenoyart "์ตœ์‹  Android ๋ฐ๋ชจ์—์„œ NNAPI๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?"์— ๋Œ€ํ•œ ์งง์€ ๋Œ€๋‹ต์ž…๋‹ˆ๋‹ค. NO์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ์งง์€ ๋Œ€๋‹ต์€ ์•„๋‹ˆ์ง€๋งŒ TF Lite ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋ชจ๋ธ์„ ๋ถ„ํ• ํ•˜๊ฑฐ๋‚˜ ํ•ด๋‹น ์‚ฌ์šฉ์ž ์ง€์ • ์ž‘์—…์„ NNAPI์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@achowdhery TensorFlow ๋ธ”๋กœ๊ทธ ๊ธฐ์‚ฌ ๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์–ธ๊ธ‰ํ•œ ์ง€์นจ์ด๊ฑฐ๋‚˜ ๋” ๋งŽ์€ ๊ฒƒ์ด ์˜ค๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋„ค. Android์—์„œ ๊ฐ์ฒด ๊ฐ์ง€ ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ์ง€์นจ์ž…๋‹ˆ๋‹ค.

@freedomtan ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
ํ›„์ฒ˜๋ฆฌ๊ฐ€ ํฌํ•จ๋œ ์ตœ์‹  ์Šคํฌ๋ฆฝํŠธ์—์„œ ์–ด๋–ค ๋ชจ๋ธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
๋‹ค์Œ๊ณผ ๊ฐ™์ด optimize_for_inference.py์˜ ์ธ์ˆ˜๋ฅผ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๊นŒ?
--input_names="์ „์ฒ˜๋ฆฌ๊ธฐ/ํ•˜์œ„"
--output_names="detection_boxes,detection_scores,num_detections,detection_classes"

ํ›„์ฒ˜๋ฆฌ ์œ ๋ฌด์— ๋”ฐ๋ฅธ ์ฐจ์ด๊ฐ€ ๋ณด์ด๋‚˜์š”?

๊ฐ์‚ฌ ํ•ด์š”!

์ถœ๋ ฅ์ด 4๊ฐœ์ธ SqueezeNet ๋ชจ๋ธ์„ tflite๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@chanchanzhang https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus ์˜ ํŠœํ† ๋ฆฌ์–ผ ๋ ๋ถ€๋ถ„์— ์žˆ๋Š” ์ƒˆ๋กœ์šด ์ง€์นจ์„ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค.
์ด๊ฒƒ์€ optimize_for_inference.py๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ์›Œํฌํ”Œ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@ashwaniag ํƒ์ง€๋ฅผ ์œ„ํ•ด ๊ทธ ํ›„ SSD๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ Mobilenet์„ SqueezeNet ๋ถ„๋ฅ˜๊ธฐ๋กœ ๊ต์ฒดํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ํ˜„์žฌ ์›Œํฌํ”Œ๋กœ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

@achowdhery ssd mobilenet v1์—์„œ TF Lite ๋ชจ๋ธ์„ ๋ณด๋‹ˆ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค. TF Lite๋Š” ssdlite mobilenet v2๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•ฉ๋‹ˆ๊นŒ?

@tenoyart ๋„ค. ๋ชจ๋“  Mobilenet SSD๋Š” ์ด ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น tflite ํŒŒ์ผ์„ ์˜คํ”ˆ ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฒ„๊ทธ๋ฅผ ์‹ ๊ณ ํ•˜์„ธ์š”.

@achowdhery ๊ฐ€ ๋งํ–ˆ๋“ฏ์ด @chanchanzhang ์€ optimized_for_inference.py object_detection/export_tflite_ssd_graph.py ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ tflite ๋ชจ๋ธ ํŒŒ์ผ์€ Android ์˜ˆ์ œ์—์„œ ์‚ฌ์šฉ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

@achowdhery ssd_mobilenet_v1_quantized_coco ๋ฐ ssd_mobilenet_v1_0.75_depth_quantized_coco ์˜ ์ฒดํฌํฌ์ธํŠธ์—๋Š” FakeQuant ๋…ธ๋“œ์™€ ํ…์„œ๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธํ•ด ์ฃผ์‹œ๊ฒ ์–ด์š”?

@freedomtan object_detection/export_tflite_ssd_graph.py๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ ๋‚ด๋ณด๋‚ธ ๊ทธ๋ž˜ํ”„์— weight_quant ๋ฐ act_quant ๋…ธ๋“œ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
Fakequant ๋…ธ๋“œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ์ •ํ™•ํ•œ ์ง€์นจ์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.
๋˜ํ•œ ์ฒดํฌํฌ์ธํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@achowdhery ํ™•์ธํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ 2๊ฐœ์—์„œ export_tflite_ssd_graph.py ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ tflite ๋ชจ๋ธ์„ ์–ป์„ ์ˆ˜ ์—†์–ด์„œ ์ฒดํฌํฌ์ธํŠธ๋ฅผ ์กฐ์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•œ ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

curl http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03.tar.gz | tar xzvf -
cd ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03
strings model.ckpt.index  |grep quant

์•„๋ฌด๊ฒƒ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@andrewharp ๊ท€ํ•˜์˜ cutosm ์ถ”๋ก  ํด๋ž˜์Šค TFLiteObjectDetectionAPIModel.java ์— ๋Œ€ํ•ด ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip ์œผ๋กœ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ๋‚ด๊ฐ€ ํ˜ธ์ถœํ•  ๋•Œ ํ•จ์ˆ˜cognImage(์ตœ์ข… ๋น„ํŠธ๋งต ๋น„ํŠธ๋งต)์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค tfLite.runForMultipleInputsOutputs(์ž…๋ ฅ๋ฐฐ์—ด, ์ถœ๋ ฅ๋งต); ์ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

์˜ค๋ฅ˜๋Š” ์ถœ๋ ฅ ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ ์ž…๋ ฅ ๋ฐฐ์—ด์˜ ๊ธธ์ด๋ณด๋‹ค ํฝ๋‹ˆ๋‹ค.
Interpreter.java์˜ ์กฐ๊ฑด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="7">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

์ด๊ฒƒ์€ ๋‚ด ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];
 imgData.rewind();
        for (int i = 0; i < inputSize; ++i) {
            for (int j = 0; j < inputSize; ++j) {
                int pixelValue = intValues[i * inputSize + j];
                if (isModelQuantized) {
                    // Quantized model
                    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
                    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
                    imgData.put((byte) (pixelValue & 0xFF));
                } else { // Float model
                    imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

์ถœ๋ ฅ ๋ฐฐ์—ด:

// Copy the input data into TensorFlow.
        Trace.beginSection("feed");
        outputLocations = new float[1][NUM_DETECTIONS][4];
        outputClasses = new float[1][NUM_DETECTIONS];
        outputScores = new float[1][NUM_DETECTIONS];
        numDetections = new float[1];

        Object[] inputArray = {imgData};
        Map<Integer, Object> outputMap = new HashMap<>();
        outputMap.put(0, outputLocations);
        outputMap.put(1, outputScores);
        outputMap.put(2, numDetections);
        outputMap.put(3, outputClasses);
        Trace.endSection();

๊ทธ๋ฆฌ๊ณ  ์ถ”๋ก :

// Run the inference call.
        Trace.beginSection("run");
        Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
        Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

        tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
        Trace.endSection();

๋‚˜๋Š” ๋‹น์‹ ์˜ TFLiteObjectDetectionAPIModel.java ํด๋ž˜์Šค์™€ ์ •ํ™•ํžˆ ๋™์ผํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์˜ค๋ฅ˜์˜ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
๋„์™€ ์ค˜์„œ ๊ณ ๋งˆ์›Œ

@achowdhery ์•ˆ๋…•ํ•˜์„ธ์š”, ๊ท€ํ•˜์˜ ๋ธ”๋กœ๊ทธ์— ๋”ฐ๋ผ ssd_mobilenet_v1_coco_2017_11_17์—์„œ ๋ชจ๋ธ์„ ๋ณ€ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ณ€ํ™˜๋œ mobilenet_ssd.tflite๋ฅผ tflite_demo.apk์—์„œ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

    java.lang.IllegalArgumentException: Cannot copy between a TensorFlowLite tensor with shape [1, 1917, 4] and a Java object with shape [1, 10, 4].

๋‚ด๊ฐ€ ์™œ ๊ทธ๊ฒƒ์„ ์–ป์—ˆ๋Š”์ง€ ์–ด๋–ค ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”.

์˜ˆ์ƒ๋˜๋Š” ์ถœ๋ ฅ ํ…์„œ์˜ ํฌ๊ธฐ๊ฐ€ 1,1917,4๊ฐ€ ์•„๋‹ˆ๋ผ 1,10,4์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋ชจ์–‘ ๋ถˆ์ผ์น˜์ž…๋‹ˆ๋‹ค. ์ด์ „ ๋ชจ๋ธ ํŒŒ์ผ์˜ ๊ฒฝ์šฐ 5์›”์˜ ๋ฐ๋ชจ ์•ฑ ๋ฒ„์ „์œผ๋กœ ํšŒ๊ท€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ณ€ํ™˜์„ ์œ„ํ•ด ์ตœ์‹  ์ถœ์‹œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

@achowdhery ๋‚ด ๋ชจ๋ธ์„ tflite๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์‹คํ–‰ํ•  ๋•Œ. ์ธํ„ฐํ”„๋ฆฌํ„ฐ->invoke() ํ˜ธ์ถœ์€ ์„ธ๊ทธ๋จผํŠธ ์˜ค๋ฅ˜๋ฅผ โ€‹โ€‹๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@ashwaniag https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus-b78971cf1193 ์—์„œ ๋‹ค์šด๋กœ๋“œํ•œ ๋ชจ๋ธ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
๋‹น์‹ ์„ ์œ„ํ•ด ์ปดํŒŒ์ผ?
๊ทธ๋ ‡๋‹ค๋ฉด ์„ธ๊ทธ๋จผํŠธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ์ƒˆ ์ง€์นจ์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.
์ž…๋ ฅ ์œ ํ˜•/ํฌ๊ธฐ ๋“ฑ์ด ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@achowdhery ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ input_arrays๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ๊ณ ๋งˆ์›Œ!

ํŠœํ† ๋ฆฌ์–ผ์„ ๋”ฐ๋ž๋‹ค๋ฉด ์—…๋ฐ์ดํŠธ๋œ ssd_mobilenet_v1_quantized_coco ๋ฐ ssd_mobilenet_v1_0.75_depth_quantized_coco๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. @achowdhery ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ๋ฐ๋ชจ ์•ฑ์—์„œ TFLiteObjectDetectionAPIModel.java ๋ฅผ ๋ณด๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. outputLocations , outputClasses , outputScores , numDetections ์ด recognizeImage ํ˜ธ์ถœ๋งˆ๋‹ค ํ• ๋‹น๋˜๋Š” ์ด์œ  ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฏธ๋ฆฌ ํ• ๋‹น๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์‚ฌ์ „ ํ• ๋‹น์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์•˜๋Š”๋ฐ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ๋‚˜์ค‘์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์ „ ํ• ๋‹น์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฏธ๋ฆฌ ํ• ๋‹นํ•˜๋Š” ์œ„์น˜๋Š” ์–ด๋””์ž…๋‹ˆ๊นŒ?

@achowdhery ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ •์  create ๋ฉ”์„œ๋“œ์— ์‚ฌ์ „ ํ• ๋‹น์„ ๊ทธ๋Œ€๋กœ ๋‘ก๋‹ˆ๋‹ค. ๋‚ด ์œ ์ผํ•œ ๊ด€์‹ฌ์‚ฌ๋Š” ์ฝ”๋“œ๊ฐ€ ์‚ฌ์ „ ํ• ๋‹น(์ •์  ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐฐ์—ด์„ ์‚ฌ์ „ ํ• ๋‹น)์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ž‘์„ฑ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์–ด๋–ค ์ด์œ ๋กœ ๋ฐฐ์—ด์ด ๊ฐ ํ˜ธ์ถœ์—์„œ ์žฌํ• ๋‹น๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @achowdhery , ์ €๋Š” ์ƒˆ๋กœ์šด Android tflite ์•ฑ ๋ฐ๋ชจ๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ssd_mobilenet_v1_coco, ssd_mobilenet_v1_0.75_depth_coco, ssd_mobilenet_v1_quantized_coco์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ssd-mobilenet ๋ชจ๋ธ์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

07-25 07:41:25.292 31515-31532/org.tensorflow.lite.demo E/AndroidRuntime: FATAL EXCEPTION: inference
    Process: org.tensorflow.lite.demo, PID: 31515
    java.lang.ArrayIndexOutOfBoundsException: length=160; index=-2147483648
        at java.util.Vector.elementData(Vector.java:734)
        at java.util.Vector.get(Vector.java:750)
        at org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:218)
        at org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:249)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)

tflite ๋ชจ๋ธ์ด ์ž˜๋ชป๋œ ํด๋ž˜์Šค ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์™ธ๋กœ ์ธํ•ด ๋ช‡ ์ดˆ ๋™์•ˆ ์ž˜ ๊ฐ์ง€ํ•œ ํ›„ ์•ฑ์ด ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.
ssd_mobilenet_v1_ppn_coco ๋Š” ์ž˜๋ชป๋œ ์ง€์ €๋ถ„ํ•œ ๊ฒฝ๊ณ„ ์ƒ์ž, ๋ ˆ์ด๋ธ”๋„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

PPN์€ float ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. float ๋ณ€ํ™˜ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ TFLITE ๋ชจ๋ธ์„ ๋ณ€ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
๊ทธ๋Ÿฐ ๋‹ค์Œ DetectorActivity.java์—์„œ ๋‹ค์Œ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ์ธ ์ •์  ์ตœ์ข… ๋ถ€์šธ TF_OD_API_IS_QUANTIZED = true;

๋‚˜๋Š” ๊ทธ ๊ตฌ์„ฑ์„ ์•Œ๊ณ  ์žˆ์—ˆ๋‹ค. ์‹ค์ œ๋กœ ํ•ด๋‹น ์„ค์ •์ด ์ž˜๋ชป๋˜๋ฉด ์•ฑ์ด ์ „ํ˜€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ArrayIndexOutOfBoundsException์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํŠœํ† ๋ฆฌ์–ผ์˜ ๋„์ปค๋„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๊ดœ์ฐฎ์•„. ์ •ํ™•ํ•œ ์žฌํ˜„ ์ง€์นจ๊ณผ ํ•จ๊ป˜ ์ƒˆ GitHub ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•˜์„ธ์š”. PPN ๋ชจ๋ธ์€ Java ์•ฑ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ํšŒ์‹ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”. ArrayIndexOutOfBoundsException์€ ssd_mobilenet_v1_0.75_depth_quantized_coco, ssdlite_mobilenet_v2_coco์—๋„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. PPN๊ณผ์˜ ์ฐจ์ด์ ์€ ํ•ด๋‹น ์˜ˆ์™ธ๋กœ ์ธํ•ด ์•ฑ์ด ์ถฉ๋Œํ•˜๊ธฐ ์ „์— ์˜ฌ๋ฐ”๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@achowdhery ์ƒˆ๋กœ์šด model_main.py์— ๋ฒ„๊ทธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— legacy/train.py๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ tflite์— ๋Œ€ํ•ด 4๊ฐœ์˜ ์ถœ๋ ฅ์œผ๋กœ ๋ชจ๋ธ์„ ํ›ˆ๋ จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
https://github.com/tensorflow/models/issues/4798

@ashwaniag ๋‘ ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์–‘์žํ™”๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. graph_rewriter ํ•จ์ˆ˜๋Š” ์–‘์žํ™” ์—ฐ์‚ฐ์ด ์ถ”๊ฐ€๋˜๋Š” ์œ„์น˜์ž…๋‹ˆ๋‹ค.

@achowdhery : https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
iOS์—์„œ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ์ œ ๋˜๋Š” ์ƒ˜ํ”Œ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ง€๊ธˆ๊นŒ์ง€ ๋‚ด๊ฐ€ ์ฐพ์€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ ํ•ญ์ƒ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” https://github.com/YijinLiu/tf-cpu/blob/master/benchmark/obj_detect_lite.cc ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ iOS ๋ฐ๋ชจ ์•ฑ์€ ssd ๋ฐ float ๋ชจ๋ธ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@achowdhery tensorflow v1.9๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ธ”๋กœ๊ทธ์˜ ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ tflite๋กœ ๋ณ€ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์–ด๋–ค ํƒ์ง€๋„ ์–ป์ง€ ๋ชปํ•œ๋‹ค. ์ด๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ค ์ƒ๊ฐ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@ashwaniag COCO ๋˜๋Š” ์• ์™„ ๋™๋ฌผ? ์ •ํ™•ํ•œ ์žฌํ˜„ ์ง€์นจ์œผ๋กœ ์ƒˆ ๋ฒ„๊ทธ๋ฅผ ์—ฌ์‹ญ์‹œ์˜ค. ๋‹ค๋ฅธ GitHub ์‚ฌ์šฉ์ž๋Š” Tensorflow 1.10๊ณผ์˜ ์ž‘์—…์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

@achowdhery ๋‚ด ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ ์„ธํŠธ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” mobilenetv2 ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด ํ›ˆ๋ จํ–ˆ์Šต๋‹ˆ๋‹ค. .pb ๋ชจ๋ธ(tensorflow ๋ชจ๋ธ)์„ ์‹คํ–‰ํ•˜๋ฉด
์ฐพ์„ ์ˆ˜ ์—†์Œ: VAL5-04์—์„œ ์‹คํ–‰๋˜๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ์— 'NonMaxSuppressionV3'์ด ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์ž‘์—… ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ ์ค‘์ธ ๋ฐ”์ด๋„ˆ๋ฆฌ์— Op ๋ฐ Kernel์ด ๋“ฑ๋ก๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

@ashwaniag ์ƒˆ ๋ฒ„๊ทธ๋ฅผ ์—ด๊ณ  ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์ •ํ™•ํ•œ ์ง€์นจ์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.

@ashwaniag ์ด ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ๋ชจ๋‘ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. #10254 ๋ฐ #19854

@achraf-boussaada ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ณ ์ณค๋‹ค. ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.
@achowdhery ์ด์ œ ๋ฌธ์ œ๋Š” ์ „์ฒด tensorflow ๋ชจ๋ธ์€ ํ›Œ๋ฅญํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ tflite ๋ชจ๋ธ์€ ๋งค์šฐ ๋‚˜์œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@ashwaniag ๋งค์šฐ ๋‚˜์œ ๊ฒฐ๊ณผ๋ฅผ ์ •์˜ํ•˜์‹ญ์‹œ์˜ค. ์ž‘์€ ๋ฌผ๊ฑด์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋„๋ก ๋ชจ๋ธ ์ฒดํฌํฌ์ธํŠธ, ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์„ฑ ๋ฐ ๋ ˆ์ด๋ธ” ํŒŒ์ผ๊ณผ ์ƒ˜ํ”Œ ์ด๋ฏธ์ง€๋ฅผ ์ฒจ๋ถ€ํ•˜์„ธ์š”. ๊ฐ์‚ฌ ํ•ด์š”

@oopsodd ์•ˆ๋…•ํ•˜์„ธ์š”, ์ž˜๋ชป๋œ ํด๋ž˜์Šค ์ธ๋ฑ์Šค๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. "java.lang.ArrayIndexOutOfBoundsException: length=10; index=-739161663"์ด๋ผ๊ณ  ๋ถˆํ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„์™€์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์ฐธ๊ณ  iOS ๋ฐ Android์šฉ TensorFlow Lite SSD(๊ฐ์ฒด ๊ฐ์ง€) ์ตœ์†Œ ์ž‘์—… ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/baxterai/tfliteSSDminimalWorkingExample. iOS ๋ฒ„์ „์€ YijinLiu์˜ obj_detect_lite.cc(WeiboXu์˜ nms ๊ธฐ๋Šฅ ํฌํ•จ)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  Android ๋ฒ„์ „์€ https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/examples/ ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

@baxterai ์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค ! ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, ํ…Œ์ŠคํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„์˜ ๋†€๋ผ์šด ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ํ›„์ฒ˜๋ฆฌ ์ž‘์—…์— ๋Œ€ํ•ด ๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์ „ ํ›ˆ๋ จ๋œ ssd_mobilenet_v1_quantized_coco ์˜ ์ถœ๋ ฅ
model/research/object_detection/samples/configs/์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์ด ๋‹ค์Œ๊ณผ ๊ฐ™๋”๋ผ๋„ ํ˜„์žฌ ํ”„๋ ˆ์ž„์˜ ์ƒ์œ„ 10๊ฐœ ํƒ์ง€๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
ssd_mobilenet_v1_quantized_300x300_coco14_sync.config ๋ชจ๋‘๋Š” ๋” ๋†’์€ ์ด ํƒ์ง€ ํ•œ๋„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

post_processing { batch_non_max_suppression { score_threshold: 1e-8 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 100 } score_converter: SIGMOID }

์ด๊ฒƒ์€ ์ด ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์„ฑ์œผ๋กœ ๋„คํŠธ์›Œํฌ๋ฅผ ์žฌ๊ต์œกํ•˜์—ฌ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๋‹ค์Œ์˜ ์ฐจ์›์ž…๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ๊ตฌ์„ฑ์— ์˜ํ•ด 'TFLite_Detection_PostProcess'๊ฐ€ 10์œผ๋กœ ๊ณ ์ •๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

@Georg-W export_tflite_ssd_graph.py์—์„œ๋„ ์ตœ๋Œ€ ๊ฐ์ง€๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น์ค„ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@achowdhery ์•„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‚ด๊ฐ€ ๋†“์นœ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@andrewharp ๊ท€ํ•˜์˜ cutosm ์ถ”๋ก  ํด๋ž˜์Šค TFLiteObjectDetectionAPIModel.java ์— ๋Œ€ํ•ด ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip ์œผ๋กœ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ๋‚ด๊ฐ€ ํ˜ธ์ถœํ•  ๋•Œ ํ•จ์ˆ˜cognImage(์ตœ์ข… ๋น„ํŠธ๋งต ๋น„ํŠธ๋งต)์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค tfLite.runForMultipleInputsOutputs(์ž…๋ ฅ๋ฐฐ์—ด, ์ถœ๋ ฅ๋งต); ์ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

์˜ค๋ฅ˜๋Š” ์ถœ๋ ฅ ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ ์ž…๋ ฅ ๋ฐฐ์—ด์˜ ๊ธธ์ด๋ณด๋‹ค ํฝ๋‹ˆ๋‹ค.
Interpreter.java์˜ ์กฐ๊ฑด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="14">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

์ด๊ฒƒ์€ ๋‚ด ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];

```
imgData.rewind();
(int i = 0; i < inputSize; ++i) {
(int j = 0; j < inputSize; ++j) {
int pixelValue = intValues[i * inputSize + j];
if (isModelQuantized) {
// ์–‘์žํ™” ๋ชจ๋ธ
imgData.put((๋ฐ”์ดํŠธ) ((ํ”ฝ์…€ ๊ฐ’ >> 16) & 0xFF));
imgData.put((byte) ((pixelValue >> 8) & 0xFF));
imgData.put((๋ฐ”์ดํŠธ) (ํ”ฝ์…€๊ฐ’ & 0xFF));
} else { // ํ”Œ๋กœํŠธ ๋ชจ๋ธ
imgData.putFloat((((ํ”ฝ์…€ ๊ฐ’ >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat((((ํ”ฝ์…€ ๊ฐ’ >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat(((ํ”ฝ์…€ ๊ฐ’ & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

The outputs array :

// ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ TensorFlow์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
Trace.beginSection("ํ”ผ๋“œ");
outputLocations = ์ƒˆ๋กœ์šด float[1][NUM_DETECTIONS][4];
outputClasses = ์ƒˆ๋กœ์šด float[1][NUM_DETECTIONS];
outputScores = ์ƒˆ๋กœ์šด float[1][NUM_DETECTIONS];
numDetections = ์ƒˆ๋กœ์šด float[1];

    Object[] inputArray = {imgData};
    Map<Integer, Object> outputMap = new HashMap<>();
    outputMap.put(0, outputLocations);
    outputMap.put(1, outputScores);
    outputMap.put(2, numDetections);
    outputMap.put(3, outputClasses);
    Trace.endSection();
And the Inference :

// ์ถ”๋ก  ํ˜ธ์ถœ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
Trace.beginSection("์‹คํ–‰");
Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

    tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
    Trace.endSection();

```
๋‚˜๋Š” ๋‹น์‹ ์˜ TFLiteObjectDetectionAPIModel.java ํด๋ž˜์Šค์™€ ์ •ํ™•ํžˆ ๋™์ผํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์˜ค๋ฅ˜์˜ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
๋„์™€ ์ค˜์„œ ๊ณ ๋งˆ์›Œ

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๊นŒ?
๊ฐ์‚ฌ ํ•ด์š”..

@Georg-W export_tflite_ssd_graph.py์—์„œ๋„ ์ตœ๋Œ€ ๊ฐ์ง€๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น์ค„ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•

์ด๋ฏธ์ง€์—์„œ 10๊ฐœ ์ด์ƒ์˜ ๊ฐœ์ฒด๋ฅผ ๊ฐ์ง€ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค(๊ธฐ๋ณธ๊ฐ’).
๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
bazel run -c opt tensorflow/contrib/lite/ toco:toco -- --input_file=$OUTPUT_DIR/tflite_graph.pb --output_file=$OUTPUT_DIR/mobile_net_500.tflite --input_shapes=1,300,300,3 --normalized_inputs_input_array= output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_Po stProcess:1 ','TFLite_Detection_Po stProcess:2 ','TFLite_Detection_Po stProcess:3 ' --inference_type=FLOAT --max_detections=500 --max_classes_per_detection_1 --per_detection=

๋‚˜๋„ ์ˆ˜์ •ํ–ˆ๋‹ค
export_tflite_ssd_graph.py
flags.DEFINE_integer('max_detections', 500 <--- 10 ๋Œ€์‹ ,
'ํ‘œ์‹œํ•  ์ตœ๋Œ€ ํƒ์ง€(์ƒ์ž) ์ˆ˜')
flags.DEFINE_integer('max_classes_per_detection', 1,
'๊ฐ์ง€ ์ƒ์ž๋‹น ํ‘œ์‹œํ•  ํด๋ž˜์Šค ์ˆ˜')

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ Android [1,10,4]์—์„œ 10๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ์ƒ๊ฐ?

@KaviSanth ๋ฌธ์ œ์˜ ์†”๋ฃจ์…˜์—๋„ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@Stevelb ์˜ ์ด ์†”๋ฃจ์…˜์ด ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. max_detections๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์ •๋œ ๊ทธ๋ž˜ํ”„๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@achowdhery ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. @andrewharp ๊ฐ€ ์ž‘์„ฑํ•œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค ํ† ์ฝ”๋Š” ์ด๊ณณ์— ์—†์Šต๋‹ˆ๋‹ค. github ์ €์žฅ์†Œ์˜ ๋งˆ์Šคํ„ฐ ๋ฒ„์ „๊ณผ r1.95 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

bazel ์‹คํ–‰ tensorflow/contrib/lite/ toco:toco -- --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=์ „์ฒ˜๋ฆฌ๊ธฐ -output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr
์ •๋ณด: ํ˜ธ์ถœ ID: 0e58a5ef-9fee-4619-b760-aeb1c83c9661
์˜ค๋ฅ˜: 'tensorflow/contrib/lite/ toco:toco ' ๊ฑด๋„ˆ๋›ฐ๊ธฐ: ํ•ด๋‹น ํŒจํ‚ค์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. 'tensorflow/contrib/lite/toco': ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ์—์„œ ๋นŒ๋“œ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๊ฒฝ๊ณ : ๋Œ€์ƒ ํŒจํ„ด ๊ตฌ๋ฌธ ๋ถ„์„์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.
์˜ค๋ฅ˜: 'tensorflow/contrib/lite/toco' ํŒจํ‚ค์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค: ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ์—์„œ ๋นŒ๋“œ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
์ •๋ณด: ๊ฒฝ๊ณผ ์‹œ๊ฐ„: 0.179์ดˆ
์ •๋ณด: 0 ํ”„๋กœ์„ธ์Šค.
FAILED: ๋นŒ๋“œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(0๊ฐœ์˜ ํŒจํ‚ค์ง€๊ฐ€ ๋กœ๋“œ๋จ).
FAILED: ๋นŒ๋“œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(0๊ฐœ์˜ ํŒจํ‚ค์ง€๊ฐ€ ๋กœ๋“œ๋จ).
git์—์„œ ๊ฐ€์ ธ์˜จ ๋กœ์ปฌ tensorflow ํด๋”์—์„œ ํ•ด๋‹น ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์Œ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

tensorflow/lite/toco์—์„œ toco๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž‘๋™ ์—ฌ๋ถ€๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.
์ข‹์•„, ์ด toco๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์œผ๋ฉฐ contrib/lite ํด๋”์—๋Š” ์ผ๋ถ€ Python๋งŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— $DETECT_FB ๊ฒฝ๋กœ๋ฅผ $PWD/ssd_mobilenet.tflite๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android(https://github.com/tensorflow/tensorflow/blob )์˜ DetectorActivity์— .tflite ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•  ๋•Œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. /master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java)

private static final String TF_OD_API_MODEL_FILE =
            "file:///android_asset/ssd_mobilenet_v1.tflite";

E/AndroidRuntime: ์น˜๋ช…์  ์˜ˆ์™ธ: ๊ธฐ๋ณธ
ํ”„๋กœ์„ธ์Šค: myProcess, PID: 32611
java.lang.RuntimeException: ์ž…๋ ฅ ๋…ธ๋“œ 'image_tensor'๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
myPackage.myClass.TensorFlowObjectDetectionAPIModel.create(TensorFlowObjectDetectionAPIModel.java:106)

ํ•ด๋‹น ์•ฑ์—์„œ .tflite ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‚˜์š”?

@defaultUser3214 ํƒ์ง€ ์•ฑ์—์„œ ๋ถ„๋ฅ˜๊ธฐ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. MobileNet v1์€ ๋ถ„๋ฅ˜ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. MobileNet SSD ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค

@achowdhery ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz ์˜ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทผ๋ฐ ์ด๊ฒŒ ssd๋ฒ„์ „์ธ์ค„ ์•Œ์•˜์–ด์š”?

๊ทธ๋Ÿฌ๋‚˜ ์ด์ „์— .pb๋กœ ์ž‘๋™ํ–ˆ๋˜ .tflite๋กœ ๋ณ€ํ™˜๋œ ssd_mobilenet_v1_android_export.pb๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@defaultUser3214 2018๋…„ 7์›”์— ์ถœ์‹œ๋œ ์ตœ์‹  ๋ฐ๋ชจ ์•ฑ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋ชจ๋ธ์˜ ์ด์ „ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. 2018๋…„ 7์›”์— ์ตœ์‹  ๋ชจ๋ธ์„ ๊ฐ์ง€ ๋ชจ๋ธ ๋™๋ฌผ์›์—์„œ ๋‹ค์šด๋กœ๋“œํ•˜์„ธ์š”. ์•ฑ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์—ฌ์ „ํžˆ ์ฐจ๋‹จ๋˜์–ด ์žˆ์œผ๋ฉด ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ฌ์‹ญ์‹œ์˜ค.

@SteveIb TFLiteObjectDetectionAPIModel.java ์—์„œ NUM_DETECTIONS = 500๋„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ssdmobilenet v1 .pb๋ฅผ .tflite๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์Œ
Tensorflow ๊ฐ์ฒด ๊ฐ์ง€ API @aselle @achowdhery ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ pb

์ด์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? frozen_inference_graph.pb๋ฅผ .TFLITE ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

Android์˜ ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐœ์ฒด ๊ฐ์ง€์šฉ. ๋‹ค๋ฅธ ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10 ์ž์Šต์„œ์— ๋”ฐ๋ผ Windows 10์—์„œ ํ•™์Šต๋œ ssd_mobilenet_v1_pets๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? frozen_inference_graph.pb๋ฅผ .TFLITE ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

Android์˜ ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐœ์ฒด ๊ฐ์ง€์šฉ. ๋‹ค๋ฅธ ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10 ์ž์Šต์„œ์— ๋”ฐ๋ผ Windows 10์—์„œ ํ•™์Šต๋œ ssd_mobilenet_v1_pets๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์— ๋Œ€ํ•œ ํ›„์† ์กฐ์น˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ๊ฒช๊ณ  ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ๋•๊ธฐ ์œ„ํ•ด - ์ด๊ฒƒ์€ ํ›ˆ๋ จํ•  ์ž˜๋ชป๋œ ๋ชจ๋ธ ์ฒดํฌํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. .tflite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Android์—์„œ ์ž‘์—…ํ•˜๋ ค๋ฉด ์ดˆ๊ธฐ ๋ชจ๋ธ์ด MobileNet์ด์–ด์•ผ ํ•˜๊ณ  ์–‘์žํ™”๋˜์–ด์•ผ ํ•˜๋ฉฐ .config ํŒŒ์ผ์— ์ด ์ฝ”๋“œ ์„น์…˜ ๋˜๋Š” ์œ ์‚ฌํ•œ ํ•ญ๋ชฉ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

graph_rewriter { quantization { delay: 48000 weight_bits: 8 activation_bits: 8 } }

ํ˜„์žฌ tensorflow/contrib/lite/examples/android ์— ์žˆ์Šต๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ์›๋ณธ TF Android ๋ฐ๋ชจ์˜ ๋ณด๋‹ค ์™„์ „ํ•œ ํฌํŠธ์ด๋ฉฐ(Stylize ์˜ˆ์ œ๋งŒ ์—†์Œ) ์•ž์œผ๋กœ tensorflow/contrib/lite/java/demo์˜ ๋‹ค๋ฅธ ๋ฐ๋ชจ๋ฅผ ๋Œ€์ฒดํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋ณ€ํ™˜๋œ TF Lite ํ”Œ๋žซ ๋ฒ„ํผ๋Š” mobilenet_ssd_tflite_v1.zip ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๊ณ  Java ์ถ”๋ก  ๊ตฌํ˜„์€ TFLiteObjectDetectionAPIModel.java ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒ์ž๋ฅผ Java์—์„œ ์ˆ˜๋™์œผ๋กœ ๋””์ฝ”๋”ฉํ•ด์•ผ ํ•˜๊ณ  ์ƒ์ž ์ด์ „ txt ํŒŒ์ผ์„ ์•ฑ ์ž์‚ฐ์— ํŒจํ‚ค์ง•ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์—์„œ ์›๋ž˜ TF ๊ตฌํ˜„๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”„).

TOCO ๋ณ€ํ™˜ ์ค‘์—๋Š” ๋‹ค๋ฅธ ์ž…๋ ฅ ๋…ธ๋“œ(Preprocessor/sub)์™€ ๋‹ค๋ฅธ ์ถœ๋ ฅ ๋…ธ๋“œ(concat,concat_1)๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ๋ž˜ํ”„๊ฐ€ ์žฌ๊ตฌ์„ฑ๋˜๊ฑฐ๋‚˜ TF Lite๊ฐ€ TF ํŒจ๋ฆฌํ‹ฐ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ tflite์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ๋ถ€๋ถ„์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ SSD MobileNet ๋ชจ๋ธ์„ tflite ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ๋ชจ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋น ๋ฅธ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

์ด๊ฒƒ์€ ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค!

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰