์๋ .
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๋ฐ์ดํธ์
๋๋ค.
๋ฌธ์ ๊ฐ ๋ฌด์์
๋๊น?
๋ํ,
๊ฐ์ฒด ๊ฐ์ง๋ฅผ ์ํ ์ฌ์ฉ์ ์ง์ ๋ชจ๋ธ์ ๋ฐฐํฌํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด ๋ฌด์์ธ์ง ์๋ ค์ฃผ์ญ์์ค.
๋๊ฐ ์ข ๋์์ฃผ์ธ์!.
๊ฐ์ฌ ํด์.
@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 ํ๋ณตํ ๋ถํ์ ๐ฅ๐ซ ๋น์ ์ ๋ ์ ๋์ ๋๋ค! :) ๋ด๊ฐ ์ด๊ฒ์ ์คํํ ์ ์๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
์๋ ํ์ธ์, ํํ์ด์ฆ ๋ฒ์ ์ด ์์ต๋๊น?
์์ ์ง์นจ์ ๋ฐ๋ผ ์๋ํ์ง๋ง ๋ค์์ด ํ์ํ์ต๋๋ค.
@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 ์ข์ ํฌ์คํ ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ทํ์ ๋จ๊ณ์ ๋ํด ํ ๊ฐ์ง ์ง๋ฌธ์ด ์์ต๋๋ค.
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"๋ชจ์์ผ๋ก ์ฌ๊ตฌ์ฑํ๋์ง ์ดํดํ์ง ๋ชปํฉ๋๋ค. ์ค๋ณต์ผ์๋
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
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 ์ ๋ฒ๊ทธ๋ฅผ ์ด๊ณ ์ฌํ ๊ฐ๋ฅํ ์ ํํ ์ง์นจ์ ์ ๊ณตํ์ญ์์ค.
@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
์ด๊ฒ์ ๋งค๋ ฅ์ฒ๋ผ ์๋ํฉ๋๋ค!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
ํ์ฌ 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 ํ์์ผ๋ก ๋ณํํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๋ฐ๋ชจ๋ฅผ ๊ตฌ์ถํ๋ ๋น ๋ฅธ ๋จ๊ณ์ ๋๋ค.