我希望能够使用tensorflowsharp在IIS之上使用dnnclassifier(估计器)。该模型先前已在python中进行过训练。到目前为止,我现在可以生成PB文件,知道正确的输入/输出,但是我陷入了使用字符串输入的tensorflowsharp问题。
我可以创建虹膜数据集的有效.pb文件。它使用以下feate_spec:
{'SepalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'SepalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None)}
我创建了一个简单的c#控制台来尝试旋转它。输入应为“ input_example_tensor”,输出应位于“ dnn / head / predictions / probability”中。在alex_zu使用save_model_cli命令here提供帮助之后,我发现了这一点。
据我所知,所有tensorflow估计器API的工作都是这样的。
问题来了:input_example_tensor应该是一种字符串格式,该字符串格式将由ParseExample函数在内部进行解析。现在我被困住了。我已经找到TFTensor.CreateString,但这不能解决问题。
using System;
using TensorFlow;
namespace repository
{
class Program
{
static void Main(string[] args)
{
using (TFGraph tfGraph = new TFGraph()){
using (var tmpSess = new TFSession(tfGraph)){
using (var tfSessionOptions = new TFSessionOptions()){
using (var metaGraphUnused = new TFBuffer()){
//generating a new session based on the pb folder location with the tag serve
TFSession tfSession = tmpSess.FromSavedModel(
tfSessionOptions,
null,
@"path/to/model/pb",
new[] { "serve" },
tfGraph,
metaGraphUnused
);
//generating a new runner, which will fetch the tensorflow results later
var runner = tfSession.GetRunner();
//this is in the actual tensorflow documentation, how to implement this???
string fromTensorflowPythonExample = "{'SepalLength': [5.1, 5.9, 6.9],'SepalWidth': [3.3, 3.0, 3.1],'PetalLength': [1.7, 4.2, 5.4],'PetalWidth': [0.5, 1.5, 2.1],}";
//this is the problem, it's not working...
TFTensor rawInput = new TFTensor(new float[4]{5.1f,3.3f,1.7f,0.5f});
byte[] serializedTensor = System.Text.Encoding.ASCII.GetBytes(rawInput.ToString());
TFTensor inputTensor = TensorFlow.TFTensor.CreateString (serializedTensor);
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];
//printing response to the client
Console.WriteLine(result.ToString());
Console.ReadLine();
}
}
}
}
}
}
}
此示例将出现以下错误:
An unhandled exception of type 'TensorFlow.TFException' occurred in TensorFlowSharp.dll: 'Expected serialized to be a vector, got shape: []
[[Node: ParseExample/ParseExample = ParseExample[Ndense=4, Nsparse=0, Tdense=[DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT], dense_shapes=[[1], [1], [1], [1]], sparse_types=[], _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_input_example_tensor_0_0, ParseExample/ParseExample/names, ParseExample/ParseExample/dense_keys_0, ParseExample/ParseExample/dense_keys_1, ParseExample/ParseExample/dense_keys_2, ParseExample/ParseExample/dense_keys_3, ParseExample/Const, ParseExample/Const, ParseExample/Const, ParseExample/Const)]]'
如何以可以正确使用pb文件的方式序列化张量?
我还在github上发布了此问题,在这里您可以找到鸢尾花示例python文件,pb文件和控制台应用程序。我认为解决方案会产生一个 适用于所有拥有古老生产环境(如我)的tensorflow用户的灵巧解决方案。
答案 0 :(得分:0)
可以通过使用Expected serialized to be a vector, got shape: []
函数的重载来解决TFTensor.CreateString
错误:该模型显然不希望直接获取字符串,而是期望一个包含单个字符串的向量:
TFTensor inputTensor = TFTensor.CreateString(new byte[][] { bytes }, new TFShape(1));
在您的情况下,input_example_tensor
现在期望序列化的Example
原始消息(另请参见the docs和the example.proto文件)。
使用protobuf编译器,我生成了一个包含Example
类的C#文件。您可以从这里下载:https://pastebin.com/iLT8MUdR。具体来说,我将此online tool与CSharpProtoc
一起使用,并用that file中定义的消息替换了import "tensorflow/core/example/feature.proto";
行。
将文件添加到项目后,您将需要引用Google.Protobuf
的程序包。然后,您可以将序列化的示例传递给模型,如下所示:
Func<float, Tensorflow.Feature> makeFeature = (float x) => {
var floatList = new Tensorflow.FloatList();
floatList.Value.Add(x);
return new Tensorflow.Feature { FloatList = floatList };
};
var example = new Tensorflow.Example { Features = new Tensorflow.Features() };
example.Features.Feature.Add("SepalLength", makeFeature(5.1f));
example.Features.Feature.Add("SepalWidth", makeFeature(3.3f));
example.Features.Feature.Add("PetalLength", makeFeature(1.7f));
example.Features.Feature.Add("PetalWidth", makeFeature(0.5f));
TFTensor inputTensor = TFTensor.CreateString(
new [] { example.ToByteArray() }, new TFShape(1));
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];