0

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

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

其中 num_labels = 8

我正在使用来自这里的 GPU 库https://github.com/Microsoft/CNTK/wiki/NuGet-Package从 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);

谢谢

4

3 回答 3

1

CopyVariableValueTo 将存储在 Value 对象中的数据复制到提供的缓冲区中,可以采用密集(缓冲区为 List>)或 one-hot 矢量格式(缓冲区为 List>)。作为输出的 one-hot 向量格式要求每个样本只有 1 个非零值。如果输出包含多个非 zeor 值,则应使用密集输出。有关 API 的更多详细信息,请参见此处

谢谢,周

于 2017-01-20T15:49:48.400 回答
0

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

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

outputVal.CopyVariableValueTo(outputVar, outputBuffer);

CopyVariableTo() 将存储在 Value 对象中的数据复制到缓冲区中,作为具有可变长度样本的序列列表,采用 denst 格式或 one-hot 矢量格式。outputVar表示将数据从此 Value 复制到 outputBuffer 时的形状和动态。outputBuffer是一个可变长度的序列列表外部序列列表中包含的项目数是 Value 中的序列数。外部列表的每个元素代表一个序列。每个由 List 表示的序列都包含可变数量的样本。每个样本由固定数量的类型为 T 的元素组成。样本的元素数量由 sampleVariable 的形状决定。您可以找到有关 API 的详细信息这里

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

谢谢

于 2017-01-18T09:07:20.133 回答
0

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

于 2017-01-27T21:19:25.633 回答