Tensorflow: Interface Java

Créé le 9 nov. 2015  ·  112Commentaires  ·  Source: tensorflow/tensorflow

Problème pour tracer l'effort de l'interface swig pour java. Mise en œuvre commencée - sera mise à jour avec les progrès. Si quelqu'un a des commentaires/conseils, n'hésitez pas à vous joindre à la discussion !

Commentaire le plus utile

Mise à jour : j'ai réussi à faire avancer les choses avec javacpp (grâce à @saudet ) et à faire en sorte que les programmes Java lisent/exécutent les modèles TensorFlow.

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

Tous les 112 commentaires

Joli!

Déplacer ce commentaire ici depuis https://github.com/tensorflow/tensorflow/issues/3 :


Il existe une suite de tests avec une assez bonne convergence, mais actuellement c'est principalement Python avec quelques tests C++. Il existe également de nombreuses fonctionnalités pour créer des graphiques qui sont actuellement uniquement Python, en particulier la fonctionnalité de différenciation automatique, bien que cela n'ait pas d'importance pour l'évaluation des graphiques en Java. Il est prévu de déplacer cette fonctionnalité dans le C++ sous-jacent à l'avenir, auquel cas les liaisons Java SWIG seraient plus utiles pour créer des graphiques.

Si quelqu'un relève le défi Java SWIG, nous serions heureux de l'accepter en amont dans l'attente d'un examen, etc., auquel cas cela ferait partie de nos tests continus. Les détails de l'acceptation des contributions sont en train de changer pour le moment, mais cela se stabilisera.

Bonjour gars
Nous sommes également intéressés par l'adaptation de TensorFlow pour Java. @ravwojdyla Avez-vous, par hasard, commencé à travailler sur l'interface Swig pour Java ? Si vous l'avez fait, nous pourrions joindre nos efforts et collaborer à cela

Bonjour,
Je travaille sur un wrap SWIG de l'API C++ principale. Vous pouvez voir mes progrès jusqu'à présent sur ma fourche, mais ce qui se passe là-haut n'est pas terminé ; Je rencontre actuellement un problème dans lequel #include "tensorflow/core/lib/core/error_codes.pb.h" ne peut pas être résolu et je ne trouve pas le fichier souhaité dans les fichiers du projet. Une contribution de toute nature serait grandement appréciée.

Il existe des préréglages javacpp disponibles pour les bibliothèques comme Caffe et OpenCV. Voir aussi https://github.com/bytedeco/javacpp-presets/issues/111. Java-cpp active également IOS avec RoboVM

/cc @saudet

@pslam - j'ai pu travailler un peu dessus - j'aurais

Salut les gars, je crois que j'ai des liaisons assez fonctionnelles pour JavaCPP : https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow. Faites-moi savoir si vous voyez quelque chose qui pourrait être fait avec SWIG, mais pas JavaCPP. Je pourrais certainement utiliser les commentaires. (Merci pour le cc @bhack !)

Très bien fait @saudet ! J'ai presque terminé un wrap SWIG, mais il semble que votre implémentation fonctionne tout aussi bien. Je ne vois rien que mon écharpe SWIG puisse faire que le vôtre ne puisse faire. JavaCPP semble très cool, je vais devoir envisager de l'utiliser pour de futurs projets.

Salut @kylevedder , avez-vous résolu le problème lié à error_codes.pb.h ?
[Édité]
Tous les fichiers .pb.h sont compilés à partir de .proto

@tngan Oui, c'est aussi ce que j'ai découvert. De plus, les fichiers .proto de ce projet nécessitent l'utilisation de ProtoBuff3. J'utilise Ubuntu 14.04 et ProtoBuff3 n'était pas disponible dans mon gestionnaire de paquets, je l'ai donc compilé à partir des sources, que j'ai obtenues à partir de la version bêta 3.0.0 .

Le barrage routier actuel que j'essaie de résoudre est de savoir comment faire en sorte que ProtoBuff récurse sur l'ensemble de l'arborescence des fichiers et compile les fichiers .proto fichiers .h et .cc ; faire chaque dossier au coup par coup entraîne des échecs dus à des dépendances insatisfaites par rapport à d'autres fichiers .proto encore à compiler.

@kylevedder Vos wrappers SWIG sont-ils dans un référentiel séparé ou travaillez-vous dans le référentiel tensorflow ? protoc fonctionne de manière similaire aux autres compilateurs. Si vous travaillez dans le référentiel tensorflow ou utilisez Bazel, vous devrez alors configurer les cibles de construction protobuf et les dépendances entre elles.

Si vous travaillez dans un référentiel séparé et utilisez un système de build différent, vous devrez alors utiliser le plugin protobuf pour ce système de build.

Je serais heureux de vous aider à mettre en place la construction si vous le souhaitez.

@davidzchen Merci pour l'offre, toute aide est grandement appréciée.

Ce que j'ai pour l'instant :

J'ai déjà configuré Bazel et je l'ai compilé dans un fichier .whl , que j'ai ensuite remis à pip et confirmé que je pouvais exécuter le programme First TensorFlow .

J'ai généré des fichiers wrapper SWIG dans mon référentiel fork. Ils se trouvent dans un dossier sous core/javaWrapper . [[lien](https://github.com/kylevedder/tensorflow/tree/master/tensorflow/core/javaWrapper)]

Ce que j'essaye de faire :

En fin de compte, mon objectif est de générer un fichier .so qui peut être appelé en tant que bibliothèque native en Java. Actuellement, j'essaie d'utiliser g++ pour compiler l'ensemble du système dans un fichier .so ; cependant, les fichiers .proto doivent d'abord être étendus en .h s et .cc s avant cette compilation, et c'est ce que j'essaie de faire avec protoc .

Vous pouvez voir ma tentative de script wrap ici pour potentiellement avoir une meilleure idée de ce à quoi je veux en venir, bien que jusqu'à présent, toutes mes tentatives d'utilisation de protoc aient été répertoire par répertoire et, par conséquent, non dans le scénario.

Enfin, toute rétroaction sur les domaines d'amélioration serait grandement appréciée. Merci!

@kylevedder J'ai déjà une version .so dans le cadre des préréglages JavaCPP : https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow. Grâce à Bazel, c'est vraiment simple. Appliquez simplement un patch comme celui-ci :

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(

Et lancez Bazel comme ceci, par exemple :

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

AFAIK, cela devrait engloutir à peu près tout ce qui présente un intérêt pour l'API C++.

@saudet Y a-t-il une raison pour laquelle vous utilisez une règle cc_binary pour construire la bibliothèque partagée plutôt que cc_library ? Vous pouvez simplement avoir une règle cc_library avec le nom tensorflow et la cible de construction construira une bibliothèque partagée appelée libtensorflow.so .

@kylevedder Si votre objectif est de générer un fichier .so , alors quelque chose de similaire à ce que @saudet a suggéré fonctionnerait.

Si vous devez utiliser les protos TensorFlow dans le code Java, vous devrez alors ajouter des dépendances de vos cibles de construction java_* Bazel aux cibles proto_library qui génèrent les classes Java à partir du .proto fichiers.

Nous avons encore un peu de travail à faire avant d'ouvrir les règles natives proto_library (voir bazelbuild/bazel#52), mais en attendant, TensorFlow utilise les cc_proto_library et py_proto_library règles fournies par protobuf , et pour Java, vous devriez pouvoir utiliser la règle Java genproto incluse avec Bazel . Je vais vérifier avec l'équipe pour savoir quel est le calendrier pour proto_library et s'il serait intéressant d'unifier les règles fournies par Protobuf avec genproto .

Quelques autres retours :

  • Je pense qu'il serait préférable de garder les noms de répertoires cohérents et d'utiliser java_wrapper plutôt que javaWrapper
  • Peut-être qu'un meilleur endroit pour le wrapper Java serait //tensorflow/java/wrapper plutôt que //tensorflow/core/java_wrapper ?
  • En interne, nous avons des règles de construction qui prennent des fichiers .swig et génèrent les sources. C'est plus idéal car nous éviterions d'archiver les fichiers générés. Je peux jeter un coup d'œil pour voir à quel point il serait difficile pour nous d'ajouter des règles de construction SWIG pour Bazel afin de faciliter des choses comme celle-ci.

@davidzchen Aucune raison en particulier. Je suis nouveau sur Bazel et j'utilise juste linkshared=1 comme je l'ai vu mentionné sur la liste de diffusion a fonctionné. Alors merci pour l'astuce ! Je vais le mettre à jour.

@saudet Merci ! Je vérifiais juste que ce n'était pas un problème avec Bazel. :) N'hésitez pas à me le faire savoir ou à ouvrir un bogue si vous rencontrez des problèmes.

@saudet Merci pour l'info sur l'utilisation de Bazel. Moi aussi, je suis nouveau et je ne savais pas qu'il était capable de générer un .so de cette manière.

@davidzchen Merci pour l'addendum sur l'utilisation d'un cc_library , j'ai modifié l'exemple de @saudet en conséquence lorsque j'ai implémenté ma construction de wrapper Bazil . Merci également pour votre contribution concernant la structure du répertoire ; J'ai mis à jour la structure de mes dossiers pour l'aligner sur vos suggestions.

De plus, je n'étais pas très clair dans mon commentaire précédent sur la génération .so fichiers .so à partir de la source d'origine, je souhaite également inclure le fichier .cxx que SWIG génère à l' intérieur du .so afin de faciliter le JNI appels. Actuellement, je rencontre un problème dans lequel je ne parviens pas à compiler le fichier .cxx généré par SWIG ; il essaie de référencer JNI.h , un en-tête situé dans $JAVA_HOME/include/ , mais je n'arrive pas à faire comprendre à Bazel le chemin d'inclusion externe.

@davidzchen Hum, non, cc_library ne fonctionne pas. Je ne vois pas d'autre moyen pour que Bazel passe l'option -shared au compilateur : http://bazel.io/docs/be/c-cpp.html.

@saudet Je ne pense pas que vous ayez besoin de vous passer -shared . cc_library devrait construire un .so par défaut. Est-ce que ça marche pour toi?

@kylevedder Vous ne pourrez pas ajouter les en-têtes JNI de cette façon car ils se trouvent en dehors de l'espace de travail. Cependant, Bazel inclut le JDK local en tant que référentiel local et fournit un certain nombre de cibles intégrées (voir jdk.WORKSPACE et jdk.BUILD ) que vous pouvez utiliser pour dépendre du JDK local. Ceux-ci sont inclus par défaut dans chaque espace de travail Bazel.

Bazel lui-même utilise JNI et s'interface avec le JDK local de cette façon (voir src/main/native/BUILD ). Dans ce fichier BUILD, il y a deux genrule pour copier les en-têtes JNI et une cible cc_library pour la bibliothèque qu'il construit qui utilise JNI qui dépend des en-têtes, et un includes = ["."] pour que le code C++ puisse inclure l'en-tête JNI avec #include <jni.h> . Ceci n'est actuellement pas documenté car nous travaillons sur un certain nombre d'améliorations du mécanisme de référentiel externe, et le nom @local-jdk pourrait changer, mais nous pouvons l'utiliser pour TensorFlow et tout autre projet Bazel qui utilise JNI en attendant .

Voici un correctif pour votre fichier BUILD qui ajoute les cibles genrule pour copier les en-têtes JNI dont vous avez besoin et quelques modifications à la cible cc_library pour configurer les bonnes dépendances, à savoir :

  1. Ajoutez jni.h et jni_md.h , qui sont copiés dans le package actuel par les genrule s à srcs
  2. Ajoutez une dépendance sur //tensorflow/core afin que vous puissiez inclure les en-têtes sous tensorflow/core/public . Notez que les en-têtes ou tout fichier source dans un répertoire séparé se trouvent dans un package séparé du point de vue de Bazel, et vous devrez ajouter une dépendance sur la cible de construction qui contient ces fichiers.
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"],
 )

Notez qu'en général, les actions de compilation dans Bazel sont exécutées à partir de la racine de l'arborescence source, et vous devrez modifier les inclusions dans votre fichier SWIG comme suit, puis régénérer les fichiers C++ afin qu'ils aient les bonnes inclusions comme bien:

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"

Une fois que cela fonctionne, vous devez configurer la version JNI pour Linux, car le copy_link_jni_md_header genrule ne copie que l'en-tête spécifique à Linux. Pour qu'il copie le bon en-tête JNI spécifique à la plate-forme, nous devons procéder comme suit :

  1. Configurez des cpu config_setting pour d'autres plates-formes. Actuellement, tensorflow a un config_setting pour --cpu=darwin dans tensorflow/python/BUILD . Nous devrions probablement déplacer cela vers un package plus approprié tel que //tensorflow/core . Fondamentalement, nous voudrions le même ensemble de config_setting que Bazel (voir src/BUILD ).
  2. Demandez à copy_link_jni_md_header copier le bon en-tête JNI en fonction du paramètre de configuration défini à l'aide de select() , similaire à celui de Bazel . Notre genrule ressemblerait à ceci :
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 $< $@",
)

Je serais heureux de vous aider si vous rencontrez des problèmes. Faites-moi savoir si cela fonctionne pour vous.

@davidzchen cc_library génère un tas de fichiers .a, mais pas de fichier .so. J'utilise 0.1.0 comme cela était précédemment recommandé pour TensorFlow... Peut-être que c'est corrigé dans 0.1.1 ? Je vais devoir réessayer.

@davidzchen Merci beaucoup pour votre aide. J'ai suivi vos instructions et mis à jour le fichier Java wrapper fichier SWIG .i comme vous l'avez suggéré. De plus, j'ai déplacé le script wrap de core/java/wrapper vers le répertoire racine et mis à jour les liens en conséquence.

Pour l'instant, j'ai ignoré la généralisation du genrule pour le fichier jni_md.h , en me concentrant plutôt sur la construction de libtensorflow.so . Malheureusement, il me semble que libtensorflow.so n'est pas généré ; J'ai fini par rechercher dans tout mon système de fichiers quelque chose nommé une variante de "libtensorflow" et rien de pertinent n'est apparu. Il peut être nommé différemment ou cela peut être un simple cas d'erreur de l'utilisateur. De plus, il y a une possibilité qu'il peut être lié à la question que @saudet connaît le cc_library règle pour .so génération.

Encore une fois, merci pour toute votre aide, je l'apprécie vraiment.

Désolé, il s'avère que je me suis trompé. Afin de construire un .so qui inclut les dépendances transitives, ce que @saudet a fait en utilisant cc_binary avec linkshared = 1 et name = "libtensorflow.so" était correct. De la documentation cc_binary.linkshared :

Créez une bibliothèque partagée. Pour activer cet attribut, incluez linkshared=1 dans votre règle. Par défaut, cette option est désactivée. Si vous l'activez, vous devez nommer votre binaire libfoo.so (ou quelle que soit la convention de nommage des bibliothèques sur la plate-forme cible) pour une valeur raisonnable de foo.

La principale différence entre les .so construits par des cibles cc_library et les .so construits avec cc_binary utilisant la méthode décrite ci-dessus est que le cc_library artefacts srcs . C'est pourquoi la construction cc_library cibles srcs et seulement deps , comme //tensorflow/core , ne produit aucun artefact. D'autre part, les cibles cc_binary seront liées dans toutes les dépendances transitives.

Je m'excuse pour la confusion. Peut-être devrions-nous améliorer notre documentation et ajouter un exemple sur la construction de .so s.

Je suppose que vous devriez suivre ces étapes pour créer Tensorflow et toutes ses dépendances. Nous travaillons sur le portage de TensorFlow vers node.js, et j'ai implémenté un script shell pour compiler et récupérer uniquement les sources essentielles de l'ensemble du référentiel :
https://github.com/node-tensorflow/node-tensorflow/blob/1.0.0/tools/install.sh#L233 -L282

@davidzchen Merci pour les informations concernant la création d'un .so . J'ai mis à jour ma configuration en conséquence et j'ai créé un tensorflow/core/java/wrapper/example avec un testeur _extrêmement_ basique pour prouver que la fonction JNI appelle le travail .so . Notez que createWrapper.sh doit être exécuté avant d'exécuter compileAndRun.sh .

Je vais essayer d'améliorer le wrapper SWIG et de faire un meilleur exemple, celui que j'ai maintenant est simplement une preuve minimale de liaisons fonctionnelles.

Enfin, je tiens à remercier @davidzchen et @saudet pour toute leur aide ; Je n'aurais pas pu le faire sans eux.

Joli! Merci d'avoir travaillé dessus, @kylevedder !

Si vous êtes intéressé, je peux essayer d'intégrer vos scripts createWrapper.sh et compileAndRun.sh dans la construction de Bazel en 1) créant la règle Skylark SWIG et 2) en utilisant les règles Java de Bazel pour construire le code Java.

@davidzchen Ce serait génial ! Je vais travailler sur l'amélioration du wrapper SWIG et de l'exemple de base.

J'ai finalisé les préréglages pour JavaCPP et porté l'échantillon example_trainer.cc :
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow
J'ai hâte de comparer cela avec un wrapper équivalent utilisant SWIG !

On dirait que le lien API est rompu : http://bytedeco.org/javacpp-presets/tensorflow/apidocs/

@verdiyanto Désolé, je n'ai pas encore CI, mais le téléchargement des documents de l'API est assez facile, donc j'ai au moins fait cela. Prendre plaisir!

@saudet Beau travail sur les presets JavaCPP !

Une mise à jour sur mon travail : j'ai fait un peu plus de travail sur le wrapper SWIG, et vous pouvez voir le travail que j'ai fait ici . Cependant, je suis un peu à la croisée des chemins et je ne suis pas sûr de la meilleure façon de procéder.

Je suis plutôt nouveau sur SWIG, étant donné qu'il s'agit de mon premier projet majeur à l'utiliser, j'ai donc lu la documentation SWIG sur SWIG Basics et sur SWIG et Java qui explique comment SWIG fonctionne et comment envelopper C/C++ avec des wrappers Java SWIG.

La documentation explique comment SWIG convertit les pointeurs en C/C++ en objets Java opaques, c'est pourquoi vous obtenez des classes comme SWIGTYPE_p_void générées par SWIG. Le problème est qu'il n'y a pas de moyen facile de convertir des POJO en ces classes SWIG.

Ainsi, par exemple, dans tensor_c_api.h , la méthode C TF_CreateTensor() prend un void* qui pointe vers les données d'entrée et un paramètre size pour spécifier la taille de les données d'entrée en octets. C'est un modèle de conception parfaitement raisonnable pour C/C++, mais complètement absurde en Java. La méthode Java générée par SWIG TF_CreateTensor() prend un objet SWIGTYPE_p_void comme données, avec size , mais il n'y a aucun moyen de convertir un POJO tel qu'un String dans un SWIGTYPE_p_void sans écrire beaucoup de code.

Et c'est le carrefour où je me trouve actuellement : soit j'écris une tonne de méthodes de conversion C/C++ qui prennent n'importe quel type défini dans TF_DataType et les convertis en void* , soit j'écris un tas de SWIG typemaps pour faire la même chose. La documentation SWIG ne semble pas favoriser l'une ou l'autre solution, car elles le font apparemment toutes les deux de manière interchangeable.

Donc, la question est, les fonctions de conversion C/C++ ou les types SWIG ?

@kylevedder Je vois que vous commencez à comprendre pourquoi j'ai créé JavaCPP en premier lieu. :)

Je me sers de présélections JavaCPP de l » @saudet, extrêmement utiles, merci! Je l'utilise pour créer une interface Clojure vers tensorflow.

Certains commentaires:

a) Il existe une possibilité de simplification / une couche de niveau supérieur

Une grande partie de l'API JavaCPP réplique la fonctionnalité protobuf qui peut être directement réalisée sur la JVM, sans le pont. Il m'a fallu un peu de temps pour réaliser cela, mais il s'agit simplement de créer un objet protobuf à l'aide des liaisons JavaCPP, de produire cette représentation indépendante de la plate-forme à l'aide d'interop, puis de l'insérer dans la session.

J'ai fini par n'utiliser que des protobufs basés sur jvm pour construire le graphique directement, en contournant les fonctions du constructeur JavaCPP. Cela a plusieurs avantages - une API plus simple pour programmer, et aussi un joli format .toString qui montre le protobuf lisible par l'homme.

En particulier pour Clojure, il est beaucoup plus facile de décrire le graphe tensorflow en termes de structures de données, puis de les convertir directement en protobuf, que de rechercher et d'invoquer une fonction constructeur pour chaque nœud de ma structure de données.

b) Améliorations des bâtiments et des emballages

Je ne suis pas expert dans la construction de code natif, ou dans les outils de construction utilisés dans ces projets. Ce serait formidable d'avoir des artefacts maven-ized; en particulier s'ils incluaient également les classes Java protobuf générées. Il m'a fallu un temps embarrassant pour comprendre comment faire cela.

c) Il serait utile d'avoir un petit nombre de cas de test de graphes à cibler.

À l'heure actuelle, ma méthodologie est quelque peu lourde : utiliser les fonctions de construction JavaCPP pour générer un graphique, le fusionner dans mes protobufs JVM et voir la forme lisible par l'homme, et comprendre comment créer mes propres constructeurs pour créer la même forme.

Il serait utile d'avoir une petite collection de graphiques très simples qui exercent les fonctionnalités de base de TensorFlow, afin que les gens comme moi aient un ensemble raisonnable de cas de test à cibler pour l'interopérabilité dans différentes langues.

En tout cas merci pour les efforts de tous et continuez votre bon travail!

@kovasb Merci pour le retour ! Évidemment, il y a beaucoup à faire pour rendre l'interface plus naturelle à Java, Scala, Clojure, etc.

Si vous avez des classes d'assistance pour intégrer l'API C++ à l'API Java protobuf, n'hésitez pas à mettre tout cela dans le package suivant, y compris les classes Java protobuf générées elles-mêmes, et envoyez un PR :
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper
C'est à cela qu'il est destiné, et il sera automatiquement emballé dans l'artefact Maven, quelque chose que Bazel ne semble pas prendre en charge. En tout cas, merci d'avoir regardé ça !

@kovasb Une interface clojure semble vraiment intéressante. Vous avez encore du code à partager ?

Merci!

Donc, les personnes dans ce fil sont également au courant, dans https://github.com/tensorflow/tensorflow/issues/3 : la différenciation automatique ne fonctionne actuellement que si vous utilisez TF à partir de l'api python. Cela semble être un obstacle en attendant que cette fonctionnalité soit portée en C++.

Je ne comprends pas très bien le flux de données, mais peut-être est-il possible de lancer l'assistant python avec la bibliothèque C++ ?

Une autre solution que j'examine consiste simplement à utiliser Jpy ou l'un des autres ponts (quelqu'un a des recommandations?)

Si JyNi est réglé, il + jython donnerait à la JVM une histoire vraiment géniale sur l'interopérabilité de l'écosystème python. On peut rêver.

+1 pour une interface Java !

si nous pouvions utiliser javaCPP, SWIG est-il toujours nécessaire ? collaborerons-nous pour implémenter l'interface SWIG ?

@maxiwu J'aime penser que JavaCPP fait un meilleur travail que SWIG, mais je suis tout à fait pour les comparer pour le prouver :)

@kovasb Je serais très intéressé à aider/contribuer à l'interface Clojure.

@sorenmacbeth m'envoyer un e-mail à mon prénom point nom de famille à gmail, heureux de vous expliquer ce que j'ai ...

Il semble que nous ayons ici un preset Javacpp assez complet. Est-ce une solution acceptable pour « l'équipe » ?

@saudet J'essaie de créer une copie des wrappers JavaCPP, mais il semble qu'en raison du taux de changement rapide de la source tensorflow, ils ne soient compatibles ni avec la version 0.6.0 ni avec la branche principale d'aujourd'hui. Serait-il possible de les mettre à jour avec un pointeur vers le commit/la version tensorflow exact avec lequel ils ont été testés ?

@nikitakit Je viens de faire une mise à jour pour la branche master ici : https://github.com/bytedeco/javacpp-presets/commit/43bdcdf03beaaddb4bd5badf5d4f79669e9e78dd

Contrairement à Caffe, TensorFlow semble en fait sortir tous les mois environ, donc je suppose que je vais commencer à stabiliser les liaisons à ces points, en commençant par la prochaine version (0.7.0 ?)

@martinwicke Qu'en pensez-vous ?

Quand il y a une liaison Java stable, je suis heureux de travailler sur l'API Scala.

/ cc @databricks

@kovasb Je pense que j'ai raté cette première fois. Êtes-vous en train de dire que toute la magie de l'auto-différenciation que nous obtenons en utilisant TensorFlow via python est implémentée dans python, pas dans les bibliothèques c++ ? Donc, en pratique, une API Java devrait soit ré-implémenter tout cela, soit être juste une autre bibliothèque numérique ? Je ne suis pas assez familier avec les composants internes de TensorFlow ou de la colle python pour comprendre exactement ce que le levage lourd est fait où.

@drdozer c'est @girving , puis en regardant un peu la source moi-même. Réimplémenter des trucs en Java semble être un non-starter. Je suggère de regarder les commentaires dans #3

Si quelqu'un est vraiment intéressé, je recommanderais simplement d'essayer de faire des exemples de formation en utilisant l'API Java (jusqu'à présent, je viens de voir / de faire le chemin vers l'avant).

Je me demande jusqu'où nous irions en exécutant le code Python avec Jython ...

Je pense que la couche API Python a beaucoup de logique que l'API de la couche C++ n'expose pas.
J'essayais de suivre le chemin JavaCpp mais à la fin, il y aura beaucoup de code de duplication et il sera difficile de maintenir la cohérence lorsque quelque chose change dans l'implémentation Python.

Le chemin le plus simple consiste probablement à utiliser Jython comme @saudet l' avait mentionné auparavant ...

Il a été attribué dans https://github.com/tensorflow/tensorflow/issues/476 à @josh11b. S'il travaille dessus, cela n'a pas de sens d'utiliser Jython.

Si nous utilisons jython, le code c++ fonctionnera-t-il toujours ? Je cherche à l'utiliser pour un serveur en Java mais je suis coincé entre essayer directement une route Java ou simplement envoyer les données sur un socket à un processus Python

J'aimerais mentionner que bien que l'API Java n'inclue pas beaucoup de fonctionnalités telles que l'auto-différenciation, je n'ai pas trouvé que cela constituait un obstacle pour mon propre travail. J'ai eu beaucoup de succès à générer un modèle en python, à le sérialiser dans un fichier .proto, puis à l'ouvrir via le wrapper Java pour la formation. La même chose peut être faite pour le temps de test, car je pense que la fonctionnalité Saver est disponible via les API C++ et Java.

+1

@saudet
Merci d'avoir créé javacpp et les préréglages pour tensorflow. J'ai réussi à recréer un graphique Python en Java, mais je suis bloqué en essayant de restaurer à partir d'un fichier modèle enregistré. Cette ligne ne fonctionne pas :

Tensor fn = new Tensor(tensorflow.DT_STRING, new TensorShape(1));
Tampon CharBuffer = fn.createBuffer();
buffer.put("modelfile.tf");
session.Exécuter(...);

mais le CharBuffer s'avère être NULL. Si je change DT_STRING en DT_FLOAT, j'obtiens un FloatBuffer, mais DT_STRING ne semble pas fonctionner.

@nikitakit, vous avez dit que cela fonctionnait. pourriez-vous partager votre code?

@lakshmanok

EDIT : désolé, j'ai mal lu ce que tu as dit ici. Je ne peux pas fournir d'aide pour utiliser des épargnants externes de Java

Pour référence, la partie de mon code qui importe les graphiques tensorflow est ici : https://gist.github.com/nikitakit/d3ec270aee9d930267cec3efa844d5aa

C'est en Scala, mais le portage vers Java / un autre langage JVM devrait être simple.

Mon code pour exécuter réellement les nœuds dans le graphique est malheureusement fortement lié à un framework Scala que j'utilise, vous devrez donc vous fier à la documentation de l'API tensorflow pour cette partie.

Quelqu'un a-t-il réussi à intégrer l'environnement python tensorflow dans le jvm? Dites avec jython + JyNI ? Ou tout cela est-il un peu trop expérimental pour fonctionner de manière fiable ?

Je travaille actuellement sur l'extension de l'API C pour ajouter la prise en charge de la définition de graphes. Je ne sais pas quand cela sera fait, mais c'est l'un de nos objectifs avant la 1.0.

Je travaille sur l'utilisation du flux tensoriel de Java. J'aborde le problème en utilisant jython et en modifiant la bibliothèque cpython de flux de tenseur pour accueillir un autre interpréteur python. le cpython devrait continuer à fonctionner parfaitement et mon code détecte si l'interpréteur est Jython et modifie les importations / modules pour lui permettre de fonctionner. En dessous, il utilise les liaisons javacpp pour libtensorflow_cc.so. Est-ce quelque chose que l'équipe Google serait disposée à avoir dans le dépôt officiel ? @vrv

Cela semble être une belle preuve de concept, mais je pense qu'une liaison officielle voudrait probablement se lier de manière plus native que de passer par Python :(

non, au lieu d'appeler le wrapper c-python, nous appelons le wrapper javaccp. Ce serait donc la même chose que le flux de tenseur cpython mais évalué à partir de la JVM à l'aide de Jython. Réimplémenter toute la logique python dans un autre langage semble trop, vous vous retrouvez avec une autre API. Les liaisons javacpp vous permettent d'exécuter l'inférence sans problème, mais le modèle doit être construit/entraîné à partir d'un script cpython pour le moment.

Quelqu'un a-t-il envisagé de faire fonctionner tensorflow avec Kotlin? Cela semble un ajustement plus naturel et c'est toujours 100% java à la fin de la journée. Je trouve que le langage Kotlin est un très bon compromis entre python et Java pur.

Mise à jour : j'ai réussi à faire avancer les choses avec javacpp (grâce à @saudet ) et à faire en sorte que les programmes Java lisent/exécutent les modèles TensorFlow.

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

Merci @lakshmanok et @saudet . Le projet javacpp semble implémenter la plupart des API TensorFlow. Nous essayons d'exécuter le tensorflow/serving en Java.

L'API est simple et définie par protobuf . Maintenant, nous avons implémenté le serveur et voulons implémenter le client en Java. Il suffit de construire le TensorProto en Java et d'invoquer l'appel gRPC . TensorFlow fournit des fonctions d'assistance pour convertir des tableaux à plusieurs dimensions pour Python et C++, mais pas Java.

Pouvez-vous dire comment utiliser javacpp ou implémenter nous-mêmes pour cela ?

Ce que vous recherchez est probablement déjà dans https://github.com/bytedeco/javacpp-presets/blob/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper/tensorflow.java mais faites le moi savoir s'il manque quelque chose là-bas. Merci!

est-ce encore en cours d'élaboration ? existe-t-il un référentiel github officiel pour ce projet de portage ? Je vois quelques repos aléatoires, mais je ne peux pas le dire.

Oui, mais probablement en octobre/novembre. Nous utilisons l'API C au lieu de passer à l'API C++. En attendant, vous pouvez utiliser les fixations mentionnées par saudet.

comment en êtes-vous venu à la conclusion d'utiliser l'API C ? nous travaillons sur un
interface ruby ​​utilisant swig:
http://github.com/somaticio/tensorflow.rb

Le mar. 13 sept. 2016 à 18:22, Jonathan Hseu [email protected]
a écrit:

Oui, mais probablement en octobre/novembre. Nous utilisons l'API C
au lieu de passer à l'API C++. En attendant, vous pouvez utiliser le
fixations dont saudet a parlé.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/tensorflow/tensorflow/issues/5#issuecomment-246844192 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAA5v3g86Z6D1rz-aTGdMyMWnQZhrZUYks5qpyIJgaJpZM4Getd8
.

À l'avenir, nous préférerions que toutes les liaisons de langage utilisent l'API C. Un doc est à venir.

Vous pouvez voir un exemple d'utilisation ici :
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/go

Il n'y a aucune urgence, cependant, et construire sur SWIG est très bien pour le moment.

@jhseu Cela signifie-t-il que l'API C sera étendue pour couvrir tout ce à quoi les liaisons Python ont actuellement accès ?

Waouh, gros changement. J'espère que cela a été décidé plus tôt. Quoi qu'il en soit pour voir les docs
plus tôt ?

Le mer. 14 sept. 2016 à 17:56, Samuel Audet [email protected]
a écrit:

@jhseu https://github.com/jhseu Cela signifie-t-il que l'API C sera
étendu pour couvrir tout ce à quoi les liaisons Python ont actuellement accès ?

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -247167887,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAA5vwfBJoZC2s33_7E9Xy6-NYNUjHjnks5qqG2FgaJpZM4Getd8
.

@saudet La plupart des fonctionnalités, sauf à court terme, il manquera certaines choses (comme les dégradés, les optimiseurs).
@jtoy Il n'y a aucune urgence pour vous à migrer. SWIG continuera à travailler pendant un certain temps.

Les documents décrivent simplement comment le faire et les conventions de nommage. Cependant, vous pouvez commencer à migrer vers l'API C sans eux :
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

Merci @saudet . J'ai trouvé ceci dans stackoverflow sur la génération de TensorProto avec l'API pure protobuf. Et voici l' exemple de code de TensorFlow servant le client Java gRPC.

@tobegit3hub Nice, si vous pouvez faire fonctionner cela avec l'API C++, veuillez l'ajouter au package d'aide des préréglages JavaCPP et envoyer une pull request ! Ce type serait intéressé par quelque chose comme ça : https://github.com/bytedeco/javacpp-presets/issues/240

@girving Est-
Je veux contribuer à tensorflow java api , je préfère l'implémenter comme python.

Salut les gars, quelqu'un a-t-il déjà commencé à travailler sur les liaisons de langage Java/Scala en utilisant l'API C ?
(au lieu de construire sur SWIG)

J'ai une interface Java/Scala fonctionnelle pour tensorflow en utilisant uniquement l'API C via JNR . Malheureusement, je n'ai pas encore la permission de l'ouvrir. Je posterai ici si et quand je le sortirai. C'est encore un travail en cours, mais c'est très fonctionnel.

@jdolson L'API que vous exposez accepte-t-elle les objets tampon de protocole de TensorFlow ? L'un des plus gros problèmes que j'ai rencontrés avec les préréglages javacpp de @saudet est que lorsque vous manipulez des objets tenseurs dans le code client Java, vous avez affaire à un org.tensorflow.framework.TensorProto qui est généré par le compilateur de tampon de protocole lorsque configuré pour sortir java. Mais dans le wrapper de l'API TensorFlow, vous avez affaire à un org.bytedeco.javacpp.tensorflow.TensorProto.TensorProto qui est généré par javacpp lorsqu'il pointe vers le code c généré par le compilateur de tampon de protocole lorsqu'il est configuré pour produire du C. Étant donné que les types sont ' De même, vous ne pouvez pas utiliser directement les tenseurs de votre code Java lors de l'appel de l'API TensorFlow enveloppée.

@Intropy Oui, je compile toutes les sources tensorflow *.proto en code source Java avec protoc et j'utilise ces classes dans l'API.

@jhseu L'interface API C est-elle toujours sur la bonne voie pour être publiée en novembre ? Si non, quel est l'état actuel ?

@eaplatanios : L'API C est pour la plupart stable (et le sera officiellement d'ici la 1.0) et utilisable bien qu'elle ne soit pas complète (il manque toujours la possibilité de gradient automatiquement les calculs sur le graphique). Un document décrivant comment l'API C peut être utilisée pour créer des liaisons linguistiques se trouve à l' adresse https://www.tensorflow.org/how_tos/language_bindings/index.html

L' API Go a été implémentée en utilisant l'API C comme premier exemple de suivi du document ci-dessus.

Nous espérons que les liaisons Java seront également construites par-dessus (en utilisant JNI) et avons commencé à explorer un peu cela. Tous les commentaires / leçons apprises gens ont basé sur l' utilisation de merveilleux travail de @saudet à obtenir JavaCPP travail serait agréable de connaître.

J'ai quelques suggestions basées sur l'utilisation des liaisons JavaCPP.

Premièrement, étant donné que les tampons de protocole se compilent directement en Java, les versions Java doivent être utilisées. De préférence, je pense que les tampons de protocole qui participent à l'API devraient être disponibles séparément en tant que module maven et devraient être fournis avec les définitions de proto afin que les utilisateurs d'une pile Java aient un moyen simple d'obtenir les définitions aussi bien binaires qu'un simple moyen d'obtenir les définitions proto à inclure dans d'autres définitions proto.

Deuxièmement, il serait utile de trouver la version minimale de libc dont TensorFlow a besoin et de s'appuyer sur celle-ci.

Troisièmement, il est beaucoup plus facile d'utiliser une API bien conçue qu'une API générée automatiquement. Je sais que c'est évident et ressemble à un coup de feu à JavaCPP. Je ne le pense pas. Je suis vraiment content que l'interface générée automatiquement existe. Il _is_ utilisable. Mais cela nécessite des circonlocutions étranges, il y a beaucoup de verrues et il est assez difficile de lire le code pour comprendre comment faire ce que vous essayez de faire. Je souhaite que cette suggestion soit plus utile que "vous devriez le faire bien", mais je suppose que le fait est que l'API C++ et l'API python sont différentes. Les deux sont simples car ils s'adaptent à leur environnement d'une manière que le code converti automatiquement est peu susceptible de correspondre.

Il aurait peut-être été plus agréable de prendre en charge le backend C de Swig et de générer également l'API TF C via Swig : https://github.com/swig/swig/issues/800 afin que d'autres langages comme Go, Ruby, R puissent utiliser le C api pour écrire leurs propres liaisons.

Nous avons une API C existante pour ajouter la prise en charge de n'importe quelle langue avec un C FFI :
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

(Et c'est ce qui est utilisé pour créer les liaisons Go, Java, Rust, etc. pour TensorFlow)

L'API C est-elle accessible via JNA ?

@jhseu Je voulais dire, il aurait peut-être été généré plus tôt à partir de l'API C++, avant d'implémenter manuellement l'API C.

@ Quantum64 , voici une liaison Scala de tensorflow qui utilise JNA.

Puisque ce problème est toujours ouvert, comment
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java
en cours de mise en œuvre et quel était le PR pour le commit ?

@hsaputra : Pouvez-vous préciser ce que vous recherchez ? Il existe plusieurs commits qui contribuent au code dans tensorflow/java , dont la plupart sont référencés dans ce numéro (comme 2b1cd28, d73a266 et bien d'autres entre les deux)

HI @asimshankar , merci pour la réponse.

Je me demande simplement quel a été le chemin emprunté par tensorflow/java pour implémenter l'API Java puisque ce ticket n'est pas fermé.
Il y a eu des discussions sur l'utilisation de JavaCPP vs SWIG vs appel via Jython.

Semblait-il que le tensorflow/java est implémenté avec JNI direct pour appeler les API C à la place ?

Correct.

Hey,

Je viens de faire fonctionner ces fixations Swig hier. J'ai une demande de changement d'API. Actuellement, pour générer des Tensors, une réflexion est requise et le format des tableaux est un peu compliqué, car ils nécessitent l'utilisation de tableaux Java natifs à n dimensions. Pouvons-nous conserver cette interface, mais également ajouter quelques méthodes pour créer des tenseurs qui nécessitent des tableaux à 1 dimension et spécifier la forme à l'aide d'un autre tableau de long ? J'imagine que ça pourrait ressembler à ça :

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);

Cela conduirait également à la possibilité de créer des tenseurs int8, int16, uint8, uint16, uint32, ce qui facilitera la compatibilité.

Dois-je en faire un problème ? Ou est-ce que ça va ici ?

Aussi, plus qu'heureux de tenter de développer ces méthodes.

@hollinwilkins : J'espère que le PR # 6577 résout ce problème, avec juste un léger ajustement à la méthode d'usine que vous proposez :

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

@asimshankar C'est super ! Merci pour la réponse rapide. On dirait que c'est assez proche d'être fusionné aussi :+1:

J'essaie d'utiliser la nouvelle API Java, et j'ai rencontré certaines choses qui la rendent plus difficile à utiliser que je ne le pense :

  1. L'API Java doit accepter un objet GraphDef. Actuellement, il n'accepte qu'un tableau d'octets représentant le binaire sérialisé du tampon du protocole GraphDef. Il est étrange d'exiger une étape de sérialisation/désérialisation à la limite de la bibliothèque.
  2. Session.Runner.feed devrait pouvoir accepter org.tensorflow.framework.TensorProto ou il devrait y avoir un bon moyen de créer org.tensorflow.Tensor à partir de org.tensorflow.framework.TensorProto.
  3. Session.Runner.run renvoie une liste d'objets Tensor. Comme ci-dessus, il devrait y avoir un moyen facile d'obtenir la sortie TensorProto soit directement, soit en donnant à org.tensorflow.Tensor un bon moyen de convertir en TensorProto.
  4. Session.Runner.run avale le statut. Il devrait y avoir un moyen d'obtenir ces informations sur les échecs, peut-être en lançant une exception.

De plus, il est possible que j'aie manqué le moyen de gérer cela, mais il me semble que je ne peux pas obtenir tous les types de tenseurs pris en charge dans la sortie de run. Par exemple, si mon tenseur de sortie est de type INT16, il n'y a aucun moyen d'en extraire la valeur. Il n'y a pas de Tensor.shortValue ou similaire, et Tensor.intValue semble exiger une correspondance exacte. Je me base sur la lecture de DEFINE_GET_SCALAR_METHOD dans tensor_jni.cc.

@Intropy : Merci pour vos commentaires et ils ont vraiment du sens. Pour l'instant, je peux partager avec vous quelques réflexions rapides :

RE : protobufs : à ce stade, nous essayons de garder l'API principale indépendante de protobufs pour un certain nombre de raisons (y compris l'utilisation sur des systèmes à ressources limitées où quelque chose comme nanproto peut être plus approprié). Donc, c'est la raison pour laquelle nous avons hésité, mais c'est quelque chose auquel nous réfléchissons et les suggestions sont appréciées. Une possibilité est d'avoir toutes les fonctionnalités liées à protobuf dans un package séparé afin qu'il y ait une séparation claire.

Donc, revenons à vos points :

  1. Voir au dessus. Cependant, je parierais qu'il existe de nombreux cas où le byte[] plus de sens (comme la lecture du graphique à partir d'un fichier ou d'un canal réseau)

  2. Point pris

  3. Voir au dessus.

  4. Session.runner.run ne devrait session_jni.cc:166 ). Si cela ne se produit pas, veuillez signaler un bogue.

Vous avez raison, tous les types ne sont pas encore pris en charge, mais devraient être assez faciles à ajouter. Si vous avez un besoin urgent des types manquants, n'hésitez pas à déposer un problème et/ou à envoyer un PR. Les contributions sont les bienvenues :)

@asimshankar Merci pour vos réflexions.

Concernant le premier point, ce n'est pas vraiment grave. Comme vous le dites, il y a des moments où un byte[] a le plus de sens. Dans mon propre cas d'utilisation, j'ai un InputStream, qui est trivial à convertir en byte[]. L'API de tampon de protocole rend la conversion simple. Je considère simplement le byte[] comme une verrue sur l'API car vous allez devoir désérialiser de toute façon (dans TF_GraphImportGraphDef) et de cette façon vous perdez une certaine sécurité de type. Il y a aussi la sérialisation json de proto3 à considérer.

Sur le statut de déglutition, vous avez raison. J'ai raté l'exception non vérifiée.

Le moyen le plus évident de gérer 2 et 3 est de donner à org.tensorflow.Tensor une usine qui convertit à partir d'un TensorProto et d'un autre toTensorProto(). Si les cas d'utilisation limités en ressources sont le problème avec les tampons de protocole, alors les personnes dans ces circonstances ne pourraient tout simplement pas utiliser ces fonctions. Le problème est que les personnes qui utilisent ces fonctions paieraient le coût d'une conversion qui pourrait probablement être évitée en faisant en sorte que le Tensor stocke ses données directement dans un protobuff. Je n'ai jamais travaillé avec jni auparavant, j'ai donc du mal à suivre la façon dont les données sont stockées, mais il semble qu'il traite essentiellement nativeHandle comme un pointeur vers un TF_Tensor qui a un TensorBuffer qui est traité essentiellement comme un vide de taille *.

Pourrions-nous séparer ce problème et classer les problèmes séparément pour chaque fonctionnalité de l'interface Java ? Cela facilitera le suivi/l'analyse, nous pourrons alors clore ce problème.

@drpngx : Mon intention est d'apporter quelques modifications supplémentaires (lecture des tenseurs à partir des tampons) avant de fermer cela comme nous l'avons fait pour Go et que les fonctionnalités/bogues soient classés individuellement. Alors j'espère bientôt.

Ça sonne bien, merci !

D'accord, il semble que nous ayons suffisamment de base sur laquelle construire (par exemple, assez pour construire l' exemple LabelImage et les gens déposent des demandes de bogues/de fonctionnalités plus spécifiques.

Je vais clore ce sujet. Il y a encore beaucoup à faire dans l'API Java, mais discutons/suivons-les dans des numéros séparés. Merci!

@asimshankar, nous sommes en train de sélectionner un framework d'apprentissage en profondeur (mxnet/tf) et nos etl/api sont basés sur le flux spark/akka... Existe-t-il un plan pour ajouter le support Distributed_runtime à l'API Java pour exécuter une formation parallèle de modèle à l'aide de ps nœuds ? Le nœud ps est essentiel pour nous dans de nombreux cas d'utilisation... les préréglages javacpp peuvent être plus faciles à exporter pour la première coupe puisque l'API C elle-même ne semble pas contenir de distribution_runtime...

@debasish83 : Inclure le runtime distribué en lui-même est trivial, mais il existe un tas de constructions de niveau supérieur dans l'API Python comme la classe Estimator qui prennent en charge un tas de choses (checkpointing, résumé de sauvegarde, etc. qui rendre la visualisation via TensorBoard triviale) qui peut le rendre plus approprié pour exécuter les tâches de formation en Python.

Tout cela peut être construit en utilisant les primitives existantes dans l'API Java, mais la bonne approche dépendra de vos besoins précis.

Peut-être devrions-nous synchroniser hors fil?

@asimshankar Existe-t-il déjà un moyen à partir de la liaison Java tensorflow pour récupérer des informations à partir d'un graphDef (construit à partir du fichier .pb du graphique sur le disque) comme la liste des nœuds, le format d'entrée et de sortie ou s'agit-il d'une fonctionnalité entrante ? Merci!

@asimshankar Je ne suis pas sûr de comprendre ce qui manque pour faire de la formation avec TF Java. Est-ce un problème de bibliothèque numérique (numpy manquant) ? Je veux dire, si vous n'êtes pas intéressé par TensorBoard dataviz, mais que vous vous entraînez uniquement, en utilisant une bibliothèque numérique Java native, pourquoi utiliser python uniquement pour la formation (comme vous le suggérez à propos de la classe Estimator ) ?

Merci.

Quel est l'état des modèles d'entraînement en Java ? J'ai pensé à écrire un plugin ImageJ (suite d'analyse d'images populaire et gratuite) pour appliquer des approches telles que https://arxiv.org/pdf/1505.04597.pdf (récemment très populaire dans la segmentation d'images pour le suivi cellulaire et les applications biomédicales). Je pense qu'il serait utile de fournir une gamme de modèles pré-entraînés et de permettre aux utilisateurs de les affiner pour leur cas d'utilisation spécifique. J'ai étudié DL4J à cet effet. Existe-t-il des plans concrets pour permettre l'intégration dans les liaisons TF Java ?

@bergwerf : La formation en Java est certainement possible, sinon particulièrement pratique.
Vous pouvez trouver un exemple sur https://github.com/tensorflow/models/tree/master/samples/languages/java/training

(Aussi, je suis sûr que vous êtes au courant, mais voir aussi https://imagej.net/TensorFlow)

Oh, génial ! Mes informations doivent être obsolètes alors ;-). je pensais avoir lu
quelque part, l'API Java n'était destinée qu'à prédire avec des
des modèles. Je vais regarder l'exemple.

Le mercredi 28 mars 2018, à 22 h 01, Asim Shankar [email protected] a écrit :

@bergwerf https://github.com/bergwerf : La formation en Java est certainement
éventuellement, sinon particulièrement pratique.
Vous pouvez trouver un échantillon sur
https://github.com/tensorflow/models/tree/master/samples/languages/java/training

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/tensorflow/tensorflow/issues/5#issuecomment-377015867 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AEQJ1UD9-xACQAII5996ees_UFJ_NzL-ks5ti-wSgaJpZM4Getd8
.

@asimshankar c'est génial 👍 💯 🥇 , je vais ajouter à mon repo https://github.com/loretoparisi/tensorflow-java

Cette page vous a été utile?
0 / 5 - 0 notes