我正在尝试导入一个在Keras/Tensorflow中创建的模型,并将其用于Unity项目中的推理。
我已经成功地导入了模型,并通过在图形中打印输入和输出节点的名称进行了验证。但是,当我尝试从运行器获取输出值时,我得到了这个异常。
TFException:正在尝试使用未初始化的值action_W [[Node:_device="/job:localhost/replica:0/task:0/cpu:0"]] _W/_class== IdentityT=DT_FLOAT,_class="loc:@action_W",action TensorFlow.TFStatus.CheckMaybeRaise (TensorFlow.TFStatus incomingStatus,System.Boolean last) (at <6ed6db22f8874deba74ffe3e566039be>:0) TensorFlow.TFSession.Run (TensorFlow.TFOutput[] inputs,TensorFlow.TFTensor[] inputValues,TensorFlow.TFOutput[] outputs,TensorFlow.TFOperation[] targetOpers,TensorFlow.TFBuffer,,)输入状态) (at <6ed6db22f8874deba74ffe3e566039be>:0) TensorFlow.TFSession+Runner.Run (TensorFlow.TFStatus status) (at <6ed6db22f8874deba74ffe3e566039be>:0) RecordArbitraryData.ModelPredict (System.Single,TensorFlow.TFStatus ) (at Assets/Scripts/Spells/RecordArbitraryData.cs:230) RecordArbitraryData.FixedUpdate () (at Assets/Scripts/Spells/RecordArbitraryData.cs:95)
下面是我使用的两个函数。在我的unity脚本中,InstantiateModel被称为OnStart()。当用户将输入传递给脚本时,将调用ModelPredict。
void InstantiateModel(){
string model_name = "simple_as_binary";
//Instantiate Graph
graphModel = Resources.Load (model_name) as TextAsset;
graph = new TFGraph ();
graph.Import (graphModel.bytes);
session = new TFSession (graph);
}
void ModelPredict(float[,] input){
using (graph) {
using (session) {
//Assign input tensors
var runner = session.GetRunner ();
runner.AddInput (graph [input_node_name] [0], input);
//Calculate and access output of graph
runner.Fetch (graph[output_node_name][0]);
Debug.Log ("Output node name: " + graph [output_node_name].Name);
float[,] recurrent_tensor = runner.Run () [0].GetValue () as float[,];
//var results = runner.Run();
//Debug.Log("Prediciton: " + results);
}
}
}感谢任何帮助- TensorflowSharp对我来说是非常新的。
发布于 2018-04-19 11:59:11
我能够解决我的大部分问题。我目前的模型是统一预测的,但只预测了四个类中的第一个类。我的猜测是,这与没有从检查点文件中正确初始化权重有关?编辑:我的值在传递到神经网络之前没有被标准化。
前言:Mozilla Firefox最适合显示tensorboard;我花了很长时间才意识到google chrome导致我的图形不可见(tensorboard是我能够找出需要用于输入和输出的节点的方式)。
第一期:我正在将一个.pb文件重命名为一个.bytes文件。这是不正确的,因为模型的权重来自检查点文件,并被赋予.pb文件中保存的节点。这是导致变量未初始化的原因。这些变量用于训练,在使用freeze_graph函数后将其删除。
第二个问题:我使用的是创建的名为‘checkpoint’的文件,它抛出了一个错误。然后,我将检查点的名称更改为“test”,并在freeze_graph函数中使用此名称。调用检查点文件时,我被要求使用‘test.ckpt’。我假设这个函数知道根据.ckpt自动抓取这三个文件?没有“.ckpt”的“‘Test”不起作用。
第三个问题:当使用freeze_graph函数时,我需要用text=False导出keras/tf中的.pb文件。我测试了True和False;True抛出了一个关于“错误连接”的错误。
第四期:Tensorboard在没有任何组织的情况下很难使用。使用tf.name_scope不仅在可视化方面有很大帮助,而且确保我在TensorFlowSharp中使用/引用了正确的节点。在keras中,我发现将最终的密集层和激活分离到它们自己的作用域中是很有帮助的,这样我就可以找到正确的输出节点。我的网络的其余部分被放在一个‘body’作用域中,并且是‘input’作用域中的唯一输入层。name_scope函数在节点名前面加上‘scopename/’。我不认为这是必要的,但它对我有帮助。
第五期:tensorflowsharp作为统一包发布的版本不是最新的。这导致‘keras _training_phase’的keras占位符出现问题。在keras中,您可以将其与+ input之类的输入一起传递。我试图通过创建一个新的TFTensor(bool)来做同样的事情,但是我得到了一个错误‘由于它的保护级别而无法访问。在我的unity TensorFlowSharp版本中,bool和TFTensor之间的隐式转换是一个错误。为了解决这个问题,我必须使用在这个stackoverflow solution中找到的一个函数,在这个函数中,.bytes文件被读入,keras_training_phase的占位符被找到,并被换出为设置为false的布尔常量。这对我来说很有效,因为我的模型是用python预先训练的,所以对于试图训练和测试模型的人来说,这可能不是一个很好的修复方法。使用freeze_graph函数删除此节点的条件将非常有用。
希望有人觉得这篇文章有用!
https://stackoverflow.com/questions/49583240
复制相似问题