Я пытаюсь переписать код Python для mnist_client
на с ++. Поскольку я новичок в tenorflow и TF, у меня возникли некоторые трудности. Я прошел учебники и пример клиента C ++ (inception_client
).
питон mnist_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)]]
Я обучил модель, как в учебнике, и проверил, что самые мелкие данные, которые я прочитал, в порядке.
Из этого:
tenorflow Неверный аргумент: в [0] нет матрицы ,
я понимаю MatMul
нужны как минимум 2-мерные данные. Но я прошел через код C ++ для inception_client
и питон mnist_client
и оба читают данные изображения в массив 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]))
Как и ожидалось, исправление было очевидным.
Все, что нужно было сделать, это добавить другое измерение:
proto.mutable_tensor_shape()->add_dim()->set_size(image_size);
получить [image_size,1]
форма.
Других решений пока нет …