2017-08-02 14 views
0

我正在尝试将C++的mnist_client的python代码重写。由于我对tensorflow和TF服务不熟悉,所以我遇到了一些困难。我浏览了教程和C++客户端示例(inception_client)。 Python的mnist_client作品没有任何问题,但是当我跑我的C++客户端它给我的arg[0] is not a matrix将mnist客户端重写为C++(arg [0]不是矩阵)

gRPC call return code: 3: In[0] is not a matrix 
[[Node: MatMul = MatMul[T=DT_FLOAT, _output_shapes=[[?,10]], transpose_a=false, transpose_b=false, _device="/job:localhost/replica:0/task:0/cpu:0"](_arg_x_0_0, Variable/read)]] 

我训练的模型在教程和我检查,我读了minst数据是确定的。

来自: tensorflow Invalid argument: In[0] is not a matrix, 我知道MatMul需要至少2-dim数据。但是,我通过了inception_client和python mnist_client的C++代码,并且都将图像数据读入1-dim char数组... 我在这里丢失了什么?

inception_client代码:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/example/inception_client.cc

任何帮助将非常感激。 :)

class ServingClient{ 
public: 
ServingClient(std::shared_ptr<Channel> channel) : stub_(PredictionService::NewStub(channel)){} 

tensorflow::string callPredict(const tensorflow::string &model_name, 
           const tensorflow::string &model_signature, 
           const int num_tests){ 
PredictRequest request; 
PredictResponse response; 
ClientContext context; 
int image_size; 
int image_offset = 16; 
int label_offset = 8; 

request.mutable_model_spec()->set_name(model_name); 
request.mutable_model_spec()->set_signature_name(model_signature); 

google::protobuf::Map<tensorflow::string, tensorflow::TensorProto> &inputs = *request.mutable_inputs(); 

std::fstream imageFile("t10k-images-idx3-ubyte", std::ios::binary | std::ios::in); 
std::fstream labelFile("t10k-labels-idx1-ubyte", std::ios::binary | std::ios::in); 

labelFile.seekp(0); 
imageFile.seekp(0); 

uint32_t magic_number_images; 
uint32_t nImages; 
uint32_t magic_number_labels; 
uint32_t rowsI =0; 
uint32_t rowsL =0; 
uint32_t colsI = 0; 
uint32_t colsL = 0; 


imageFile.read((char *)&magic_number_images, sizeof(magic_number_images)); 
imageFile.read((char *)&nImages, sizeof(nImages)); 
imageFile.read((char *)(&rowsI), sizeof(rowsI)); 
imageFile.read((char *)&colsI, sizeof(colsI)); 

image_size = ReverseInt(rowsI) * ReverseInt(colsI); 

labelFile.read((char *)&magic_number_labels, sizeof(magic_number_labels)); 
labelFile.read((char *)&rowsL, sizeof(rowsL)); 

for(int i=0; i<num_tests; i++){ 
    tensorflow::TensorProto proto; 

    labelFile.seekp(label_offset); 
    imageFile.seekp(image_offset); 

    //read mnist image 
    char *img = new char[image_size](); 
    char label = 0; 
    imageFile.read((char *)img, image_size); 

    image_offset += image_size; 
    //read label 
    labelFile.read(&label, 1); 
    label_offset++; 

    //predict 
    proto.set_dtype(tensorflow::DataType::DT_STRING); 
    proto.add_string_val(img, image_size); 
    proto.mutable_tensor_shape()->add_dim()->set_size(1); 
    inputs["images"] = proto; 

    Status status = stub_->Predict(&context, request, &response); 
    delete[] img; 

    if(status.ok()){ 
    std::cout << "status OK." << std::endl; 
    OutMap &map_outputs = *response.mutable_outputs(); 
    OutMap::iterator iter; 
    int output_index = 0; 

    for(iter = map_outputs.begin(); iter != map_outputs.end(); ++iter){ 
     tensorflow::TensorProto &result_tensor_proto = iter->second; 
     tensorflow::Tensor tensor; 
     //check if response converted succesfully 
     bool converted = tensor.FromProto(result_tensor_proto); 
     if (converted) { 
      std::cout << "the result tensor[" << output_index << "] is:" << std::endl 
         << tensor.SummarizeValue(10) << std::endl; 
     } 
     else { 
      std::cout << "the result tensor[" << output_index 
         << "] convert failed." << std::endl; 
     } 
     ++output_index; 
       } 
     } 
    else{ 
     std::cout << "gRPC call return code: " << status.error_code() << ": " 
      << status.error_message() << std::endl; 
      } 
     } 
imageFile.close(); 
labelFile.close(); 
} 

private: 
    std::unique_ptr<PredictionService::Stub> stub_; 

}; 

编辑1:我认为这个问题必须在模型中是如何创建的,哪些方面是客户端发送的数据。 我用火车和出口这台尺寸模型所提供的Python程序:

feature_configs = {'x': tf.FixedLenFeature(shape=[784], dtype=tf.float32),} 
tf_example = tf.parse_example(serialized_tf_example, feature_configs) 
x = tf.identity(tf_example['x'], name='x') # use tf.identity() to assign name 
y_ = tf.placeholder('float', shape=[None, 10]) 
w = tf.Variable(tf.zeros([784, 10])) 
b = tf.Variable(tf.zeros([10])) 

回答

0

正如预期的那样,该修补程序是显而易见的。 所有这一切都必须做的是增加另一个维度:

proto.mutable_tensor_shape()->add_dim()->set_size(image_size); 

得到[image_size,1]形状。