我正在尝试重写 python 代码,以便mnist_client
到 c++。由于我是张量流和 TF 服务的新手,所以我遇到了一些困难。我浏览了教程和 c++ 客户端示例 (inception_client
(。 Pythonmnist_client
没有任何问题,但是当我运行我的 c++ 客户端时,它给了我arg[0] is not a matrix
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)]]
我按照教程中的方式训练了模型,并检查了我读取的最小数据是否正常。
由此: 张量流参数无效:In[0] 不是矩阵, 我知道MatMul
至少需要 2 暗的数据。但是,我浏览了inception_client
和 pythonmnist_client
的 c++ 代码,并将图像数据读取到 1 点字符数组中...... 我在这里错过了什么?
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]))
正如预期的那样,修复是显而易见的。 所有需要做的是添加另一个维度:
proto.mutable_tensor_shape()->add_dim()->set_size(image_size);
以获得[image_size,1]
形状。