我已经用python和使用capi
编写了最少的代码。此代码加载premade
图并通过它运行测试图像。使用capi
似乎无法获得与通过python运行相同的结果。
Linux Ubuntu 16.04
我已经安装了tf并使用bazel
构建了库。
我尝试了各种版本,但为此实验将其固定在1.9。
Python 3.5.2
bazel 0.13.0
gcc 5.4
no cuda
我正在尝试运行android移动示例提供的图表ssd_mobilenet_v1_android_export.pb
。
我正在使用this test image
我有简单的python代码(下面的代码),该代码可加载图形,向其提供图像并读取各种张量。此图的末尾有一个称为num_detections
的操作,我正在阅读张量以检查是否成功。
使用dog.jpg
,我得到3.0
的结果。其他测试图像会给出适当的结果。
我正在用capi(下面的代码)重复该实验,但是我得到的唯一结果是0
。
我看的第一个明显的地方是我的图像输入。第二个图形op是ToFloat
操作。我一直在用它来检查进入提要的像素数据的值。它们是相同的。解码后,我检查图像没有翻转并且颜色通道的顺序相同。然后,我开始进一步查找该图,在每个操作中采样张量的值。我发现它们几乎是相同的,直到它们进入一长串的卷积运算,似乎值逐渐趋于不同为止-就像它们在前几个运算元中一样,然后开始显示出越来越远的差异。
不可用的验证码:
#include <png.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <tensorflow/c/c_api.h>
typedef unsigned char byte;
const int num_channels = 3;
struct Image {
byte* data;
int width, height;
int dataSize() {
return width * height * num_channels;
}
};
Image open_image(const char* filename) {
Image image;
int dataSize = image.width * image.height * num_channels;
png::image< png::rgb_pixel > png_import(filename);
image.width = png_import.get_width();
image.height = png_import.get_height();
image.data = (byte*)malloc(image.dataSize());
for(int y=0; y<image.height; y++) {
for(int x=0; x<image.width; x++) {
png::rgb_pixel pixel = png_import.get_pixel(x,y);
byte* data = &image.data[(y*image.width+x)*num_channels];
*data++ = pixel.red;
*data++ = pixel.green;
*data++ = pixel.blue;
}
}
printf("%s loaded, %dx%d\n", filename, image.width, image.height);
return image;
}
TF_Graph* open_graph(const char* filename, TF_Status* status) {
TF_Graph* graph = TF_NewGraph();
TF_ImportGraphDefOptions* opts = TF_NewImportGraphDefOptions();
FILE* fp = fopen(filename, "r");
fseek(fp, 0L, SEEK_END);
int file_size = ftell(fp);
rewind(fp);
char* graph_content = (char*)malloc(file_size);
fread(graph_content, file_size, 1, fp);
fclose(fp);
TF_Buffer tfBuffer;
tfBuffer.data = graph_content;
tfBuffer.length = file_size;
TF_GraphImportGraphDef(graph, &tfBuffer, opts, status);
free(graph_content);
if(TF_GetCode(status) != TF_OK) {
printf("%s\n", TF_Message(status));
return 0;
}
printf("Successfully loaded graph\n");
return graph;
}
void TensorDeallocator(void* data, size_t len, void* arg)
{
}
int main(int argi, char** argc) {
printf("TensorFlow C library version %s\n", TF_Version());
TF_Status* status = TF_NewStatus();
TF_Graph* graph = open_graph(argc[1], status);
Image image = open_image(argc[2]);
int64_t dims[] = {1, image.width, image.height, num_channels};
TF_Tensor* image_tensor = TF_NewTensor(
TF_UINT8, dims, 4,
image.data, image.dataSize(),
TensorDeallocator, 0
);
TF_Operation* input_image_op = TF_GraphOperationByName(graph, "image_tensor");
if(!input_image_op) {
printf("Failed to find Op '%s'", "image_tensor");
return 1;
}
TF_Output image_input;
image_input.oper = input_image_op;
image_input.index = 0;
TF_Output inputs[1] = {image_input};
TF_Operation* num_detection_op = TF_GraphOperationByName(graph, "num_detections");
if(!num_detection_op) {
printf("Failed to find Op '%s'", "num_detections");
return 1;
}
TF_Output num_detection_output;
num_detection_output.oper = num_detection_op;
num_detection_output.index = 0;
TF_Output outputs[1] = {num_detection_output};
TF_Tensor* output_tensors[1];
TF_SessionOptions * options = TF_NewSessionOptions();
TF_Session* session = TF_NewSession( graph, options, status );
TF_SessionRun(session, 0,
&image_input, &image_tensor, 1,
outputs, output_tensors, 1,
0, 0,
0, status
);
if(TF_GetCode(status) != TF_OK) {
printf("%s\n", TF_Message(status));
}
else {
printf("Ran successfully\n");
float* f = (float*)TF_TensorData(output_tensors[0]);
printf("TF data %f\n", f[0]);
}
free(image.data);
return 0;
}
有效的python代码:
import data_helpers
import sys
import tensorflow as tf
import numpy as np
from tensorflow.python.platform import gfile
from tensorflow.python.util import compat
from tensorflow.core.protobuf import saved_model_pb2
def read_graph(model_filename):
with gfile.FastGFile(model_filename, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
g_in = tf.import_graph_def(graph_def)
return g_in
def printOps():
for op in tf.get_default_graph().get_operations():
print(op.name)
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: run_image_on_graph.py [input graph filepath] [output image filepath]")
exit(1)
graph_file = sys.argv[1]
image_file = sys.argv[2]
image = data_helpers.import_image(image_file)
with tf.Session() as sess:
read_graph(graph_file)
graph = tf.get_default_graph()
image_tensor = graph.get_tensor_by_name("import/image_tensor:0")
num_detections = graph.get_tensor_by_name("import/num_detections:0")
detection_scores = graph.get_tensor_by_name("import/detection_scores:0")
detection_boxes = graph.get_tensor_by_name("import/detection_boxes:0")
debug = graph.get_tensor_by_name("import/ToFloat:0")
image = np.array([data_helpers.import_image(image_file)])
print("sess = " + str(sess.run([num_detections], feed_dict={
image_tensor: image})
))
我的方法明显有什么问题吗?