I'm working on a solution to do gesture recognition using the Kinect sensor.
Now I'm using Accord .NET to train the HMM.
I have a dataset with saved gestures. This dataset has 11 gestures and each one has 32 frames with 18 points saved.
So I have a (double [12] [32,18]) input dataset and a (int[12]) output dataset, but when i do:
double error = teacher.Run(inputSequences, output), it gives me this : "Specified argument was out of the range of valid values."
Does anyone knows how to solve this? Should treat the dataset before using it o on the hmm teacher or the dataset is ok like this?
I have used Accord.NET in the past and its really one of the best implementations for a HMM engine. However, when I trained my HMM, I passed the HMM parameters (namely PI, A and B) to the Baum Welch Teacher with the input data set supplied using an organized excel sheet. (similar to what Accord's author himself has used in his project). I somehow feel that since you are storing your data set as a multi-dimensional array and directly supplying it to the teacher, its unable to process it properly. Maybe you could supply one gesture record at a time or change the storage structure of your data set altogether. I advice going through the entire example of Accord if you haven't already because it worked just fine for me.
The problem might have been that the teaching algorithm expects the training sequences to be in the form double[12][32][18], rather than double[12][32,18]. The training data should be a collection of sequences of multivariate points. It should also be necessary to note that, if you have 11 possible classes of gestures, the integer labels given in the int[12] array should be comprised of values between 0 and 10 only.
Thus if you have 12 gesture samples, each containing 32 frames, and each frame is a vector of 18 points, you should be feeding the teacher with a double[12][32][18] array containing the observations and a int[12] array containing the expected class labels.
The example below, extracted from the HiddenMarkovClassifierLearning documentation page should help to give an idea how the vectors should be organized!
// 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 };
In the above code, we have set the problem for 2 sequences of observations, where each sequence containing 5 observations, and in which each observations is comprised of 2 values. As you can see, this is a double[2][5][2] array. The array of class labels is given by a int[2], containing only values ranging from 0 to 1.
Now, to make the example more complete, we can continue creating and training the model using the following code:
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);
And now we can test the model, asserting that the output class label indeed matches what we are expecting:
// 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);
Related
List<int[,]> table = new List<int[,]> { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
This isn't right, but I'm stumped on how to do it.
Basically in the end I want to say table[0] and get back the first tuple, table[2] and get back the second tuple, and so on.
What is the correct format (if I have the right data model) or the correct data structure for what I want to do?
I have a pretty hefty list of tuples in the above format, And I like to stay with the format if at all possible.
im trying to program an easy dice game for mobile in unity with c# (its called 10000, maybe you know it).
In the game you have 6 dices, you get when you roll for exapmle three times a 6 600 points for four times a 3 3000 points and so on.
Thats why i have to check if there are at least 3 dices with the same number, and with Mathf.Approximately
and a lot of if's the code would be really ugly and long.
So whats the easiest way to get around this problem?
// cubes values
int[] values = new int[6]
{
3, 4, 3, 6, 1, 3
};
// group values (key => value, value => count key)
var group = values.GroupBy(v => v);
// if there are 3 or more identical cubes
if (group.Any(g => g.Count() >= 3))
{
}
I am trying to make a Multi Label Support Vector Machine using Accord.NET framework (MultilabelSupportVectorMachine Class) but based on the example it's difficult to understand the encoding e.g.:
// Sample input data
double[][] inputs =
{
new double[] { 0 },
new double[] { 3 },
new double[] { 1 },
new double[] { 2 },
};
// Outputs for each of the inputs
int[][] outputs =
{
new[] { -1, 1, -1 },
new[] { -1, -1, 1 },
new[] { 1, 1, -1 },
new[] { -1, -1, -1 },
};
What if my output is a matrix which contains integer values not within the -1 and +1 range, what encoding should we use to convert the data into this format?
This is the format of the output the MultiLabelSupportVectorMachine would return if you compute something with it. MultiClassSupportVectorMachine returns a single int because it is used when you are sure that an example matches only a single class whereas MultiLabelSupportVectorMachine returns an array which shows which classes does the example match and is used when an example can match more classes.
It works like this:
The output array length is between 0(inclusive) and the number of classes. So if you have 4 classes you'll have an output array like this:
{ -1, -1, 1, -1 }
This means that the output class is 2, because the index of 1 is 2.
I hope that now you know how the output of this class works and that this gives you directions how to format your example output.
Additional info: If you want to use MultiLabelSupportVectorMachine, but you want to get only one output class you can just take the first index of 1 in the output array. I recommend this only if you are certain that One-Vs-All serves you better than One-Vs-One.
function [ samples,y, energies] = energy( speech, fs )
window_ms = 200;
threshold = 0.75;
window = window_ms*fs/1000;
speech = speech(1:(length(speech) - mod(length(speech),window)),1);
samples = reshape(speech,window,length(speech)/window);
energies = sqrt(sum(samples.*samples))';
vuv = energies > threshold;
y=vuv;
I have this matlab code and I need to write this code in c#. However I couldn't understand the last part of the code. Also i think speech corresponds to a data List or array according to first part of code. If it does not, please can someone explain what this code is doing. I just want to know logic. fs = 1600 or 3200;
The code takes an array representing a signal. It then breaks it into pieces according to a window of specified length, compute the energy in each segment, and finds out which segments have energy above a certain threshold.
Lets go over the code in more details:
speech = speech(1:(length(speech) - mod(length(speech),window)),1);
the above line is basically making sure that the input signal's length is a multiples of the window length. So say speech was an array of 11 values, and window length was 5, then the code would simply keep only the first 10 values (from 1 to 5*2) removing the last remaining one value.
The next line is:
samples = reshape(speech,window,length(speech)/window));
perhaps it is best explained with a quick example:
>> x = 1:20;
>> reshape(x,4,[])
ans =
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
so it reshapes the array into a matrix of "k" rows (k being the window length), and as many columns as needed to complete the array. So the first "K" values would be the first segment, the next "k" values are the second segment, and so on..
Finally the next line is computing the signal energy in each segment (in a vectorized manner).
energies = sqrt(sum(samples.*samples))';
List<int> speech = new List<int>();
int window = 0;
int length = speech.Count();
int result = length % window;
int r = length - result;
// speech = speech(1: r, 1)
This:
(length(speech) - mod(length(speech),window)
is a formula
([length of speech] - [remainder of (speech / window)])
so try
(length(speech) - (length(speech) % window))
% is the symbol equivalent to mod(..)
EDIT I should say that I assume that is what mod(..) is in your code :)
I currently have this function:
public double Max(double[] x, double[] y)
{
//Get min and max of x array as integer
int xMin = Convert.ToInt32(x.Min());
int xMax = Convert.ToInt32(x.Max());
// Generate a list of x values for input to Lagrange
double i = 2;
double xOld = Lagrange(xMin,x,y);
double xNew = xMax;
do
{
xOld = xNew;
xNew = Lagrange(i,x,y);
i = i + 0.01;
} while (xOld > xNew);
return i;
}
This will find the minimum value on a curve with decreasing slope...however, given this curve, I need to find three minima.
How can I find the three minima and output them as an array or individual variables? This curve is just an example--it could be inverted--regardless, I need to find multiple variables. So once the first min is found it needs to know how to get over the point of inflection and find the next... :/
*The Lagrange function can be found here.** For all practical purposes, the Lagrange function will give me f(x) when I input x...visually, it means the curve supplied by wolfram alpha.
*The math-side of this conundrum can be found here.**
Possible solution?
Generate an array of input, say x[1,1.1,1.2,1.3,1.4...], get an array back from the Lagrange function. Then find the three lowest values of this function? Then get the keys corresponding to the values? How would I do this?
It's been a while since I've taken a numerical methods class, so bear with me. In short there are a number of ways to search for the root(s) of a function, and depending on what your your function is (continuous? differentiable?), you need to choose one that is appropriate.
For your problem, I'd probably start by trying to use Newton's Method to find the roots of the second degree Lagrange polynomial for your function. I haven't tested out this library, but there is a C# based numerical methods package on CodePlex that implements Newton's Method that is open source. If you wanted to dig through the code you could.
The majority of root finding methods have cousins in the broader CS topic of 'search'. If you want a really quick and dirty approach, or you have a very large search space, consider something like Simulated Annealing. Finding all of your minima isn't guaranteed but it's fast and easy to code.
Assuming you're just trying to "brute force" calculate this to a certain level of prcision, you need your algorithm to basically find any value where both neighbors are greater than the current value of your loop.
To simplify this, let's just say you have an array of numbers, and you want to find the indices of the three local minima. Here's a simple algorithm to do it:
public void Test()
{
var ys = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4 };
var indices = GetMinIndices(ys);
}
public List<int> GetMinIndices(int[] ys)
{
var minIndices = new List<int>();
for (var index = 1; index < ys.Length; index++)
{
var currentY = ys[index];
var previousY = ys[index - 1];
if (index < ys.Length - 1)
{
var neytY = ys[index + 1];
if (previousY > currentY && neytY > currentY) // neighbors are greater
minIndices.Add(index); // add the index to the list
}
else // we're at the last index
{
if (previousY > currentY) // previous is greater
minIndices.Add(index);
}
}
return minIndices;
}
So, basically, you pass in your array of function results (ys) that you calculated for an array of inputs (xs) (not shown). What you get back from this function is the minimum indices. So, in this example, you get back 8, 14, and 17.