在Tensorflow C ++ API中为占位符张量提供值

时间:2017-07-12 10:10:13

标签: python c++ machine-learning tensorflow deep-learning

我使用(Tensorflow)Python API重新训练了Inception-v3模型,并通过修改tensorflow / tensorflow / examples / image_retraining / retrain.py并使用以下修改在.pb中保存了一个独立的Graph,以便在分类之前添加一个删除层层:

def nn_layer(input_tensor, input_dim, output_dim, layer_name, activation_name='activation', act=tf.nn.softmax):
# Adding a name scope ensures logical grouping of the layers in the graph.
with tf.name_scope(layer_name):
# This Variable will hold the state of the weights for the layer
with tf.name_scope('weights'):
weights = weight_variable([input_dim, output_dim])
variable_summaries(weights, layer_name + '/weights')
with tf.name_scope('dropout'):
keep_prob = tf.placeholder(tf.float32)
tf.scalar_summary('dropout_keep_probability', keep_prob)
drop = tf.nn.dropout(input_tensor, keep_prob)
variable_summaries(drop, layer_name + '/dropout')
with tf.name_scope('biases'):
biases = bias_variable([output_dim])
variable_summaries(biases, layer_name + '/biases')
preactivate = tf.matmul(drop, weights) + biases
tf.histogram_summary(layer_name + '/pre_activations', preactivate)
with tf.name_scope(activation_name):
activations = act(preactivate)
tf.histogram_summary(layer_name + '/activations', activations)
return preactivate, activations, keep_prob

在python中生成预测的代码如下:

softmax_tensor = sess.graph.get_tensor_by_name('final_layer/final_result/Softmax:0')
predictions = sess.run(softmax_tensor, { 'DecodeJpeg/contents:0':image_data, 'final_layer/dropout/Placeholder:0': 1.})

python代码的C ++对应部分如下:

string input_layer = "Mul";
string output_layer = "final_layer/dropout/Placeholder:0";
Status run_status = session->Run({{input_layer, resized_tensor}}, {output_layer}, {}, &outputs);

C ++代码最终会出现以下错误消息:

Running model failed: Invalid argument: You must feed a value for placeholder tensor 'final_layer/dropout/Placeholder'

我应该在上面的C ++代码中更改什么才能删除此错误?换句话说,如何在python代码中更改C ++代码中的占位符值。很多天以来我一直困在这个问题上。任何帮助将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

您的C ++代码与Python代码不同。

在python中你得到了

softmax_tensor = sess.graph.get_tensor_by_name('final_layer/final_result/Softmax:0')
predictions = sess.run(softmax_tensor, { 'DecodeJpeg/contents:0':image_data, 'final_layer/dropout/Placeholder:0': 1.})

因此,您的feed_dict{ 'DecodeJpeg/contents:0':image_data, 'final_layer/dropout/Placeholder:0': 1.}

表示:使用DecodeJpeg/contents:0覆盖image_data的值,并使用final_layer/dropout/Placeholder:0覆盖1.的值。

在C ++中,您得到了:

Status run_status = session->Run({{input_layer, resized_tensor}}, {output_layer}, {}, &outputs);

这个,你的feed_dict等价物是第一个输入参数,即:

{{input_layer, resized_tensor}}

这意味着:使用input_layer覆盖resized_tensor

第一个问题是您正在尝试覆盖节点Mul而不是上面的节点DecodeJpeg/contents:0

此外,缺少占位符的覆盖。

但是,你的C ++代码中有些混乱,因为你调用output_tensor实际上是placeholder

TL; DR

如果你的Python代码应该像

那样
Status run_status = session->Run({
    {"DecodeJpeg/contents", resized_tensor},
    {"final_layer/dropout/Placeholder", 1f}
}, {"final_layer/final_result/Softmax"}, {}, &outputs);

这意味着:

使用DecodeJpeg/contents覆盖resize_tensor的节点值。 用1覆盖final_layer/dropout/Placeholder的节点值。

获取节点final_layer/final_result/Softmax的值。 将结果放入outputs