Skip to content

haebin-seong/tf-c-api

Repository files navigation

Introduction

This is a repo showing various ways of using tensorflow and its variants.

Python prebuilt

pip install --upgrade --pre tensorflow-gpu

  • ๊ฐ release์— ๋งž๋Š” cuda์™€ cudnn์„ ์„ค์น˜ํ•ด์•ผํ•œ๋‹ค
  • ํ˜„์žฌ latest release๋Š” tensorflow 1.13.1 , ์ด์— ๋งž๋Š” ๊ฑด cuda 10.0, cudnn 7.x

C prebuilt

https://www.tensorflow.org/install/lang_c ์—์„œ Windows GPU only ๋‹ค์šด๋กœ๋“œ, ์••์ถ• ํ•ด์ œ

https://storage.googleapis.com/tensorflow ์—ฌ๊ธฐ์„œ ์‹ ๋ฒ„์ „๋“ค์˜ prebuilt๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค

prebuilt๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋นŒ๋“œ๋œ ๋Œ€์ƒ CUDA ๋ฒ„์ „์„ ์•Œ์•„์•ผํ•œ๋‹ค!!!

https://www.tensorflow.org/install/source_windows ์—ฌ๊ธฐ์„œ ํ™•์ธ (1.12.0์€ CUDA 9.0์„ ๊น”์•„์•ผํ•จ, 9.2๋Š” ์•ˆ ๋˜๋‹ˆ ์ฃผ์˜)

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2017\Visual Studio Tools์— ์žˆ๋Š” ๊ฐœ๋ฐœ์ž ๋ช…๋ น ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‚ฌ์šฉ

dumpbin /exports tensorflow.dll > dumpbin.txt

dumpbin.txt ์—์„œ name๋ถ€๋ถ„๋งŒ ๋”ฐ๋กœ ๋นผ๊ณ , ๋งจ ์œ„์— EXPORTS๋ฅผ ๋„ฃ์–ด์„œ tensorflow.def๋กœ ์ €์žฅํ•˜์ž (๋‚˜์˜ ๊ฒฝ์šฐ๋Š” vs code์˜ Shift+Alt+Click ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ์Œ )

dumpbin.txt ์˜ˆ์‹œ

    ordinal hint RVA      name

          1    0 02D78C80 ??0?$MaybeStackArray@D$0CI@@icu_62@@AEAA@AEBV01@@Z
          2    1 035F9D10 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@$$QEAV01@@Z
          3    2 035F9D70 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@H@Z
          4    3 035F9DF0 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@XZ
          5    4 03603B80 ??0Appendable@icu_62@@QEAA@AEBV01@@Z
          6    5 03603B80 ??0Appendable@icu_62@@QEAA@XZ

tensorflow.def ์˜ˆ์‹œ

EXPORTS
??0?$MaybeStackArray@D$0CI@@icu_62@@AEAA@AEBV01@@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@$$QEAV01@@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@H@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@XZ
??0Appendable@icu_62@@QEAA@AEBV01@@Z

lib /def:tensorflow.def /OUT:tensorflow.lib /MACHINE:X64 ๋กœ tensorflow.lib ์ƒ์„ฑ

๊ทธ๋ ‡๋‹ค๋ฉด 3 ํŒŒ์ผ์ด ์ค€๋น„๊ฐ€ ๋˜์—ˆ์„ ๊ฒƒ์ด๋‹ค

  • tensorflow.lib - lib
  • tensorflow.dll - dll
  • c_api.h - header

C build from source

tensorflow/tensorflow#24963

tensorflow/tensorflow#24885

์•„์ง windows์ง€์›์ด ๋งŽ์ด ๋ฏธํกํ•œ ์ƒํƒœ๋ผ์„œ ์˜ค๋ฅ˜๊ฐ€ ๋งŽ์œผ๋‹ˆ ์œ ์˜


https://www.tensorflow.org/install/source_windows์—์„œ Build the pip package ์ „๊นŒ์ง€์˜ ๊ณผ์ •์„ ํ•ด์ฃผ์ž

bazel 0.21.0 installation

bazel 0.21.0 (๋„ˆ๋ฌด ๋†’์€ ๋ฒ„์ „์„ ๋ฐ›์œผ๋ฉด ํ…์„œํ”Œ๋กœ์šฐ๊ฐ€ ํ˜ธํ™˜์ด ์•ˆ ๋œ๋‹ค) ์„ ๋ฐ›์ž

bazel, msys2, Visual C++ Build Tools 2015(๋‚ด ๊ฒฝ์šฐ๋Š” VS2017์—์„œ ์ถ”๊ฐ€ ์˜ต์…˜์„ ์ฒดํฌํ•ด์„œ ์„ค์น˜ํ–ˆ์Œ) ์„ค์น˜


tensoflow 1.13.1 : https://github.com/tensorflow/tensorflow/releases

python configure.py

  • windows์—์„  XLA JIT support ๋„๊ธฐ (์•„์ง ์ง€์›์ด ์•ˆ ๋˜๋Š”๋“ฏ) : tensorflow/tensorflow#24218
  • ROCm์€ AMD gpu์šฉ์ด๋ผ๊ณ  ํ•˜๋‹ˆ ๋„๊ธฐ
  • ์ข‹์€ cpu (์ผ๋‹จ์€ 6์„ธ๋Œ€ ์ด์ƒ?)์—์„  optimization flag์— /arch:AVX2๋ฅผ ์จ์ฃผ์ž (์–ด์ฐจํ”ผ ์ค‘์š”ํ•œ๊ฑด gpu์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋‹ฅ ์ฐจ์ด๋Š” ์—†์„๋“ฏ)
  • ์ปดํŒŒ์ผ ํƒ€์ž„ ์ค„์ด๋Š” eigen strong inline์€ ์ผœ๋„ ๋˜๋Š”๋ฐ, ๋งŒ์•ฝ ๋นŒ๋“œ๊ฐ€ ์‹คํŒจํ•˜๋ฉด ๊บผ๋ณด์ž
  • CUDA๋Š” ์›ํ•˜๋Š” ๋ฒ„์ „์„ ์ ์ž (1.13.1์€ 10.0์ด default๋‹ค), ์—ฌ๊ธฐ์„œ ์ •ํ™•ํ•˜๊ฒŒ ์†Œ์ˆ˜ ํ•œ์ž๋ฆฌ๊นŒ์ง€ ์ ์–ด์•ผ ๋‚˜์ค‘์— dll์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค
  • cudnn์€ 7.4.2๋ผ๊ณ  ํ•ด์ค˜๋„ ๋˜๋Š”๋ฐ 7์ด๋ผ๊ณ ๋งŒ ํ•ด๋„ ๋˜๋Š”๋“ฏ(default)
  • RTX 2080์˜ CUDA compute capability๋Š” 7.5์ด๋‹ˆ 7.5๊นŒ์ง€ ํฌํ•จํ•ด์ฃผ์ž 3.5,7.5

bazel build --config opt //tensorflow/tools/lib_package:libtensorflow ํ•˜๋ฉด gpu support ๋จ ์ด๋ฏธ python configure.py์—์„œ CUDA์˜ต์…˜์„ ์คฌ๊ธฐ ๋•Œ๋ฌธ์— --config=cuda๋ฅผ ๋”ฐ๋กœ ์•ˆ ํ•ด๋„ ๋˜๋Š”๋“ฏํ•˜๋‹ค. ํ™ˆํŽ˜์ด์ง€์— ๋‚˜์™€์žˆ๋Š” ์ปค๋งจ๋“œ๋Š” ์˜ˆ์ „ ๋ฒ„์ „์ธ๋“ฏ.

๊ทธ๋ ‡๋‹ค๋ฉด 3 ํŒŒ์ผ์ด ์ค€๋น„๊ฐ€ ๋˜์—ˆ์„ ๊ฒƒ์ด๋‹ค

  • liblibtensorflow.so.ifso - lib - bazel-bin/tensorflow/liblibtensorflow.so.ifso

  • libtensorflow.so - dll - bazel-bin/tensorflow/libtensorflow.so

  • c_api.h - header - bazel-bin/tensorflow/tools/lib_package/libtensorflow.tar.gz ์••์ถ• ํ•ด์ œ ํ›„ include/tensorflow/c/c_api.h

Using C Api

์•ž์„œ ๋งํ•œ lib, dll, header๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ์จ์ฃผ๋ฉด ๋œ๋‹ค.

C Api๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” graph definition์„ protobuf(.pb) ํ˜•์‹์œผ๋กœ ๋นผ๋‚ด์•ผ ํ•œ๋‹ค. ๋˜ ํ•„์š”ํ•œ operation์ด ์žˆ์œผ๋ฉด operation์˜ ์ด๋ฆ„, operation์— ํ•„์š”ํ•œ input ๋˜๋Š” output tensor์˜ shape๊ณผ type์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ด๋Ÿฐ ์‹์˜ ์˜ˆ์‹œ๋กœ ๋ง์ด๋‹ค.

import tensorflow as tf

# Batch of input and target output (1x1 matrices)
x = tf.placeholder(tf.float32, shape=[None, 1, 1], name='input')
y = tf.placeholder(tf.float32, shape=[None, 1, 1], name='target')

# Trivial linear model
y_ = tf.identity(tf.layers.dense(x, 1), name='output')

# Optimize loss
loss = tf.reduce_mean(tf.square(y_ - y), name='loss')
optimizer = tf.train.AdamOptimizer()
train_op = optimizer.minimize(loss, name='train')

init = tf.global_variables_initializer()

# tf.train.Saver.__init__ adds operations to the graph to save
# and restore variables.
saver_def = tf.train.Saver().as_saver_def()

print('Run this operation to initialize variables     : ', init.name)
print('Run this operation for a train step            : ', train_op.name)
print('Feed this tensor to set the checkpoint filename: ', saver_def.filename_tensor_name)
print('Run this operation to save a checkpoint        : ', saver_def.save_tensor_name)
print('Run this operation to restore a checkpoint     : ', saver_def.restore_op_name)

# Write the graph out to a file.
with open('graph.pb', 'wb') as f:
  f.write(tf.get_default_graph().as_graph_def().SerializeToString())

๋˜ checkpoint ํŒŒ์ผ๋กœ weight๋ฅผ ๋ณต๊ตฌํ•ด์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด, checkpoint ํŒŒ์ผ๋„ ํ•„์š”ํ•˜๋‹ค. (.index, .data~)

ํ•„์š”ํ•œ operation์˜ ์ด๋ฆ„๋“ค์€ ๋ณดํ†ต input, output, train, initializer, checkpoint save, checkpoint restore, checkpoint filename set ํ•˜๋Š” operation์ด๋‹ค.

๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ ์•Œ์•„๋‚ธ operation์˜ ์ด๋ฆ„๋“ค๋กœ C api์—์„œ operation๋“ค์„ ์ฐพ๊ณ , TF_SessionRun์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค.

Tensor๋Š” ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ์™€ dimension์„ ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ์€ ์ œ๊ฐ€ ๊ตฌํ˜„ํ•ด๋‚ธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Œ€๋กœ ์“ฐ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

fcn_model()์€

  • logs๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด ๊ฑฐ๊ธฐ์—์„œ restore๋ฅผ ํ•œ ํ›„, prediction์„ ๋ณด์—ฌ์ค€ ํ›„ training์„ ์ผ์ •๋Ÿ‰ ํ•œ ํ›„ ๋‹ค์‹œ ๊ฐœ์„ ๋œ prediction์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
  • logs๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†์œผ๋ฉด weight initialization์„ ํ•œ ํ›„, prediction์„ ๋ณด์—ฌ์ค€ ํ›„ training์„ ์ผ์ •๋Ÿ‰ ํ•œ ํ›„ ๋‹ค์‹œ ๊ฐœ์„ ๋œ prediction์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

C api Tip

  • Tensor์˜ shape๊ณผ type์„ tensorboard๋‚˜ python์—์„œ print(t.shape, t.dtype) ๋“ฑ์œผ๋กœ ํ™•์ธํ•˜์ž. ๊ฐ€๋”์”ฉ t.dtype์ด ๊ทธ๋ž˜ํ”„์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ถœ๋ ฅ๋˜๋Š”๊ฒƒ ๊ฐ™๊ธด ํ•˜๋‹ˆ(float32 -> float64๊ฐ™์ด ์‚ฌ์†Œํ•˜๊ฒŒ) ๊ทธ๋ž˜ํ”„๋ฅผ ๋ณด๋Š”๊ฒŒ ์ œ์ผ ํ™•์‹คํ•œ ๋“ฏ
  • Graph op ์ด๋ฆ„๋„ tensorboard๋‚˜ python์—์„œ ํ™•์ธํ•ด์„œ ์ ์šฉ
  • DT_BOOL์€ int ๋ฐฐ์—ด๋กœ ๋จน์—ฌ์ค˜๋„ ์ž˜ ์ธ์‹๋œ๋‹ค. ๋˜๋„๋ก int๋กœ ์ฃผ์ž (vector ๊ด€๋ จํ•œ ์ด์Šˆ ๋•Œ๋ฌธ์—)
  • DT_FLOAT : float
  • DT_INT32 : int
  • DT_INT64 : int64_t

C++ build from source

tensorflow๊ฐ€ windows์—์„œ c++ api ์ง€์›์„ ์•„์ง ์ž˜ ์•ˆ ํ•ด์„œ ์–ด๋А ์ •๋„์˜ hack์ด ํ•„์š”ํ•˜๋‹ค.

์•„์ง ์‹œ์ž‘ ๋‹จ๊ณ„ : tensorflow/tensorflow#26152

cuda 7.0~8.0์„ ์“ฐ๋˜ ๊ณผ๊ฑฐ ๋ฒ„์ „์—์„œ๋Š” Cmake๋ฅผ ์ง€์›ํ–ˆ์ง€๋งŒ, ํ˜„์žฌ ๋ฒ„์ „์—์„œ๋Š” Cmake ์ง€์›์ด ๋Š๊ฒจ ์•ˆ ๋˜๊ณ , bazel์„ ์ด์šฉํ•œ ์ปดํŒŒ์ผ์„ ์ง€์›ํ•œ๋‹ค.

์‹ฌ์ง€์–ด tensorflow๊ฐ€ ๊ณต์‹์œผ๋กœ ์ง€์›ํ•˜๋Š” C++ api๋Š” tensorflow project๋ฅผ ์ „๋ถ€ compileํ•˜๋ฉด์„œ tensorflow ๋‚ด๋ถ€์— ๋‚ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋„ฃ์–ด tensorflow์˜ ๋ฐฉ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ์ปดํŒŒ์ผํ•ด์•ผํ•˜๋Š” ๋‹จ์ ์ด ์žˆ์–ด ๋ฐฐํฌ์šฉ์œผ๋กœ๋Š” ๋ถ€์ ํ•ฉํ•˜๋‹ค.

๋‹คํ–‰ํžˆ ์–ด๋А ์ •๋„์˜ hack์„ ํ†ตํ•ด shared library๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ƒˆ์œผ๋‹ˆ ๊ทธ๊ฒƒ์„ ์“ฐ๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

์ด repo๋ฅผ ๋”ฐ๋ฅธ๋‹ค : https://github.com/guikarist/tensorflow-windows-build-script

์ด repo์—์„œ๋Š” tensorflow์—์„œ ์ง€์›ํ•˜๋Š” bazel build์—๋‹ค ์ถ”๊ฐ€๋กœ ์œˆ๋„์šฐ์—์„œ shared library์˜ ํ˜•ํƒœ๋กœ ์“ฐ๊ธฐ ์œ„ํ•œ ํŒจ์น˜ ์ž‘์—…์„ ๋ชจ์•„๋†“์€ repo์ด๋‹ค.

์ด repo์˜ ๋‚ด์šฉ๋Œ€๋กœ ์ปดํŒŒ์ผ์„ ํ–ˆ์œผ๋ฉด ํ•ด์•ผ ํ•  ์ผ์€ bazel build์˜ ๊ฒฐ๊ณผ์—์„œ ์ ์ ˆํ•œ ํŒŒ์ผ๋“ค์„ includeํ•ด์ฃผ๋Š” ๊ฒƒ์ธ๋ฐ, ์•„์ง๊นŒ์ง€ ์ถฉ๋ถ„ํžˆ symbol์„ ๋‹ค ๋ชจ์•„๋†“์€ static lib๊ฐ€ ์—†๋Š” ์ƒํƒœ๋ผ์„œ ๋‚ด๊ฐ€ ํ•„์š”ํ•œ symbol์„ ํŒŒ์•…ํ•˜๊ณ  ๋‹ค์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•ด์•ผํ•œ๋‹ค. (์ด๊ฒŒ ๋ฌด์Šจ ์†Œ๋ฆฌ์ธ์ง€๋Š” ์ถ”ํ›„์— ์„ค๋ช…)

๋นŒ๋“œ๊ฐ€ ๋๋‚˜๋ฉด c api์ฒ˜๋Ÿผ

bazel-bin/tensorflow/libtensorflow_cc.so -> tensorflow_cc.dll

bazel-bin/tensorflow/liblibtensorflow_cc.so.ifso -> tensorflow_cc.lib

๋กœ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

include

๋”ฐ๋กœ includeํ•ด์•ผํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ถ”์ถœํ•ด์ฃผ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"

$tfLibDir = "$pwd\tensorflow-1.13.1_cc"
Remove-Item $tfLibDir -ErrorAction SilentlyContinue -Force -Recurse
mkdir $tfLibDir | Out-Null

$tfSourceDir = "D:\tf-win\source"

# Tensorflow lib and dll
Copy-Item  $tfSourceDir\bazel-bin\tensorflow\libtensorflow_cc.so $tfLibDir\tensorflow_cc.dll
Copy-Item  $tfSourceDir\bazel-bin\tensorflow\liblibtensorflow_cc.so.ifso $tfLibDir\tensorflow_cc.lib

# Tensorflow includes
Copy-Item $tfSourceDir\tensorflow\core $tfLibDir\include\tensorflow\core -Recurse -Filter "*.h"
Copy-Item $tfSourceDir\tensorflow\cc $tfLibDir\include\tensorflow\cc -Recurse -Filter "*.h"

Copy-Item $tfSourceDir\bazel-genfiles\tensorflow\core $tfLibDir\include_pb\tensorflow\core -Recurse -Filter "*.h"
Copy-Item $tfSourceDir\bazel-genfiles\tensorflow\cc $tfLibDir\include_pb\tensorflow\cc -Recurse -Filter "*.h"

# Protobuf includes.
Copy-Item $tfSourceDir\bazel-source\external\protobuf_archive\src\google $tfLibDir\include_proto\google -Recurse -Filter "*.h" 

# Absl includes.
Copy-Item $tfSourceDir\bazel-source\external\com_google_absl\absl $tfLibDir\include_absl\absl -Recurse -Filter "*.h" 

# Eigen includes
Copy-Item $tfSourceDir\bazel-source\external\eigen_archive\ $tfLibDir\include_eigen_archive -Recurse
Copy-Item $tfSourceDir\third_party\eigen3 $tfLibDir\include_eigen\third_party\eigen3\ -Recurse
preprocessor definition
COMPILER_MSVC
NOMINMAX

์‹คํ–‰ํ•ด๋ณด๊ณ  external symbol์ด ์—†๋‹ค๊ณ  ๋œจ๋ฉด ๊ทธ ์‹ฌ๋ณผ๋“ค์„ ๊ฐ€์ง€๊ณ  tf_exported_symbols_msvc.lds์— ๋„ฃ๊ณ  ๋‹ค์‹œ ๋นŒ๋“œํ•˜๋ฉด ๋œ๋‹ค.

TF Lite

https://www.tensorflow.org/lite/guide/get_started

TF Lite model๋กœ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡๋ช‡ operation, type๋“ฑ์˜ ์ œ์•ฝ ์กฐ๊ฑด์ด ์žˆ๋‹ค.

fcn ๋ชจ๋ธ์˜ ๊ฒฝ์šฐ์—๋Š” shape์ด scalar์ธ๊ฒŒ ์ œ์•ฝ ์กฐ๊ฑด์— ๊ฑธ๋ ค์„œ, (1) shape์œผ๋กœ ๋ฐ”๊ฟ”์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค.

TF_BOOL ์ง€์› ์•ˆ ํ•จ : tensorflow/tensorflow#20741

TF Lite๋Š” android java api๋ฅผ ์จ์„œ application(apk)๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ด๋ก  ์ƒ์œผ๋กœ๋Š” .tflite ํŒŒ์ผ๋กœ ๋ฐ”๊พธ๊ธฐ๋งŒ ํ•˜๋ฉด ๋‹ค ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ชจ๋ธ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ๋ฉด interpreter๊ฐ€ ๋ป—์–ด๋ฒ„๋ ค์„œ ํ˜„์‹ค์ ์œผ๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. (8 bit quantization ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•ด๋„ 100MB ์ด์ƒ์ž„)

๊ตฌ๊ธ€์—์„œ ์ถ”์ฒœํ•˜๋Š” ๋ชจ๋ธ์ธ ๋ชจ๋ฐ”์ผ์šฉ์œผ๋กœ ์ตœ์ ํ™”๋œ deeplab์œผ๋กœ ํ•˜๋ฉด ์ž˜ ๋œ๋‹ค.

https://www.tensorflow.org/lite/models/segmentation/overview

์‹ค์‹œ๊ฐ„ segmentation apk ์˜ˆ์‹œ : https://github.com/tantara/JejuNet

TF Js

tensorflow js๋Š” ๋ธŒ๋ผ์šฐ์ €๋กœ ๊ฐ€๋™๋˜๋ฏ€๋กœ ๋งค์šฐ ์ ‘๊ทผ์„ฑ์ด ํŽธ๋ฆฌํ•˜๋‹ค.

์ด๊ฒƒ ์—ญ์‹œ tfjs๊ฐ€ ์š”๊ตฌํ•˜๋Š” ํ˜•์‹์œผ๋กœ model์„ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋ฉฐ, operation์ด๋‚˜ type๋“ฑ์˜ ์ œ์•ฝ์€ ์žˆ์ง€๋งŒ, ์ด๋ฒˆ fcn model์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฑธ๋ฆฌ๋Š” ์ œ์•ฝ์ด ์—†์–ด์„œ ์ž˜ ๋๋‹ค.

๋‹ค๋งŒ ์ด ๊ฒฝ์šฐ ๋ฌธ์ œ์ ์€ ์—ญ์‹œ ๋„ˆ๋ฌด๋‚˜๋„ ํฐ fcn model์ด๋‹ค. ์ด๋ก  ์ƒ์œผ๋กœ๋Š” ์•„๋ฌด ๋ชจ๋ธ์ด๋‚˜ ๋ณ€ํ™˜ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ํ˜„์‹ค์ ์œผ๋กœ ์›น ํ™˜๊ฒฝ์—์„œ ์“ฐ๊ธฐ์— ๋ถˆํŽธํ•  ์ •๋„๋กœ model์ด ์ปค์„œ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๋Š” ์‹œ๊ฐ„์ด ๋„ˆ๋ฌด ๋А๋ฆฌ๋‹ค.

๋˜ opencv๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋„์›€์ด ์—†์œผ๋ฏ€๋กœ tensor๋ผ๋ฆฌ์˜ ์—ฐ์‚ฐ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๋ฐฉ์‹์ด ๊นŒ๋‹ค๋กœ์›Œ, image Overlay๋ฅผ ๋น„๊ต์  ํ—ˆ์ ‘ํ•˜๊ฒŒ ํ•  ์ˆ˜๋ฐ–์— ์—†์—ˆ๋‹ค. (ํ˜„์žฌ ์ œ๊ฐ€ ์˜ˆ์‹œ๋กœ ํ•ด๋†“์€ visualization์ด ๋ถ€์ •ํ™•ํ•จ) ์ด๊ฒƒ์€ ๋‚˜์ค‘์— ์ง„์งœ๋กœ ์‚ฌ์šฉํ•  ์ผ์ด ์žˆ์„๋•Œ๋Š” ์ œ๋Œ€๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค.

http://imnotkind.tk/~imnotkind/tfjs/

Conversion

Python TF graph -> pb file

this is NOT freezing, so we can use this pb for training!

init = tf.global_variables_initializer()
saver_def = tf.train.Saver().as_saver_def()
    
print('Run this operation to initialize variables     : ', init.name)
print('Run this operation for a train step            : ', train_op.name)
print('Feed this tensor to set the checkpoint filename: ', saver_def.filename_tensor_name)
print('Run this operation to save a checkpoint        : ', saver_def.save_tensor_name)
print('Run this operation to restore a checkpoint     : ', saver_def.restore_op_name)
    
with open('fcn.pb', 'wb') as f:
    f.write(tf.get_default_graph().as_graph_def().SerializeToString())

pb file + checkpoint -> frozen pb file

freeze_graph --input_graph=/tmp/mobilenet_v1_224.pb \
  --input_checkpoint=/tmp/checkpoints/mobilenet-10202.ckpt \
  --input_binary=true \
  --output_graph=/tmp/frozen_mobilenet_v1_224.pb \
  --output_node_names=MobileNetV1/Predictions/Reshape_1
import sys
import tensorflow as tf
from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib


# Freeze the graph

input_graph_path = 'model/fcn.pb'
checkpoint_path = 'model/fcn-ckpt/model.ckpt-haebin' #prefix of checkpoint, only need .index and .data-???, not .meta
input_saver_def_path = ""
input_binary = True
output_node_names = "Pred"
restore_op_name = "save/restore_all"
filename_tensor_name = "save/Const:0"
output_frozen_graph_name = 'model/frozen_fcn.pb'
#output_optimized_graph_name = 'optimized_'+MODEL_NAME+'.pb'
clear_devices = True


freeze_graph.freeze_graph(input_graph_path, input_saver_def_path,
                          input_binary, checkpoint_path, output_node_names,
                          restore_op_name, filename_tensor_name,
                          output_frozen_graph_name, clear_devices, "")

frozen pb file -> tflite file

tflite_convert `
  --output_file=model/frozen_fcn.tflite `
  --graph_def_file=model/frozen_fcn.pb `
  --input_arrays=input_image,keep_probability `
  --output_arrays=Pred `
  --input_shapes=1,256,256,3:1 `
  --output_format=TFLITE `
  --inference_type=QUANTIZED_UINT8 `
  --std_dev_values=128,0 --mean_values=128,1 `
  --default_ranges_min=-6 --default_ranges_max=6
import tensorflow as tf

graph_def_file = "model/mymodel.pb"
input_arrays = ["input/Placeholder", "input/Placeholder_2"]
output_arrays = ["output/ArgMax"]

converter = tf.lite.TFLiteConverter.from_frozen_graph(
  graph_def_file, input_arrays, output_arrays)
tflite_model = converter.convert()

open("model/mymodel.tflite", "wb").write(tflite_model)
tflite_convert `
  --output_file=model/frozen_fcn.tflite `
  --graph_def_file=model/frozen_fcn.pb `
  --input_arrays=input_image `
  --output_arrays=Pred `
  --input_shapes=1,256,256,3 `
  --output_format=TFLITE `
  --inference_type=QUANTIZED_UINT8 `
  --std_dev_values=128 --mean_values=128 `
  --default_ranges_min=-6 --default_ranges_max=6

import/์™€ :0๋Š” ๋นผ๋„ ๋œ๋‹ค

tensorflow/tensorflow#23932 : scalar value๋Š” [1]๋กœ ๋Œ€์ฒด

frozen pb -> tf js

tensorflowjs_converter `
    --input_format=tf_frozen_model `
    --output_node_names='Pred' `
    --saved_model_tags=serve `
    --output_json=true `
    frozen_fcn.pb `
    frozen_fcn.js

pip install tensorflowjs==0.8.5 tensorflow/tfjs#1541

pb์—์„œ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑด ๊ตฌ๋ฒ„์ „ ๋ฟ์ด๋‹ค. ๊ตฌ๋ฒ„์ „์„ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

์˜ค๋ฅ˜ ๋œจ๋Š” ๊ฒฝ์šฐ : pip install numpy --upgrade : https://stackoverflow.com/questions/54665842/when-importing-tensorflow-i-get-the-following-error-no-module-named-numpy-cor

https://www.tensorflow.org/js/tutorials/conversion/import_saved_model

keras h5 -> pb

from keras import backend as K
from keras.models import load_model
import tensorflow as tf

model = load_model('model/my_model.h5')

#print(model.summary())  (None,300,300,3) -> (None, 5)
print(model.input)
print(model.output)
print(model.targets)
#print(dir(model))
#print(K.learning_phase())
K.set_learning_phase(0) #0 : test, 1 : train
#print(K.learning_phase())

sess = K.get_session()

saver = tf.train.Saver()
saver.save(sess, 'keras/keras.ckpt')

sess.graph.as_default()
graph = sess.graph


saver_def = saver.as_saver_def()
print('Feed this tensor to set the checkpoint filename: ', saver_def.filename_tensor_name)
print('Run this operation to save a checkpoint        : ', saver_def.save_tensor_name)
print('Run this operation to restore a checkpoint     : ', saver_def.restore_op_name)

with open('keras/keras.pb', 'wb') as f:
    f.write(graph.as_graph_def().SerializeToString())

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด inference๋Š” ์™„๋ฒฝํ•œ๋ฐ, ๋ฌธ์ œ๋Š” training์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ tensorflow model์—์„œ๋Š” training operation์„ ๊ฐ€๋™ํ•˜๋ฉด training์ด ๋˜์ง€๋งŒ, keras์˜ ๊ฒฝ์šฐ ๊ทธ๋ ‡์ง€ ์•Š๊ณ  ์ผ์ผํžˆ keras๊ฐ€ model์˜ ๊ณณ๊ณณ์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ set_learning_phase()ํ•จ์ˆ˜๊ฐ€ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ž˜์„œ ๋งŒ์•ฝ keras๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ชจ๋ธ์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•ˆ๋‹ค ํ•˜๋”๋ผ๋„, ๊ทธ๋ž˜ํ”„ ๋ณ€ํ™˜์€ c api์—์„œ๋Š” ํ•  ์ˆ˜ ์—†๋Š” ์ผ์ด๋ผ์„œ ๋ถˆ๊ฐ€๋Šฅ์ธ ๊ฒƒ ๊ฐ™๋‹ค. ๋งŒ์•ฝ keras๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์“ฐ๋Š” train op๊ฐ€ ์žˆ์–ด์„œ ๊ทธ๊ฒƒ๋งŒ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค๋ฉด, ๊ฐ€๋Šฅํ•  ๊ฒƒ์ด๋‹ค.

์ด์Šˆ๋กœ ์˜ฌ๋ ค๋†“์€ ์ƒํƒœ : tensorflow/tensorflow#28681

About

Using tensorflow c api, c++ api, tf lite, tf js, model conversion in Windows

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors