web-dev-qa-db-fra.com

Comment créer et utiliser Google TensorFlow C ++ api

Je suis vraiment impatient de commencer à utiliser la nouvelle bibliothèque Tensorflow de Google en C++. Le site Web et la documentation ne sont vraiment pas clairs quant à la façon de construire l'API C++ du projet et je ne sais pas par où commencer.

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

137
theideasmith

Pour commencer, vous devez télécharger le code source depuis Github, par 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) se trouve dans tensorflow/core. À l'heure actuelle, seuls les interface de session C++ et les API C sont pris en charge. Vous pouvez utiliser l'un ou l'autre pour exécuter les graphiques TensorFlow construits à l'aide de l'API Python et sérialisés dans un tampon de protocole GraphDef. Il existe également une fonctionnalité expérimentale pour la création de graphiques en C++, mais elle n’a pas pour le moment aussi complète que l’API Python (par exemple, aucune prise en charge de la différenciation automatique à l’heure actuelle). Vous pouvez voir un exemple de programme qui construit ici un petit graphique en C++ .

La deuxième partie de l'API C++ est l'API permettant d'ajouter un nouveau OpKernel, qui est la classe contenant les implémentations de noyaux numériques pour le processeur et le processeur graphique. Il existe de nombreux exemples montrant comment les construire dans tensorflow/core/kernels, ainsi qu'un tutoriel pour l'ajout d'un nouvel op en C++ .

51
mrry

Pour ajouter au message de @ mrry, j'ai créé un tutoriel qui explique comment charger un graphique TensorFlow avec l'API C++. C'est très minime et devrait vous aider à comprendre comment toutes les pièces s'assemblent. Voici la viande de celui-ci:

Exigences:

  • Bazel installé
  • Cloner le repo TensorFlow

Structure du dossier:

  • 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:

  • Pour le moment, il faut que les choses soient construites dans le référentiel TensorFlow.
  • Le binaire compilé est énorme (103 Mo).

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

27
Jim

Si vous souhaitez éviter à la fois de construire vos projets avec Bazel et de générer un grand fichier 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 (les règles fournies n'incluent pas toutes les fonctionnalités C++).
  • Construisez la bibliothèque partagée TensorFlow.
  • Installez des versions spécifiques de Eigen et Protobuf ou ajoutez-les en tant que dépendances externes.
  • Configurez votre projet CMake pour utiliser la bibliothèque TensorFlow.
15
cjweeks

Tout d'abord, après avoir installé protobuf et eigen, vous souhaitez construire Tensorflow:

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

Copiez ensuite les en-têtes d'inclusion et la bibliothèque partagée dynamique suivants dans /usr/local/lib et /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 en utilisant 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
15
lababidi

Si vous envisagez d'utiliser Tensorflow c ++ api sur un paquet autonome, vous aurez probablement besoin de tensorflow_cc.so (il existe également une version c api tensorflow.so) pour générer la version c ++ que vous pouvez utiliser:

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

Remarque 1: Si vous souhaitez ajouter la prise en charge intrinsèque, vous pouvez ajouter cet indicateur en tant que: --copt=-msse4.2 --copt=-mavx

Remarque 2: Si vous envisagez également d'utiliser OpenCV sur votre projet, vous rencontrez un problème lorsque vous utilisez les deux bibliothèques ensemble ( problème avec tensorflow ) et vous devez utiliser --config=monolithic.

Après avoir construit 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 reliez 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 indiquer à votre compilateur que vous allez utiliser les normes c ++ 11.

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

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

14
Renan Wille

Si cela ne vous dérange pas d'utiliser CMake, il y a aussi tensorflow_cc projet qui construit et installe l'API TF C++ pour vous, ainsi que des cibles CMake pratiques que vous pouvez associer. Le projet README contient un exemple et des fichiers Docker faciles à suivre.

8
Floop

Vous pouvez utiliser ce ShellScript pour installer (la plupart) ses dépendances, cloner, construire, compiler et obtenir tous les fichiers nécessaires dans le dossier ../src/includes:

https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh

8
Ivan Seidel

Si vous ne voulez pas construire Tensorflow vous-même et que votre système d'exploitation est Debian ou Ubuntu, vous pouvez télécharger des packages préconfigurés 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 y a des instructions écrites pour geler un point de contrôle dans Tensorflow (TFLearn) et charger ce modèle pour 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.

7
kecsap

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

Installez TF via pip (pip install tensorflow ou pip install tensorflow-gpu). Trouvez 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. Créez ensuite un lien symbolique vers cette bibliothèque appelée lib_pywrap_tensorflow.so à un emplacement où votre système de génération le trouve (par exemple, /usr/lib/local). Le préfixe lib est important! Vous pouvez également lui attribuer un autre nom lib*.so - si vous l'appelez libtensorflow.so, vous obtiendrez peut-être une meilleure compatibilité avec d'autres programmes conçus pour fonctionner avec TF.

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

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

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

Encore une fois: cette méthode est officiellement non 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 temps de liaison ou d’exécution impairs. Mais je suis capable de charger un graphe stocké, de restaurer les poids et d’exécuter l’inférence, qui est la fonctionnalité la plus recherchée en C++ par OMI.

4
Martin Pecka

Tensorflow lui-même ne fournit que des exemples très basiques sur les API C++.
Voici une bonne ressource qui comprend des exemples de jeux de données, rnn, lstm, cnn, etc.
exemples de tensorflow c ++

1
Rock Zhuang

les réponses ci-dessus sont suffisamment explicites pour montrer comment construire la bibliothèque, mais comment collecter les en-têtes reste délicat. Je partage ici le petit script que j'utilise pour copier les en-têtes nécessaires.

SOURCE est le premier paramètre, qui est le répertoire source (build) de tensorflow;
DST est le deuxième paramètre, qui est le include directory qui contient les en-têtes collectés. (par exemple, dans 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
0
hakunami