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

问题描述 投票:0回答:2

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

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++ 代码中的占位符值。我已经被这个问题困扰很多天了。任何帮助将不胜感激。

python c++ machine-learning tensorflow deep-learning
2个回答
2
投票

您的 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;博士

如果你的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


0
投票

要解决该错误,您需要在 C++ 代码中为占位符张量“final_layer/dropout/Placeholder”提供一个值,就像在 Python 代码中一样。

在 C++ 代码中,您使用

session->Run()
来执行模型。您需要传递一个类似字典的结构,其中包含占位符名称及其相应的值。以下是修改 C++ 代码以为 dropout 占位符提供值的方法:

string input_layer = "Mul";
string output_layer = "final_layer/dropout/Placeholder:0";

// Define the placeholder value
Tensor keep_prob(DT_FLOAT, TensorShape({}));
keep_prob.scalar<float>()() = 1.0; // Set the dropout keep probability here

// Run the session with the provided placeholder value
Status run_status = session->Run({{input_layer, resized_tensor}, {output_layer, keep_prob}}, {output_layer}, {}, &outputs);
© www.soinside.com 2019 - 2024. All rights reserved.