Come costruire e utilizzare Google TensorFlow C ++ api


169

Sono davvero impaziente di iniziare a utilizzare la nuova libreria Tensorflow di Google in C ++. Il sito Web e i documenti non sono chiari in termini di come creare l'API C ++ del progetto e non so da dove iniziare.

Qualcuno con più esperienza può aiutare scoprendo e condividendo una guida all'uso dell'API C ++ di tensorflow?


4
+1 per la tua domanda. Qualche possibilità di installare / compilare su Windows? Il sito Web mostra solo Linux / Mac. È necessaria una guida per eseguire il bazel. Questo esempio potrebbe essere un buon punto di partenza per imparare: github.com/tensorflow/tensorflow/tree/master/tensorflow/…
alrama

Questa domanda non ha ancora una risposta. Come installare solo le librerie API C ++ tensorflow C ++ non ha una guida e la risposta accettata non fornisce alcuna prova su come farlo, anche attraverso uno qualsiasi dei collegamenti multipli forniti.
iantonuk,

Per Windows, ho trovato questa domanda e la sua risposta accettata molto utili. Costruendo il progetto trainer di esempio, si crea l'intero progetto TensorFlow come libreria statica, quindi si collega ad esso. Puoi realizzare i tuoi progetti e collegare TensorFlow allo stesso modo.
omatai,

Risposte:


2

Un'alternativa all'utilizzo dell'API C ++ di Tensorflow che ho trovato è l'uso di cppflow .

È un wrapper C ++ leggero attorno all'API C di Tensorflow . Ottieni eseguibili molto piccoli e si collega al libtensorflow.sofile già compilato. Ci sono anche esempi di utilizzo e usi CMAKE invece di Bazel.


55

Per iniziare, dovresti scaricare il codice sorgente da Github, seguendo le istruzioni qui (avrai bisogno di Bazel e una versione recente di GCC).

L'API C ++ (e il backend del sistema) è in tensorflow/core. Al momento, sono supportate solo l' interfaccia della sessione C ++ e l' API C. È possibile utilizzare uno di questi per eseguire grafici TensorFlow che sono stati creati utilizzando l'API Python e serializzati in un GraphDefbuffer di protocollo. Esiste anche una funzione sperimentale per la creazione di grafici in C ++, ma attualmente non è così completa come l'API Python (ad esempio, nessun supporto per la differenziazione automatica al momento). Qui puoi vedere un programma di esempio che crea un piccolo grafico in C ++ .

La seconda parte dell'API C ++ è l'API per l'aggiunta di una nuova OpKernel, ovvero la classe contenente implementazioni di kernel numerici per CPU e GPU. Esistono numerosi esempi di come incorporarli tensorflow/core/kernels, nonché un tutorial per aggiungere una nuova operazione in C ++ .


7
Non sono mostrate istruzioni di installazione per C ++ tensorflow.org/install , ma ci sono programmi di esempio mostrati tensorflow.org/api_guides/cc/guide che chiaramente usa C ++ api. Come hai installato esattamente C ++ per Tensorflow?
user3667089

@ user3667089 L'ubicazione della procedura di installazione si trova ora su tensorflow.org/install/install_sources
Dwight

6
@Dwight Ho visto quella pagina prima ma non vedo alcuna informazione su C ++
user3667089

2
@ user3667089 Le intestazioni, dopo la procedura di installazione sopra, saranno posizionate nella cartella dist-pacchetti della distribuzione python scelta durante la procedura di installazione (come /usr/local/lib/python2.7/dist-packages). In quella cartella ci sarà una cartella tensorflow / include, che avrà tutte le intestazioni. Dovrai fare un po 'di lavoro per assicurarti che tutto ciò che stai costruendo abbia sul suo percorso di inclusione. Personalmente uso CMAKE, quindi sto arrancando attraverso questo .
Dwight,

4
Questa non è una vera risposta fino a questa data. Si inizia con "Per iniziare" e quindi non collega informazioni pertinenti in un luogo in cui le persone in cerca di guida qui avrebbero già cercato. Non riesce quindi a fornire il passaggio successivo, cambiando argomento.
iantonuk,

28

Per aggiungere al post di @ mrry, ho messo insieme un tutorial che spiega come caricare un grafico TensorFlow con l'API C ++. È molto minimale e dovrebbe aiutarti a capire come tutti i pezzi si incastrano. Ecco la carne di esso:

Requisiti:

  • Bazel installato
  • Clone TensorFlow repo

Struttura delle cartelle:

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

COSTRUIRE:

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

Due avvertenze per le quali ci sono probabilmente soluzioni alternative:

  • In questo momento, nel repository TensorFlow deve avvenire la costruzione di cose .
  • Il binario compilato è enorme (103 MB).

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


1
Ciao Jim questo tutorial è ancora il modo migliore / più semplice per compilare un progetto c ++ con TF? O c'è un modo più semplice ora come previsto alla fine del tuo post?
Sander,

3
Credo che ora ci sia una regola di build integrata. Ho inviato un PR per questo qualche tempo fa. Non sono sicuro delle avvertenze. Mi aspetto che il primo rimanga perché è il risultato di Bazel, non di TF. Il secondo potrebbe probabilmente essere migliorato.
Jim

Ho seguito che tutorial, ma quando si esegue ./loaderottengo un errore: Not found: models/train.pb.
9a dimensione,

3
Esiste un modo per avere il tuo progetto al di fuori della directory del codice sorgente di TensorFlow?
Seanny123,

sì, come renderlo esteriore dato che hai condiviso la libreria .so di tensorflow?
Xyz,

15

Se desideri evitare sia di costruire i tuoi progetti con Bazel sia di generare un grande binario, ho assemblato un repository che istruisce l'uso della libreria C ++ TensorFlow con CMake. Puoi trovarlo qui . Le idee generali sono le seguenti:

  • Clonare il repository TensorFlow.
  • Aggiungi una regola di build a tensorflow/BUILD(quelle fornite non includono tutte le funzionalità C ++).
  • Costruisci la libreria condivisa TensorFlow.
  • Installa versioni specifiche di Eigen e Protobuf o aggiungile come dipendenze esterne.
  • Configura il tuo progetto CMake per utilizzare la libreria TensorFlow.

15

Innanzitutto, dopo l'installazione protobufe eigen, ti piacerebbe costruire Tensorflow:

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

Quindi copia le seguenti intestazioni e libreria dinamica condivisa su /usr/local/libe /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/

Infine, compila usando un esempio:

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

Credo che non sia necessario installare protobuf ed eigen. La configurazione dell'area di lavoro bazel include regole per scaricare e creare tali componenti.
4

infine, la folle guida di costruzione UFFICIALE su tensorflow.org/install/source è per la creazione di moduli pip, tks per l'opzione di costruzione "tensorflow: libtensorflow_cc.so", non è nemmeno documentata su tensorflow.org
datdinhquoc

@lababidi quali dipendenze c ++ dovrebbero essere prima del comando 'bazel build'? sto affrontando il problema che la compilazione non riesce dopo un'ora, è difficile testarla ancora e ancora
datdinhquoc

15

Se stai pensando di usare Tensorflow c ++ api su un pacchetto autonomo probabilmente avrai bisogno di tensorflow_cc.so (esiste anche una versione ac api tensorflow.so) per costruire la versione c ++ che puoi usare:

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

Nota 1: se si desidera aggiungere il supporto intrinseco, è possibile aggiungere questi flag come: --copt=-msse4.2 --copt=-mavx

Nota2: Se stai pensando di usare anche OpenCV sul tuo progetto, c'è un problema quando usi entrambe le librerie insieme ( problema di tensorflow ) e dovresti usare --config=monolithic.

Dopo aver creato la libreria, è necessario aggiungerla al progetto. Per fare ciò puoi includere questi percorsi:

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

E collega la biblioteca al tuo progetto:

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

E quando stai costruendo il tuo progetto dovresti anche specificare al tuo compilatore che userai gli standard c ++ 11.

Nota a margine: percorsi relativi alla versione 1.5 di tensorflow (potrebbe essere necessario verificare se nella tua versione è cambiato qualcosa).

Anche questo link mi ha aiutato molto a trovare tutte queste informazioni: link


1
Avevo bisogno di questo percorso aggiuntivo da tensorflow/bazel-tensorflow/external/com_google_absl
compilare


8

Se non ti dispiace usare CMake, esiste anche un progetto tensorflow_cc che costruisce e installa l'API TF C ++ per te, insieme a comodi target CMake a cui puoi collegarti. Il progetto README contiene un esempio e file Docker che puoi facilmente seguire.


8

Se non vuoi creare Tensorflow da solo e il tuo sistema operativo è Debian o Ubuntu, puoi scaricare pacchetti predefiniti con le librerie Tensorflow C / C ++. Questa distribuzione può essere utilizzata per inferenza C / C ++ con CPU, il supporto GPU non è incluso:

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

Ci sono istruzioni scritte su come congelare un checkpoint in Tensorflow (TFLearn) e caricare questo modello per l'inferenza con l'API C / C ++:

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

Attenzione: sono lo sviluppatore di questo progetto Github.


5

Uso un hack / soluzione alternativa per evitare di dover costruire da solo l'intera libreria TF (che consente di risparmiare tempo (è impostato in 3 minuti), spazio su disco, installazione di dipendenze di sviluppo e dimensioni del file binario risultante). È ufficialmente non supportato, ma funziona bene se vuoi semplicemente saltare rapidamente dentro.

Installare TF attraverso pip ( pip install tensorflowo pip install tensorflow-gpu). Quindi trova la sua libreria _pywrap_tensorflow.so(TF 0. * - 1.0) o _pywrap_tensorflow_internal.so(TF 1.1+). Nel mio caso (Ubuntu) si trova in /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. Quindi crea un link simbolico a questa libreria chiamato lib_pywrap_tensorflow.soda qualche parte dove lo trova il tuo sistema di compilazione (ad es /usr/lib/local.). Il prefisso libè importante! Puoi anche dargli un altro lib*.sonome: se lo chiami libtensorflow.so, potresti ottenere una migliore compatibilità con altri programmi scritti per funzionare con TF.

Quindi crea un progetto C ++ come sei abituato (CMake, Make, Bazel, qualunque cosa ti piaccia).

E poi sei pronto a collegarti a questa libreria per avere TF disponibile per i tuoi progetti (e devi anche collegarti a python2.7librerie)! In CMake, ad esempio, basta aggiungere target_link_libraries(target _pywrap_tensorflow python2.7).

I file di intestazione C ++ si trovano attorno a questa libreria, ad esempio in /usr/local/lib/python2.7/dist-packages/tensorflow/include/ .

Ancora una volta: in questo modo non è ufficialmente supportato e si possono riscontrare vari problemi. La libreria sembra essere staticamente collegata ad esempio a protobuf, quindi è possibile che si verifichino problemi di link-time o run-time dispari. Ma sono in grado di caricare un grafico memorizzato, ripristinare i pesi ed eseguire l'inferenza, che è IMO la funzionalità più desiderata in C ++.


Non sono riuscito a farlo funzionare. Ho avuto un sacco di errori di tempo di collegamento su riferimenti indefiniti alle cose di Python come:undefined reference to 'PyType_IsSubtype'
0xcaff

Oh, grazie per averlo sottolineato ... Devi anche collegarti alla python2.7libreria ... Modificherò il post di conseguenza.
Martin Pecka,

@MartinPecka L'ho provato su Raspbian Buster con armv7l (Raspberry PI 2). Le ultime ruote Python 2.7 e 3.7 disponibili sono per 1.14.0, ma sto prendendo di mira 2.0.0. Grazie comunque, ho annullato il tuo hack.
Daisuke Aramaki,


2

le risposte sopra sono abbastanza buone per mostrare come costruire la libreria, ma come raccogliere le intestazioni sono ancora difficili. qui condivido il piccolo script che uso per copiare le intestazioni necessarie.

SOURCEè il primo parametro, che è la sorgente tensorflow (build) direcoty;
DSTè il secondo parametro, ovvero le include directoryprese delle intestazioni raccolte. (es. 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

1
questo è stato un frammento davvero utile, si è verificato un problema durante la creazione di una directory, quindi ho dovuto aggiungerlo mkdir -p $DST/tensorflow$target_dirprimacp $line $DST/tensorflow/$target_dir
user969068

@hakunami Ho fatto un'idea di questa sceneggiatura . Fatemi sapere cosa ne pensate. Se vuoi creare il tuo senso, rimuoverò il mio e clonerò il tuo.
Daisuke Aramaki,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.