Cómo construir y usar la API de Google TensorFlow C ++

169

Estoy realmente ansioso por comenzar a usar la nueva biblioteca de Tensorflow de Google en C ++. El sitio web y los documentos no son claros en términos de cómo construir la API C ++ del proyecto y no sé por dónde empezar.

¿Puede alguien con más experiencia ayudar descubriendo y compartiendo una guía para usar la API C ++ de tensorflow?

theideasmith
fuente
44
+1 por tu pregunta. ¿Alguna posibilidad de instalar / compilar en Windows? El sitio web muestra solo Linux / Mac. Se necesita una guía para ejecutar bazel. Este ejemplo podría ser un buen punto de partida para aprender: github.com/tensorflow/tensorflow/tree/master/tensorflow/…
alrama
Esta pregunta aún no tiene una respuesta. Cómo instalar solo las bibliotecas API C ++ tensorflow C ++ no tiene una guía, y la respuesta aceptada no brinda ninguna guía sobre cómo hacerlo, incluso a través de cualquiera de los múltiples enlaces proporcionados.
iantonuk
Para Windows, encontré esta pregunta y su respuesta aceptada más útil. Al construir el proyecto de entrenador de ejemplo, construye todo el proyecto TensorFlow como una biblioteca estática, luego se vincula a él. Puede hacer sus propios proyectos y vincular TensorFlow de la misma manera.
omatai

Respuestas:

2

Una alternativa al uso de Tensorflow C ++ API que encontré es usar cppflow .

Es un contenedor ligero de C ++ alrededor de Tensorflow C API . Obtiene ejecutables muy pequeños y se vincula con el libtensorflow.soarchivo ya compilado. También hay ejemplos de uso y usa CMAKE en lugar de Bazel.

Bersan
fuente
55

Para comenzar, debe descargar el código fuente de Github, siguiendo las instrucciones aquí (necesitará Bazel y una versión reciente de GCC).

La API de C ++ (y el back-end del sistema) está en tensorflow/core. En este momento, solo se admite la interfaz de sesión de C ++ y la API de C ++ . Puede usar cualquiera de estos para ejecutar gráficos de TensorFlow que se han creado utilizando la API de Python y serializados en un GraphDefbúfer de protocolo. También hay una característica experimental para construir gráficos en C ++, pero actualmente no tiene todas las funciones como la API de Python (por ejemplo, no hay soporte para la diferenciación automática en este momento). Puede ver un programa de ejemplo que crea un pequeño gráfico en C ++ aquí .

La segunda parte de la API de C ++ es la API para agregar una nueva OpKernel, que es la clase que contiene implementaciones de núcleos numéricos para CPU y GPU. Existen numerosos ejemplos de cómo construirlos tensorflow/core/kernels, así como un tutorial para agregar una nueva operación en C ++ .

señor
fuente
77
No se muestran instrucciones de instalación para C ++ tensorflow.org/install , pero hay programas de ejemplo que se muestran tensorflow.org/api_guides/cc/guide que claramente están usando la api de C ++. ¿Cómo instaló exactamente C ++ para Tensorflow?
user3667089
@ user3667089 La ubicación del procedimiento de instalación ahora se encuentra en tensorflow.org/install/install_sources
Dwight
66
@Dwight Vi esa página antes pero no veo ninguna información sobre C ++
user3667089
2
@ user3667089 Los encabezados, después del procedimiento de instalación anterior, se ubicarán dentro de la carpeta dist-packages de la distribución de python que elija durante el procedimiento de instalación (como /usr/local/lib/python2.7/dist-packages). En esa carpeta habrá una carpeta tensorflow / include, que tendrá todos los encabezados. Tendrás que hacer un poco de trabajo para asegurarte de que todo lo que estás construyendo tiene ese camino de inclusión. Yo personalmente uso CMAKE, así que estoy pasando por esto .
Dwight
44
Esta no es una respuesta real hasta la fecha. Comienza con "Para comenzar" y luego no vincula información relevante en un lugar que las personas que buscan orientación aquí ya buscarían. Luego no proporciona el siguiente paso, cambiando de tema.
iantonuk
28

Para agregar a la publicación de @ mrry, preparé un tutorial que explica cómo cargar un gráfico TensorFlow con la API de C ++. Es muy mínimo y debería ayudarlo a comprender cómo encajan todas las piezas. Aquí está la carne:

Requisitos:

  • Bazel instalado
  • Clon TensorFlow repo

Estructura de carpetas:

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

CONSTRUIR:

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

Dos advertencias para las cuales probablemente hay soluciones:

  • En este momento, la construcción de cosas debe suceder dentro del repositorio de TensorFlow.
  • El binario compilado es enorme (103MB).

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

Jim
fuente
1
Hola jim ¿sigue siendo este tutorial la forma mejor / más fácil de compilar un proyecto de c ++ con TF? ¿O hay una manera más fácil ahora como predices al final de tu publicación?
Sander
3
Creo que ahora hay una regla de compilación incorporada. Le envié un RP hace un tiempo. No estoy seguro de las advertencias. Esperaría que el primero permanezca como resultado de Bazel, no de TF. El segundo probablemente podría mejorarse.
Jim
He seguido ese tutorial, pero cuando se ejecuta ./loaderconsigo un error: Not found: models/train.pb.
Novena dimensión
3
¿Hay alguna forma de tener su proyecto fuera del directorio de código fuente de TensorFlow?
Seanny123
sí, ¿cómo hacerlo fuera dado que has compartido .so biblioteca de tensorflow?
Xyz
15

Si desea evitar construir sus proyectos con Bazel y generar un binario grande, he reunido un repositorio que indica el uso de la biblioteca TensorFlow C ++ con CMake. Lo puedes encontrar aquí . Las ideas generales son las siguientes:

  • Clone el repositorio TensorFlow.
  • Agregue una regla de compilación a tensorflow/BUILD(las proporcionadas no incluyen toda la funcionalidad de C ++).
  • Construya la biblioteca compartida TensorFlow.
  • Instale versiones específicas de Eigen y Protobuf, o agréguelos como dependencias externas.
  • Configure su proyecto CMake para usar la biblioteca TensorFlow.
cjweeks
fuente
15

Primero, después de instalar protobufy eigen, te gustaría construir Tensorflow:

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

Luego, copie los siguientes encabezados y biblioteca compartida dinámica en /usr/local/liby /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/

Por último, compile usando un ejemplo:

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
fuente
Creo que no es necesario instalar protobuf y eigen. La configuración del espacio de trabajo de Bazel incluye reglas para descargar y construir esos componentes.
4dan
finalmente, la loca guía de compilación OFICIAL en tensorflow.org/install/source es para construir el módulo pip, tks para la opción de compilación "tensorflow: libtensorflow_cc.so", ni siquiera está documentada en tensorflow.org
datdinhquoc
@lababidi, ¿qué dependencias de c ++ deberían ser antes del comando 'bazel build'? Me enfrento al problema de que la compilación falla después de una hora, esto es difícil de probar una y otra vez
datdinhquoc
15

Si está pensando en usar la API de Tensorflow c ++ en un paquete independiente, probablemente necesitará tensorflow_cc.so (También hay una versión de la API ac tensorflow.so) para construir la versión de c ++ que puede usar:

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

Nota 1: Si desea agregar soporte intrínseco, puede agregar estos indicadores como: --copt=-msse4.2 --copt=-mavx

Nota 2: Si también está pensando en usar OpenCV en su proyecto, hay un problema al usar ambas libs juntas ( problema de tensorflow ) y debería usarlo --config=monolithic.

Después de construir la biblioteca, debe agregarla a su proyecto. Para hacerlo, puede incluir estos caminos:

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

Y vincule la biblioteca a su proyecto:

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

Y cuando esté construyendo su proyecto, también debe especificar a su compilador que va a utilizar los estándares de c ++ 11.

Nota al margen: rutas relativas a la versión 1.5 de tensorflow (es posible que deba verificar si en su versión algo cambió).

También este enlace me ayudó mucho a encontrar toda esta información: enlace

Renan Wille
fuente
1
Necesitaba esta ruta de inclusión adicional para compilar con la versión 1.11:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S
8

Si no le importa usar CMake, también hay un proyecto tensorflow_cc que construye e instala la API TF C ++ para usted, junto con objetivos convenientes de CMake con los que puede vincularse. El proyecto README contiene un ejemplo y archivos Docker que puede seguir fácilmente.

Floop
fuente
8

Si no desea construir Tensorflow usted mismo y su sistema operativo es Debian o Ubuntu, puede descargar paquetes preconstruidos con las bibliotecas Tensorflow C / C ++. Esta distribución se puede usar para la inferencia C / C ++ con CPU, el soporte de GPU no está incluido:

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

Hay instrucciones escritas sobre cómo congelar un punto de control en Tensorflow (TFLearn) y cargar este modelo para inferencia con la API C / C ++:

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

Cuidado: soy el desarrollador de este proyecto Github.

kecsap
fuente
5

Utilizo un truco / solución alternativa para evitar tener que construir toda la biblioteca TF (lo que ahorra tiempo (se configura en 3 minutos), espacio en disco, instalación de dependencias de desarrollo y tamaño del binario resultante). Oficialmente no es compatible, pero funciona bien si solo quieres saltar rápidamente.

Instale TF a través de pip ( pip install tensorflowo pip install tensorflow-gpu). Luego encuentre su biblioteca _pywrap_tensorflow.so(TF 0. * - 1.0) o _pywrap_tensorflow_internal.so(TF 1.1+). En mi caso (Ubuntu) está ubicado en /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. Luego, cree un enlace simbólico a esta biblioteca llamada en lib_pywrap_tensorflow.soalgún lugar donde su sistema de compilación lo encuentre (por ejemplo /usr/lib/local). ¡El prefijo libes importante! También puede darle otro lib*.sonombre: si lo llama libtensorflow.so, puede obtener una mejor compatibilidad con otros programas escritos para trabajar con TF.

Luego crea un proyecto C ++ como estás acostumbrado (CMake, Make, Bazel, lo que quieras).

¡Y luego está listo para vincular contra esta biblioteca para tener TF disponible para sus proyectos (y también debe vincular contra python2.7bibliotecas)! En CMake, por ejemplo, solo agrega target_link_libraries(target _pywrap_tensorflow python2.7).

Los archivos de encabezado de C ++ se encuentran alrededor de esta biblioteca, por ejemplo, en /usr/local/lib/python2.7/dist-packages/tensorflow/include/.

Una vez más: de esta manera no se admite oficialmente y puede ejecutar varios problemas. La biblioteca parece estar estáticamente vinculada, por ejemplo, a protobuf, por lo que puede ejecutar problemas de tiempo de enlace o de tiempo de ejecución impares. Pero puedo cargar un gráfico almacenado, restaurar los pesos y ejecutar la inferencia, que es IMO la funcionalidad más deseada en C ++.

Martin Pecka
fuente
No pude hacer que esto funcione. Recibí un montón de errores de tiempo de enlace sobre referencias indefinidas a cosas de Python como:undefined reference to 'PyType_IsSubtype'
0xcaff
Oh, gracias por señalarlo ... También debes vincular contra la python2.7biblioteca ... Editaré la publicación en consecuencia.
Martin Pecka
@ MartinPecka Probé esto en Raspbian Buster con armv7l (Raspberry PI 2). Las últimas ruedas Python 2.7 y 3.7 disponibles son para 1.14.0, pero estoy apuntando a 2.0.0. Gracias de todos modos, voté por tu truco.
Daisuke Aramaki
2

Tensorflow solo proporciona ejemplos muy básicos sobre las API de C ++.
Aquí hay un buen recurso que incluye ejemplos de conjuntos de datos, rnn, lstm, cnn y más
ejemplos de tensorflow c ++

Rock Zhuang
fuente
2

las respuestas anteriores son lo suficientemente buenas como para mostrar cómo construir la biblioteca, pero cómo recopilar los encabezados aún es complicado. aquí comparto el pequeño script que uso para copiar los encabezados necesarios.

SOURCEes el primer parámetro, que es el origen de la fuente de tensorflow (compilación);
DSTes el segundo parámetro, que include directorycontiene los encabezados recopilados. (por ejemplo, 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
fuente
1
esto fue un fragmento realmente útil, hubo un problema al crear un directorio, así que tuve que agregar esto mkdir -p $DST/tensorflow$target_dirantescp $line $DST/tensorflow/$target_dir
user969068
@hakunami Saqué una esencia de este guión . Déjame saber lo que piensas. Si quieres hacer tu propia esencia, eliminaré la mía y clonaré la tuya.
Daisuke Aramaki