我们正在使用针对CNTK的C#API构建LSTM网络,但根据CNTK文档的当前水平,很难确定输入的正确形状/尺寸。
我们有一个在每个时间t都有一个值(一个数字)的时间序列,我们想使用该时间序列的先前744个值的序列来使用LSTM进行预测。此外,我们是否想制作一个具有25个序列的微型批处理,其CNTK.InputVariable的形状应如下所示:
[0] 744
[1] 1
[2] 25
或
[0] 1
[1] 744
[2] 25
…然后,如果我们不是在每个时间t都有一个值,而是有两个值,那么CNTK.InputVariable形状将如何?
答案 0 :(得分:0)
如果使用递归网络(LSTM,GRU),则需要知道什么是静态轴和动态轴。
静态轴用于描述输入数据形式(在第一种情况下,它是等级1和大小1:new int {1}
的向量)。
动态轴用于指定输入数据(在您的情况下为new int {1}
)的顺序(在您的情况下为744,可变长度)。为了指示应将动态轴用于序列,请在输入参数 dynamicAxes中指定此轴: new[] { Axis.DefaultBatchAxis() }
var inputDimension = 1; //for two values is 2 etc.
var inputShape = new { inputDimension };
var input = Variable.InputVariable(inputShape, DataType.Double, "input", new[] { Axis.DefaultBatchAxis() });
并确保正确准备小批处理(创建一个小批处理的示例):
var device = DeviceDescriptor.CPUDevice;
var inputDimension = 1;
var outputDimension = 1;
var minibatchSize = 25;
var oneMinibatchFeaturesData = new List<List<double[]>>(minibatchSize)
{
new List<double[]> //first sequence
{
new double[] { 23 },//t=1. Array.Length = inputDimension
new double[] { 25 },//t=2
//...
new double[] { 65 },//t=744
},
new List<double[]> //second seqeunce
{
new double[] { 76 }, //t=1
new double[] { 236 },//t=2
//...
new double[] { 87 }, //t=744
},
//...
new List<double[]> //twenty fifth sequence
{
new double[] { 9 }, //t=1
new double[] { 2 },//t=2
//...
new double[] { 90 }, //t=744
},
};
var oneMinibatchLabelsData = new List<double[]>(minibatchSize)
{
new double[] { 1 },//label of first sequence. Array.Length = outputDimension
new double[] { 5 },//label of second sequence
//...
new double[] { 3 }//label of twenty fifth sequence
};
var features = Value.CreateBatchOfSequences(new[] { inputDimension }, oneMinibatchFeaturesData.Select(sequence => sequence.SelectMany(value => value)), device);
var labels = Value.CreateBatch(new[] { outputDimension }, oneMinibatchLabelsData.SelectMany(value => value), device);
序列的长度可以是任意的。一个小批量可以包含不同长度的序列。
LSTM很难训练这种长度的序列。如果序列的长度始终是744,那么您可能应该使用输入尺寸为744的简单FNN。答案 1 :(得分:0)
我建议对CNTK读者进行深入研究!
@Stanislav Grigorev是正确的。
输入维度完全取决于您的数据集。例如,此处示例中的ATIS如下所示:
可以在here中找到代码示例。
使用读取器读取数据:
IList<StreamConfiguration> streamConfigurations = new StreamConfiguration[]
{
new StreamConfiguration(featuresName, inputDim, true, "S0"),
// new StreamConfiguration(featuresName, inputDim, true, "S1"), // Not used in the old example.
new StreamConfiguration(labelsName, numOutputClasses, false, "S2")
};
以及使用TextFormatMinibatchSource的读数:
var minibatchSource = MinibatchSource.TextFormatMinibatchSource(
Path.Combine(DataFolder, "Train.ctf"),
streamConfigurations,
MinibatchSource.InfinitelyRepeat,
true);
var featureStreamInfo = minibatchSource.StreamInfo(featuresName);
var labelStreamInfo = minibatchSource.StreamInfo(labelsName);
然后在while循环中一行:
var minibatchData = minibatchSource.GetNextMinibatch(minibatchSize, device);
读取每个小批量。这对于任何阅读代码的人来说都是显而易见的,但是为了说明读取数据的方式,我提供了这个示例。
数据集参数在代码示例中给出:
const int inputDim = 2000;
const int numOutputClasses = 5;
这些数字正确无误很重要!
我已经建立了一个网站:http://www.cntking.com/,试图使C#和CNTK运转起来,我认为它是一种被低估的机器学习语言C#。