Comment créer et utiliser l'API Google TensorFlow C ++

169

J'ai vraiment hâte de commencer à utiliser la nouvelle bibliothèque Tensorflow de Google en C ++. Le site Web et la documentation ne sont vraiment pas clairs sur la façon de créer l'API C ++ du projet et je ne sais pas par où commencer.

Une personne plus expérimentée peut-elle aider en découvrant et en partageant un guide d'utilisation de l'API C ++ de tensorflow?

theideasmith
la source
4
+1 pour votre question. Une chance d'installer / compiler sur Windows? Le site Web affiche uniquement Linux / Mac. Un guide pour faire fonctionner bazel est nécessaire. Cet exemple pourrait être un bon point de départ pour apprendre: github.com/tensorflow/tensorflow/tree/master/tensorflow/…
alrama
Cette question n'a toujours pas de réponse. Comment installer uniquement les bibliothèques API C ++ tensorflow C ++ n'a pas de guide à ce sujet, et la réponse acceptée ne donne aucune indication sur la façon de procéder, même via l'un des multiples liens fournis.
iantonuk
Pour Windows, j'ai trouvé cette question et sa réponse acceptée très utiles. En créant l'exemple de projet de formation, vous créez le projet TensorFlow entier en tant que bibliothèque statique, puis créez un lien vers celui-ci. Vous pouvez créer vos propres projets et lier TensorFlow de la même manière.
omatai

Réponses:

2

Une alternative à l'utilisation de l'API Tensorflow C ++ que j'ai trouvée consiste à utiliser cppflow .

Il s'agit d'un wrapper C ++ léger autour de l' API C Tensorflow . Vous obtenez de très petits exécutables et il est lié au libtensorflow.sofichier déjà compilé. Il existe également des exemples d'utilisation et vous utilisez CMAKE au lieu de Bazel.

Bersan
la source
55

Pour commencer, vous devez télécharger le code source depuis Github, en suivant les instructions ici (vous aurez besoin de Bazel et d'une version récente de GCC).

L'API C ++ (et le backend du système) est au format tensorflow/core. À l'heure actuelle, seules l' interface de session C ++ et l' API C sont prises en charge. Vous pouvez utiliser l'un ou l'autre pour exécuter des graphiques TensorFlow qui ont été créés à l'aide de l'API Python et sérialisés dans un GraphDeftampon de protocole. Il existe également une fonctionnalité expérimentale pour la construction de graphiques en C ++, mais ce n'est actuellement pas aussi complet que l'API Python (par exemple, pas de support pour l'auto-différenciation pour le moment). Vous pouvez voir un exemple de programme qui construit un petit graphique en C ++ ici .

La deuxième partie de l'API C ++ est l'API pour l'ajout d'un nouveau OpKernel, qui est la classe contenant les implémentations de noyaux numériques pour CPU et GPU. Il existe de nombreux exemples sur la façon de les intégrer tensorflow/core/kernels, ainsi qu'un tutoriel pour ajouter une nouvelle opération en C ++ .

mrry
la source
7
Aucune instruction d'installation pour C ++ n'est montrée tensorflow.org/install , mais il y a des exemples de programmes montrés tensorflow.org/api_guides/cc/guide qui utilisent clairement l' API C ++. Comment avez-vous installé exactement C ++ pour Tensorflow?
user3667089
@ user3667089 L'emplacement de la procédure d'installation se trouve maintenant sur tensorflow.org/install/install_sources
Dwight
6
@Dwight J'ai vu cette page avant mais je ne vois aucune information sur C ++
user3667089
2
@ user3667089 Les en-têtes, après la procédure d'installation ci-dessus, seront situés dans le dossier dist-packages de la distribution python que vous avez choisie lors de la procédure d'installation (comme /usr/local/lib/python2.7/dist-packages). Dans ce dossier, il y aura un dossier tensorflow / include, qui aura tous les en-têtes. Vous devrez faire un peu de travail pour vous assurer que tout ce que vous construisez a ce chemin d'inclusion. Personnellement , j'utilise CMAKE, donc je suis chemine dans ce .
Dwight
4
Ce n'est pas une vraie réponse à ce jour. Il commence par «Pour commencer», puis ne lie aucune information pertinente à un endroit que les personnes qui recherchent des conseils ici auraient déjà recherché. Il échoue alors à fournir l'étape suivante, en changeant de sujet.
iantonuk
28

Pour ajouter à l'article de @ mrry, j'ai mis en place un tutoriel qui explique comment charger un graphe TensorFlow avec l'API C ++. C'est très minime et devrait vous aider à comprendre comment toutes les pièces s'emboîtent. En voici la viande:

Exigences:

  • Bazel installé
  • Cloner le dépôt TensorFlow

Structure des dossiers:

  • tensorflow/tensorflow/|project name|/
  • tensorflow/tensorflow/|project name|/|project name|.cc (e.g. https://gist.github.com/jimfleming/4202e529042c401b17b7)
  • tensorflow/tensorflow/|project name|/BUILD

CONSTRUIRE:

cc_binary(
    name = "<project name>",
    srcs = ["<project name>.cc"],
    deps = [
        "//tensorflow/core:tensorflow",
    ]
)

Deux mises en garde pour lesquelles il existe probablement des solutions de contournement:

  • À l'heure actuelle, la construction des choses doit se faire dans le repo TensorFlow.
  • Le binaire compilé est énorme (103 Mo).

https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f

Jim
la source
1
Bonjour Jim. ce tutoriel est-il toujours le moyen le meilleur / le plus simple de compiler un projet c ++ avec TF? Ou y a-t-il un moyen plus simple maintenant, comme vous le prévoyez à la fin de votre message?
Sander le
3
Je crois qu'il existe maintenant une règle de construction intégrée. J'ai soumis un PR pour cela il y a quelque temps. Je ne suis pas sûr des mises en garde. Je m'attendrais à ce que le premier reste car c'est le résultat de Bazel, pas de TF. Le second pourrait probablement être amélioré.
Jim
J'ai suivi ce tutoriel, mais lors de l' exécution , ./loaderje reçois une erreur: Not found: models/train.pb.
9th Dimension
3
Existe-t-il maintenant un moyen de placer votre projet en dehors du répertoire de code source de TensorFlow?
Seanny123
oui, comment le faire sortir étant donné que vous avez partagé la bibliothèque .so de tensorflow?
Xyz
15

Si vous souhaitez éviter à la fois de construire vos projets avec Bazel et de générer un gros binaire, j'ai assemblé un référentiel expliquant l'utilisation de la bibliothèque TensorFlow C ++ avec CMake. Vous pouvez le trouver ici . Les idées générales sont les suivantes:

  • Clonez le référentiel TensorFlow.
  • Ajoutez une règle de construction à tensorflow/BUILD(celles fournies n'incluent pas toutes les fonctionnalités C ++).
  • Créez la bibliothèque partagée TensorFlow.
  • Installez des versions spécifiques d'Eigen et Protobuf ou ajoutez-les en tant que dépendances externes.
  • Configurez votre projet CMake pour utiliser la bibliothèque TensorFlow.
cjweeks
la source
15

Tout d'abord, après l'installation de protobufet eigen, vous souhaitez créer Tensorflow:

./configure
bazel build //tensorflow:libtensorflow_cc.so

Copiez ensuite les en-têtes d'inclusion suivants et la bibliothèque partagée dynamique dans /usr/local/libet /usr/local/include:

mkdir /usr/local/include/tf
cp -r bazel-genfiles/ /usr/local/include/tf/
cp -r tensorflow /usr/local/include/tf/
cp -r third_party /usr/local/include/tf/
cp -r bazel-bin/libtensorflow_cc.so /usr/local/lib/

Enfin, compilez à l'aide d'un exemple:

g++ -std=c++11 -o tf_example \
-I/usr/local/include/tf \
-I/usr/local/include/eigen3 \
-g -Wall -D_DEBUG -Wshadow -Wno-sign-compare -w  \
-L/usr/local/lib/libtensorflow_cc \
`pkg-config --cflags --libs protobuf` -ltensorflow_cc tf_example.cpp
lababidi
la source
Je crois qu'il n'est pas nécessaire d'installer protobuf et eigen. La configuration de l'espace de travail bazel inclut des règles pour télécharger et créer ces composants.
4dan
enfin, le guide de construction officiel fou à tensorflow.org/install/source est pour la construction du module pip, tks pour l'option de construction "tensorflow: libtensorflow_cc.so", il n'est même pas documenté sur tensorflow.org
datdinhquoc
@lababidi quelles dépendances C ++ devraient être avant la commande 'bazel build'? Je suis confronté au problème que la construction échoue après une heure, il est difficile de tester la construction encore et encore
datdinhquoc
15

Si vous envisagez d'utiliser l'api Tensorflow c ++ sur un package autonome, vous aurez probablement besoin de tensorflow_cc.so (il existe également une version api ac tensorflow.so) pour créer la version c ++ que vous pouvez utiliser:

bazel build -c opt //tensorflow:libtensorflow_cc.so

Remarque 1: Si vous souhaitez ajouter une prise en charge intrinsèque, vous pouvez ajouter ces indicateurs comme: --copt=-msse4.2 --copt=-mavx

Remarque 2: Si vous envisagez d'utiliser OpenCV sur votre projet également, il y a un problème lors de l'utilisation des deux bibliothèques ensemble ( problème tensorflow ) et vous devez utiliser --config=monolithic.

Après avoir créé la bibliothèque, vous devez l'ajouter à votre projet. Pour ce faire, vous pouvez inclure ces chemins:

tensorflow
tensorflow/bazel-tensorflow/external/eigen_archive
tensorflow/bazel-tensorflow/external/protobuf_archive/src
tensorflow/bazel-genfiles

Et liez la bibliothèque à votre projet:

tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so (unused if you build with --config=monolithic)
tensorflow/bazel-bin/tensorflow/libtensorflow_cc.so

Et lorsque vous construisez votre projet, vous devez également spécifier à votre compilateur que vous allez utiliser les normes c ++ 11.

Note latérale: Chemins relatifs à la version 1.5 de tensorflow (vous devrez peut-être vérifier si dans votre version quelque chose a changé).

De plus, ce lien m'a beaucoup aidé à trouver toutes ces infos: lien

Renan Wille
la source
1
J'avais besoin de ce chemin d'inclusion supplémentaire pour construire avec la version 1.11:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S
8

Si cela ne vous dérange pas d'utiliser CMake, il existe également un projet tensorflow_cc qui crée et installe l'API TF C ++ pour vous, ainsi que des cibles CMake pratiques avec lesquelles vous pouvez vous lier. Le projet README contient un exemple et des fichiers Docker que vous pouvez facilement suivre.

Floop
la source
8

Si vous ne souhaitez pas créer Tensorflow vous-même et que votre système d'exploitation est Debian ou Ubuntu, vous pouvez télécharger des packages préconstruits avec les bibliothèques Tensorflow C / C ++. Cette distribution peut être utilisée pour l'inférence C / C ++ avec CPU, le support GPU n'est pas inclus:

https://github.com/kecsap/tensorflow_cpp_packaging/releases

Il existe des instructions écrites sur la façon de figer un point de contrôle dans Tensorflow (TFLearn) et de charger ce modèle pour l'inférence avec l'API C / C ++:

https://github.com/kecsap/tensorflow_cpp_packaging/blob/master/README.md

Attention: je suis le développeur de ce projet Github.

kecsap
la source
5

J'utilise un hack / contournement pour éviter d'avoir à construire moi-même toute la bibliothèque TF (ce qui économise à la fois du temps (il est configuré en 3 minutes), de l'espace disque, l'installation des dépendances de développement et la taille du binaire résultant). Il n'est officiellement pas pris en charge, mais fonctionne bien si vous voulez simplement vous lancer rapidement.

Installez TF via pip ( pip install tensorflowou pip install tensorflow-gpu). Recherchez ensuite sa bibliothèque _pywrap_tensorflow.so(TF 0. * - 1.0) ou _pywrap_tensorflow_internal.so(TF 1.1+). Dans mon cas (Ubuntu), il se trouve à /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. Ensuite, créez un lien symbolique vers cette bibliothèque appelée lib_pywrap_tensorflow.soquelque part où votre système de construction la trouve (par exemple /usr/lib/local). Le préfixe libest important! Vous pouvez également lui donner un autre lib*.sonom - si vous l'appelez libtensorflow.so, vous obtiendrez une meilleure compatibilité avec d'autres programmes écrits pour fonctionner avec TF.

Créez ensuite un projet C ++ comme vous en avez l'habitude (CMake, Make, Bazel, ce que vous voulez).

Et puis vous êtes prêt à créer un lien avec cette bibliothèque pour avoir TF disponible pour vos projets (et vous devez également créer un lien avec des python2.7bibliothèques)! Dans CMake, vous ajoutez par exemple target_link_libraries(target _pywrap_tensorflow python2.7).

Les fichiers d'en-tête C ++ se trouvent autour de cette bibliothèque, par exemple dans /usr/local/lib/python2.7/dist-packages/tensorflow/include/ .

Encore une fois: cette méthode n'est officiellement pas prise en charge et vous pouvez exécuter divers problèmes. La bibliothèque semble être liée statiquement à, par exemple, protobuf, vous pouvez donc exécuter des problèmes de liaison ou d'exécution étranges. Mais je suis capable de charger un graphique stocké, de restaurer les pondérations et d'exécuter l'inférence, qui est la fonctionnalité la plus recherchée de l'OMI en C ++.

Martin Pecka
la source
Je n'ai pas pu faire fonctionner ça. J'ai eu un tas d'erreurs de temps de liaison à propos de références non définies à des trucs python comme:undefined reference to 'PyType_IsSubtype'
0xcaff
Oh, merci de l'avoir signalé ... Vous devez également créer un lien vers la python2.7bibliothèque ... Je vais éditer le message en conséquence.
Martin Pecka
@MartinPecka J'ai essayé ceci sur Raspbian Buster avec le armv7l (Raspberry PI 2). Les dernières roues Python 2.7 et 3.7 disponibles sont pour 1.14.0, mais je cible la 2.0.0. Merci quand même, j'ai voté pour votre hack.
Daisuke Aramaki
2

Tensorflow lui-même ne fournit que des exemples très basiques sur les API C ++.
Voici une bonne ressource qui comprend des exemples d'ensembles de données, rnn, lstm, cnn et d'autres
exemples Tensorflow C ++

Rock Zhuang
la source
2

Les réponses ci-dessus sont assez bonnes pour montrer comment construire la bibliothèque, mais comment collecter les en-têtes est toujours délicat. ici je partage le petit script que j'utilise pour copier les en-têtes nécessaires.

SOURCEest le premier paramètre, qui est la direcoty source (build) de tensorflow;
DSTest le deuxième paramètre, qui include directorycontient les en-têtes collectés. (par exemple en cmake, include_directories(./collected_headers_here)).

#!/bin/bash

SOURCE=$1
DST=$2
echo "-- target dir is $DST"
echo "-- source dir is $SOURCE"

if [[ -e $DST ]];then
    echo "clean $DST"
    rm -rf $DST
    mkdir $DST
fi


# 1. copy the source code c++ api needs
mkdir -p $DST/tensorflow
cp -r $SOURCE/tensorflow/core $DST/tensorflow
cp -r $SOURCE/tensorflow/cc $DST/tensorflow
cp -r $SOURCE/tensorflow/c $DST/tensorflow

# 2. copy the generated code, put them back to
# the right directories along side the source code
if [[ -e $SOURCE/bazel-genfiles/tensorflow ]];then
    prefix="$SOURCE/bazel-genfiles/tensorflow"
    from=$(expr $(echo -n $prefix | wc -m) + 1)

    # eg. compiled protobuf files
    find $SOURCE/bazel-genfiles/tensorflow -type f | while read line;do
        #echo "procese file --> $line"
        line_len=$(echo -n $line | wc -m)
        filename=$(echo $line | rev | cut -d'/' -f1 | rev )
        filename_len=$(echo -n $filename | wc -m)
        to=$(expr $line_len - $filename_len)

        target_dir=$(echo $line | cut -c$from-$to)
        #echo "[$filename] copy $line $DST/tensorflow/$target_dir"
        cp $line $DST/tensorflow/$target_dir
    done
fi


# 3. copy third party files. Why?
# In the tf source code, you can see #include "third_party/...", so you need it
cp -r $SOURCE/third_party $DST

# 4. these headers are enough for me now.
# if your compiler complains missing headers, maybe you can find it in bazel-tensorflow/external
cp -RLf $SOURCE/bazel-tensorflow/external/eigen_archive/Eigen $DST
cp -RLf $SOURCE/bazel-tensorflow/external/eigen_archive/unsupported $DST
cp -RLf $SOURCE/bazel-tensorflow/external/protobuf_archive/src/google $DST
cp -RLf $SOURCE/bazel-tensorflow/external/com_google_absl/absl $DST
hakunami
la source
1
c'était un extrait vraiment utile, il y avait un problème lors de la création d'un répertoire, je devais donc l'ajouter mkdir -p $DST/tensorflow$target_diravantcp $line $DST/tensorflow/$target_dir
user969068
@hakunami J'ai fait l'essentiel de ce script . Laissez-moi savoir ce que vous pensez. Si vous voulez créer votre propre contenu, je supprimerai le mien et clonerai le vôtre.
Daisuke Aramaki