How can I execute a TensorFlow graph from protobuf in C ++?

I have a simple tutorial on the code form and output it to a .pb file, as shown below:

mnist_softmax_train.py

x = tf.placeholder("float", shape=[None, 784], name='input_x') y_ = tf.placeholder("float", shape=[None, 10], name='input_y') W = tf.Variable(tf.zeros([784, 10]), name='W') b = tf.Variable(tf.zeros([10]), name='b') tf.initialize_all_variables().run() y = tf.nn.softmax(tf.matmul(x,W)+b, name='softmax') cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy, name='train_step') train_step.run(feed_dict={x:input_x, y_:input_y}) 

In C ++, I load the same graph and load fake data for testing:

 Tensor input_x(DT_FLOAT, TensorShape({10,784})); Tensor input_y(DT_FLOAT, TensorShape({10,10})); Tensor W(DT_FLOAT, TensorShape({784,10})); Tensor b(DT_FLOAT, TensorShape({10,10})); Tensor input_test_x(DT_FLOAT, TensorShape({1,784})); for(int i=0;i<10;i++){ for(int j=0;j<10;j++) input_x.matrix<float>()(i,i+j) = 1.0; input_y.matrix<float>()(i,i) = 1.0; input_test_x.matrix<float>()(0,i) = 1.0; } std::vector<std::pair<string, tensorflow::Tensor>> inputs = { { "input_x", input_x }, { "input_y", input_y }, { "W", W }, { "b", b }, { "input_test_x", input_test_x }, }; std::vector<tensorflow::Tensor> outputs; status = session->Run(inputs, {}, {"train_step"}, &outputs); std::cout << outputs[0].DebugString() << "\n"; 

However, this does not fail:

 Invalid argument: Input 0 of node train_step/update_W/ApplyGradientDescent was passed float from _recv_W_0:0 incompatible with expected float_ref. 

The graph works correctly in Python. How can I run it correctly in C ++?

+6
source share
1 answer

The problem is that you run the "train_step" target, which does a lot more work than just output. In particular, he is trying to update the variables W and b using the gradient descent step. Error message

 Invalid argument: Input 0 of node train_step/update_W/ApplyGradientDescent was passed float from _recv_W_0:0 incompatible with expected float_ref. 

... means that one of the nodes you tried to run ( "train_step/update_W/ApplyGradientDescent" ) was expecting a modified input (with type float_ref ), but it received immutable input (with type float ), because the value was loaded into .

There are (at least) two possible solutions:

  • If you want to see predictions for a given input and given weights, select "softmax:0" instead of "train_step" in the Session::Run() call.

  • If you want to be trained in C ++, do not feed W and b , but instead assign values ​​to these variables, and then continue with "train_step" . It may be easier for you to create tf.train.Saver when plotting in Python, and then call the operations it creates to save and restore values ​​from a breakpoint.

+5
source

All Articles