我正在研究使用Kinect传感器进行手势识别的解决方案。 现在我正在使用Accord .NET来训练HMM。 我有一个保存手势的数据集。该数据集有11个手势,每个手势有32个帧,保存18个点。
所以我有一个(双[12] [32,18])输入数据集和一个(int [12])输出数据集,但当我这样做时: double error = teacher.Run(inputSequences,output),它给出了这个:“指定的参数超出了有效值的范围。”
有谁知道如何解决这个问题?应该在使用它之前对数据集进行处理o在hmm教师上还是数据集是这样的吗?
答案 0 :(得分:1)
我过去使用过Accord.NET,它确实是HMM引擎的最佳实现之一。然而,当我训练我的HMM时,我将HMM参数(即PI,A和B)传递给Baum Welch教师,其输入数据集使用有组织的excel表提供。 (类似于雅阁的作者自己在他的项目中使用的)。我不知何故觉得,由于您将数据集存储为多维数组并直接将其提供给教师,因此无法正确处理它。也许您可以一次提供一个手势记录或完全更改数据集的存储结构。如果您还没有,我建议您浏览整个雅阁的例子,因为它对我来说效果很好。
答案 1 :(得分:0)
问题可能是教学算法希望训练序列采用 double[12][32][18]
的形式,而不是 double[12][32,18]
。训练数据应该是多变量点序列的集合。还需要注意的是,如果你有11种可能的手势类,int[12]
数组中给出的整数标签应该只包含0到10之间的值。
因此,如果您有12个手势样本,每个样本包含32个帧,并且每个帧是18个点的向量,您应该向教师提供包含观察结果的double[12][32][18]
数组和int[12]
包含预期类标签的数组。
从HiddenMarkovClassifierLearning documentation page中提取的以下示例应该有助于了解如何组织向量!
// Create a Continuous density Hidden Markov Model Sequence Classifier
// to detect a multivariate sequence and the same sequence backwards.
double[][][] sequences = new double[][][]
{
new double[][]
{
// This is the first sequence with label = 0
new double[] { 0, 1 },
new double[] { 1, 2 },
new double[] { 2, 3 },
new double[] { 3, 4 },
new double[] { 4, 5 },
},
new double[][]
{
// This is the second sequence with label = 1
new double[] { 4, 3 },
new double[] { 3, 2 },
new double[] { 2, 1 },
new double[] { 1, 0 },
new double[] { 0, -1 },
}
};
// Labels for the sequences
int[] labels = { 0, 1 };
在上面的代码中,我们设定了2个观测序列的问题,其中每个序列包含5个观测值,其中每个观测值由2个值组成。如您所见,这是一个双[2] [5] [2]数组。类标签数组由int [2]给出,仅包含0到1之间的值。
现在,为了使示例更加完整,我们可以使用以下代码继续创建和训练模型:
var initialDensity = new MultivariateNormalDistribution(2);
// Creates a sequence classifier containing 2 hidden Markov Models with 2 states
// and an underlying multivariate mixture of Normal distributions as density.
var classifier = new HiddenMarkovClassifier<MultivariateNormalDistribution>(
classes: 2, topology: new Forward(2), initial: initialDensity);
// Configure the learning algorithms to train the sequence classifier
var teacher = new HiddenMarkovClassifierLearning<MultivariateNormalDistribution>(
classifier,
// Train each model until the log-likelihood changes less than 0.0001
modelIndex => new BaumWelchLearning<MultivariateNormalDistribution>(
classifier.Models[modelIndex])
{
Tolerance = 0.0001,
Iterations = 0,
FittingOptions = new NormalOptions()
{
Diagonal = true, // only diagonal covariance matrices
Regularization = 1e-5 // avoid non-positive definite errors
}
}
);
// Train the sequence classifier using the algorithm
double logLikelihood = teacher.Run(sequences, labels);
现在我们可以测试模型,断言输出类标签确实符合我们的预期:
// Calculate the probability that the given
// sequences originated from the model
double likelihood, likelihood2;
// Try to classify the 1st sequence (output should be 0)
int c1 = classifier.Compute(sequences[0], out likelihood);
// Try to classify the 2nd sequence (output should be 1)
int c2 = classifier.Compute(sequences[1], out likelihood2);