Tensorflow: ์ž๋ฐ” ์ธํ„ฐํŽ˜์ด์Šค

์— ๋งŒ๋“  2015๋…„ 11์›” 09์ผ  ยท  112์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: tensorflow/tensorflow

Java์šฉ swig ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋…ธ๋ ฅ์„ ์ถ”์ ํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„ ์‹œ์ž‘ - ์ง„ํ–‰ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. ์˜๊ฒฌ/ํŒ์ด ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์œผ๋ฉด ์–ธ์ œ๋“ ์ง€ ํ† ๋ก ์— ์ฐธ์—ฌํ•˜์‹ญ์‹œ์˜ค!

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

์—…๋ฐ์ดํŠธ: @saudet ๋•๋ถ„์— javacpp๋กœ ์ž‘์—…์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  Java ํ”„๋กœ๊ทธ๋žจ์—์„œ TensorFlow ๋ชจ๋ธ์„ ์ฝ๊ฑฐ๋‚˜ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

https://medium.com/google-cloud/how-to-invoke-a-trained-tensorflow-model-from-java-programs-27ed5f4f502d#.tx8nyds5v

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

๋ฉ‹์ง„!

https://github.com/tensorflow/tensorflow/issues/3 ์—์„œ ์ด ๋Œ“๊ธ€์„ ์—ฌ๊ธฐ๋กœ


์ƒ๋‹นํžˆ ์ข‹์€ ์ˆ˜๋ ด์„ ๊ฐ€์ง„ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๊ฐ€ ์žˆ์ง€๋งŒ ํ˜„์žฌ๋Š” ๋ช‡ ๊ฐ€์ง€ C++ ํ…Œ์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ ๋Œ€๋ถ€๋ถ„ Python์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ํ˜„์žฌ Python ์ „์šฉ์ธ ๊ทธ๋ž˜ํ”„๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋งŽ์€ ๊ธฐ๋Šฅ, ํŠนํžˆ ์ž๋™ ๋ฏธ๋ถ„ ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ Java์—์„œ ๊ทธ๋ž˜ํ”„๋ฅผ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ์ด ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ C++๋กœ ์ด๋™ํ•  ๊ณ„ํš์ด ์žˆ์œผ๋ฉฐ, ์ด ์‹œ์ ์—์„œ Java SWIG ๋ฐ”์ธ๋”ฉ์€ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ์— ๋” ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ Java SWIG ์ฑŒ๋ฆฐ์ง€๋ฅผ ๋งก๋Š”๋‹ค๋ฉด ๊ฒ€ํ† ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋“ฑ์˜ ์—…์ŠคํŠธ๋ฆผ์„ ๊ธฐ๊บผ์ด ์ˆ˜๋ฝํ•  ๊ฒƒ์ด๋ฉฐ, ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ์˜ ์ง€์†์ ์ธ ํ…Œ์ŠคํŠธ์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ถ€๊ธˆ ์ˆ˜๋ฝ์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ํ˜„์žฌ ์œ ๋™์ ์ด์ง€๋งŒ ์•ˆ์ •ํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„
๋˜ํ•œ TensorFlow for Java๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. @ravwojdyla ํ˜น์‹œ Swig Interface for Java ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์…จ์Šต๋‹ˆ๊นŒ? ๋‹น์‹ ์ด ์žˆ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ์˜ ๋…ธ๋ ฅ์— ๋™์ฐธํ•˜๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ํ˜‘๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์‹ญ๋‹ˆ๊นŒ,
์ €๋Š” ๋ฉ”์ธ C++ API์˜ SWIG ๋žฉ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ํฌํฌ์—์„œ ์ง€๊ธˆ๊นŒ์ง€์˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ ์•„์ง ๋๋‚˜์ง€ ์•Š์€ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ #include "tensorflow/core/lib/core/error_codes.pb.h" ์„(๋ฅผ) ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๊ณ  ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ๋‚ด์—์„œ ์›ํ•˜๋Š” ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ž…๋ ฅ๋„ ํฌ๊ฒŒ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Caffe ๋ฐ OpenCV์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” javacpp ์‚ฌ์ „ ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/bytedeco/javacpp-presets/issues/111 ๋„

/cc @saudet

@pslam - ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค - ํ™•์‹คํžˆ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ €๋Š” JavaCPP์— ๋Œ€ํ•œ ๊ฝค ๊ธฐ๋Šฅ์ ์ธ ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค: https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow. SWIG๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ JavaCPP๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ๋‚˜๋Š” ํ™•์‹คํžˆ ํ”ผ๋“œ๋ฐฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (cc @bhack ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!)

@saudet ์•„์ฃผ ๋ฉ‹์ง€๊ฒŒ ์™„์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค! SWIG ๋žฉ์„ ๊ฑฐ์˜ ์™„๋ฃŒํ–ˆ์ง€๋งŒ ๊ตฌํ˜„๋„ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด SWIG ๋žฉ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ ์ค‘ ๊ท€ํ•˜๊ฐ€ ํ•  ์ˆ˜ ์—†๋Š” ์ผ์€ ์—†์Šต๋‹ˆ๋‹ค. JavaCPP๋Š” ๋งค์šฐ ๋ฉ‹์ง„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ–ฅํ›„ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@kylevedder๋‹˜ , error_codes.pb.h ์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์…จ์Šต๋‹ˆ๊นŒ?
[ํŽธ์ง‘๋จ]
๋ชจ๋“  .pb.h ํŒŒ์ผ์€ .proto์—์„œ ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.

@tngan ๋„ค, ์ €๋„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ํ”„๋กœ์ ํŠธ์˜ .proto ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ProtoBuff3๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” Ubuntu 14.04๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž์—์„œ ProtoBuff3๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— 3.0.0 ๋ฒ ํƒ€ ๋ฆด๋ฆฌ์Šค ์—์„œ ๊ฐ€์ ธ์˜จ ์†Œ์Šค์—์„œ ์ปดํŒŒ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜๋Š” ํ˜„์žฌ ์žฅ์• ๋ฌผ์€ ProtoBuff๊ฐ€ ์ „์ฒด ํŒŒ์ผ ํŠธ๋ฆฌ์—์„œ ์žฌ๊ท€ํ•˜๋„๋ก ํ•˜๊ณ  .proto ํŒŒ์ผ์„ .h ๋ฐ .cc ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๊ฐ ํด๋”๋ฅผ ์กฐ๊ธˆ์”ฉ ์ˆ˜ํ–‰ํ•˜๋ฉด ์•„์ง ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์€ .proto ํŒŒ์ผ์— ๋Œ€ํ•œ ๋งŒ์กฑ์Šค๋Ÿฝ์ง€ ๋ชปํ•œ ์ข…์†์„ฑ์œผ๋กœ ์ธํ•ด ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@kylevedder SWIG ๋ž˜ํผ๊ฐ€ ๋ณ„๋„์˜ ์ €์žฅ์†Œ์— ์žˆ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด tensorflow ์ €์žฅ์†Œ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? protoc ๋Š” ๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. tensorflow ์ €์žฅ์†Œ์—์„œ ์ž‘์—…ํ•˜๊ฑฐ๋‚˜ Bazel์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ protobuf ๋นŒ๋“œ ๋Œ€์ƒ๊ณผ ์ด๋“ค ๊ฐ„์˜ ์ข…์†์„ฑ์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ณ„๋„์˜ ์ €์žฅ์†Œ์—์„œ ์ž‘์—…ํ•˜๊ณ  ๋‹ค๋ฅธ ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด protobuf ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์›ํ•˜์‹œ๋ฉด ๋นŒ๋“œ ์„ค์ •์„ ๋„์™€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

@davidzchen ์ œ์•ˆ์— ๊ฐ์‚ฌ๋“œ๋ฆฌ๋ฉฐ ๋ชจ๋“  ๋„์›€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ:

์ €๋Š” ์ด๋ฏธ Bazel์„ ์„ค์ •ํ•˜๊ณ  .whl ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ํŒŒ์ผ์„ pip ๋„˜๊ฒผ๊ณ  First TensorFlow ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ถ„๊ธฐ๋œ ์ €์žฅ์†Œ์— SWIG ๋ž˜ํผ ํŒŒ์ผ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. core/javaWrapper ์•„๋ž˜์˜ ํด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค. [[๋งํฌ](https://github.com/kylevedder/tensorflow/tree/master/tensorflow/core/javaWrapper)]

๋‚ด๊ฐ€ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ:

๊ถ๊ทน์ ์œผ๋กœ ๋‚ด ๋ชฉํ‘œ๋Š” Java์—์„œ ๊ธฐ๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜ ์žˆ๋Š” .so ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ g++๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์ฒด ์‹œ์Šคํ…œ์„ .so ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ .proto ํŒŒ์ผ์€ ์ด ์ปดํŒŒ์ผ ์ „์— ๋จผ์ € .h ๋ฐ .cc ๋กœ ํ™•์žฅ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ด๊ฒƒ์ด protoc ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ protoc ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ชจ๋“  ์‹œ๋„๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ณ„๋กœ ์ด๋ฃจ์–ด์กŒ์œผ๋ฏ€๋กœ ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” ์•„๋‹ˆ์—ˆ์ง€๋งŒ ๋žฉ ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ๋‚˜์˜ ์‹œ๋„๋ฅผ ์—ฌ๊ธฐ ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค protoc ์Šคํฌ๋ฆฝํŠธ์—์„œ.

๋งˆ์ง€๋ง‰์œผ๋กœ, ๊ฐœ์„  ์˜์—ญ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์€ ํฌ๊ฒŒ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

@kylevedder ์ €๋Š” ์ด๋ฏธ JavaCPP ์‚ฌ์ „ ์„ค์ •์˜ ์ผ๋ถ€๋กœ .so ๋นŒ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค: https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow. Bazel ๋•๋ถ„์— ์ •๋ง ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒจ์น˜๋ฅผ ์ ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

diff -ruN tensorflow/tensorflow/cc/BUILD tensorflow-patch/tensorflow/cc/BUILD
--- tensorflow/tensorflow/cc/BUILD  2015-11-22 00:00:02.441829192 +0900
+++ tensorflow-patch/tensorflow/cc/BUILD    2015-11-14 11:15:12.689330351 +0900
@@ -75,6 +75,17 @@
     ],
 )

+cc_binary(
+    name = "libtensorflow.so",
+    copts = tf_copts(),
+    linkshared = 1,
+    deps = [
+        ":cc_ops",
+        "//tensorflow/core:kernels",
+        "//tensorflow/core:tensorflow",
+    ],
+)
+
 filegroup(
     name = "all_files",
     srcs = glob(

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Bazel์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

bazel build -c opt //tensorflow/cc:libtensorflow.so

AFAIK, ์ด๊ฒƒ์€ C++ API์— ๋Œ€ํ•œ ๊ด€์‹ฌ์˜ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ง‘์–ด์‚ผํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@saudet cc_library ๋Œ€์‹  cc_binary ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๋ฆ„์ด tensorflow cc_library ๊ทœ์น™๋งŒ ์žˆ์œผ๋ฉด ๋นŒ๋“œ ๋Œ€์ƒ์ด libtensorflow.so ๋ผ๋Š” ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.

@kylevedder ๋ชฉํ‘œ๊ฐ€ .so ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด @saudet์ด ์ œ์•ˆํ•œ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ๊ฒƒ์ด ์ž‘๋™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Java ์ฝ”๋“œ์—์„œ TensorFlow ํ”„๋กœํ† ์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ java_* Bazel ๋นŒ๋“œ ๋Œ€์ƒ์—์„œ .proto ์—์„œ Java ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” proto_library ๋Œ€์ƒ์— ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. .proto ํŒŒ์ผ.

๊ธฐ๋ณธ proto_library ๊ทœ์น™์„ ๊ณต๊ฐœํ•˜๊ธฐ ์ „์— ์•„์ง ํ•ด์•ผ ํ•  ์ผ์ด ์•ฝ๊ฐ„ ์žˆ์ง€๋งŒ(bazelbuild/bazel#52 ์ฐธ์กฐ) TensorFlow๋Š” cc_proto_library ๋ฐ py_proto_library ๊ทœ์น™์€ protobuf ์—์„œ Bazel์— ํฌํ•จ๋œ Java genproto ๊ทœ์น™ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. proto_library ๋Œ€ํ•œ ํƒ€์ž„๋ผ์ธ์ด ๋ฌด์—‡์ธ์ง€, Protobuf์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ทœ์น™์„ genproto ๋กœ ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ€๊ณผ ํ•จ๊ป˜ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ํ”ผ๋“œ๋ฐฑ:

  • ๋‚˜๋Š” ์ผ๊ด€์„ฑ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„์„ ์œ ์ง€ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐ java_wrapper ๋ณด๋‹ค๋Š” javaWrapper
  • ์•„๋งˆ๋„ Java ๋ž˜ํผ์— ๋Œ€ํ•œ ๋” ๋‚˜์€ ์œ„์น˜๋Š” //tensorflow/java/wrapper ๋ณด๋‹ค๋Š” //tensorflow/core/java_wrapper ์ผ๊นŒ์š”?
  • ๋‚ด๋ถ€์ ์œผ๋กœ .swig ํŒŒ์ผ์„ ๊ฐ€์ ธ์™€ ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋นŒ๋“œ ๊ทœ์น™์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒ์„ฑ๋œ ํŒŒ์ผ์„ ์ฒดํฌ์ธํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. Bazel์ด ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ SWIG ๋นŒ๋“œ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์–ด๋ ค์šด์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@davidzchen ํŠน๋ณ„ํ•œ ์ด์œ ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ €๋Š” Bazel์„ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๊ณ  ๋ฉ”์ผ๋ง ๋ฆฌ์ŠคํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ linkshared=1 ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํŒ์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์—…๋ฐ์ดํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@saudet ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! Bazel์— ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์ค‘์ด์—ˆ์Šต๋‹ˆ๋‹ค. :) ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์–ธ์ œ๋“ ์ง€ ์•Œ๋ ค์ฃผ๊ฑฐ๋‚˜ ๋ฒ„๊ทธ๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”.

@saudet Bazel ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ •๋ณด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋„ ์ฒ˜์Œ์ด๊ณ  ๊ทธ๋Ÿฐ ์‹์œผ๋กœ .so ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

@davidzchen cc_library ์‚ฌ์šฉ์— ๋Œ€ํ•œ ๋ถ€๋ก์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. Bazil ๋ž˜ํผ ๋นŒ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ @saudet ์˜ ์˜ˆ์ œ๋ฅผ

๋˜ํ•œ .so ํŒŒ์ผ ์ƒ์„ฑ์— ๋Œ€ํ•œ ์ด์ „ ์˜๊ฒฌ์—์„œ ๋ช…ํ™•ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ชฉํ‘œ๋Š” ์ƒ์„ฑํ•˜๋Š” ๋™์•ˆ .so ์›๋ณธ ์†Œ์Šค์—์„œ ํŒŒ์ผ์„ ๋˜ํ•œ ํฌํ•จ ํ•  $ # $ 4 $ # $๋ฅผ ๊ฟ€๊บฝ ๊ฟ€๊บฝ๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ํŒŒ์ผ์„ ๋‚ด๋ถ€์˜ .so JNI๋ฅผ์„ ์ด‰์ง„ํ•˜๊ธฐ ์œ„ํ•ด ์ „ํ™”. ํ˜„์žฌ SWIG์—์„œ ์ƒ์„ฑํ•œ .cxx ํŒŒ์ผ์„ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฐธ์กฐํ•˜๋ ค๊ณ  JNI.h ์—์žˆ๋Š” ํ—ค๋” $JAVA_HOME/include/ ํ•˜์ง€๋งŒ ์™ธ๋ถ€ ๊ฒฝ๋กœ๋ฅผ ํฌํ•จ ์ดํ•ด Bazel์„ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@davidzchen ํ , ์•„๋‹ˆ, cc_library ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Bazel์ด -shared ์˜ต์…˜์„ ์ปดํŒŒ์ผ๋Ÿฌ์— ์ „๋‹ฌํ•˜๋„๋ก ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. http://bazel.io/docs/be/c-cpp.html.

@saudet ๋ณธ์ธ์ด -shared ๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”๋Š” ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. cc_library ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ .so ๋ฅผ ๋นŒ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ๋‹น์‹ ์„ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

@kylevedder JNI ํ—ค๋”๋Š” ์ž‘์—… ๊ณต๊ฐ„ ์™ธ๋ถ€์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Bazel์€ ๋กœ์ปฌ JDK๋ฅผ ๋กœ์ปฌ ์ €์žฅ์†Œ ๋กœ ํฌํ•จํ•˜๊ณ  ๋กœ์ปฌ JDK์— ์˜์กดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋‚ด์žฅ ๋Œ€์ƒ( jdk.WORKSPACE ๋ฐ ํ•ด๋‹น jdk.BUILD )์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ Bazel ์ž‘์—… ๊ณต๊ฐ„์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Bazel ์ž์ฒด๋Š” JNI๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋กœ์ปฌ JDK์™€ ์ธํ„ฐํŽ˜์ด์Šคํ•ฉ๋‹ˆ๋‹ค( src/main/native/BUILD ). ์ด ๋นŒ๋“œ ํŒŒ์ผ์—์„œ์ด ๋‘ ๊ฐ€์ง€ genrule s๋ฅผ JNI ํ—ค๋”์™€ ๋ณต์‚ฌ cc_library ๋Š” ํ—ค๋”์— ๋”ฐ๋ผ ์‚ฌ์šฉ JNI, ๊ทธ ๊ฑด๋ฌผ๋˜์–ด์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ๋Œ€์ƒ๊ณผ includes = ["."] ๊ทธ๋ž˜์„œ C ++ ์ฝ”๋“œ์™€ JNI ํ—ค๋”๋ฅผ ํฌํ•จ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” #include <jni.h> . ์ด๊ฒƒ์€ ํ˜„์žฌ ์™ธ๋ถ€ ์ €์žฅ์†Œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ๊ฐœ์„  ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๊ณ  @local-jdk ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ ๋™์•ˆ JNI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” TensorFlow ๋ฐ ๊ธฐํƒ€ Bazel ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. .

์—ฌ๊ธฐ์— ์ถ”๊ฐ€ ๋นŒ๋“œ ํŒŒ์ผ์— ๋Œ€ํ•œ ํŒจ์น˜์ž…๋‹ˆ๋‹ค genrule ๋‹น์‹ ์ด ํ•„์š”๋กœํ•˜๋Š” JNI ํ—ค๋”์™€ ์ผ๋ถ€ ๋ณ€๊ฒฝ ๋ณต์‚ฌ์˜ ๋Œ€์ƒ์„ cc_library ์ฆ‰, ์˜ฌ๋ฐ”๋ฅธ ์ข…์†์„ฑ์„ ์„ค์ •ํ•˜๋Š” ๋ชฉํ‘œ๋Š” :

  1. genrule ์—์„œ srcs ์˜ํ•ด ํ˜„์žฌ ํŒจํ‚ค์ง€์— ๋ณต์‚ฌ๋œ jni.h ๋ฐ jni_md.h ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  2. tensorflow/core/public ์•„๋ž˜์— ํ—ค๋”๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋„๋ก //tensorflow/core ์— ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ํ—ค๋” ๋˜๋Š” ์†Œ์Šค ํŒŒ์ผ์€ Bazel์˜ ๊ด€์ ์—์„œ ๋ณผ ๋•Œ ๋ณ„๋„์˜ ํŒจํ‚ค์ง€์— ์žˆ์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ํŒŒ์ผ์ด ํฌํ•จ๋œ ๋นŒ๋“œ ๋Œ€์ƒ์— ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
diff --git a/tensorflow/core/java/wrapper/BUILD b/tensorflow/core/java/wrapper/BUILD
index 72b4076..04a3394 100644
--- a/tensorflow/core/java/wrapper/BUILD
+++ b/tensorflow/core/java/wrapper/BUILD
@@ -7,10 +7,30 @@ exports_files(["LICENSE"])
 load("/tensorflow/tensorflow", "tf_copts")
 load("/tensorflow/tensorflow", "tf_gen_op_wrappers_cc")

+genrule(
+    name = "copy_link_jni_md_header",
+    srcs = ["//external:jni_md_header-linux"],
+    outs = ["jni_md.h"],
+    cmd = "cp -f $< $@",
+)
+
+genrule(
+    name = "copy_link_jni_header",
+    srcs = ["//external:jni_header"],
+    outs = ["jni.h"],
+    cmd = "cp -f $< $@",
+)
+
 cc_library(
     name = "java_wrapper",
-    srcs = glob(["*.cc","*.cxx","*.h"]),
-    copts = ["-I$$JAVA_HOME/include/", "-I$$JAVA_HOME/include/linux/"],
+    srcs = glob(["*.cc", "*.cxx", "*.h"]) + [
+        ":jni.h",
+        ":jni_md.h",
+    ],
+    includes = ["."],
+    deps = [
+        "//tensorflow/core",
+    ],
     visibility = ["//visibility:public"],
 )

์ผ๋ฐ˜์ ์œผ๋กœ Bazel์˜ ์ปดํŒŒ์ผ ์ž‘์—…์€ ์†Œ์Šค ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ์—์„œ ์‹คํ–‰๋˜๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด SWIG ํŒŒ์ผ์˜ ํฌํ•จ์„ ๋ณ€๊ฒฝํ•œ ๋‹ค์Œ C++ ํŒŒ์ผ์„ ๋‹ค์‹œ ์ƒ์„ฑํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ ํฌํ•จ์„ ๊ฐ–๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž˜:

diff --git a/tensorflow/core/java/wrapper/tensor_c_api.i b/tensorflow/core/java/wrapper/tensor_c_api.i
index d08b571..9ab1fa1 100644
--- a/tensorflow/core/java/wrapper/tensor_c_api.i
+++ b/tensorflow/core/java/wrapper/tensor_c_api.i
@@ -1,8 +1,8 @@
 %module tensor_c_api_module
 %{
-#include "../../public/tensor_c_api.h"
+#include "tensorflow/core/public/tensor_c_api.h"
 %}
-%include "../../public/tensor_c_api.h"
+%include "tensorflow/core/public/tensor_c_api.h"
 %include "stddef.h"

์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋ฉด copy_link_jni_md_header genrule ๋Š” Linux ์ „์šฉ ํ—ค๋”๋งŒ ๋ณต์‚ฌํ•˜๋ฏ€๋กœ Linux์šฉ JNI ๋นŒ๋“œ๊ฐ€ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ํ”Œ๋žซํผ๋ณ„ JNI ํ—ค๋”๋ฅผ ๋ณต์‚ฌํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ๋‹ค๋ฅธ ํ”Œ๋žซํผ์— ๋Œ€ํ•ด cpu config_setting ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ tensorflow์—๋Š” config_setting ์˜ --cpu=darwin ์— ๋Œ€ํ•œ tensorflow/python/BUILD ์žˆ์Šต๋‹ˆ๋‹ค. //tensorflow/core ์™€ ๊ฐ™์€ ๋” ์ ์ ˆํ•œ ํŒจํ‚ค์ง€๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Bazel๊ณผ ๋™์ผํ•œ config_setting ์„ธํŠธ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค( src/BUILD ).
  2. copy_link_jni_md_header ๊ฐ€ select() ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ •ํ•œ ๊ตฌ์„ฑ ์„ค์ •์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅธ JNI ํ—ค๋”๋ฅผ ๋ณต์‚ฌํ•˜๋„๋ก ํ•˜์‹ญ์‹œ์˜ค . genrule ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
genrule(
    name = "copy_link_jni_md_header",
    srcs = select({
        "//tensorflow/core:darwin": ["//external:jni_md_header-darwin"],
        "//tensorflow/core:darwin_x86_64": ["//external:jni_md_header-darwin"],
        "//tensorflow/core:freebsd": ["//external:jni_md_header-freebsd"],
        "//conditions:default": ["//external:jni_md_header-linux"],
    }),
    outs = ["jni_md.h"],
    cmd = "cp -f $< $@",
)

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ธฐ๊บผ์ด ๋„์™€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‹น์‹ ์„ ์œ„ํ•ด ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

@davidzchen cc_library๋Š” .a ํŒŒ์ผ์„ ๋งŽ์ด ์ƒ์„ฑํ•˜์ง€๋งŒ .so ํŒŒ์ผ์€ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. TensorFlow์— ๋Œ€ํ•ด ์ด์ „์— ๊ถŒ์žฅ๋œ ๋Œ€๋กœ 0.1.0์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค... 0.1.1์—์„œ ์ˆ˜์ •๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์‹œ ์‹œ๋„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@davidzchen ๋„์›€์„ ์ฃผ์…”์„œ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ง€์‹œ์— ๋”ฐ๋ผ Java ๋ž˜ํผ BUILD ํŒŒ์ผ ๊ณผ SWIG .i ํŒŒ์ผ ์„ ์ œ์•ˆํ•œ ๋Œ€๋กœ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋žฉ ์Šคํฌ๋ฆฝํŠธ๋ฅผ core/java/wrapper ์—์„œ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™ํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ๋งํฌ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ jni_md.h ํŒŒ์ผ์— ๋Œ€ํ•œ ์ผ๋ฐ˜ํ™” genrule ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  libtensorflow.so ๋นŒ๋“œ์— ์ง‘์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„ libtensorflow.so ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. "libtensorflow"์˜ ๋ณ€์ข…์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ชจ๋“  ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ๊ฒ€์ƒ‰ํ–ˆ๊ณ  ๊ด€๋ จ ํ•ญ๋ชฉ์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„์ด ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๊ณ  ๋‹จ์ˆœํ•œ ์‚ฌ์šฉ์ž ์˜ค๋ฅ˜์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, @saudet ์ด .so ์ƒ์„ฑ์— ๋Œ€ํ•œ cc_library ๊ทœ์น™์œผ๋กœ ๊ฒช๊ณ  ์žˆ๋Š” ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ชจ๋“  ๋„์›€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ž˜๋ชป ์•Œ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด .so @saudet ์‚ฌ์šฉ ์•Š์•˜๋‹ค ๋ฌด์—‡ ์ด์  ์ข…์†์„ฑ ํฌํ•จํ•˜๋Š” cc_binary ๊ฐ€์ง„ linkshared = 1 ๋ฐ name = "libtensorflow.so" ์ •ํ™•ํ–ˆ๋‹ค. cc_binary.linkshared ๋ฌธ์„œ์—์„œ :

๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ์†์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๊ทœ์น™์— linkshared=1์„ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ์˜ต์…˜์€ ๊บผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ์„ฑํ™”ํ•˜๋ฉด foo์˜ ํ•ฉ๋ฆฌ์ ์ธ ๊ฐ’์— ๋Œ€ํ•ด ๋ฐ”์ด๋„ˆ๋ฆฌ ์ด๋ฆ„์„ libfoo.so(๋˜๋Š” ๋Œ€์ƒ ํ”Œ๋žซํผ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ช…๋ช… ๊ทœ์น™)๋กœ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„์˜ ์ฃผ๋œ ์ฐจ์ด์  .so '์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ง„ s๋Š” cc_library ํƒ€๊ฒŸ๊ณผ .so ๋นŒ๋“œ cc_binary ์ƒ๊ธฐ ๋ฐฉ๋ฒ•์€ ์ƒ๊ธฐ ์ด์šฉ์€ ๊ทธ cc_library ์•„ํ‹ฐํŒฉํŠธ์—๋Š” srcs ์˜ ์ฝ”๋“œ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์ถ•ํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค cc_library ์•„๋‹ˆ์˜ค ๋ชฉํ‘œ srcs ๋งŒ deps ๊ฐ™์€, //tensorflow/core ๋ชจ๋“  ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— cc_binary ๋Œ€์ƒ์€ ๋ชจ๋“  ์ „์ด์  ์ข…์†์„ฑ์— ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

ํ˜ผ๋ž€์„ ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” ๋ฌธ์„œ๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  .so ๋นŒ๋“œ์— ๋Œ€ํ•œ ์˜ˆ์ œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Tensorflow์™€ ๋ชจ๋“  ์ข…์†์„ฑ์„ ๋นŒ๋“œํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” TensorFlow๋ฅผ node.js๋กœ ์ด์‹ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ „์ฒด ์ €์žฅ์†Œ์—์„œ ํ•„์ˆ˜ ์†Œ์Šค๋งŒ ์ปดํŒŒ์ผํ•˜๊ณ  ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/node-tensorflow/node-tensorflow/blob/1.0.0/tools/install.sh#L233 -L282

@davidzchen .so ์ƒ์„ฑ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ์— ๋”ฐ๋ผ ๋‚ด ์„ค์ •์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋‚œ ์ƒ์„ฑ ํ•œ tensorflow/core/java/wrapper/example _extremely_ ๊ธฐ๋ณธ ํ…Œ์Šคํ„ฐ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ์—๊ฒŒ JNI ํ•จ์ˆ˜ ํ˜ธ์ถœ .so ์ž‘์—…. ์ฐธ๊ณ  createWrapper.sh ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ์‹คํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค compileAndRun.sh .

๋‚˜๋Š” SWIG ๋ž˜ํผ๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ๋” ๋‚˜์€ ์˜ˆ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ๋ฐ”์ธ๋”ฉ ์ž‘์—…์— ๋Œ€ํ•œ ์ตœ์†Œํ•œ์˜ ์ฆ๊ฑฐ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋„์›€์„ ์ฃผ์‹  @davidzchen ๊ณผ @saudet ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค ์—†์ด๋Š” ์ด๊ฒƒ์„ ํ•  ์ˆ˜ ์—†์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฉ‹์ง„! ์ž‘์—…ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, @kylevedder!

๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด 1) Skylark SWIG ๊ทœ์น™์„ ์ƒ์„ฑํ•˜๊ณ  2) Bazel์˜ Java ๊ทœ์น™ ์„ ์‚ฌ์šฉํ•˜์—ฌ Java ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•˜์—ฌ createWrapper.sh ๋ฐ compileAndRun.sh ์Šคํฌ๋ฆฝํŠธ๋ฅผ Bazel ๋นŒ๋“œ์— ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@davidzchen ์ •๋ง ์ข‹๊ฒ ๊ตฐ์š”! SWIG ๋ž˜ํผ์™€ ๊ธฐ๋ณธ ์˜ˆ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

JavaCPP์— ๋Œ€ํ•œ ์‚ฌ์ „ ์„ค์ •์„ ์™„๋ฃŒํ•˜๊ณ  example_trainer.cc ์ƒ˜ํ”Œ์„ ์ด์‹ํ–ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow
SWIG๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋™๋“ฑํ•œ ๋ž˜ํผ์™€ ์ด๊ฒƒ์„ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค!

API ๋งํฌ๊ฐ€ ์†์ƒ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค: http://bytedeco.org/javacpp-presets/tensorflow/apidocs/

@verdiyanto ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์•„์ง CI๊ฐ€ ์—†์ง€๋งŒ API ๋ฌธ์„œ๋ฅผ ์—…๋กœ๋“œํ•˜๋Š” ๊ฒƒ์€ ์ถฉ๋ถ„ํžˆ ์‰ฝ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Œํ•œ ๊ทธ๋ ‡๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฆ๊ธฐ๋‹ค!

@saudet JavaCPP ์‚ฌ์ „ ์„ค์ •์— ๋Œ€ํ•œ ์ข‹์€ ์ž‘์—…์ž…๋‹ˆ๋‹ค!

๋‚ด ์ž‘์—…์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ: SWIG ๋ž˜ํผ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—์„œ ์ˆ˜ํ–‰ํ•œ ์ž‘์—…์„ ๋ณผ ์ˆ˜

์ €๋Š” SWIG๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ฃผ์š” ํ”„๋กœ์ ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— SWIG๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ SWIG์˜ ์ž‘๋™ ๋ฐฉ์‹๊ณผ C/C++๋ฅผ SWIG Java ๋ž˜ํผ๋กœ ๋ž˜ํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹คํ–‰ํ•˜๋Š” SWIG ๊ธฐ๋ณธ ์‚ฌํ•ญ ๊ณผ SWIG ๋ฐ Java ์— ๋Œ€ํ•œ SWIG ์„ค๋ช…์„œ๋ฅผ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์„œ์—์„œ๋Š” SWIG๊ฐ€ C/C++์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ถˆํˆฌ๋ช…ํ•œ Java ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด SWIG์— ์˜ํ•ด ์ƒ์„ฑ๋œ SWIGTYPE_p_void ์™€ ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์–ป๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” POJO๋ฅผ ์ด๋Ÿฌํ•œ SWIG ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด tensor_c_api.h ์—์„œ C ๋ฉ”์„œ๋“œ TF_CreateTensor() ๋Š” ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” void* ์™€ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•˜๋Š” size ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”์ดํŠธ ๋‹จ์œ„์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ. ์ด๊ฒƒ์€ C/C++์—์„œ๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ํ•ฉ๋ฆฌ์ ์ธ ๋””์ž์ธ ํŒจํ„ด์ด์ง€๋งŒ Java์—์„œ๋Š” ์™„์ „ํžˆ ๋ฌด์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. SWIG ์ƒ์„ฑ Java ๋ฉ”์„œ๋“œ TF_CreateTensor() ๋Š” size ์™€ ํ•จ๊ป˜ SWIGTYPE_p_void ๊ฐœ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ String ๊ณผ ๊ฐ™์€ POJO๋ฅผ ๋ณ€ํ™˜ํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค SWIGTYPE_p_void ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ํ•„๊ธฐ์—†์ด.

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ํ˜„์žฌ ๊ฑฐ์ง“๋ง์„ ํ•˜๋Š” ๊ต์ฐจ๋กœ์ž…๋‹ˆ๋‹ค. TF_DataType ์ •์˜๋œ ๋ชจ๋“  ์œ ํ˜•์„ ์ทจํ•˜๊ณ  void* ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ˆ˜๋งŽ์€ C/C++ ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•์„ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ๊ฐ™์€ ์ผ์„ ํ•˜๋Š” SWIG ํƒ€์ž…๋งต. SWIG ๋ฌธ์„œ๋Š” ๋‘ ์†”๋ฃจ์…˜ ๋ชจ๋‘ ๊ฒ‰๋ณด๊ธฐ์— ์ƒํ˜ธ ๊ตํ™˜ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ์†”๋ฃจ์…˜์„ ์„ ํ˜ธํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฌธ์ œ๋Š” C/C++ ๋ณ€ํ™˜ ํ•จ์ˆ˜ ๋˜๋Š” SWIG ์œ ํ˜• ๋งต์ž…๋‹ˆ๊นŒ?

@kylevedder ์ฒ˜์Œ์— JavaCPP๋ฅผ ๋งŒ๋“  ์ด์œ ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. :)

@saudet ์˜ JavaCPP ์‚ฌ์ „ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! tensorflow์— ๋Œ€ํ•œ Clojure ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ถ€ ์˜๊ฒฌ:

a) ๋‹จ์ˆœํ™” / ์ƒ์œ„ ๊ณ„์ธต์˜ ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ JavaCPP API๋Š” ๋ธŒ๋ฆฟ์ง€ ์—†์ด JVM์—์„œ ์ง์ ‘ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” protobuf ๊ธฐ๋Šฅ์„ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๊นจ๋‹ซ๋Š” ๋ฐ ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์ง€๋งŒ JavaCPP ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ protobuf ๊ฐ์ฒด๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  interop์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ํ”Œ๋žซํผ ๋…๋ฆฝ์ ์ธ ํ‘œํ˜„์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ ์ด๋ฅผ Session์— ์ฑ„์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” Jvm ๊ธฐ๋ฐ˜ protobufs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JavaCPP ์ƒ์„ฑ์ž ๊ธฐ๋Šฅ์„ ์šฐํšŒํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋์„ ๋งบ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๊ธฐ์— ๋” ๊ฐ„๋‹จํ•œ API์™€ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” protobuf๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฉ‹์ง„ .toString ํ˜•์‹์ž…๋‹ˆ๋‹ค.

ํŠนํžˆ Clojure์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๊ด€์ ์—์„œ tensorflow ๊ทธ๋ž˜ํ”„๋ฅผ ์„ค๋ช…ํ•œ ๋‹ค์Œ protobuf๋กœ ์ง์ ‘ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๋‚ด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๊ฐ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ฐพ์•„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค.

b) ๋นŒ๋“œ ๋ฐ ํŒจํ‚ค์ง€ ๊ฐœ์„ 

์ €๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œํ•˜๊ฑฐ๋‚˜ ์ด๋Ÿฌํ•œ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉ๋˜๋Š” ๋นŒ๋“œ ๋„๊ตฌ์— ๋Œ€ํ•œ ์ „๋ฌธ๊ฐ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. maven-ized ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ƒ์„ฑ๋œ Java protobuf ํด๋ž˜์Šค๋„ ํฌํ•จ๋œ ๊ฒฝ์šฐ. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ด๋Š” ๋ฐ ๋‹นํ™ฉ์Šค๋Ÿฌ์šด ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

c) ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๊ทธ๋ž˜ํ”„ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์ˆ˜๊ฐ€ ์ ์€ ๊ฒƒ์ด ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ ์ œ ๋ฐฉ๋ฒ•๋ก ์€ ๋‹ค์†Œ ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค. JavaCPP ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ๋‚ด JVM protobuf์— ๋งˆ์ƒฌ๋งํ•˜๊ณ , ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•์‹์„ ๋ณด๊ณ , ๋™์ผํ•œ ํ˜•์‹์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ž์ฒด ์ƒ์„ฑ์ž๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ƒ…๋‹ˆ๋‹ค.

TensorFlow์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๊ทธ๋ž˜ํ”„์˜ ์ž‘์€ ์ปฌ๋ ‰์…˜์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ๊ฒƒ์ด๋ฏ€๋กœ ๋‚˜์™€ ๊ฐ™์€ ์‚ฌ๋žŒ๋“ค์€ ๋‹ค์–‘ํ•œ ์–ธ์–ด์— ๋Œ€ํ•œ ์ƒํ˜ธ ์šด์šฉ์„ฑ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ํ•ฉ๋ฆฌ์ ์ธ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์„ธํŠธ๋ฅผ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ๋ชจ๋‘์˜ ๋…ธ๋ ฅ์— ๊ฐ์‚ฌํ•˜๊ณ  ์ข‹์€ ์ผ์„ ๊ณ„์†ํ•˜์‹ญ์‹œ์˜ค!

@kovasb ํ”ผ๋“œ๋ฐฑ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋ถ„๋ช…ํžˆ Java, Scala, Clojure ๋“ฑ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณด๋‹ค ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•ด์•ผ ํ•  ์ผ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

C++ API์™€ Java protobuf API๋ฅผ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๋„์šฐ๋ฏธ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ƒ์„ฑ๋œ Java protobuf ํด๋ž˜์Šค ์ž์ฒด๋ฅผ ํฌํ•จํ•˜์—ฌ ๋‹ค์Œ ํŒจํ‚ค์ง€์— ๋ชจ๋“  ๊ฒƒ์„ ์ž์œ ๋กญ๊ฒŒ ๋„ฃ๊ณ  PR์„ ๋ณด๋‚ด์‹ญ์‹œ์˜ค.
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper
์ด๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”์ด๋ฉฐ Bazel์ด ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” Maven ์•„ํ‹ฐํŒฉํŠธ์— ์ž๋™์œผ๋กœ ํŒจํ‚ค์ง•๋ฉ๋‹ˆ๋‹ค. ์–ด์จŒ๋“ , ์ด๊ฒƒ์— ๋Œ€ํ•ด ์กฐ์‚ฌํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@kovasb ํด๋กœ์ € ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ •๋ง ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์•„์ง ๊ณต์œ ํ•  ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

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

๋”ฐ๋ผ์„œ ์ด ์Šค๋ ˆ๋“œ์˜ ์‚ฌ๋žŒ๋“ค์€ https://github.com/tensorflow/tensorflow/issues/3์—์„œ ๋ฌธ์ œ๊ฐ€ ์ œ๊ธฐ๋˜์—ˆ์Œ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Python API์—์„œ TF๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ์ž๋™ ๋ฏธ๋ถ„์€ ํ˜„์žฌ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ C++๋กœ ํฌํŒ…๋˜๋Š” ๊ธฐ๋Šฅ์„ ๋ณด๋ฅ˜ ์ค‘์ธ ์‡ผ์Šคํ† ํผ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์ž˜ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜์ง€๋งŒ C++ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ํŒŒ์ด์ฌ ๋„์šฐ๋ฏธ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€๋ณด๊ณ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์€ Jpy ๋˜๋Š” ๋‹ค๋ฅธ ๋ธŒ๋ฆฌ์ง€ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค (์ถ”์ฒœํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?) JyNi๋„ ๊ฝค ํฅ๋ฏธ๋กญ์ง€ ๋งŒ ํ™ฉ๊ธˆ ์‹œ๊ฐ„๊ณผ๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€์Šต๋‹ˆ๋‹ค (๋” ๋งŽ์€ ์ถ”์ง„๋ ฅ / ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค)

JyNi๊ฐ€ ์ •๋ฆฌ๋˜๋ฉด + jython์€ JVM์— ์ •๋ง ๋ฉ‹์ง„ ์Šคํ† ๋ฆฌ์™€ python ์ƒํƒœ๊ณ„ ์ƒํ˜ธ ์šด์šฉ์„ฑ์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฟˆ์„ ๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Java ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฒฝ์šฐ +1!

javaCPP๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด SWIG๊ฐ€ ์—ฌ์ „ํžˆ ํ•„์š”ํ•œ๊ฐ€์š”? SWIG ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํ˜‘๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@maxiwu JavaCPP๊ฐ€ SWIG๋ณด๋‹ค ๋” ๋‚˜์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์‹ค์ œ๋กœ ์ด๋ฅผ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. :)

@kovasb ์ €๋Š” Clojure ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋•๊ณ  ๊ธฐ์—ฌํ•˜๋Š” ๋ฐ ๋งค์šฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@sorenmacbeth gmail์— ์žˆ๋Š” ๋‚ด ์ด๋ฆ„ ์ ์œผ๋กœ ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด์ฃผ์„ธ์š”.

์—ฌ๊ธฐ์— ์•„์ฃผ ์™„์ „ํ•œ Javacpp ์‚ฌ์ „ ์„ค์ •์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. "ํŒ€"์— ์ ํ•ฉํ•œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๊นŒ?

@saudet JavaCPP ๋ž˜ํผ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜์ง€๋งŒ tensorflow ์†Œ์Šค์˜ ๋น ๋ฅธ ๋ณ€๊ฒฝ ์†๋„ ๋•Œ๋ฌธ์— 0.6.0 ๋ฆด๋ฆฌ์Šค๋‚˜ ์˜ค๋Š˜๋‚ ์˜ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธํ•œ ์ •ํ™•ํ•œ tensorflow ์ปค๋ฐ‹/๋ฒ„์ „์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@nikitakit ๋ฐฉ๊ธˆ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/bytedeco/javacpp-presets/commit/43bdcdf03beaaddb4bd5badf5d4f79669e9e78dd

ํ•˜์ง€๋งŒ Caffe์™€ ๋‹ฌ๋ฆฌ TensorFlow๋Š” ์‹ค์ œ๋กœ ๋งค๋‹ฌ ์ •๋„ ๋ฆด๋ฆฌ์Šค๋ฅผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์œผ๋ฏ€๋กœ ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค(0.7.0?)๋ถ€ํ„ฐ ๊ทธ ์‹œ์ ์—์„œ ๋ฐ”์ธ๋”ฉ ์•ˆ์ •ํ™”๋ฅผ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@martinwicke ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

์•ˆ์ •์ ์ธ Java ๋ฐ”์ธ๋”ฉ์ด ์žˆ์œผ๋ฉด Scala API๋กœ ์ž‘์—…ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

/ ์ฐธ์กฐ @databricks

@kovasb ์ฒ˜์Œ์œผ๋กœ ๋†“์นœ ๊ฒƒ ๊ฐ™์•„์š”. Python์„ ํ†ตํ•ด TensorFlow๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๋ฉ‹์ง„ ์ž๋™ ๋ฏธ๋ถ„ ๋งˆ๋ฒ•์ด C++ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ Python ๋‚ด์—์„œ ๊ตฌํ˜„๋œ๋‹ค๋Š” ๋ง์”€์ด์‹ ๊ฐ€์š”? ๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ Java API๋Š” ์ด ๋ชจ๋“  ๊ฒƒ์„ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋˜ ๋‹ค๋ฅธ ์ˆซ์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” TensorFlow์˜ ๋‚ด๋ถ€๋‚˜ ํŒŒ์ด์ฌ ๊ธ€๋ฃจ์˜ ๋‚ด๋ถ€์— ์ต์ˆ™ํ•˜์ง€ ์•Š์•„ ์–ด๋””์—์„œ ๋ฌด๊ฑฐ์šด ๋ฌผ๊ฑด์„ ๋“ค์–ด ์˜ฌ๋ฆฌ๋Š” ์ผ์ด ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

@drdozer @girving ์˜ ์˜๊ฒฌ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋‹ค์Œ ์†Œ์Šค๋ฅผ ์•ฝ๊ฐ„ ์ฐพ์•„ ๋ณด๋‹ˆ ์ œ ์ดํ•ด์ž…๋‹ˆ๋‹ค. Java๋กœ ์žฌ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‹œ์ž‘์ด ์•„๋‹Œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. # 3์˜ ๋Œ“๊ธ€์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ •๋ง๋กœ ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด Java API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ๊ต์œก ์˜ˆ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค(์ง€๊ธˆ๊นŒ์ง€๋Š” ์ •๋ฐฉํ–ฅ ๊ฒฝ๋กœ๋ฅผ ๋ณด๊ฑฐ๋‚˜ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค).

์ž์ด์ฌ์œผ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์–ด๋””๊นŒ์ง€ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์„์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค...

Python API ๊ณ„์ธต์—๋Š” C++ ๊ณ„์ธต API๊ฐ€ ๋…ธ์ถœํ•˜์ง€ ์•Š๋Š” ๋งŽ์€ ๋…ผ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๋‚˜๋Š” JavaCpp ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ฅด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ๊ฒฐ๊ตญ์—๋Š” ๋งŽ์€ ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๊ณ  Python ๊ตฌํ˜„์—์„œ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋” ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ @saudet ์ด ์ด์ „์— ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ Jython์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค ...

https://github.com/tensorflow/tensorflow/issues/476 ์—์„œ @josh11b์— ํ• ๋‹น๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ์ด ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด Jython์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ž์ด์ฌ์„ ์‚ฌ์šฉํ•˜๋ฉด C++ ์ฝ”๋“œ๊ฐ€ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? Java์—์žˆ๋Š” ์„œ๋ฒ„์— ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ ํ•˜์ง€๋งŒ Java ๊ฒฝ๋กœ๋ฅผ ์ง์ ‘ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์†Œ์ผ“์„ ํ†ตํ•ด Python ํ”„๋กœ์„ธ์Šค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ ์‚ฌ์ด์—์„œ ๋ง‰ํ˜”์Šต๋‹ˆ๋‹ค.

Java API์— ์ž๋™ ๋ฏธ๋ถ„๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ ์ด๊ฒƒ์ด ์ œ ์ž‘์—…์— ์žฅ์• ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์–ธ๊ธ‰ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ํŒŒ์ด์ฌ์—์„œ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•˜๊ณ  .proto ํŒŒ์ผ๋กœ ์ง๋ ฌํ™”ํ•œ ๋‹ค์Œ ํ›ˆ๋ จ์„ ์œ„ํ•ด Java ๋ž˜ํผ๋ฅผ ํ†ตํ•ด ์—ฌ๋Š” ๋ฐ ํฐ ์„ฑ๊ณต์„ ๊ฑฐ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. Saver ๊ธฐ๋Šฅ์€ C++ ๋ฐ Java API๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ์‹œ๊ฐ„์—๋„ ๋™์ผํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

+1

@saudet
javacpp์™€ tensorflow์šฉ ์‚ฌ์ „ ์„ค์ •์„ ๋งŒ๋“ค์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. Java์—์„œ Python ๊ทธ๋ž˜ํ”„๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋‹ค์‹œ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ์ €์žฅ๋œ ๋ชจ๋ธ ํŒŒ์ผ์—์„œ ๋ณต์›ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋ฉˆ์ถฅ๋‹ˆ๋‹ค. ์ด ์ค„์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค:

ํ…์„œ fn = new Tensor(tensorflow.DT_STRING, new TensorShape(1));
CharBuffer ๋ฒ„ํผ = fn.createBuffer();
buffer.put("๋ชจ๋ธ ํŒŒ์ผ.tf");
์„ธ์…˜.์‹คํ–‰(...);

๊ทธ๋Ÿฌ๋‚˜ CharBuffer๋Š” NULL๋กœ ํŒ๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. DT_STRING์„ DT_FLOAT๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด FloatBuffer๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ DT_STRING์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@nikitakit ๋‹น์‹ ์€ ์ด๊ฒƒ์ด ์ž‘๋™ํ•œ๋‹ค๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@lakshmanok

ํŽธ์ง‘: ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋งํ•œ ๋‚ด์šฉ์„ ์ž˜๋ชป ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. Java์—์„œ ์™ธ๋ถ€ ๋ณดํ˜ธ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ๋‚ด ์ฝ”๋“œ์—์„œ tensorflow ๊ทธ๋ž˜ํ”„๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://gist.github.com/nikitakit/d3ec270aee9d930267cec3efa844d5aa

Scala์— ์žˆ์ง€๋งŒ Java/๋‹ค๋ฅธ JVM ์–ธ์–ด๋กœ ํฌํŒ…ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ๊ทธ๋ž˜ํ”„์—์„œ ๋…ธ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋‚ด ์ฝ”๋“œ๋Š” ๋ถˆํ–‰ํžˆ๋„ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” Scala ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํฌ๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” tensorflow API ๋ฌธ์„œ์— ์˜์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฌ๋“ ์ง€ jvm์— python tensorflow ํ™˜๊ฒฝ์„ ํฌํ•จํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๊นŒ? ์ž์ด์ฌ + JyNI๋กœ ๋งํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์ด ๋ชจ๋“  ๊ฒƒ์ด ์•ˆ์ •์ ์œผ๋กœ ์ž‘๋™ํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ์‹คํ—˜์ ์ž…๋‹ˆ๊นŒ?

์ €๋Š” ํ˜„์žฌ ๊ทธ๋ž˜ํ”„ ์ •์˜์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด C API๋ฅผ ํ™•์žฅํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–ธ์ œ ์™„์„ฑ๋ ์ง€๋Š” ๋ชจ๋ฅด์ง€๋งŒ 1.0 ์ด์ „์— ์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

Java์—์„œ ํ…์„œ ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” jython์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ํŒŒ์ด์ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ์ˆ˜์šฉํ•˜๋„๋ก ํ…์„œ ํ๋ฆ„ cpython ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋ฌธ์ œ์— ์ ‘๊ทผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. cpython์€ ๊ณ„์†ํ•ด์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ด์•ผ ํ•˜๋ฉฐ ๋‚ด ์ฝ”๋“œ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ Jython์ธ์ง€ ๊ฐ์ง€ํ•˜๊ณ  ์ž‘๋™ํ•˜๋„๋ก ๊ฐ€์ ธ์˜ค๊ธฐ/๋ชจ๋“ˆ์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์•„๋ž˜์—์„œ libtensorflow_cc.so์— ๋Œ€ํ•œ javacpp ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด Google ํŒ€์ด ๊ณต์‹ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๊ณต๊ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ? @vrv

๊ทธ๊ฒƒ์€ ์ข‹์€ ๊ฐœ๋… ์ฆ๋ช…์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๊ณต์‹ ๋ฐ”์ธ๋”ฉ์€ ์•„๋งˆ๋„ Python์„ ํ†ตํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, c-python ๋ž˜ํผ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  javaccp ๋ž˜ํผ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ cpython ํ…์„œ ํ๋ฆ„๊ณผ ๋™์ผํ•˜์ง€๋งŒ Jython์„ ์‚ฌ์šฉํ•˜์—ฌ JVM์—์„œ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ์ „์ฒด python ๋…ผ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉฐ ๋‹ค๋ฅธ API๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค. javacpp ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ ์—†์ด ์ถ”๋ก ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ˜„์žฌ๋กœ์„œ๋Š” ๋ชจ๋ธ์ด cpython ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋นŒ๋“œ/ํŠธ๋ ˆ์ด๋‹๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Kotlin์œผ๋กœ tensorflow๋ฅผ ์ž‘๋™์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณธ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋” ์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์ด๊ณ  ํ•˜๋ฃจ๊ฐ€ ๋๋‚  ๋•Œ ์—ฌ์ „ํžˆ 100 % ์ž๋ฐ”์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” Kotlin ์–ธ์–ด๊ฐ€ ํŒŒ์ด์ฌ๊ณผ ์ˆœ์ˆ˜ ์ž๋ฐ” ์‚ฌ์ด์˜ ์•„์ฃผ ์ข‹์€ ์ค‘๊ฐ„ ์ง€์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ: @saudet ๋•๋ถ„์— javacpp๋กœ ์ž‘์—…์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  Java ํ”„๋กœ๊ทธ๋žจ์—์„œ TensorFlow ๋ชจ๋ธ์„ ์ฝ๊ฑฐ๋‚˜ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

https://medium.com/google-cloud/how-to-invoke-a-trained-tensorflow-model-from-java-programs-27ed5f4f502d#.tx8nyds5v

@lakshmanok ๋ฐ @saudet ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. javacpp ํ”„๋กœ์ ํŠธ๋Š” ๋Œ€๋ถ€๋ถ„์˜ TensorFlow API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Java์—์„œ tensorflow/serving ์„ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

API๋Š” ๊ฐ„๋‹จํ•˜๊ณ  protobuf ์ •์˜๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๋Š” ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ–ˆ๊ณ  Java์—์„œ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. Java์—์„œ TensorProto ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  gRPC ํ˜ธ์ถœ์„ ํ˜ธ์ถœํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. TensorFlow๋Š” Java๊ฐ€ ์•„๋‹Œ Python ๋ฐ C++์šฉ์œผ๋กœ ๋‹ค์ค‘ ์ฐจ์› ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋„์šฐ๋ฏธ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

javacpp ํ•˜๊ฑฐ๋‚˜ ์ด๋ฅผ ์œ„ํ•ด ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์ด ์ฐพ๊ณ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋งˆ๋„ ์ด๋ฏธ https://github.com/bytedeco/javacpp-presets/blob/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper/tensorflow.java์— ์žˆ์ง€๋งŒ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ๊ฑฐ๊ธฐ์— ๋ญ”๊ฐ€ ๋น ์ง„๋‹ค๋ฉด. ๊ฐ์‚ฌ ํ•ด์š”!

์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์ž‘์—… ์ค‘์ž…๋‹ˆ๊นŒ? ์ด ํฌํŒ… ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ณต์‹ github ์ €์žฅ์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‘ ๊ฐœ์˜ ์ž„์˜์˜ repos๋ฅผ ๋ณด์•˜์ง€๋งŒ ๋งํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋„ค, ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ 10์›”/11์›”์— ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” C++ API๋กœ SWIGingํ•˜๋Š” ๋Œ€์‹  C API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ saudet๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ C API๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์…จ๋‚˜์š”? ์šฐ๋ฆฌ๋Š” ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค
swig๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฃจ๋น„ ์ธํ„ฐํŽ˜์ด์Šค:
http://github.com/somaticio/tensorflow.rb

2016๋…„ 9์›” 13์ผ ํ™”์š”์ผ ์˜คํ›„ 6์‹œ 22๋ถ„, Jonathan Hseu [email protected]
์ผ๋‹ค:

๋„ค, ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ 10์›”/11์›”์— ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” C API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค
C++ API๋กœ ์ „ํ™˜ํ•˜๋Š” ๋Œ€์‹ . ๊ทธ๋™์•ˆ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
saudet๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ฐ”์ธ๋”ฉ.

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -246844192,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAA5v3g86Z6D1rz-aTGdMyMWnQZhrZUYks5qpyIJgaJpZM4Getd8
.

์•ž์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์–ธ์–ด ๋ฐ”์ธ๋”ฉ์ด C API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ๊ฐ€ ์ค€๋น„ ์ค‘์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ์‚ฌ์šฉ ์˜ˆ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/go

ํ•˜์ง€๋งŒ ๊ธด๊ธ‰ํ•œ ์ƒํ™ฉ์€ ์•„๋‹ˆ๋ฉฐ ์ง€๊ธˆ์€ SWIG๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@jhseu ์ด๋Š” C API๊ฐ€ ํ˜„์žฌ Python ๋ฐ”์ธ๋”ฉ์ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ํฌํ•จํ•˜๋„๋ก ํ™•์žฅ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

์™€์šฐ, ํฐ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋” ์ผ์ฐ ๊ฒฐ์ •๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ๋ฌธ์„œ๋ฅผ ๋ณด๋ ค๋ฉด
๋” ๋นจ๋ฆฌ?

2016๋…„ 9์›” 14์ผ ์ˆ˜์š”์ผ ์˜คํ›„ 5์‹œ 56๋ถ„, Samuel Audet [email protected]
์ผ๋‹ค:

@jhseu https://github.com/jhseu C API๊ฐ€
Python ๋ฐ”์ธ๋”ฉ์ด ํ˜„์žฌ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ํฌํ•จํ•˜๋„๋ก ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -247167887,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAA5vwfBJoZC2s33_7E9Xy6-NYNUjHjnks5qqG2FgaJpZM4Getd8
.

@saudet ๋‹จ๊ธฐ์ ์œผ๋กœ๋Š” ์ผ๋ถ€ ๊ธฐ๋Šฅ(์˜ˆ: ๊ทธ๋ž˜๋””์–ธํŠธ, ์˜ตํ‹ฐ๋งˆ์ด์ €)์„ ์ œ์™ธํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
@jtoy ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ด ๊ธ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. SWIG๋Š” ๋‹น๋ถ„๊ฐ„ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์„œ๋Š” ๊ทธ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋ช…๋ช… ๊ทœ์น™์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋“ค ์—†์ด C API๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

@saudet ๊ฐ์‚ฌ TensorProto ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด stackoverflow ์—์„œ ์ด๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ gRPC Java ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” TensorFlow์˜ ์˜ˆ์ œ ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค.

@tobegit3hub ์ข‹์Šต๋‹ˆ๋‹ค . C++ API๋กœ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด JavaCPP ์‚ฌ์ „ ์„ค์ •์˜ ๋„์šฐ๋ฏธ ํŒจํ‚ค์ง€์— ์ถ”๊ฐ€ํ•˜๊ณ  ํ’€ ์š”์ฒญ์„ ๋ณด๋‚ด์ฃผ์„ธ์š”! ์ด ์‚ฌ๋žŒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์— ๊ด€์‹ฌ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค: https://github.com/bytedeco/javacpp-presets/issues/240

@girving javacpp ๊ฐ€ ์ด๋ฏธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๊นŒ?
tensorflow java api์— ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฏธ C API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Java/Scala ์–ธ์–ด ๋ฐ”์ธ๋”ฉ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๊นŒ?
( SWIG ์œ„์— ๊ตฌ์ถ•ํ•˜๋Š” ๋Œ€์‹  )

JNR์„ ํ†ตํ•ด C API๋งŒ ์‚ฌ์šฉํ•˜๋Š” tensorflow์— ๋Œ€ํ•œ ์ž‘๋™ํ•˜๋Š” Java/Scala ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, ๋‚˜๋Š” ์•„์ง ๊ทธ๊ฒƒ์„ ๊ณต๊ฐœํ•  ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ถœ์‹œ๋˜๋ฉด ์—ฌ๊ธฐ์— ๊ฒŒ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„์ง ์ง„ํ–‰ ์ค‘์ธ ์ž‘์—…์ด์ง€๋งŒ ๋งค์šฐ ๊ธฐ๋Šฅ์ ์ž…๋‹ˆ๋‹ค.

@jdolson ๋…ธ์ถœํ•˜๋Š” API๊ฐ€ TensorFlow์˜ ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ ๊ฐ์ฒด๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ @saudet์—์„œ javacpp ์‚ฌ์ „ ์„ค์ •์„ ์‚ฌ์šฉ ํ–ˆ์–ด ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ๋‹น์‹ ์€ ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ ์ปดํŒŒ์ผ๋Ÿฌ ๋•Œ์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” org.tensorflow.framework.TensorProto ๋‹น์‹ ์—๊ฒŒ ์ž๋ฐ” ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์žˆ์–ด ๊ฑฐ๋ž˜๋ฅผ ํ…์„œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ์ž๋ฐ”๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TensorFlow API ๋ž˜ํผ์—์„œ๋Š” C๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ๊ตฌ์„ฑ๋  ๋•Œ ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ƒ์„ฑ๋œ c ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ๋•Œ javacpp์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” org.bytedeco.javacpp.tensorflow.TensorProto.TensorProto๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ž˜ํ•‘๋œ TensorFlow API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž๋ฐ” ์ฝ”๋“œ์˜ ํ…์„œ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@Intropy ์˜ˆ, protoc ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  tensorflow *.proto ์†Œ์Šค๋ฅผ Java ์†Œ์Šค ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๊ณ  API์—์„œ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@jhseu C API ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„์ง 11์›” ์•ˆ์— ์ถœ์‹œ๋  ์˜ˆ์ •์ธ๊ฐ€์š”? ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ํ˜„์žฌ ์ƒํƒœ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

@eaplatanios : C API๋Š” ๋Œ€๋ถ€๋ถ„ ์•ˆ์ •์ ์ด๋ฉฐ(๊ณต์‹์ ์œผ๋กœ 1.0๊นŒ์ง€ ๋  ์˜ˆ์ •์ž„) ์™„์ „ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ž˜ํ”„์— ๋Œ€ํ•œ ์ž๋™ ๊ธฐ์šธ๊ธฐ ๊ณ„์‚ฐ ๊ธฐ๋Šฅ์ด ์—ฌ์ „ํžˆ ๋ˆ„๋ฝ๋จ). C API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ธ์–ด ๋ฐ”์ธ๋”ฉ์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์„œ๋Š” https://www.tensorflow.org/how_tos/language_bindings/index.html์— ์žˆ์Šต๋‹ˆ๋‹ค.

Go API ๋Š” ์œ„์˜ ๋ฌธ์„œ๋ฅผ ๋”ฐ๋ฅด๋Š” ์ฒซ ๋ฒˆ์งธ ์˜ˆ๋กœ C API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” JNI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์œ„์— Java ๋ฐ”์ธ๋”ฉ๋„ ๊ตฌ์ถ•ํ•˜๊ธฐ๋ฅผ ํฌ๋งํ•˜๊ณ  ์กฐ๊ธˆ ํƒ์ƒ‰ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. @saudet ์˜ JavaCPP ์ž‘๋™์— ๋Œ€ํ•œ ํ›Œ๋ฅญํ•œ ์ž‘์—…์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ๋žŒ๋“ค์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์˜๊ฒฌ/๋ฐฐ์›€์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

JavaCPP ๋ฐ”์ธ๋”ฉ ์‚ฌ์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒซ์งธ, ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ๊ฐ€ ์ž๋ฐ”๋กœ ์ง์ ‘ ์ปดํŒŒ์ผ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ” ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋ฐ”๋žŒ์งํ•˜๊ฒŒ๋Š” API์— ์ฐธ์—ฌํ•˜๋Š” ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ๋Š” maven ๋ชจ๋“ˆ๋กœ ๋ณ„๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ณ  proto ์ •์˜์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ Java ์Šคํƒ์˜ ์‚ฌ๋žŒ๋“ค์ด ์ •์˜๋ฅผ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ proto ์ •์˜์— ํฌํ•จํ•˜๊ธฐ ์œ„ํ•ด proto ์ •์˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋‘˜์งธ, TensorFlow๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” libc์˜ ์ตœ์†Œ ๋ฒ„์ „์„ ์ฐพ๊ณ  ์ด์— ๋”ฐ๋ผ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์…‹์งธ, ์ž๋™ ์ƒ์„ฑ๋œ API๋ณด๋‹ค ์‹ ์ค‘ํ•˜๊ฒŒ ์„ค๊ณ„๋œ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋ช…๋ฐฑํ•˜๊ณ  JavaCPP์˜ ํ•œ ๋ฐฉ์ฒ˜๋Ÿผ ๋“ค๋ฆฐ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์ •๋ง ๊ธฐ์ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ƒํ•œ ๋งํˆฌ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์‚ฌ๋งˆ๊ท€๊ฐ€ ๋งŽ์œผ๋ฉฐ ํ•˜๋ ค๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด ๊ฝค ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ์ด "์ž˜ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค"๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ์š”์ ์€ C++ API์™€ python API๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋‹ค๋ฅธ์ง€ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์ž๋™์œผ๋กœ ๋ณ€ํ™˜๋œ ์ฝ”๋“œ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ํ™˜๊ฒฝ์— ๋งž๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

Go, Ruby, R๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Swig์˜ C ๋ฐฑ์—”๋“œ๋ฅผ ์ง€์›ํ•˜๊ณ  Swig๋ฅผ ํ†ตํ•ด TF C API๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://github.com/swig/swig/issues/800 ์ž์‹ ์˜ ๋ฐ”์ธ๋”ฉ์„ ์ž‘์„ฑํ•˜๋Š” C API.

C FFI๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  ์–ธ์–ด์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์กด C API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

(๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด TensorFlow์šฉ Go, Java, Rust ๋“ฑ ๋ฐ”์ธ๋”ฉ์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค)

JNA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C API์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@jhseu ๋‚ด ๋ง์€, C API๋ฅผ ์ˆ˜๋™์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ์ด์ „์— C++ API์—์„œ ์ƒ์„ฑ๋˜์—ˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

@Quantum64 , ๋‹ค์Œ ์€ JNA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” tensorflow์˜ Scala ๋ฐ”์ธ๋”ฉ์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์•„์ง ์—ด๋ ค ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ป๊ฒŒ
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java
๊ตฌํ˜„ ์ค‘์ด๋ฉฐ ์ปค๋ฐ‹์— ๋Œ€ํ•œ PR์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@hsaputra : ๋‹น์‹ ์ด ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ž์„ธํžˆ tensorflow/java ์˜ ์ฝ”๋“œ์— ๊ธฐ์—ฌํ•˜๋Š” ์ปค๋ฐ‹์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์œผ๋ฉฐ, ๋Œ€๋ถ€๋ถ„์ด ์ด ๋ฌธ์ œ์—์„œ ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค(์˜ˆ: 2b1cd28, d73a266 ๋ฐ ๊ทธ ์‚ฌ์ด์˜ ๋งŽ์€ ๋‹ค๋ฅธ ์ปค๋ฐ‹).

์•ˆ๋…•ํ•˜์„ธ์š” @asimshankar , ๋‹ต๋ณ€ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด ํ‹ฐ์ผ“์ด ๋‹ซํžˆ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— tensorflow/java ์ด Java API๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ทจํ•˜๋Š” ๊ฒฝ๋กœ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
JavaCPP ์‚ฌ์šฉ ๋Œ€ SWIG ์‚ฌ์šฉ ๋Œ€ Jython์„ ํ†ตํ•œ ํ˜ธ์ถœ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ํ† ๋ก ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

tensorflow/java ๊ฐ€ ์ง์ ‘ JNI๋กœ ๊ตฌํ˜„๋˜์–ด ๋Œ€์‹  C API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๊นŒ?

์˜ณ์€.

์ด๋ด,

์–ด์ œ Swig ๋ฐ”์ธ๋”ฉ์ด ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. API ๋ณ€๊ฒฝ ์š”์ฒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ Tensors๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋ฆฌํ”Œ๋ ‰์…˜์ด ํ•„์š”ํ•˜๋ฉฐ ๋ฐฐ์—ด ํ˜•์‹์€ n์ฐจ์› ๋„ค์ดํ‹ฐ๋ธŒ Java ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ์–ด์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ 1์ฐจ์› ๋ฐฐ์—ด์„ ํ•„์š”๋กœ ํ•˜๋Š” ํ…์„œ๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค๋ฅธ long ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ์–‘์„ ์ง€์ •ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

double[] matrix = {1.414, 2.718, 3.1415, 3.4, 56.7, 89.0};
long[] shape = {2, 3};

// add a method for each primitive type
org.tensorflow.Tensor tensor = org.tensorflow.Tensor.createDouble(matrix, shape);

์ด๊ฒƒ์€ ๋˜ํ•œ ํ˜ธํ™˜์„ฑ์— ๋„์›€์ด ๋˜๋Š” int8, int16, uint8, uint16, uint32 ํ…์„œ๋ฅผ ์ƒ์„ฑํ•  ๊ฐ€๋Šฅ์„ฑ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.

์ด๊ฑธ ๋ฌธ์ œ๋กœ ํ•ด์•ผ ํ•˜๋‚˜? ์•„๋‹ˆ๋ฉด ์—ฌ๊ธฐ ๊ดœ์ฐฎ๋‚˜์š”?

๋˜ํ•œ ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ์˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@hollinwilkins : PR #6577์ด ์ œ์•ˆํ•œ ๊ณต์žฅ ๋ฐฉ์‹์„ ์•ฝ๊ฐ„๋งŒ ์ˆ˜์ •ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Tensor tensor = Tensor.create(shape, DoubleBuffer.wrap(matrix));

@asimshankar ๋ฉ‹์ง€๋„ค์š” ! ๋น ๋ฅธ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ณ‘ํ•ฉ์—๋„ ๊ฑฐ์˜ ๊ทผ์ ‘ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค :+1:

์ƒˆ๋กœ์šด Java API๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ๋ช‡ ๊ฐ€์ง€ ์‚ฌํ•ญ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ์ž๋ฐ” API๋Š” GraphDef ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„๋“ค์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ GraphDef ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ์˜ ์ง๋ ฌํ™”๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ”์ดํŠธ ๋ฐฐ์—ด๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฒฝ๊ณ„์—์„œ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ๋‹จ๊ณ„๋ฅผ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค.
  2. Session.Runner.feed๋Š” org.tensorflow.framework.TensorProto๋ฅผ ์ˆ˜๋ฝํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ฑฐ๋‚˜ org.tensorflow.framework.TensorProto์—์„œ org.tensorflow.Tensor๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  3. Session.Runner.run์€ Tensor ๊ฐœ์ฒด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์œ„์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ง์ ‘ ๋˜๋Š” org.tensorflow.Tensor์— TensorProto๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์—ฌ TensorProto ์ถœ๋ ฅ์„ ์–ป๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  4. Session.Runner.run์€ ์ƒํƒœ๋ฅผ ์‚ผํ‚ต๋‹ˆ๋‹ค. ์˜ˆ์™ธ๋ฅผ ๋˜์ ธ์„œ ์‹คํŒจ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋†“์ณค์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹คํ–‰์˜ ์ถœ๋ ฅ์—์„œ โ€‹โ€‹์ง€์›๋˜๋Š” ๋ชจ๋“  ํ…์„œ ์œ ํ˜•์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด ์ถœ๋ ฅ ํ…์„œ๊ฐ€ dtype INT16์ธ ๊ฒฝ์šฐ ๊ฐ’์„ ์ถ”์ถœํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. Tensor.shortValue ๋“ฑ์ด ์—†๊ณ  Tensor.intValue๊ฐ€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. tensor_jni.cc์—์„œ DEFINE_GET_SCALAR_METHOD๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

@Intropy : ๊ท€ํ•˜์˜ ์˜๊ฒฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฌ๋ฉฐ ํ™•์‹คํžˆ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋ช‡ ๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ์ƒ๊ฐ์„ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

RE: protobufs: ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ํ•ต์‹ฌ API๋ฅผ protobufs์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ง€ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค( nanproto ์™€ ๊ฐ™์€ ๊ฒƒ์ด ๋” ์ ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์†Œ์Šค ์ œํ•œ ์‹œ์Šคํ…œ์—์„œ์˜ ์‚ฌ์šฉ ํฌํ•จ). ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๊ฐ€ ์ฃผ์ €ํ–ˆ๋˜ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•˜๊ณ  ์ œ์•ˆ์„ ๊ฐ์‚ฌํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•œ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์€ ๋ชจ๋“  protobuf ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ๋ณ„๋„์˜ ํŒจํ‚ค์ง€์— ํฌํ•จํ•˜์—ฌ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์‹œ ์š”์ ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ:

  1. ์œ„ ์ฐธ์กฐ. ํ•˜์ง€๋งŒ byte[] ๊ฐ€ ๋” ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๋Š” ์ ์— ๋ฒ ํŒ…ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ํŒŒ์ผ ๋˜๋Š” ๋„คํŠธ์›Œํฌ ์ฑ„๋„์—์„œ ๊ทธ๋ž˜ํ”„ ์ฝ๊ธฐ)

  2. ์š”์ ์„ ์•Œ์•˜์–ด

  3. ์œ„ ์ฐธ์กฐ.

  4. Session.runner.run ๋Š” ์‚ผํ‚ค๋Š” ์ƒํƒœ๊ฐ€ ์•„๋‹ˆ ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค( session_jni.cc:166 ). ์ด๊ฒƒ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉด ๋ฒ„๊ทธ๋ฅผ ์‹ ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

๋งž์Šต๋‹ˆ๋‹ค. ์•„์ง ๋ชจ๋“  ์œ ํ˜•์ด ์ง€์›๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ ์‰ฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๋ฝ๋œ ์œ ํ˜•์— ๋Œ€ํ•œ ๊ธด๊ธ‰ํ•œ ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•˜๊ฑฐ๋‚˜ PR์„ ๋ณด๋‚ด์ฃผ์‹ญ์‹œ์˜ค. ๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค :)

@asimshankar ์ƒ๊ฐ

์ฒซ ๋ฒˆ์งธ ์š”์ ์— ๊ด€ํ•ด์„œ๋Š” ์‹ค์ œ๋กœ ํฐ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ๋งํ–ˆ๋“ฏ์ด byte[]๊ฐ€ ๊ฐ€์žฅ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ž์‹ ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์—๋Š” byte[]๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์‰ฌ์šด InputStream์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ API๋Š” ๋ณ€ํ™˜์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์–ด์จŒ๋“  (TF_GraphImportGraphDef์—์„œ) ์—ญ์ง๋ ฌํ™”ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— API์— ๋Œ€ํ•œ byte[] ์‚ฌ๋งˆ๊ท€๋ฅผ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ผ๋ถ€ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ณ ๋ คํ•ด์•ผ ํ•  proto3์˜ json ์ง๋ ฌํ™”๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ผํ‚ค๋Š” ์ƒํƒœ์—์„œ๋Š” ๋งž์Šต๋‹ˆ๋‹ค. ํ™•์ธ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ๋ฅผ ๋†“์ณค์Šต๋‹ˆ๋‹ค.

2์™€ 3์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ€์žฅ ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์€ TensorProto์™€ ์ผ๋ถ€ toTensorProto()์—์„œ ๋ณ€ํ™˜ํ•˜๋Š” ํŒฉํ† ๋ฆฌ๋ฅผ org.tensorflow.Tensor์— ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๊ฐ€ ์ œํ•œ๋œ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ํ”„๋กœํ† ์ฝœ ๋ฒ„ํผ์˜ ๋ฌธ์ œ์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ์ƒํ™ฉ์— ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์€ ๋‹จ์ˆœํžˆ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด Tensor๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ protobuff์— ์ง์ ‘ ์ €์žฅํ•˜๋„๋ก ํ•จ์œผ๋กœ์จ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€ํ™˜ ๋น„์šฉ์„ ์ง€๋ถˆํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ „์— jni๋กœ ์ž‘์—…ํ•œ ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€๋งŒ ๋ณธ์งˆ์ ์œผ๋กœ ํฌ๊ธฐ๊ฐ€ ์ง€์ •๋œ void*์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌ๋˜๋Š” TensorBuffer๊ฐ€ ์žˆ๋Š” TF_Tensor์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ nativeHandle์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ๋ถ„ํ•ดํ•˜๊ณ  Java ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ถ”์ /๋ถ„์„์ด ๋” ์‰ฌ์›Œ์ง€๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@drpngx : ๋‚ด ์˜๋„๋Š” Go์—์„œ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์ด ์ž‘์—…์„ ์ข…๋ฃŒํ•˜๊ณ  ๊ธฐ๋Šฅ/๋ฒ„๊ทธ๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ œ์ถœํ•˜๊ธฐ ์ „์— (๋ฒ„ํผ์—์„œ ํ…์„œ ์ฝ๊ธฐ) ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์–ป๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ณง ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ข‹์€ ์†Œ๋ฆฌ, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ข‹์•„, ๊ตฌ์ถ•ํ•  ๊ธฐ๋ฐ˜์ด ์ถฉ๋ถ„ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(์˜ˆ: LabelImage ์˜ˆ์ œ ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜๊ณ  ์‚ฌ๋žŒ๋“ค์ด ๋” ๊ตฌ์ฒด์ ์ธ ๋ฒ„๊ทธ/๊ธฐ๋Šฅ ์š”์ฒญ์„ ์ œ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. Java API์—๋Š” ์—ฌ์ „ํžˆ ํ•ด์•ผ ํ•  ์ผ์ด ๋งŽ์ง€๋งŒ ๋ณ„๋„์˜ ๋ฌธ์ œ์—์„œ ๋…ผ์˜/์ถ”์ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

@asimshankar ์šฐ๋ฆฌ๋Š” ๋”ฅ ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ(mxnet/tf)๋ฅผ ์„ ํƒํ•˜๋Š” ๊ณผ์ •์— ์žˆ์œผ๋ฉฐ etl/api๋Š” spark/akka ํ๋ฆ„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค... ps๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ธ ๋ณ‘๋ ฌ ๊ต์œก์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด Java API์— distribution_runtime ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋…ธ๋“œ ? ps ๋…ธ๋“œ๋Š” ๋งŽ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค... C API ์ž์ฒด์— distribution_runtime์ด ์—†๋Š” ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— javacpp ์‚ฌ์ „ ์„ค์ •์€ ์ฒซ ๋ฒˆ์งธ ์ปท์„ ์œ„ํ•ด ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค...

@debasish83 : ๋ถ„์‚ฐ ๋Ÿฐํƒ€์ž„ ์ž์ฒด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์†Œํ•˜์ง€๋งŒ Python API์—๋Š” Estimator ํด๋ž˜์Šค์™€ ๊ฐ™์€ ๋งŽ์€ ์ผ(์ฒดํฌํฌ์ธํŠธ, ์š”์•ฝ ์ €์žฅ ๋“ฑ)์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋†’์€ ์ˆ˜์ค€์˜ ๊ตฌ์กฐ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. TensorBoard๋ฅผ ํ†ตํ•ด ์‹œ๊ฐํ™”๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ) Python์—์„œ ๊ต์œก ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ๋” ์ ํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ชจ๋“  ๊ฒƒ์€ Java API์˜ ๊ธฐ์กด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์ •ํ™•ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” ์Šค๋ ˆ๋“œ์—์„œ ๋™๊ธฐํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

@asimshankar ๋…ธ๋“œ ๋ชฉ๋ก, ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ํ˜•์‹๊ณผ ๊ฐ™์€ graphDef(๋””์Šคํฌ์— ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์˜ .pb ํŒŒ์ผ์—์„œ ๋นŒ๋“œ๋จ)์—์„œ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” tensorflow Java ๋ฐ”์ธ๋”ฉ์˜ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋“ค์–ด์˜ค๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”!

@asimshankar TF Java๋กœ ๊ต์œก์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ๋ฌด์—‡์ด ๋ถ€์กฑํ•œ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ˆซ์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ(numpy ๋ˆ„๋ฝ)? TensorBoard dataviz์—๋Š” ๊ด€์‹ฌ์ด ์—†์ง€๋งŒ ๊ธฐ๋ณธ Java ์ˆซ์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ต์œก๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ ๊ต์œก์šฉ์œผ๋กœ๋งŒ Python์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ( Estimator ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ œ์•ˆํ•œ ๋Œ€๋กœ)?

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

Java์—์„œ ํ•™์Šต ๋ชจ๋ธ์˜ ์ƒํƒœ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ €๋Š” ImageJ(์ธ๊ธฐ ์žˆ๋Š” ๋ฌด๋ฃŒ ์ด๋ฏธ์ง€ ๋ถ„์„ ์ œํ’ˆ๊ตฐ) ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•˜์—ฌ https://arxiv.org/pdf/1505.04597.pdf (์ตœ๊ทผ ์„ธํฌ ์ถ”์  ๋ฐ ์ƒ๋ฌผ ์˜ํ•™ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์œ„ํ•œ ์ด๋ฏธ์ง€ ๋ถ„ํ• ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋จ)์™€ ๊ฐ™์€ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ๋‹ค์–‘ํ•œ ๋ชจ๋ธ์„ ์ œ๊ณตํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋งž๊ฒŒ ์ด๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ด ๋ชฉ์ ์„ ์œ„ํ•ด DL4J๋ฅผ ์กฐ์‚ฌํ•ด ์™”์Šต๋‹ˆ๋‹ค. TF Java ๋ฐ”์ธ๋”ฉ์— ๋งž์ถœ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์ฒด์ ์ธ ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@bergwerf : ํŠน๋ณ„ํžˆ ํŽธ๋ฆฌํ•˜์ง€ ์•Š๋”๋ผ๋„ Java๋กœ ํ›ˆ๋ จํ•˜๋Š” ๊ฒƒ์€ ํ™•์‹คํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
https://github.com/tensorflow/models/tree/master/samples/languages/java/training ์—์„œ ์ƒ˜ํ”Œ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋˜ํ•œ, ๋‚˜๋Š” ๋‹น์‹ ์ด ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•˜์ง€๋งŒ https://imagej.net/TensorFlow๋„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค)

์˜ค, ๊ต‰์žฅํ•˜๋‹ค! ๋‚ด ์ •๋ณด๋Š” ์˜ค๋ž˜๋œ ๊ฒƒ์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค ;-). ๋‚˜๋Š” ๋‚ด๊ฐ€ ์ฝ์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค
์–ด๋”˜๊ฐ€์—์„œ Java API๋Š” ์‚ฌ์ „ ํ›ˆ๋ จ๋œ
๋ชจ๋ธ. ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

2018๋…„ 3์›” 28์ผ ์ˆ˜์š”์ผ 22:01 Asim Shankar [email protected]์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

@bergwerf https://github.com/bergwerf : Java ๊ต์œก์€ ํ™•์‹คํžˆ
ํŠนํžˆ ํŽธ๋ฆฌํ•˜์ง€ ์•Š๋‹ค๋ฉด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์—์„œ ์ƒ˜ํ”Œ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/tensorflow/models/tree/master/samples/languages/java/training

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/tensorflow/tensorflow/issues/5#issuecomment-377015867 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AEQJ1UD9-xACQAII5996ees_UFJ_NzL-ks5ti-wSgaJpZM4Getd8
.

@asimshankar ๊ต‰์žฅํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘ ๐Ÿ’ฏ ๐Ÿฅ‡ , ๋‚ด ์ €์žฅ์†Œ์— ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค https://github.com/loretoparisi/tensorflow-java

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