Tensorflow: واجهة جافا

تم إنشاؤها على ٩ نوفمبر ٢٠١٥  ·  112تعليقات  ·  مصدر: tensorflow/tensorflow

مشكلة لتتبع جهد واجهة swig لجافا. تم بدء التنفيذ - سيتم التحديث مع التقدم. إذا كان لدى أي شخص أي تعليقات / نصائح - فلا تتردد في الانضمام إلى المناقشة!

التعليق الأكثر فائدة

تحديث: تمكنت من الحصول على الأشياء بنجاح مع javacpp (بفضل saudet )

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 :


هناك مجموعة اختبارية ذات تقارب جيد إلى حد ما ، لكنها حاليًا في الغالب Python مع عدد قليل من اختبارات C ++. هناك أيضًا الكثير من الوظائف لإنشاء الرسوم البيانية الموجودة حاليًا في Python فقط ، ولا سيما وظيفة التمايز التلقائي ، على الرغم من أن هذا لا يهم لتقييم الرسوم البيانية في Java. هناك خطط لنقل هذه الوظيفة إلى C ++ الأساسية في المستقبل ، وعند هذه النقطة ستكون ارتباطات Java SWIG أكثر فائدة لإنشاء الرسوم البيانية.

إذا قبل شخص ما تحدي Java SWIG ، فسيسعدنا قبوله في انتظار المراجعة الأولية ، وما إلى ذلك ، وعند هذه النقطة سيكون جزءًا من اختبارنا المستمر. تفاصيل قبول المساهمات في حالة تغير مستمر في الوقت الحالي ، لكن ذلك سيستقر.

مرحبا يا شباب
نحن مهتمون أيضًا بتكييف TensorFlow مع Java. ravwojdyla هل

أهلا،
أنا أعمل على غلاف SWIG لواجهة برمجة تطبيقات C ++ الرئيسية. يمكنك أن ترى تقدمي حتى الآن على مفترقتي ، لكن ما يحدث لم ينته ؛ أواجه حاليًا مشكلة يتعذر فيها حل #include "tensorflow/core/lib/core/error_codes.pb.h" ولا يمكنني العثور على الملف المقصود في أي مكان داخل ملفات المشروع. المدخلات من أي نوع ستكون موضع تقدير كبير.

هناك إعداد مسبق لـ javacpp متاح للمكتبيين مثل Caffe و OpenCV. راجع أيضًا https://github.com/bytedeco/javacpp-presets/issues/111. تعمل Java-cpp أيضًا على تمكين IOS مع RoboVM

/ ccsaudet

pslam - لقد تمكنت من العمل قليلاً على هذا - يمكنني بالتأكيد استخدام بعض المساعدة!

مرحبًا يا شباب ، أعتقد أن لدي روابط وظيفية جدًا لـ JavaCPP: https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow. اسمحوا لي أن أعرف إذا كنت ترى أي شيء يمكن القيام به مع SWIG ، ولكن ليس JavaCPP. يمكنني بالتأكيد استخدام ردود الفعل. (شكرًا على ccbhack!)

متقن جدا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 هل أغلفة protoc يعمل بشكل مشابه للمترجمين الآخرين. إذا كنت تعمل في مستودع Tensorflow أو كنت تستخدم Bazel ، فستحتاج إلى إعداد أهداف بناء protobuf والتبعيات فيما بينها.

إذا كنت تعمل في مستودع منفصل وتستخدم نظام إنشاء مختلف ، فستحتاج إلى استخدام المكون الإضافي protobuf لنظام الإنشاء هذا.

يسعدني مساعدتك في إنشاء المبنى إذا كنت ترغب في ذلك.

davidzchen شكرًا لك على العرض ، أي وكل مساعدة محل تقدير كبير.

ما لدي حتى الآن:

لقد قمت بالفعل بإعداد Bazel وحصلت عليه لتجميعه في ملف .whl ، والذي سلمته بعد ذلك إلى pip وأكدت أنه يمكنني تشغيل برنامج First TensorFlow .

لقد قمت بإنشاء ملفات مجمعة SWIG في مستودعي المتشعب. هم في مجلد تحت core/javaWrapper . [[رابط] (https://github.com/kylevedder/tensorflow/tree/master/tensorflow/core/javaWrapper)]

ما أحاول القيام به:

في النهاية ، هدفي هو إنشاء ملف .so والذي يمكن تسميته كمكتبة أصلية في Java. حاليًا ، أحاول استخدام g ++ لتجميع النظام بأكمله في ملف .so ؛ ومع ذلك ، يجب توسيع ملفات .proto أولاً إلى .h s و .cc s قبل هذا التجميع ، وهذا ما أحاول فعله بـ protoc .

يمكنك أن ترى محاولتي في سكربت التفاف هنا للحصول على فكرة أفضل عما أحصل عليه ، على الرغم من أن جميع محاولاتي حتى الآن لاستخدام protoc كانت دليلًا بدليل ، وبالتالي لا في البرنامج النصي.

أخيرًا ، سيكون أي تعليق على مجالات التحسين موضع تقدير كبير. شكرا!

kylevedder لدي بالفعل بناء .so كجزء من إعدادات JavaCPP المسبقة: 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 ++.

saudet هل هناك سبب لاستخدامك قاعدة cc_binary لإنشاء المكتبة المشتركة بدلاً من cc_library ؟ يمكنك فقط الحصول على قاعدة cc_library بالاسم tensorflow وسيقوم هدف الإصدار بإنشاء مكتبة مشتركة تسمى libtensorflow.so .

kylevedder إذا كان هدفك هو إنشاء ملف .so ، فإن شيئًا مشابهًا لما اقترحه saudet سيعمل.

إذا كنت بحاجة إلى استخدام بروتوس TensorFlow في كود Java ، فستحتاج إلى إضافة التبعيات من أهداف إنشاء java_* Bazel إلى أهداف proto_library التي تنشئ فئات Java من .proto ملفات.

لا يزال أمامنا القليل من العمل قبل أن نفتح المصدر القواعد الأصلية proto_library (انظر bazelbuild / bazel # 52) ، ولكن في الوقت الحالي ، يستخدم TensorFlow cc_proto_library و py_proto_library يتم توفير قواعد ، وبالنسبة لجافا ، يجب أن تكون قادرًا على استخدام قاعدة Java genproto المضمنة مع Bazel . سوف أتحقق مع الفريق لمعرفة الجدول الزمني لـ proto_library وما إذا كان من المفيد توحيد القواعد التي قدمتها Protobuf بـ genproto .

عدد قليل من أجزاء أخرى من ردود الفعل:

  • أعتقد أنه سيكون من الأفضل الحفاظ على اتساق أسماء الدلائل واستخدام java_wrapper بدلاً من javaWrapper
  • ربما يكون المكان الأفضل لغلاف Java هو //tensorflow/java/wrapper بدلاً من //tensorflow/core/java_wrapper ؟
  • داخليًا ، لدينا بعض قواعد الإنشاء التي تأخذ ملفات .swig وتقوم بإنشاء المصادر. هذا هو أكثر مثالية لأننا نتجنب إيداع الملفات التي تم إنشاؤها. يمكنني إلقاء نظرة لمعرفة مدى صعوبة إضافة بعض قواعد إنشاء SWIG لشركة Bazel لجعل أشياء مثل هذه أسهل.

davidzchen لا يوجد سبب خاص. أنا جديد في Bazel وأستخدم فقط linkshared=1 كما رأيته في القائمة البريدية نجح. لذا شكرا على النصيحة! سأقوم بتحديث ذلك.

saudet شكرا! كنت أتحقق فقط للتأكد من أنها لم تكن مشكلة مع Bazel. :) لا تتردد في إخباري أو فتح خطأ إذا واجهت أي مشكلة.

saudet شكرًا على المعلومات حول استخدام Bazel. أنا أيضًا جديد عليه ولم أدرك أنه قادر على توليد .so بهذه الطريقة.

davidzchen شكرًا على الملحق الخاص باستخدام cc_library ، لقد قمت بتعديل المثال من saudet وفقًا لذلك عندما قمت بتطبيق المجمع الخاص بي . أيضًا ، شكرًا لك على المدخلات المتعلقة بهيكل الدليل ؛ لقد قمت بتحديث بنية المجلد الخاص بي لتتماشى مع اقتراحاتكم.

بالإضافة إلى ذلك ، لم أكن واضحًا جدًا في تعليقي السابق حول إنشاء ملفات .so ؛ بينما هدفي هو إنشاء ملف .so من المصدر الأصلي ، أريد أيضًا تضمين ملف .cxx الذي أنشأته SWIG داخل .so لتسهيل عملية JNI المكالمات. حاليًا ، أواجه مشكلة حيث لا يمكنني الحصول على ملف SWIG الذي تم إنشاؤه .cxx لتجميعه ؛ إنها تحاول الإشارة إلى JNI.h ، وهو رأس يقع في $JAVA_HOME/include/ ، لكن يبدو أنني لا أستطيع جعل Bazel يفهم مسار التضمين الخارجي.

davidzchen Hum ، كلا ، cc_library لا يعمل. لا أرى أي طريقة أخرى لجعل Bazel يمرر الخيار -shared إلى المترجم: http://bazel.io/docs/be/c-cpp.html.

saudet لا أعتقد أنك بحاجة إلى تمرير -shared بنفسك. يجب أن يبني cc_library .so افتراضيًا. هل هذا مناسب لك؟

kylevedder لن تتمكن من إضافة رؤوس JNI بهذه الطريقة لأنها خارج مساحة العمل. ومع ذلك ، يتضمن Bazel JDK المحلي كمستودع محلي ويوفر عددًا من الأهداف المضمنة (انظر jdk.WORKSPACE والمقابل jdk.BUILD ) التي يمكنك استخدامها للاعتماد على JDK المحلي. يتم تضمينها افتراضيًا في كل مساحة عمل Bazel.

Bazel نفسها تستخدم JNI وواجهات مع JDK المحلي بهذه الطريقة (انظر src/main/native/BUILD ). في ملف BUILD هذا ، يوجد genrule s لنسخ رؤوس JNI وهدف cc_library للمكتبة التي يبنيها والتي تستخدم JNI التي تعتمد على الرؤوس ، و includes = ["."] بحيث يمكن أن يتضمن كود C ++ رأس JNI بـ #include <jni.h> . لم يتم توثيق هذا حاليًا لأننا نعمل على عدد من التحسينات على آلية المستودع الخارجي ، وقد يتغير اسم @local-jdk ، لكن يمكننا استخدامه لـ TensorFlow وأي مشروع Bazel آخر يستخدم JNI في هذه الأثناء .

إليك ملف تصحيح لملف BUILD يضيف أهداف genrule لنسخ رؤوس JNI التي تحتاجها وبعض التغييرات على الهدف cc_library لإعداد التبعيات الصحيحة ، وهي:

  1. أضف jni.h و jni_md.h ، والتي يتم نسخها إلى الحزمة الحالية بواسطة genrule s إلى srcs
  2. أضف تبعية على //tensorflow/core بحيث يمكنك تضمين الرؤوس تحت tensorflow/core/public . لاحظ أن الرؤوس أو أي ملف مصدر في دليل منفصل موجود في حزمة منفصلة عن وجهة نظر 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"

بمجرد أن يعمل هذا ، سيكون لديك إعداد JNI build for Linux نظرًا لأن copy_link_jni_md_header genrule ينسخ فقط الرأس الخاص بـ Linux. لجعله ينسخ رأس JNI الصحيح الخاص بالنظام الأساسي ، سنحتاج إلى القيام بما يلي:

  1. قم بإعداد cpu config_setting s للأنظمة الأساسية الأخرى. حاليًا ، يحتوي Tensorflow على config_setting مقابل --cpu=darwin في tensorflow/python/BUILD . ربما يجب علينا نقل هذه الحزمة الأكثر ملاءمة مثل //tensorflow/core . بشكل أساسي ، نريد نفس مجموعة config_setting s مثل Bazel (انظر src/BUILD ).
  2. احصل على copy_link_jni_md_header انسخ رأس JNI الصحيح بناءً على إعداد التكوين الذي تم تعيينه باستخدام select() ، على غرار ذلك الموجود في Bazel . سيبدو 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. أنا أستخدم 0.1.0 كما كان موصى به سابقًا لـ TensorFlow ... ربما تم إصلاحه في 0.1.1؟ سآخذ للمحاولة مرة أخرى.

davidzchen شكرا جزيلا لك على مساعدتك. لقد اتبعت التعليمات الخاصة بك وقمت بتحديث ملف غلاف Java BUILD بالإضافة إلى SWIG .i كما اقترحت. بالإضافة إلى ذلك ، قمت بنقل سكربت الالتفاف من core/java/wrapper إلى الدليل الجذر وقمت بتحديث الروابط وفقًا لذلك.

في الوقت الحالي ، لقد تخطيت التعميم genrule jni_md.h للملف libtensorflow.so . لسوء الحظ ، يبدو لي كما لو أن libtensorflow.so لم يتم إنشاؤه ؛ انتهى بي الأمر بالبحث في نظام الملفات بالكامل عن أي شيء يسمى متغيرًا من "libtensorflow" ولم يظهر أي شيء ذي صلة. قد يتم تسميته بشكل مختلف أو قد تكون هذه حالة بسيطة لخطأ المستخدم. بالإضافة إلى ذلك، هناك احتمال أنه قد تكون ذات صلة لهذه القضية أنsaudet تشهد مع cc_library قاعدة ل .so جيل.

مرة أخرى ، أشكركم على كل ما قدمتموه من مساعدة ، وأنا أقدر ذلك حقًا.

آسف ، اتضح أنني كنت مخطئا. من أجل بناء .so يتضمن التبعيات متعدية ، ما فعله saudet باستخدام cc_binary مع linkshared = 1 و name = "libtensorflow.so" كان صحيحًا. من وثائق cc_binary.linkshared :

أنشئ مكتبة مشتركة. لتمكين هذه السمة ، قم بتضمين linkshared = 1 في قاعدتك. افتراضيا هذا الخيار هو خارج. إذا قمت بتمكينه ، فيجب عليك تسمية الملف الثنائي libfoo.so (أو أيًا كان اصطلاح تسمية المكتبات على النظام الأساسي الهدف) لبعض القيمة المعقولة لـ foo.

الفرق الرئيسي بين .so إنشاؤه بواسطة أهداف cc_library و .so المبني باستخدام cc_binary باستخدام الطريقة الموضحة أعلاه هو أن cc_library artifacts على الكود الموجود بـ srcs . هذا هو السبب في أن إنشاء أهداف cc_library بدون srcs و deps ، مثل //tensorflow/core ، لا ينتج عنه أي قطع أثرية. من ناحية أخرى ، سيتم ربط أهداف cc_binary في جميع التبعيات متعدية.

أعتذر عن الارتباك. ربما يجب علينا تحسين وثائقنا وإضافة مثال على إنشاء .so s.

أعتقد أنه يجب عليك اتباع هذه الخطوات لبناء 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!

إذا كنت مهتمًا ، فيمكنني محاولة دمج البرامج النصية الخاصة بك createWrapper.sh و compileAndRun.sh في إصدار Bazel بواسطة 1) إنشاء قاعدة Skylark SWIG و 2) باستخدام قواعد Java الخاصة بـ Bazel لإنشاء كود Java.

davidzchen سيكون ذلك رائعا! سأعمل على تحسين غلاف SWIG والمثال الأساسي.

لقد أنهيت الإعدادات المسبقة لـ JavaCPP وقمت بنقل عينة example_trainer.cc :
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow
نتطلع إلى مقارنة هذا بغلاف مكافئ باستخدام SWIG!

يبدو أن رابط واجهة برمجة التطبيقات معطل: http://bytedeco.org/javacpp-presets/tensorflow/apidocs/

verdiyanto معذرة ، ليس لدي CI حتى الآن ، لكن تحميل مستندات API سهل بما فيه الكفاية ، لذلك قمت بذلك على الأقل. يتمتع!

saudet عمل جيد على إعدادات JavaCPP المسبقة!

تحديث لعملي: لقد أنجزت المزيد من العمل على غلاف SWIG ، ويمكنك رؤية العمل الذي أنجزته هنا . ومع ذلك ، فأنا في مفترق طرق قليلاً ولست متأكدًا من أفضل طريقة للمضي قدمًا.

أنا جديد إلى حد ما على SWIG ، نظرًا لأن هذا هو أول مشروع رئيسي لي باستخدامه ، لذلك قرأت وثائق SWIG حول SWIG Basics وعلى SWIG و Java والتي تعمل من خلال كيفية عمل SWIG وكيفية التفاف C / C ++ بأغلفة SWIG Java.

تشرح الوثائق كيف يحول SWIG المؤشرات في C / C ++ إلى كائنات Java غير شفافة ، وهذا هو سبب حصولك على فئات مثل SWIGTYPE_p_void التي أنشأتها SWIG. تكمن المشكلة في عدم وجود طريقة سهلة لتحويل POJOs إلى فئات SWIG هذه.

لذلك ، على سبيل المثال ، في tensor_c_api.h ، تأخذ طريقة C TF_CreateTensor() void* الذي يشير إلى بيانات الإدخال ومعلمة size لتحديد حجم إدخال البيانات بالبايت. هذا نمط تصميم معقول تمامًا لـ C / C ++ ، لكنه غير منطقي تمامًا في Java. طريقة Java التي تم إنشاؤها بواسطة SWIG TF_CreateTensor() تأخذ كائن SWIGTYPE_p_void كبياناتها ، إلى جانب size ، ولكن لا توجد طريقة لتحويل POJO مثل String إلى SWIGTYPE_p_void بدون كتابة الكثير من التعليمات البرمجية.

وهذا هو مفترق الطرق الذي أكذب عليه حاليًا: إما أن أكتب عددًا كبيرًا من طرق تحويل C / C ++ التي تأخذ أي نوع محدد في TF_DataType وتحول إلى void* ، أو أكتب مجموعة من أنماط SWIG للقيام بنفس الشيء. لا يبدو أن وثائق SWIG تفضل أيًا من الحلين ، حيث يبدو أنهما يعملان بالتبادل.

إذن ، السؤال هو ، وظائف تحويل C / C ++ أو خرائط أنماط SWIG؟

kylevedder أرى أنك بدأت تفهم سبب إنشاء JavaCPP في المقام الأول. :)

لقد تم استخدامsaudet الصورة المسبقة JavaCPP، مفيدة للغاية، وذلك بفضل! أنا أستخدمه لبناء واجهة Clojure لتدفق التنسور.

بعض التعليقات:

أ) هناك فرصة للتبسيط / طبقة أعلى مستوى

يكرر الكثير من JavaCPP api وظائف protobuf التي يمكن تحقيقها مباشرة على JVM ، بدون الجسر. لقد أخذني بعض الشيء لأدرك ذلك ، لكن المرء ببساطة يقوم ببناء كائن protobuf باستخدام ارتباطات JavaCPP ، مما ينتج هذا التمثيل المستقل للنظام الأساسي باستخدام interop ، ثم حشوها في الجلسة.

لقد انتهيت فقط من استخدام protobufs المستندة إلى jvm لإنشاء الرسم البياني مباشرةً ، متجاوزًا وظائف مُنشئ JavaCPP. هذا له العديد من المزايا - أبسط لبرمجة API ، وكذلك تنسيق .toString لطيف الذي يعرض protobuf الذي يمكن للبشر قراءته.

بالنسبة إلى Clojure على وجه الخصوص ، من الأسهل بكثير وصف الرسم البياني لتدفق التنسور من حيث هياكل البيانات ثم تحويلها مباشرة إلى بروتوبوف ، بدلاً من البحث واستدعاء دالة مُنشئ لكل عقدة في بنية البيانات الخاصة بي.

ب) تحسينات البناء والحزمة

لست خبيرًا في بناء كود أصلي ، أو في أدوات البناء المستخدمة في هذه المشاريع. سيكون من الرائع أن يكون لديك قطع أثرية مخضرمة ؛ على وجه الخصوص إذا تضمنت أيضًا فئات java protobuf التي تم إنشاؤها. لقد استغرق الأمر وقتًا محرجًا بالنسبة لي لمعرفة كيفية القيام بذلك.

ج) قد يكون من المفيد أن يكون لديك عدد صغير من حالات اختبار الرسم البياني لاستهدافها.

في الوقت الحالي ، منهجتي مرهقة إلى حد ما: استخدم وظائف مُنشئ JavaCPP لإنشاء رسم بياني ، وقم بتضمينه في نماذج JVM الخاصة بي ورؤية النموذج الذي يمكن قراءته بواسطة الإنسان ، واكتشف كيفية إنشاء المُنشئ الخاص بي لإنشاء نفس النموذج.

قد يكون من المفيد أن يكون لديك مجموعة صغيرة من الرسوم البيانية البسيطة جدًا التي تمارس الوظائف الأساسية لـ TensorFlow ، بحيث يكون لدى الأشخاص مثلي مجموعة معقولة من حالات الاختبار لاستهدافها من أجل التوافق مع لغات مختلفة.

على أي حال شكرا لجهود الجميع واستمروا في العمل الجيد!

kovasb شكرا على ردود الفعل! من الواضح أن هناك الكثير مما يجب القيام به لجعل الواجهة أكثر طبيعية بالنسبة إلى Java و Scala و Clojure وما إلى ذلك.

إذا كان لديك فئات مساعدة لدمج واجهة برمجة تطبيقات C ++ مع واجهة برمجة تطبيقات Java protobuf ، فلا تتردد في وضع كل ذلك في الحزمة التالية ، بما في ذلك فئات Java protobuf التي تم إنشاؤها نفسها ، وإرسال PR:
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper
هذا هو الغرض منه ، وسيتم تعبئته تلقائيًا في قطعة أثرية Maven ، وهو شيء لا يدعمه Bazel. على أي حال ، شكرا للنظر في هذا!

kovasb تبدو واجهة clojure مثيرة للاهتمام حقًا. حصلت على أي رمز للمشاركة حتى الآن؟

شكرا!

لذا فإن الأشخاص في هذا الموضوع يدركون أيضًا ، في https://github.com/tensorflow/tensorflow/issues/3 تم رفعه: التمايز التلقائي لا يعمل حاليًا إلا إذا كنت تستخدم TF من python api. يبدو هذا وكأنه أداة عرض معلقة في انتظار تلك الوظيفة التي يتم نقلها إلى C ++.

لا أفهم تمامًا تدفق البيانات ولكن ربما يكون من الممكن تشغيل عناصر مساعد Python مع C ++ lib؟

الحل الآخر الذي أتطلع إليه هو استخدام Jpy أو أحد الجسور الأخرى (أي شخص لديه توصيات؟) تبدو JyNi أيضًا مثيرة للاهتمام ولكنها بعيدة جدًا عن وقت الذروة (على الرغم من أنه سيكون من الرائع رؤية المزيد من الزخم / المجتمع وراءها)

إذا تم فرز JyNi ، فسيؤدي + jython إلى منح JVM قصة رائعة حقًا لإعادة نظام التشغيل المتداخل لنظام Python. يمكن للمرء أن يحلم.

+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؟)

@ مارتينويك ما رأيك؟

عندما يكون هناك ارتباط ثابت لجافا ، يسعدني العمل على Scala API.

/ cc databricks

kovasb أعتقد أنني فاتني هذه المرة الأولى من خلال. هل تقول أن كل سحر التمايز التلقائي اللطيف الذي نحصل عليه من استخدام TensorFlow عبر Python يتم تنفيذه داخل Python ، وليس ضمن libs c ++؟ لذا من الناحية العملية ، قد تحتاج Java API إما إلى إعادة تنفيذ كل هذا ، أو ستكون مجرد مكتبة رقمية أخرى؟ لست على دراية كافية بالأجزاء الداخلية لـ TensorFlow أو غراء الثعبان لفهم بالضبط ما يتم فيه رفع الأحمال الثقيلة.

drdozer هذا ما أفهمه ، بناءً على تعليقات girving ثم أبحث عن المصدر قليلاً بنفسي. يبدو أن إعادة تنفيذ الأشياء في Java أمر غير ناجح. أقترح النظر في التعليقات في رقم 3

إذا كان شخص ما مهتمًا حقًا ، فإنني أوصي فقط بمحاولة القيام ببعض الأمثلة التدريبية باستخدام Java api (حتى الآن رأيت / قمت للتو بالمسار الأمامي).

أتساءل إلى أي مدى سنصل إلى تشغيل كود Python مع Jython ...

أعتقد أن طبقة Python API بها الكثير من المنطق الذي لا تعرضه واجهة برمجة تطبيقات طبقة C ++.
كنت أحاول اتباع مسار JavaCpp ولكن في النهاية سيكون هناك الكثير من رموز النسخ وسيكون من الصعب الحفاظ على التناسق عندما يتغير شيء ما في تطبيق Python.

ربما يكون المسار الأسهل هو استخدام جايثون كما ذكر saudet من قبل ...

تم تعيينه في https://github.com/tensorflow/tensorflow/issues/476 إلى @ josh11b. إذا كان يعمل على هذا لا معنى لاستخدام Jython.

إذا استخدمنا jython ، فهل سيظل كود c ++ يعمل؟ أتطلع لاستخدام هذا لخادم موجود في Java ولكني عالق بين تجربة مسار Java مباشرة أو مجرد إرسال البيانات عبر مأخذ إلى عملية Python

أود أن أذكر أنه على الرغم من أن Java API لا تتضمن الكثير من الميزات مثل التمايز التلقائي ، إلا أنني لم أجد أن هذا يمثل حاجزًا لعملي الخاص. لقد حققت نجاحًا كبيرًا في إنشاء نموذج في Python ، وتسلسله إلى ملف .proto ، ثم فتحه من خلال غلاف Java للتدريب. يمكن القيام بنفس الشيء لوقت الاختبار ، لأنني أعتقد أن وظيفة Saver متاحة من خلال واجهات برمجة تطبيقات C ++ و Java.

+1

saudet
شكرًا لإنشاء javacpp والإعدادات المسبقة لـ Tensorflow. لقد تمكنت من إعادة إنشاء رسم بياني Python في Java بنجاح ، لكنني عالق في محاولة الاستعادة من ملف نموذج محفوظ. هذا الخط لا يعمل:

Tensor fn = Tensor جديد (Tensorflow.DT_STRING ، TensorShape جديد (1)) ؛
المخزن المؤقت CharBuffer = fn.createBuffer () ،
buffer.put ("modelfile.tf") ؛
جلسة تشغيل (...) ؛

لكن CharBuffer تبين أنه NULL. إذا قمت بتغيير DT_STRING إلى DT_FLOAT ، فسأحصل على FloatBuffer ، ولكن يبدو أن DT_STRING لا تعمل.

nikitakit قلت أنك حصلت على هذا للعمل. هل يمكنك مشاركة الرمز الخاص بك؟

تضمين التغريدة

تحرير: آسف ، أخطأت في قراءة ما قلته هنا. لا يمكنني تقديم أي مساعدة لاستخدام برامج حفظ خارجية من Java

كمرجع ، يوجد جزء من الكود الخاص بي الذي يستورد الرسوم البيانية لـ tensorflow هنا: https://gist.github.com/nikitakit/d3ec270aee9d930267cec3efa844d5aa

إنه في Scala ، ولكن يجب أن يكون النقل إلى Java / لغة JVM أخرى مباشرًا.

لسوء الحظ ، فإن الكود الخاص بي لتشغيل العقد فعليًا في الرسم البياني مرتبط بشدة بإطار عمل Scala الذي أستخدمه ، لذلك سيتعين عليك الاعتماد على مستندات tensorflow API لهذا الجزء.

هل حصل أي شخص على أي مكان مع تضمين بيئة tensorflow الثعبان في JVM؟ قل مع جايثون + جيني؟ أم أن هذا كله تجريبي إلى حد ما بحيث يتعذر عليك العمل بشكل موثوق؟

أنا أعمل حاليًا على توسيع C API لإضافة دعم لتعريف الرسم البياني. لست متأكدا متى سيتم ذلك ، لكنه أحد أهدافنا قبل 1.0.

أنا أعمل على استخدام تدفق موتر من جافا. أنا أقترب من المشكلة باستخدام jython وتعديل مكتبة cpython لتدفق الموتر لاستيعاب مترجم Python آخر. يجب أن يستمر cpython في العمل بشكل لا تشوبه شائبة وأن الكود الخاص بي يكتشف ما إذا كان المترجم هو Jython ويقوم بتعديل الواردات / الوحدات للسماح لها بالعمل. تحته يستخدم روابط javacpp لـ libtensorflow_cc.so. هل هذا شيء سيكون فريق Google مفتوحًا للحصول عليه في الريبو الرسمي؟ تضمين التغريدة

يبدو هذا كإثبات جيد للمفهوم ، لكنني أعتقد أن الارتباط الرسمي قد يرغب على الأرجح في الارتباط بشكل أصلي أكثر من المرور عبر Python :(

لا ، فبدلاً من استدعاء غلاف c-python ، نسمي غلاف javaccp. لذلك سيكون نفس الشيء مثل تدفق موتر cpython ولكن يتم تقييمه من JVM باستخدام Jython. يبدو أن إعادة تنفيذ منطق Python بالكامل بلغة أخرى أمر مبالغ فيه ، وينتهي بك الأمر بواجهة برمجة تطبيقات أخرى. تسمح لك روابط javacpp بتشغيل Inference دون مشكلة ولكن النموذج يجب أن يتم بناؤه / تدريبه من برنامج نصي cpython في الوقت الحالي.

هل نظر أي شخص في جعل Tensorflow يعمل مع Kotlin؟ يبدو مناسبًا أكثر ولا يزال جافا بنسبة 100٪ في نهاية اليوم. أجد أن لغة Kotlin هي حل وسط لطيف للغاية بين Python و Java الصافية.

تحديث: تمكنت من الحصول على الأشياء بنجاح مع javacpp (بفضل saudet )

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

شكرا lakshmanok و saudet . يبدو أن مشروع javacpp يطبق معظم واجهات برمجة تطبيقات TensorFlow. نحن نحاول تشغيل tensorflow / الخدمة في Java.

واجهة برمجة التطبيقات بسيطة ومحددة بواسطة protobuf . الآن قمنا بتنفيذ الخادم ونريد تطبيق العميل في Java. تحتاج فقط إلى إنشاء TensorProto في Java واستدعاء استدعاء gRPC . يوفر TensorFlow وظائف مساعدة لتحويل مصفوفات الأبعاد المتعددة لـ Python و C ++ ، ولكن ليس Java.

هل يمكنك معرفة كيفية استخدام javacpp أو التنفيذ بأنفسنا لهذا؟

ربما يكون ما تبحث عنه موجودًا بالفعل في https://github.com/bytedeco/javacpp-presets/blob/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper/tensorflow.java ولكن أخبرني إذا كان هناك شيء مفقود. شكرا!

هل هذا لا يزال قيد العمل؟ هل يوجد مستودع جيثب رسمي لمشروع النقل هذا؟ أرى بضع عمليات إعادة شراء عشوائية ، لكن لا يمكنني معرفة ذلك.

نعم ، ولكن ربما في وقت ما في أكتوبر / نوفمبر. نحن نستخدم C API بدلاً من SWIGing لواجهة برمجة تطبيقات C ++. في غضون ذلك ، يمكنك استخدام الروابط التي ذكرها saudet.

كيف توصلت إلى الاستنتاج باستخدام واجهة برمجة تطبيقات C؟ نحن نعمل على أ
واجهة روبي باستخدام swig:
http://github.com/somaticio/tensorflow.rb

يوم الثلاثاء ، 13 سبتمبر 2016 ، الساعة 6:22 مساءً ، جوناثان هسو إخطارات @github.com
كتب:

نعم ، ولكن ربما في وقت ما في أكتوبر / نوفمبر. نحن نستخدم C API
بدلاً من SWIGing إلى واجهة برمجة تطبيقات C ++. في غضون ذلك ، يمكنك استخدام ملف
الأغلفة التي ذكرها سعود.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -246844192 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAA5v3g86Z6D1rz-aTGdMyMWnQZhrZUYks5qpyIJgaJpZM4Getd8
.

من الآن فصاعدًا ، نفضل أن تستخدم جميع روابط اللغة واجهة برمجة تطبيقات C. وثيقة قادمة.

يمكنك مشاهدة مثال على الاستخدام هنا:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/go

ومع ذلك ، ليس هناك حاجة ملحة ، والبناء فوق SWIG أمر جيد في الوقت الحالي.

jhseu هل يعني ذلك أن واجهة برمجة تطبيقات C سيتم توسيعها لتشمل كل ما يمكن لربط بايثون الوصول إليه حاليًا؟

واو ، تغيير كبير. أتمنى أن يكون هذا قد تقرر في وقت سابق. على أي حال لرؤية المستندات
عاجلا؟

يوم الأربعاء 14 سبتمبر 2016 الساعة 5:56 مساءً ، Samuel Audet [email protected]
كتب:

jhseu https://github.com/jhseu هل هذا يعني أن واجهة برمجة تطبيقات سي ستكون كذلك
تم توسيعها لتشمل كل ما يمكن الوصول إليه حاليًا من روابط Python؟

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -247167887 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAA5vwfBJoZC2s33_7E9Xy6-NYNUjHjnks5qqG2FgaJpZM4Getd8
.

saudet معظم الوظائف ، إلا على المدى القصير ، والمحسّنات ).
jtoy ليس هناك

تصف المستندات فقط كيفية القيام بذلك واصطلاحات التسمية. يمكنك البدء في الترحيل إلى C API بدونها ، على الرغم من:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

شكرا saudet . لقد وجدت هذا في stackoverflow حول إنشاء TensorProto باستخدام واجهة برمجة تطبيقات protobuf الخالصة. وإليك مثال الكود الخاص بعميل جافا gRPC لخدمة TensorFlow.

@ tobegit3hub Nice ، إذا كان بإمكانك إجراء هذا العمل باستخدام واجهة برمجة تطبيقات C ++ ، فيرجى إضافته إلى الحزمة المساعدة لإعدادات JavaCPP المسبقة وإرسال طلب سحب! سيكون هذا الرجل مهتمًا بشيء من هذا القبيل: https://github.com/bytedeco/javacpp-presets/issues/240

girving هل javacpp يحل المشكلة بالفعل؟
أرغب في المساهمة في tensorflow java api ، أفضل تنفيذه مثل python.

مرحبًا يا شباب ، هل بدأ شخص ما بالفعل في العمل على ارتباطات لغة Java / Scala باستخدام واجهة برمجة تطبيقات C؟
(بدلاً من البناء فوق SWIG)

لديّ واجهة Java / Scala تعمل لتدفق التنسور باستخدام واجهة برمجة تطبيقات C فقط عبر JNR . لسوء الحظ ، ليس لدي إذن بفتح المصدر. سوف أنشر هنا إذا وعندما أفرج عنه. لا يزال هذا العمل قيد التقدم ، لكنه وظيفي للغاية.

jdolson هل تقبل واجهة برمجة التطبيقات التي تعرضها كائنات المخزن المؤقت لبروتوكول TensorFlow؟ واحدة من أكبر المشكلات التي واجهتها باستخدام إعدادات javacpp المسبقة من saudet هي أنه عندما تتعامل مع كائنات موتر في كود عميل Java ، فإنك تتعامل مع org.tensorflow.framework.TensorProto الذي تم إنشاؤه بواسطة برنامج التحويل البرمجي المؤقت للبروتوكول عندما تم تكوينه لإخراج جافا. ولكن في غلاف واجهة برمجة تطبيقات TensorFlow ، فأنت تتعامل مع org.bytedeco.javacpp.tensorflow.TensorProto.TensorProto الذي تم إنشاؤه بواسطة javacpp عند الإشارة إلى رمز c الذي تم إنشاؤه بواسطة برنامج التحويل البرمجي المؤقت للبروتوكول عند تكوينه لإنتاج C. نفس الشيء لا يمكنك استخدام موترات كود جافا الخاص بك مباشرة عند استدعاء TensorFlow API.

Intropy نعم ، أقوم بتجميع جميع مصادر tensorflow *.proto إلى كود مصدر Java باستخدام protoc واستخدام هذه الفئات في واجهة برمجة التطبيقات.

jhseu هل لا تزال واجهة C API على المسار الصحيح ليتم إصدارها في وقت ما خلال شهر نوفمبر؟ إذا لم يكن كذلك ، فما هو الوضع الحالي؟

eaplatanios : واجهة C API مستقرة في الغالب (وستكون كذلك رسميًا بحلول 1.0) وقابلة للاستخدام على الرغم من عدم اكتمالها (لا تزال تفتقد القدرة على حسابات التدرج تلقائيًا للرسم البياني). يوجد مستند يصف كيفية استخدام C API لبناء روابط اللغة على https://www.tensorflow.org/how_tos/language_bindings/index.html

تم تنفيذ Go API باستخدام C API كمثال أول لاتباع المستند أعلاه.

نأمل أن يتم بناء روابط Java فوق هذا أيضًا (باستخدام JNI) وقد بدأنا في استكشاف ذلك قليلاً. أي تعليقات / معلومات اعتمدها الأشخاص على استخدام عمل

لدي بعض الاقتراحات بناءً على استخدام ارتباطات JavaCPP.

أولاً ، نظرًا لأن المخازن المؤقتة للبروتوكول يتم تجميعها مباشرة إلى جافا ، يجب استخدام إصدارات جافا. على نحو مفضل ، أعتقد أن المخازن المؤقتة للبروتوكول التي تشارك في واجهة برمجة التطبيقات يجب أن تكون متاحة بشكل منفصل كوحدة نمطية مخضرمة ويجب أن تأتي مع التعريفات الأولية بحيث يكون لدى الأشخاص في حزمة Java طريقة سهلة للحصول على التعريفات باعتبارها ثنائية وكذلك سهلة طريقة للحصول على التعريفات الأولية لتضمينها في التعريفات الأولية الأخرى.

ثانيًا ، سيكون من المفيد العثور على الحد الأدنى من إصدار libc الذي يحتاجه TensorFlow والبناء عليه.

ثالثًا ، من الأسهل استخدام واجهة برمجة تطبيقات مصممة بعناية أكثر من استخدام واجهة برمجة تطبيقات يتم إنشاؤها تلقائيًا. أعلم أن هذا أمر واضح ويبدو نوعًا ما مثل لقطة في JavaCPP. لا أقصد أن يكون الأمر كذلك. أنا سعيد حقًا لوجود الواجهة التي تم إنشاؤها تلقائيًا. _ هو _ صالح للاستخدام. لكنها تتطلب إطالات غريبة ، ولديها الكثير من الثآليل ، ومن الصعب جدًا قراءة الكود لمعرفة كيفية القيام بما تحاول القيام به. أتمنى أن يكون هذا الاقتراح أكثر فائدة من "يجب أن تجعله جيدًا" ، ولكن أعتقد أن النقطة المهمة هي أن ننظر إلى مدى اختلاف واجهة برمجة تطبيقات C ++ وواجهة برمجة تطبيقات Python. كلاهما واضح ومباشر لأنهما يلائمان بيئتهما بطريقة من غير المرجح أن تتطابق التعليمات البرمجية المحولة تلقائيًا.

ربما كان من الأجمل دعم الواجهة الخلفية C لـ Swig وإنشاء واجهة برمجة تطبيقات TF C عبر Swig أيضًا: https://github.com/swig/swig/issues/800 بحيث يمكن للغات أخرى مثل Go و Ruby و R استخدام C api لكتابة الارتباطات الخاصة بهم.

لدينا واجهة برمجة تطبيقات C موجودة لإضافة دعم لأي لغة باستخدام C FFI:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

(وهذا هو ما يتم استخدامه لبناء روابط Go و Java و Rust وما إلى ذلك لـ TensorFlow)

هل يمكن الوصول إلى C API باستخدام JNA ؟

jhseu قصدته ، ربما تم إنشاؤه من C ++ API في وقت سابق ، قبل تنفيذ C API يدويًا.

@ Quantum64 ، هنا رابط Scala لـ Tensorflow الذي يستخدم JNA.

نظرًا لأن هذه المشكلة لا تزال مفتوحة ، فكيف يتم ذلك
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java
قيد التنفيذ وماذا كانت العلاقات العامة للالتزام؟

@ hsaputra : هل يمكنك توضيح ما تبحث عنه؟ هناك التزامات متعددة تساهم في الكود في tensorflow/java ، معظمها مشار إليه في هذه المشكلة (مثل 2b1cd28 ، d73a266 وغيرها الكثير فيما بينهما)

مرحبا asimshankar ، شكرا على الرد.

أنا فقط أتساءل ما هو المسار الذي سلكه tensorflow/java لتنفيذ Java API لأن هذه التذكرة ليست مغلقة.
كانت هناك مناقشات حول استخدام JavaCPP vs SWIG vs call عبر Jython.

يبدو أنه تم تنفيذ tensorflow/java مع JNI المباشر لاستدعاء C APIs بدلاً من ذلك؟

صيح.

مهلا،

لقد حصلت للتو على روابط Swig هذه تعمل بالأمس. لدي طلب لتغيير API. في الوقت الحالي ، من أجل إنشاء انعكاس Tensors ، يلزم تنسيق المصفوفات قليلاً ، لأنها تتطلب استخدام مصفوفات Java الأصلية ذات الأبعاد n. هل يمكننا الاحتفاظ بهذه الواجهة ، ولكن أيضًا إضافة بعض الطرق لإنشاء الموترات التي تتطلب مصفوفات أحادية البعد وتحديد الشكل باستخدام مصفوفة أخرى طويلة؟ أتخيل أنه يمكن أن يبدو مثل هذا:

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:

أحاول استخدام واجهة برمجة تطبيقات جافا الجديدة ، وقد صادفت بعض الأشياء التي تجعل استخدامها أصعب مما أعتقد أنه يجب أن يكون:

  1. يجب أن تقبل واجهة برمجة تطبيقات جافا كائن GraphDef. لا يقبل حاليًا سوى صفيف بايت يمثل الثنائي المتسلسل لمخزن بروتوكول GraphDef المؤقت. من الغريب أن تتطلب خطوة التسلسل / إلغاء التسلسل عند حدود المكتبة.
  2. يجب أن تكون Session.Runner.feed قادرة على قبول org.tensorflow.framework.TensorProto أو يجب أن تكون هناك طريقة جيدة لإنشاء org.tensorflow.Tensor من org.tensorflow.framework.TensorProto.
  3. تُرجع Session.Runner.run قائمة بكائنات Tensor. على غرار ما ورد أعلاه ، يجب أن تكون هناك طريقة سهلة للحصول على إخراج TensorProto إما بشكل مباشر أو عن طريق إعطاء org.tensorflow.Tensor طريقة جيدة للتحويل إلى TensorProto.
  4. Session.Runner.run يبتلع الحالة. يجب أن تكون هناك طريقة للحصول على هذه المعلومات حول الإخفاقات ، ربما من خلال طرح استثناء.

أيضًا ، من المحتمل أن أكون قد فاتني طريقة التعامل مع هذا ، لكن يبدو لي أنني لا أستطيع الحصول على جميع أنواع الموتر المدعومة في الإخراج من التشغيل. على سبيل المثال ، إذا كان موتر الإخراج الخاص بي من نوع dtype INT16 ، فلا توجد طريقة لاستخراج القيمة منه. لا يوجد Tensor.shortValue أو ما شابه ، ويبدو أن Tensor.intValue تتطلب تطابقًا تامًا. أنا أسند هذا إلى قراءة DEFINE_GET_SCALAR_METHOD في tensor_jni.cc.

Intropy : شكرًا على تعليقاتك وهي بالتأكيد منطقية. في الوقت الحالي يمكنني مشاركة بعض الأفكار السريعة معك:

RE: protobufs: في هذه المرحلة نحاول الحفاظ على API الأساسية مستقلة عن protobufs لعدد من الأسباب (بما في ذلك الاستخدام في أنظمة محدودة الموارد حيث قد يكون شيء مثل nanproto أكثر ملاءمة). لذلك ، هذا هو سبب ترددنا ، لكنه شيء نفكر فيه ونقدر الاقتراحات. أحد الاحتمالات هو الحصول على جميع الوظائف ذات الصلة بالبروتوبوف في حزمة منفصلة بحيث يكون هناك فصل واضح.

لذا ، لنعد إلى نقاطك:

  1. أنظر فوق. على الرغم من ذلك ، أراهن أن هناك العديد من الحالات التي يكون فيها byte[] أكثر منطقية (مثل قراءة الرسم البياني من ملف أو قناة شبكة)

  2. أخذت النقطة

  3. أنظر فوق.

  4. يجب ألا يكون Session.runner.run حالة ابتلاع. إذا كان هناك خطأ ، فسيتم طرح استثناء ( session_jni.cc:166 ). إذا لم يحدث ذلك ، يرجى تقديم خطأ.

أنت على حق ، ليست كل الأنواع مدعومة حتى الآن ، ولكن يجب أن تكون سهلة بما يكفي للإضافة. إذا كانت لديك حاجة ملحة للأنواع المفقودة ، فلا تتردد في تقديم مشكلة و / أو إرسال PR. نرحب بالمساهمات :)

asimshankar شكرا على أفكارك.

فيما يتعلق بالنقطة الأولى ، إنها ليست مشكلة كبيرة حقًا. كما تقول ، هناك أوقات يكون فيها البايت [] أكثر منطقية. في حالة الاستخدام الخاصة بي ، لدي InputStream ، وهو أمر بسيط للتحويل إلى بايت []. واجهة برمجة تطبيقات المخزن المؤقت للبروتوكول تجعل التحويل مباشرًا. أنا فقط أعتبر البايت [] ثؤلولًا على واجهة برمجة التطبيقات لأنك ستضطر إلى إلغاء التسلسل على أي حال (في TF_GraphImportGraphDef) وبهذه الطريقة تفقد نوعًا من الأمان. هناك أيضًا تسلسل json الخاص بـ proto3 الذي يجب مراعاته.

في حالة البلع ، أنت على حق. فاتني الاستثناء الذي لم يتم التحقق منه.

الطريقة الأكثر وضوحًا للتعامل مع 2 و 3 هي إعطاء org.tensorflow. تحكم في المصنع الذي يتحول من TensorProto وبعض إلى TensorProto (). إذا كانت حالات الاستخدام المحدود للموارد هي المشكلة مع المخازن المؤقتة للبروتوكول ، فلن يتمكن الأشخاص في هذه الظروف ببساطة من استخدام هذه الوظائف. تكمن المشكلة في أن الأشخاص الذين يستخدمون هذه الوظائف سيدفعون تكلفة التحويل الذي يمكن تجنبه على الأرجح من خلال جعل Tensor يخزن بياناته مباشرة في بروتوبوف. لم أعمل مطلقًا مع jni من قبل ، لذلك أواجه مشكلة في متابعة كيفية تخزين البيانات ، ولكن يبدو أنه يتعامل بشكل أساسي مع العنصر الأصلي كمؤشر لجهاز TF_Tensor الذي يحتوي على TensorBuffer يتم التعامل معه بشكل أساسي على أنه فراغ بحجم *.

هل يمكننا تفكيك هذه المشكلة وتقديم مشكلات منفصلة لكل ميزة في واجهة Java؟ ستجعل التتبع / التحليل أسهل ، ثم يمكننا إغلاق هذه المشكلة.

drpngx : أعتزم إجراء بعض التغييرات

يبدو جيدا. شكر!

حسنًا ، يبدو أن لدينا قاعدة كافية للبناء عليها (على سبيل المثال ، ما يكفي لبناء مثال LabelImage ويقوم الأشخاص بتقديم طلبات أخطاء / ميزات أكثر تحديدًا.

سأقوم بإغلاق هذه القضية. لا يزال هناك الكثير للقيام به في Java API ، ولكن دعونا نناقش / نتتبع تلك الموجودة في مشكلات منفصلة. شكرا!

asimshankar نحن بصدد اختيار إطار عمل التعلم العميق (mxnet / tf) ويعتمد etl / api الخاص بنا على Spark / akka flow ... هل هناك خطة لإضافة دعم الموزع_runtime إلى Java API لتشغيل نموذج التدريب المتوازي باستخدام ps العقد؟ تعتبر عقدة ps أمرًا بالغ الأهمية بالنسبة لنا للعديد من حالات الاستخدام ... قد يكون تصدير إعدادات javacpp المسبقة أسهل للقطع الأول نظرًا لأن واجهة برمجة تطبيقات C نفسها لا يبدو أنها تحتوي على وقت تشغيل مُوزع ...

@ debasish83 : يعد تضمين وقت التشغيل الموزع في حد ذاته أمرًا تافهًا ، ولكن هناك مجموعة من التركيبات ذات المستوى الأعلى في واجهة برمجة تطبيقات Python مثل فئة Estimator التي تهتم بمجموعة من الأشياء (نقاط التفتيش ، وحفظ الملخص ، إلخ. جعل التصور من خلال TensorBoard تافهًا) مما قد يجعله أكثر ملاءمة لتشغيل وظائف التدريب في Python.

كل هذا يمكن بناؤه باستخدام العناصر الأولية الموجودة في Java API ، لكن النهج الصحيح سيعتمد على احتياجاتك الدقيقة.

ربما يجب علينا مزامنة خارج الموضوع؟

asimshankar هل هناك طريقة بالفعل من رابط Java tensorflow لاسترداد المعلومات من GraphDef (مبني من ملف .pb للرسم البياني على القرص) مثل قائمة العقد وتنسيق الإدخال والإخراج أم أنها ميزة واردة؟ شكرا!

asimshankar لست متأكدًا من فهم ما ينقص التدريب باستخدام TF Java. هل هي مشكلة المكتبة الرقمية (النقود المفقودة)؟ أعني إذا لم تكن مهتمًا ببيانات TensorBoard ، ولكنك تتدرب فقط ، باستخدام مكتبة رقمية Java أصلية ، فلماذا تستخدم Python للتدريب فقط (كما تقترح حول فئة Estimator

شكرا.

ما حالة نماذج التدريب في جافا؟ لقد كنت أفكر في كتابة البرنامج المساعد 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 فقط للتنبؤ باستخدام مدرب مسبقًا
عارضات ازياء. سوف أنظر إلى المثال.

في يوم الأربعاء ، 28 مارس 2018 ، الساعة 22:01 كتب عاصم شانكار [email protected] :

bergwerf https://github.com/bergwerf : التدريب في جافا بالتأكيد
ربما ، إن لم يكن مناسبًا بشكل خاص.
يمكنك العثور على عينة في
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 التقييمات