Como criar e usar a API do Google TensorFlow C ++

169

Estou realmente ansioso para começar a usar a nova biblioteca Tensorflow do Google em C ++. O site e os documentos são realmente pouco claros em termos de como criar a API C ++ do projeto e não sei por onde começar.

Alguém com mais experiência pode ajudar descobrindo e compartilhando um guia para usar a API C ++ do tensorflow?

theideasmith
fonte
4
+1 para sua pergunta. Alguma chance de instalar / compilar no Windows? O site mostra apenas Linux / Mac. É necessário um guia para executar o bazel. Este exemplo pode ser um bom ponto de partida para aprender: github.com/tensorflow/tensorflow/tree/master/tensorflow/…
alrama
Esta pergunta ainda não tem resposta. Como instalar apenas as bibliotecas da API C ++ tensorflow C ++ não tem um guia, e a resposta aceita não fornece nenhuma orientação sobre como fazer isso, mesmo através de vários links fornecidos.
Iantonuk
Para Windows, achei esta pergunta e sua resposta aceita mais útil. Ao criar o projeto do treinador de exemplo, você constrói o projeto inteiro do TensorFlow como uma biblioteca estática e, em seguida, vincula-o. Você pode criar seus próprios projetos e vincular o TensorFlow da mesma maneira.
omatai

Respostas:

2

Uma alternativa ao uso da API C ++ do Tensorflow que encontrei é usar o cppflow .

É um invólucro C ++ leve em torno da API C do Tensorflow . Você obtém executáveis ​​muito pequenos e vincula-se ao libtensorflow.soarquivo já compilado. Existem também exemplos de uso e você usa CMAKE em vez de Bazel.

Bersan
fonte
55

Para começar, faça o download do código fonte do Github, seguindo as instruções aqui (você precisará do Bazel e de uma versão recente do GCC).

A API C ++ (e a infra-estrutura do sistema) é em tensorflow/core. No momento, apenas a interface da sessão C ++ e a API C estão sendo suportadas. Você pode usar qualquer um destes para executar gráficos TensorFlow que foram criados usando a API Python e serializados em um GraphDefbuffer de protocolo. Há também um recurso experimental para a construção de gráficos em C ++, mas atualmente não é tão completo quanto a API Python (por exemplo, atualmente não há suporte para diferenciação automática). Você pode ver um programa de exemplo que cria um pequeno gráfico em C ++ aqui .

A segunda parte da API C ++ é a API para adicionar um novo OpKernel, que é a classe que contém implementações de kernels numéricos para CPU e GPU. Existem inúmeros exemplos de como incorporá-los tensorflow/core/kernels, bem como um tutorial para adicionar uma nova operação em C ++ .

mrry
fonte
7
Nenhuma instrução de instalação para C ++ é mostrada tensorflow.org/install , mas existem programas de exemplo mostrados tensorflow.org/api_guides/cc/guide que claramente usam a API C ++. Como exatamente você instalou o C ++ para Tensorflow?
user3667089
@ user3667089 O local do procedimento de instalação agora está localizado em tensorflow.org/install/install_sources
Dwight
6
@Dwight vi essa página antes, mas eu não vejo qualquer informação sobre C ++
user3667089
2
@ user3667089 Os cabeçalhos, após o procedimento de instalação acima, estarão localizados na pasta dist-packages da distribuição python que você escolher durante o procedimento de instalação (como /usr/local/lib/python2.7/dist-packages). Nessa pasta, haverá uma pasta tensorflow / include, que terá todos os cabeçalhos. Você precisará trabalhar um pouco para garantir que tudo o que você está construindo tenha o caminho de inclusão. Eu pessoalmente uso o CMAKE, por isso estou me esquivando disso .
Dwight
4
Esta não é uma resposta real até esta data. Começa com "Para começar" e, em seguida, vincula nenhuma informação relevante em um local que as pessoas que procuram orientação aqui já procuraram. Em seguida, ele não fornece o próximo passo, mudando de assunto.
Iantonuk
28

Para adicionar à postagem de @ mrry, montei um tutorial que explica como carregar um gráfico TensorFlow com a API C ++. É muito mínimo e deve ajudá-lo a entender como todas as peças se encaixam. Aqui está a carne:

Requisitos:

  • Bazel instalado
  • Repositório de clones TensorFlow

Estrutura de pastas:

  • 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",
    ]
)

Duas advertências para as quais provavelmente existem soluções alternativas:

  • No momento, a criação de coisas precisa acontecer no repositório TensorFlow.
  • O binário compilado é enorme (103MB).

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

Jim
fonte
1
Olá Jim. este tutorial ainda é a melhor / mais fácil maneira de compilar um projeto c ++ com TF? Ou existe uma maneira mais fácil agora, como você prevê no final de sua postagem?
Sander
3
Acredito que agora existe uma regra de compilação interna. Enviei um PR para isso há um tempo. Não tenho certeza sobre as advertências. Eu esperaria que o primeiro permanecesse, como resultado de Bazel, não de TF. O segundo provavelmente poderia ser melhorado.
Jim
Eu segui esse tutorial, mas quando executando ./loadereu recebo um erro: Not found: models/train.pb.
9th Dimension
3
Existe agora uma maneira de ter seu projeto fora do diretório de código-fonte do TensorFlow?
Seanny123
sim, como fazê-lo fora, se você compartilhou a biblioteca .so do tensorflow?
Xyz 26/05
15

Se você deseja evitar criar seus projetos com o Bazel e gerar um binário grande, montei um repositório instruindo o uso da biblioteca TensorFlow C ++ com o CMake. Você pode encontrá-lo aqui . As idéias gerais são as seguintes:

  • Clone o repositório TensorFlow.
  • Adicione uma regra de construção a tensorflow/BUILD(as fornecidas não incluem toda a funcionalidade do C ++).
  • Crie a biblioteca compartilhada TensorFlow.
  • Instale versões específicas do Eigen e Protobuf ou adicione-as como dependências externas.
  • Configure seu projeto CMake para usar a biblioteca TensorFlow.
cjweeks
fonte
15

Primeiro, após a instalação protobufe eigen, você deseja criar o Tensorflow:

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

Em seguida, copie os seguintes cabeçalhos de inclusão e biblioteca compartilhada dinâmica para /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/

Por fim, compile usando um exemplo:

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
fonte
Eu acredito que não é necessário instalar o protobuf e o eigen. A configuração do espaço de trabalho do bazel inclui regras para baixar e construir esses componentes.
4dan
Finalmente, o Guia de criação do OFICIAL louco em tensorflow.org/install/source é para a construção de módulo pip, tks para a opção de compilação "tensorflow: libtensorflow_cc.so", não é mesmo documentado em tensorflow.org
datdinhquoc
@ lababidi o que dependências c ++ devem ser antes do comando 'bazel build'? i estou enfrentando problema que a construção falhar depois de uma hora, isso é difícil de build de teste novo e de novo
datdinhquoc
15

Se você estiver pensando em usar a API do Tensorflow c ++ em um pacote independente, provavelmente precisará do tensorflow_cc.so (também existe uma versão da API ap tensensflow.so) para criar a versão do c ++ que você pode usar:

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

Nota1: Se você deseja adicionar suporte intrínseco, pode adicionar esses sinalizadores como: --copt=-msse4.2 --copt=-mavx

Nota2: Se você está pensando em usar o OpenCV também no seu projeto, há um problema ao usar as duas bibliotecas juntas ( problema do tensorflow ) e você deve usá-lo --config=monolithic.

Depois de criar a biblioteca, você precisa adicioná-la ao seu projeto. Para fazer isso, você pode incluir estes caminhos:

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

E vincule a biblioteca ao seu projeto:

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

E ao criar seu projeto, você também deve especificar ao seu compilador que irá usar os padrões c ++ 11.

Nota: Caminhos relativos à tensorflow versão 1.5 (pode ser necessário verificar se na sua versão alguma coisa mudou).

Também este link me ajudou muito a encontrar todas essas informações: link

Renan Wille
fonte
1
Eu precisava desse caminho de inclusão adicional para construir com a versão 1.11:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S 23/10/18
8

Se você não se importa em usar o CMake, também existe o projeto tensorflow_cc que cria e instala a API TF C ++ para você, juntamente com os convenientes destinos do CMake com os quais você pode se conectar. O projeto README contém um exemplo e Dockerfiles que você pode seguir facilmente.

Floop
fonte
8

Se você não quiser criar o Tensorflow por conta própria e seu sistema operacional for Debian ou Ubuntu, poderá fazer o download de pacotes pré-construídos com as bibliotecas Tensorflow C / C ++. Esta distribuição pode ser usada para inferência C / C ++ com CPU, o suporte a GPU não está incluído:

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

Existem instruções escritas como congelar um ponto de verificação no Tensorflow (TFLearn) e carregar este modelo para inferência com a API C / C ++:

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

Cuidado: eu sou o desenvolvedor deste projeto do Github.

kecsap
fonte
5

Eu uso um hack / solução alternativa para evitar ter que construir toda a biblioteca TF (o que economiza tempo (é configurado em 3 minutos), espaço em disco, instalação de dependências de desenvolvimento e tamanho do binário resultante). É oficialmente não suportado, mas funciona bem se você quiser entrar rapidamente.

Instale o TF através do pip ( pip install tensorflowou pip install tensorflow-gpu). Em seguida, encontre sua biblioteca _pywrap_tensorflow.so(TF 0. * - 1.0) ou _pywrap_tensorflow_internal.so(TF 1.1+). No meu caso (Ubuntu) está localizado em /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. Em seguida, crie um link simbólico para essa biblioteca chamado em lib_pywrap_tensorflow.soalgum lugar onde seu sistema de construção o encontre (por exemplo /usr/lib/local). O prefixo libé importante! Você também pode dar outro lib*.sonome a ele - se você o chamar libtensorflow.so, poderá obter uma melhor compatibilidade com outros programas criados para trabalhar com o TF.

Em seguida, crie um projeto C ++ como você está acostumado (CMake, Make, Bazel, o que quiser).

E então você está pronto para vincular-se a essa biblioteca para ter o TF disponível para seus projetos (e também para vincular-se a python2.7bibliotecas)! No CMake, por exemplo, basta adicionar target_link_libraries(target _pywrap_tensorflow python2.7).

Os arquivos de cabeçalho C ++ estão localizados em torno desta biblioteca, por exemplo, em /usr/local/lib/python2.7/dist-packages/tensorflow/include/.

Mais uma vez: dessa forma, não há suporte oficial e você pode executar vários problemas. A biblioteca parece estar estaticamente vinculada a, por exemplo, protobuf, portanto, você pode executar problemas estranhos no tempo do link ou no tempo de execução. Mas sou capaz de carregar um gráfico armazenado, restaurar os pesos e executar inferência, que é a IMO a funcionalidade mais desejada em C ++.

Martin Pecka
fonte
Não consegui fazer isso funcionar. Eu tenho um monte de erros de tempo de link sobre referências indefinidas a coisas como python como:undefined reference to 'PyType_IsSubtype'
0xcaff 1/17/17
Ah, obrigado por apontar ... Você também deve vincular a python2.7biblioteca ... Eu vou editar a postagem de acordo.
Martin Pecka
@MartinPecka Eu tentei isso no Raspbian Buster com o armv7l (Raspberry PI 2). As últimas rodas Python 2.7 e 3.7 disponíveis são para a 1.14.0, mas eu estou visando a 2.0.0. Obrigado de qualquer maneira, votei no seu hack.
Daisuke Aramaki
2

O próprio Tensorflow fornece apenas exemplos muito básicos sobre APIs C ++.
Aqui está um bom recurso que inclui exemplos de conjuntos de dados, exemplos de rnn, lstm, cnn e mais
tensorflow c ++

Rock Zhuang
fonte
2

as respostas acima são boas o suficiente para mostrar como criar a biblioteca, mas como coletar os cabeçalhos ainda são complicados. aqui compartilho o pequeno script que utilizo para copiar os cabeçalhos necessários.

SOURCEé o primeiro parâmetro, que é o direcoty da fonte do tensorflow (compilação);
DSTé o segundo parâmetro, que include directorycontém os cabeçalhos coletados. (por exemplo, em 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
fonte
1
este era trecho realmente útil, houve um problema ao criar um diretório, então eu tinha para adicionar este mkdir -p $DST/tensorflow$target_dirantescp $line $DST/tensorflow/$target_dir
user969068
@hakunami Eu fiz um resumo desse script . Diz-me o que pensas. Se você quiser criar sua própria essência, eu removerei a minha e clonarei a sua.
Daisuke Aramaki