CNTK.GPU管理C#Eval API:调用outputVal.CopyVariableValueTo时的System.Runtime.InteropServices.SEHException

时间:2017-01-18 01:00:25

标签: c# .net cntk

我训练了一个模型,通过抓取序列中最后一个单词的标签来标记序列:

Sequential([
            Embedding(emb_dim),
            cntk.ops.sequence.last(Recurrence(LSTM(hidden_dim), go_backwards=False)), 
            Dense(num_labels)
        ])

其中num_labels = 8

我正在使用这里的https://github.com/Microsoft/CNTK/wiki/NuGet-Package GPU库来使用C#(CNTK v2.0.beta8.0)中的模型:

Variable outputVar = modelFunc.Outputs.Single(); 
var outputDataMap = new Dictionary<Variable, Value>();
outputDataMap.Add(outputVar, null);
modelFunc.Evaluate(inputDataMap, outputDataMap, device);
Value outputVal = outputDataMap[outputVar];

而outputVal是: 尺寸:计数= 3 等级:3 TotalSize:8

而outputVar是: 尺寸:计数= 1 等级:1 TotalSize:8

以上是否正确?我希望outputVar和outputVal具有相同的Dimensions / Rank / TotalSize。 另外,如何提取返回的类?基本上我应该为outputData使用什么C#类型?我尝试了两个嵌套列表,如github上的示例,但没有任何运气。 outputVal.CopyVariableValueTo(outputVar,outputData);

谢谢

3 个答案:

答案 0 :(得分:1)

CopyVariableValueTo将存储在Value对象中的数据复制到提供的缓冲区中,密集(缓冲区为List&gt;)或单热矢量格式(缓冲区为List&gt;)。作为输出的单热矢量格式要求每个样本仅具有1个非零值。如果输出包含多个非zeor值,则应使用密集输出。有关API的更多详细信息,请here

谢谢, 周

答案 1 :(得分:0)

是的,这是正确的。变量的形状基本上是张量形状,但Value对象的形状通常包含2个额外的维度:一个是序列轴,另一个是批处理轴,因为Value对象可以表示一批多个序列,每个序列具有可变长度样本。每个样本的形状应与Variable的形状相同。在您的情况下,似乎您在输出中只有1个样本,因此序列和批处理长度为1(您可以检查outputVal.Shape.Dimensions 1和[2]),并且TotalSize是相同的作为outputVar.Shape.TotalSize。

要从Value中提取数据,您可以使用

outputVal.CopyVariableValueTo(outputVar, outputBuffer);

CopyVariableTo()将存储在Value对象中的数据复制到缓冲区中,作为具有可变长度样本的序列列表,可以是denst格式,也可以是单热矢量格式。 outputVar 表示将数据从此Value复制到 outputBuffer 时的形状和动态轴。 outputBuffer 是具有可变长度的序列列表。外部序列列表中包含的项目数是值中的序列数。外部列表的每个元素代表一个序列。由List表示的每个序列包含可变数量的样本。每个样本由固定数量的元素T组成。样本的元素数量由sampleVariable的形状决定。您可以找到有关API here

的详细信息

使用outputVal.CopyVariableValueTo(outputVar,outputData)时遇到什么问题;?

由于

答案 2 :(得分:0)

CopyVaraibleTo()有两个变体,一个是使用密集格式输出,另一个是使用单热矢量格式。对于单热的vecotr格式,CopyVariableValueTo要求输出中的每个样本只有1个非零值,否则抛出异常。 Beta 9具有更好的异常处理功能,可提供更精确的异常信息。你能试一下吗?