Erstellen und Verwenden der Google TensorFlow C ++ - API

168

Ich bin sehr gespannt darauf, Googles neue Tensorflow-Bibliothek in C ++ zu verwenden. Die Website und die Dokumente sind nur sehr unklar, wie die C ++ - API des Projekts erstellt werden soll, und ich weiß nicht, wo ich anfangen soll.

Kann jemand mit mehr Erfahrung helfen, indem er einen Leitfaden zur Verwendung der C ++ - API von tensorflow entdeckt und weitergibt?

theideasmith
quelle
4
+1 für deine Frage. Gibt es eine Möglichkeit, unter Windows zu installieren / kompilieren? Website zeigt nur Linux / Mac. Eine Anleitung zum Laufenlassen von Bazel ist erforderlich. Dieses Beispiel könnte ein guter Ausgangspunkt sein, um zu lernen: github.com/tensorflow/tensorflow/tree/master/tensorflow/…
alrama
Diese Frage hat noch keine Antwort. Wie man nur C ++ - Tensorflow installiert C ++ - API-Bibliotheken enthält keine Anleitung dazu, und die akzeptierte Antwort gibt keinen Hinweis darauf, wie dies zu tun ist, selbst über einen von mehreren bereitgestellten Links.
Iantonuk
Für Windows fand ich diese Frage und ihre akzeptierte Antwort am hilfreichsten. Durch Erstellen des Beispieltrainerprojekts erstellen Sie das gesamte TensorFlow-Projekt als statische Bibliothek und verknüpfen es dann. Sie können Ihre eigenen Projekte erstellen und TensorFlow auf die gleiche Weise verknüpfen.
Omatai

Antworten:

2

Eine Alternative zur Verwendung der Tensorflow C ++ - API, die ich gefunden habe, ist die Verwendung von cppflow .

Es ist ein leichter C ++ - Wrapper um die Tensorflow C-API . Sie erhalten sehr kleine ausführbare Dateien, die mit der libtensorflow.sobereits kompilierten Datei verknüpft sind . Es gibt auch Anwendungsbeispiele, und Sie verwenden CMAKE anstelle von Bazel.

Bersan
quelle
55

Um zu beginnen, sollten Sie den Quellcode von Github herunterladen, indem Sie den Anweisungen hier folgen (Sie benötigen Bazel und eine aktuelle Version von GCC).

Die C ++ - API (und das Backend des Systems) befindet sich in tensorflow/core. Derzeit werden nur die C ++ - Sitzungsschnittstelle und die C-API unterstützt. Sie können beide verwenden, um TensorFlow-Diagramme auszuführen, die mit der Python-API erstellt und in einen GraphDefProtokollpuffer serialisiert wurden . Es gibt auch eine experimentelle Funktion zum Erstellen von Diagrammen in C ++, die derzeit jedoch nicht so umfassend ist wie die Python-API (z. B. derzeit keine Unterstützung für die automatische Differenzierung). Hier sehen Sie ein Beispielprogramm, das in C ++ ein kleines Diagramm erstellt .

Der zweite Teil der C ++ - API ist die API zum Hinzufügen einer neuen OpKernel, der Klasse, die Implementierungen von numerischen Kerneln für CPU und GPU enthält. Es gibt zahlreiche Beispiele, wie Sie diese einbauen können tensorflow/core/kernels, sowie ein Tutorial zum Hinzufügen einer neuen Operation in C ++ .

mrry
quelle
7
Es werden keine Installationsanweisungen für C ++ angezeigt. Tensorflow.org/install , es werden jedoch Beispielprogramme angezeigt, die tensorflow.org/api_guides/cc/guide anzeigen und eindeutig die C ++ - API verwenden. Wie genau haben Sie C ++ für Tensorflow installiert?
user3667089
@ user3667089 Der Speicherort der Installationsprozedur befindet sich jetzt unter tensorflow.org/install/install_sources
Dwight
6
@ Dwight Ich habe diese Seite schon einmal gesehen, aber ich sehe keine Informationen über C ++
user3667089
2
@ user3667089 Die Header befinden sich nach dem obigen Installationsvorgang im Ordner dist-packages der Python-Distribution, die Sie während des Installationsvorgangs ausgewählt haben (z. B. /usr/local/lib/python2.7/dist-packages). In diesem Ordner befindet sich ein Ordner tensorflow / include, der alle Header enthält. Sie müssen ein wenig arbeiten, um sicherzustellen, dass alles, was Sie erstellen, auf dem Include-Pfad steht. Ich persönlich benutze CMAKE, so durch bin stapfen dies .
Dwight
4
Dies ist bis heute keine echte Antwort. Es beginnt mit "Erste Schritte" und verknüpft dann keine relevanten Informationen an einer Stelle, an der Personen, die hier nach Anleitung suchen, bereits nachgeschlagen haben. Es wird dann kein nächster Schritt zum Wechseln des Themas bereitgestellt.
iantonuk
28

Um @ mrrys Beitrag zu ergänzen, habe ich ein Tutorial zusammengestellt, in dem erklärt wird, wie ein TensorFlow-Diagramm mit der C ++ - API geladen wird. Es ist sehr minimal und soll Ihnen helfen zu verstehen, wie alle Teile zusammenpassen. Hier ist das Fleisch davon:

Bedarf:

  • Bazel installiert
  • TensorFlow-Repo klonen

Ordnerstruktur:

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

BAUEN:

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

Zwei Vorbehalte, für die es wahrscheinlich Problemumgehungen gibt:

  • Im Moment muss das Erstellen von Dingen innerhalb des TensorFlow-Repos geschehen .
  • Die kompilierte Binärdatei ist riesig (103 MB).

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

Jim
quelle
1
Hallo Jim. Ist dieses Tutorial immer noch der beste / einfachste Weg, ein C ++ - Projekt mit TF zu kompilieren? Oder gibt es jetzt einen einfacheren Weg, als Sie am Ende Ihres Beitrags vorhersagen?
Sander
3
Ich glaube, es gibt jetzt eine eingebaute Build-Regel. Ich habe vor einiger Zeit eine PR dafür eingereicht. Ich bin mir nicht sicher über die Vorbehalte. Ich würde erwarten, dass der erste bleibt, da er ein Ergebnis von Bazel ist, nicht von TF. Die zweite könnte wahrscheinlich verbessert werden.
Jim
Ich habe dieses Tutorial befolgt, aber beim Ausführen wird ./loadereine Fehlermeldung angezeigt : Not found: models/train.pb.
9. Dimension
3
Gibt es jetzt eine Möglichkeit, Ihr Projekt außerhalb des TensorFlow-Quellcodeverzeichnisses zu haben?
Seanny123
Ja, wie kann man es verdrängen, wenn man die .so-Bibliothek von Tensorflow geteilt hat?
Xyz
15

Wenn Sie vermeiden möchten, dass Sie Ihre Projekte mit Bazel erstellen und eine große Binärdatei generieren, habe ich ein Repository zusammengestellt, das die Verwendung der TensorFlow C ++ - Bibliothek mit CMake anweist. Sie finden es hier . Die allgemeinen Ideen lauten wie folgt:

  • Klonen Sie das TensorFlow-Repository.
  • Fügen Sie eine Build-Regel hinzu tensorflow/BUILD(die bereitgestellten enthalten nicht alle C ++ - Funktionen).
  • Erstellen Sie die gemeinsam genutzte TensorFlow-Bibliothek.
  • Installieren Sie bestimmte Versionen von Eigen und Protobuf oder fügen Sie sie als externe Abhängigkeiten hinzu.
  • Konfigurieren Sie Ihr CMake-Projekt für die Verwendung der TensorFlow-Bibliothek.
cjweeks
quelle
15

Zunächst möchten Sie nach der Installation von protobufund eigenTensorflow erstellen:

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

Kopieren Sie dann die folgenden Include-Header und die dynamische gemeinsam genutzte Bibliothek nach /usr/local/libund /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/

Zuletzt kompilieren Sie anhand eines Beispiels:

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
quelle
Ich glaube, es ist nicht notwendig, protobuf und eigen zu installieren. Die Konfiguration des Bazel-Arbeitsbereichs enthält Regeln zum Herunterladen und Erstellen dieser Komponenten.
4.
Schließlich ist der verrückte OFFIZIELLE Build-Leitfaden unter tensorflow.org/install/source für das Erstellen von Pip-Modulen gedacht, tks für die Build-Option "tensorflow: libtensorflow_cc.so", er ist nicht einmal auf tensorflow.org dokumentiert
datdinhquoc
@lababidi Welche C ++ - Abhängigkeiten sollten vor dem Befehl 'bazel build' bestehen? Ich habe das Problem, dass der Build nach einer Stunde fehlschlägt. Dies ist schwer immer wieder zu testen
datdinhquoc
15

Wenn Sie daran denken, Tensorflow c ++ api in einem eigenständigen Paket zu verwenden, benötigen Sie wahrscheinlich tensorflow_cc.so (es gibt auch eine ac api-Version tensorflow.so), um die C ++ - Version zu erstellen, die Sie verwenden können:

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

Hinweis 1: Wenn Sie Intrinsics-Unterstützung hinzufügen möchten, können Sie diese Flags wie folgt hinzufügen: --copt=-msse4.2 --copt=-mavx

Hinweis 2: Wenn Sie darüber nachdenken, OpenCV auch in Ihrem Projekt zu verwenden, gibt es ein Problem, wenn Sie beide Bibliotheken zusammen verwenden ( Tensorflow-Problem ), und Sie sollten es verwenden --config=monolithic.

Nach dem Erstellen der Bibliothek müssen Sie sie Ihrem Projekt hinzufügen. Dazu können Sie folgende Pfade einschließen:

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

Und verknüpfen Sie die Bibliothek mit Ihrem Projekt:

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

Und wenn Sie Ihr Projekt erstellen, sollten Sie Ihrem Compiler auch mitteilen, dass Sie C ++ 11-Standards verwenden möchten.

Randnotiz: Pfade relativ zu Tensorflow Version 1.5 (Möglicherweise müssen Sie überprüfen, ob sich in Ihrer Version etwas geändert hat).

Auch dieser Link hat mir sehr geholfen, all diese Infos zu finden: Link

Renan Wille
quelle
1
Ich brauchte diesen zusätzlichen Include-Pfad, um mit Version 1.11 zu erstellen:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S
8

Wenn es Ihnen nichts ausmacht, CMake zu verwenden, gibt es auch das Projekt tensorflow_cc , das die TF C ++ - API für Sie erstellt und installiert, sowie praktische CMake-Ziele, mit denen Sie verknüpfen können. Das Projekt README enthält ein Beispiel und Docker-Dateien, denen Sie leicht folgen können.

Floop
quelle
8

Wenn Sie Tensorflow nicht selbst erstellen möchten und Ihr Betriebssystem Debian oder Ubuntu ist, können Sie vorgefertigte Pakete mit den Tensorflow C / C ++ - Bibliotheken herunterladen. Diese Distribution kann für C / C ++ - Inferenzen mit der CPU verwendet werden. Die GPU-Unterstützung ist nicht enthalten:

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

Es gibt Anweisungen zum Einfrieren eines Prüfpunkts in Tensorflow (TFLearn) und zum Laden dieses Modells zur Inferenz mit der C / C ++ - API:

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

Achtung: Ich bin der Entwickler dieses Github-Projekts.

kecsap
quelle
5

Ich verwende einen Hack / eine Problemumgehung, um zu vermeiden, dass die gesamte TF-Bibliothek selbst erstellt werden muss (was sowohl Zeit (Einrichtung in 3 Minuten) als auch Speicherplatz, Installation von Entwicklungsabhängigkeiten und Größe der resultierenden Binärdatei spart). Es wird offiziell nicht unterstützt, funktioniert aber gut, wenn Sie nur schnell einsteigen möchten.

Installieren Sie TF durch Pip ( pip install tensorflowoder pip install tensorflow-gpu). Dann finden Sie seine Bibliothek _pywrap_tensorflow.so(TF 0. * - 1.0) oder _pywrap_tensorflow_internal.so(TF 1.1+). In meinem Fall (Ubuntu) befindet es sich bei /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. Erstellen Sie dann einen Symlink zu dieser Bibliothek, der lib_pywrap_tensorflow.soirgendwo heißt, wo Ihr Build-System ihn findet (z /usr/lib/local. B. ). Das Präfix libist wichtig! Sie können ihm auch einen anderen lib*.soNamen geben. Wenn Sie ihn aufrufen libtensorflow.so, erhalten Sie möglicherweise eine bessere Kompatibilität mit anderen Programmen, die für die Arbeit mit TF geschrieben wurden.

Erstellen Sie dann ein gewohntes C ++ - Projekt (CMake, Make, Bazel, was auch immer Sie möchten).

Und dann können Sie einfach eine Verknüpfung zu dieser Bibliothek herstellen, um TF für Ihre Projekte verfügbar zu haben (und Sie müssen auch eine Verknüpfung zu python2.7Bibliotheken herstellen)! In CMake fügen Sie zB einfach hinzu target_link_libraries(target _pywrap_tensorflow python2.7).

Die C ++ - Headerdateien befinden sich um diese Bibliothek herum, z /usr/local/lib/python2.7/dist-packages/tensorflow/include/. B. in .

Noch einmal: Dieser Weg wird offiziell nicht unterstützt und Sie können in verschiedenen Problemen laufen. Die Bibliothek scheint statisch mit z. B. Protobuf verknüpft zu sein, sodass Sie möglicherweise Probleme mit der ungeraden Verknüpfung oder Laufzeit haben. Aber ich bin in der Lage, ein gespeichertes Diagramm zu laden, die Gewichte wiederherzustellen und Inferenz auszuführen, was IMO die meistgesuchte Funktionalität in C ++ ist.

Martin Pecka
quelle
Ich konnte das nicht zum Laufen bringen. Ich habe eine Reihe von Link-Time-Fehlern über undefinierte Verweise auf Python-Sachen wie:undefined reference to 'PyType_IsSubtype'
0xcaff
Oh, danke, dass du darauf hingewiesen hast ... Du musst auch gegen die python2.7Bibliothek verlinken ... Ich werde den Beitrag entsprechend bearbeiten.
Martin Pecka
@ MartinPecka Ich habe dies auf Raspbian Buster mit dem armv7l (Raspberry PI 2) versucht. Die neuesten verfügbaren Python 2.7- und 3.7-Räder sind für 1.14.0, aber ich ziele auf 2.0.0 ab. Trotzdem danke, ich habe deinen Hack positiv bewertet.
Daisuke Aramaki
2

Tensorflow selbst bietet nur sehr grundlegende Beispiele für C ++ - APIs.
Hier ist eine gute Ressource, die Beispiele für Datasets, rnn, lstm, cnn und weitere
Tensorflow-C ++ - Beispiele enthält

Rock Zhuang
quelle
2

Die obigen Antworten sind gut genug, um zu zeigen, wie die Bibliothek erstellt wird, aber wie die Header gesammelt werden, ist immer noch schwierig. Hier teile ich das kleine Skript, mit dem ich die erforderlichen Header kopiere.

SOURCEist der erste Parameter, der die Direcoty der Tensorflow-Quelle (Build) ist;
DSTist der zweite Parameter, der include directorydie gesammelten Header enthält. (zB in 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
Hakamami
quelle
1
das war wirklich hilfreich Schnipsel, es ein Problem war , während das Erstellen eines Verzeichnisses, so dass ich diese hinzufügen hatte mkdir -p $DST/tensorflow$target_dirvorcp $line $DST/tensorflow/$target_dir
user969068
@akunami Ich habe aus diesem Skript einen Kern gemacht . Lass mich wissen was du denkst. Wenn Sie Ihren eigenen Kern machen wollen, werde ich meinen entfernen und Ihren klonen.
Daisuke Aramaki