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?
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++ .
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:
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:
https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f
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:
tensorflow/BUILD
(les règles fournies n'incluent pas toutes les fonctionnalités C++).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
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
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.
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
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.
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.
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 ++
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