“你好,TensorFlow!”使用 C API

Posted

技术标签:

【中文标题】“你好,TensorFlow!”使用 C API【英文标题】:"Hello TensorFlow!" using the C API 【发布时间】:2017-11-06 19:21:44 【问题描述】:

出于学习目的,如何使用 TensorFlow C API 编写这个 Python 示例?

import tensorflow as tf
hello = tf.constant("hello TensorFlow!")
sess=tf.Session()
print(sess.run(hello))

我试过这样:

#include <string.h>
#include <iostream.h>
#include "c_api.h"

int main( int argc, char ** argv ) 

  TF_Graph * graph = TF_NewGraph();
  TF_SessionOptions * options = TF_NewSessionOptions();
  TF_Status * status = TF_NewStatus();
  TF_Session * session = TF_NewSession( graph, options, status );
  char hello[] = "Hello TensorFlow!";
  TF_Tensor * tensor = TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( strlen( hello ) ) );
  TF_OperationDescription * operationDescription = TF_NewOperation( graph, "Const", "hello" );
  TF_Operation * operation; 
  struct TF_Output * output;

  TF_StringEncode( hello, strlen( hello ), 8 + ( char * ) TF_TensorData( tensor ), TF_StringEncodedSize( strlen( hello ) ), status );
  TF_SetAttrTensor( operationDescription, "value", tensor, status );
  TF_SetAttrType( operationDescription, "dtype", TF_TensorType( tensor ) );
  operation = TF_FinishOperation( operationDescription, status );

  output->oper = operation;
  output->index = 0;

  TF_SessionRun( session, 0,
                 0, 0, 0,  // Inputs
                 output, &tensor, 1,  // Outputs
                 &operation, 1,  // Operations
                 0, status );

  printf( "%i", TF_GetCode( status ) );

  TF_CloseSession( session, status );
  TF_DeleteSession( session, status );
  TF_DeleteStatus( status );
  TF_DeleteSessionOptions( options );  

  return 0;

我在 Windows 上使用TensorFlow.dll 测试它来自: http://ci.tensorflow.org/view/Nightly/job/nightly-libtensorflow-windows/lastSuccessfulBuild/artifact/lib_package/libtensorflow-cpu-windows-x86_64.zip

TF_SessionRun() 调用上的上述代码 GPF。一旦我们找到解决方案,如何检索输出?是否应该使用不同的张量 输出 ?上面的代码在输出和操作中都重用了它。

非常感谢

【问题讨论】:

#include &lt;iostream.h&gt; 在 C 中?那应该怎么做? 【参考方案1】:

除了偏移初始化之外,还有一个错误需要解决。这个版本似乎工作正常:

#include <iostream.h>
#include "c_api.h"

int main( int argc, char ** argv ) 

  TF_Graph * graph = TF_NewGraph();
  TF_SessionOptions * options = TF_NewSessionOptions();
  TF_Status * status = TF_NewStatus();
  TF_Session * session = TF_NewSession( graph, options, status );
  char hello[] = "Hello TensorFlow!";
  TF_Tensor * tensor = TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( strlen( hello ) ) );
  TF_Tensor * tensorOutput;
  TF_OperationDescription * operationDescription = TF_NewOperation( graph, "Const", "hello" );
  TF_Operation * operation; 
  struct TF_Output output;

  TF_StringEncode( hello, strlen( hello ), 8 + ( char * ) TF_TensorData( tensor ), TF_StringEncodedSize( strlen( hello ) ), status );
  memset( TF_TensorData( tensor ), 0, 8 );
  TF_SetAttrTensor( operationDescription, "value", tensor, status );
  TF_SetAttrType( operationDescription, "dtype", TF_TensorType( tensor ) );
  operation = TF_FinishOperation( operationDescription, status );

  output.oper = operation;
  output.index = 0;

  TF_SessionRun( session, 0,
                 0, 0, 0,  // Inputs
                 &output, &tensorOutput, 1,  // Outputs
                 &operation, 1,  // Operations
                 0, status );

  printf( "status code: %i\n", TF_GetCode( status ) );
  printf( "%s\n", ( ( char * ) TF_TensorData( tensorOutput ) ) + 9 );

  TF_CloseSession( session, status );
  TF_DeleteSession( session, status );
  TF_DeleteStatus( status );
  TF_DeleteSessionOptions( options );  

  return 0;

我们必须删除 tensorOutput 吗?不知道为什么我们必须添加 9(而不是 8)来获取字符串的开头。

【讨论】:

【参考方案2】:

TF_STRING 张量使用described here 格式编码。在您的代码中,您占用了空间(8 个字节)来编码一个偏移量,但实际上并未对其进行初始化。为此,您需要添加以下内容:

memset(TF_TensorData(tensor), 0, 8);

在调用 TF_SetAttrTensor 之前,这会将字符串元素的“偏移量”设置为 0(您正在编码一个字符串值的位置)。

对于第二个问题:您实际上并没有重复使用相同的 tensor 指针。 comments for TF_SessionRun 表明 TF_SessionRun 正在分配一个新的 TF_Tensor 对象,调用者拥有该对象。因此,在您的代码 sn-p 中,tensor 变量被覆盖以指向新分配的张量。

希望对您有所帮助。

【讨论】:

非常感谢您的帮助。我不知道字符串偏移量也必须初始化。【参考方案3】:

该示例将在安装了 TensorFlow 的 Linux 上运行,如 https://www.tensorflow.org/install/lang_c 所述,更改了 include 指令:

#include <stdio.h>
#include <string.h>
#include <tensorflow/c/c_api.h>

构建执行就足够了

gcc hello_tf.c -ltensorflow -o hello_tf

正如 TensorFlow 文档中所说的那样。

【讨论】:

以上是关于“你好,TensorFlow!”使用 C API的主要内容,如果未能解决你的问题,请参考以下文章

你好,TensorFlow

处理模块中的异常

由于 EnvironmentError 无法安装软件包:[WinError 5] 访问被拒绝:

使用 MetroWerks C/C++ 开发的 C/C++ 资源

我们如何使用WPF / C#可执行文件调试DLL(使用本机C / C ++的bulit)源?

在 C/C++ 中使用 swift 库?