Click or drag to resize
Accord.NET (logo)

HiddenConditionalRandomFieldT Class

Hidden Conditional Random Field (HCRF).
Inheritance Hierarchy
SystemObject
  Accord.MachineLearningTransformBaseT, Int32
    Accord.MachineLearningClassifierBaseT, Int32
      Accord.MachineLearningMulticlassClassifierBaseT
        Accord.Statistics.Models.FieldsHiddenConditionalRandomFieldT

Namespace:  Accord.Statistics.Models.Fields
Assembly:  Accord.Statistics (in Accord.Statistics.dll) Version: 3.5.0
Syntax
[SerializableAttribute]
public class HiddenConditionalRandomField<T> : MulticlassClassifierBase<T[]>, 
	ICloneable
Request Example View Source

Type Parameters

T
The type of the observations modeled by the field.

The HiddenConditionalRandomFieldT type exposes the following members.

Constructors
  NameDescription
Public methodHiddenConditionalRandomFieldT
Initializes a new instance of the HiddenConditionalRandomFieldT class.
Top
Properties
  NameDescription
Public propertyFunction
Gets the potential function encompassing all feature functions for this model.
Public propertyNumberOfInputs
Gets the number of inputs accepted by the model.
(Inherited from TransformBaseTInput, TOutput.)
Public propertyNumberOfOutputs
Gets the number of outputs generated by the model.
(Inherited from TransformBaseTInput, TOutput.)
Public propertyOutputs Obsolete.
Gets the number of outputs assumed by the model.
Top
Methods
  NameDescription
Public methodClone
Creates a new object that is a copy of the current instance.
Public methodCompute(T) Obsolete.
Computes the most likely output for the given observations.
Public methodCompute(T, Double) Obsolete.
Computes the most likely output for the given observations.
Public methodCompute(T, Double) Obsolete.
Computes the most likely output for the given observations.
Public methodDecide(TInput)
Computes class-label decisions for a given set of input vectors.
(Inherited from ClassifierBaseTInput, TClasses.)
Public methodDecide(T)
Computes a class-label decision for a given input.
(Overrides ClassifierBaseTInput, TClassesDecide(TInput).)
Public methodDecide(TInput, TClasses)
Computes a class-label decision for a given input.
(Inherited from ClassifierBaseTInput, TClasses.)
Public methodDecide(TInput, Boolean)
Computes class-label decisions for the given input.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodDecide(TInput, Double)
Computes class-label decisions for the given input.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodDecide(TInput, Int32)
Computes class-label decisions for the given input.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodDecide(TInput, Double)
Computes a class-label decision for a given input.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodDecode(T, Int32)
Computes the most likely state labels for the given observations, returning the overall sequence probability for this model.
Public methodDecode(T, Int32, Double)
Computes the most likely state labels for the given observations, returning the overall sequence probability for this model.
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodStatic memberLoad(Stream) Obsolete.
Loads a random field from a stream.
Public methodStatic memberLoad(String) Obsolete.
Loads a random field from a file.
Public methodLogLikelihood(T, Int32)
Computes the log-likelihood that the given observations belong to the desired output.
Public methodLogLikelihood(T, Int32)
Computes the log-likelihood that the given observations belong to the desired outputs.
Public methodLogLikelihood(T, Int32, Double)
Computes the log-likelihood that the given observations belong to the desired output.
Public methodLogLikelihood(T, Int32, Double)
Computes the log-likelihood that the given observations belong to the desired outputs.
Public methodLogPartition(T)
Computes the log-partition function ln Z(x).
Public methodLogPartition(T, Int32)
Computes the log-partition function ln Z(x,y).
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodPartition(T)
Computes the partition function Z(x).
Public methodPartition(T, Int32)
Computes the partition function Z(x,y).
Public methodSave(Stream) Obsolete.
Saves the random field to a stream.
Public methodSave(String) Obsolete.
Saves the random field to a stream.
Public methodToMultilabel
Views this instance as a multi-label classifier, giving access to more advanced methods, such as the prediction of one-hot vectors.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodTransform(TInput)
Applies the transformation to an input, producing an associated output.
(Inherited from ClassifierBaseTInput, TClasses.)
Public methodTransform(TInput)
Applies the transformation to a set of input vectors, producing an associated set of output vectors.
(Inherited from TransformBaseTInput, TOutput.)
Public methodTransform(TInput, TClasses)
Applies the transformation to an input, producing an associated output.
(Inherited from ClassifierBaseTInput, TClasses.)
Public methodTransform(TInput, Boolean)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Double)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Int32)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Boolean)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Double)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Double)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Public methodTransform(TInput, Int32)
Applies the transformation to an input, producing an associated output.
(Inherited from MulticlassClassifierBaseTInput.)
Top
Extension Methods
  NameDescription
Public Extension MethodHasMethod
Checks whether an object implements a method with the given name.
(Defined by ExtensionMethods.)
Public Extension MethodIsEqual
Compares two objects for equality, performing an elementwise comparison if the elements are vectors or matrices.
(Defined by Matrix.)
Public Extension MethodToTOverloaded.
Converts an object into another type, irrespective of whether the conversion can be done at compile time or not. This can be used to convert generic types to numeric types during runtime.
(Defined by ExtensionMethods.)
Public Extension MethodToTOverloaded.
Converts an object into another type, irrespective of whether the conversion can be done at compile time or not. This can be used to convert generic types to numeric types during runtime.
(Defined by Matrix.)
Top
Remarks

Conditional random fields (CRFs) are a class of statistical modeling method often applied in pattern recognition and machine learning, where they are used for structured prediction. Whereas an ordinary classifier predicts a label for a single sample without regard to "neighboring" samples, a CRF can take context into account; e.g., the linear chain CRF popular in natural language processing predicts sequences of labels for sequences of input samples.

While Conditional Random Fields can be seen as a generalization of Markov models, Hidden Conditional Random Fields can be seen as a generalization of Hidden Markov Model Classifiers. The (linear-chain) Conditional Random Field is the discriminative counterpart of the Markov model. An observable Markov Model assumes the sequences of states y to be visible, rather than hidden. Thus they can be used in a different set of problems than the hidden Markov models. Those models are often used for sequence component labeling, also known as part-of-sequence tagging. After a model has been trained, they are mostly used to tag parts of a sequence using the Viterbi algorithm. This is very handy to perform, for example, classification of parts of a speech utterance, such as classifying phonemes inside an audio signal.

References:

Examples

In this example, we will create a sequence classifier using a hidden Markov classifier. Afterwards, we will transform this Markov classifier into an equivalent Hidden Conditional Random Field by choosing a suitable feature function.

// Let's say we would like to do a very simple mechanism for
// gesture recognition. In this example, we will be trying to
// create a classifier that can distinguish between the words
// "hello", "car", and "wardrobe". 

// Let's say we decided to acquire some data, and we asked some
// people to perform those words in front of a Kinect camera, and,
// using Microsoft's SDK, we were able to captured the x and y
// coordinates of each hand while the word was being performed.

// Let's say we decided to represent our frames as:
// 
//    double[] frame = { leftHandX, leftHandY, rightHandX, rightHandY };
// 
// Since we captured words, this means we captured sequences of
// frames as we described above. Let's write some of those as 
// rough examples to explain how gesture recognition can be done:

double[][] hello =
{
    new double[] { 1.0, 0.1, 0.0, 0.0 }, // let's say the word
    new double[] { 0.0, 1.0, 0.1, 0.1 }, // hello took 6 frames
    new double[] { 0.0, 1.0, 0.1, 0.1 }, // to be recorded.
    new double[] { 0.0, 0.0, 1.0, 0.0 },
    new double[] { 0.0, 0.0, 1.0, 0.0 },
    new double[] { 0.0, 0.0, 0.1, 1.1 },
};

double[][] car =
{
    new double[] { 0.0, 0.0, 0.0, 1.0 }, // the car word
    new double[] { 0.1, 0.0, 1.0, 0.1 }, // took only 4.
    new double[] { 0.0, 0.0, 0.1, 0.0 },
    new double[] { 1.0, 0.0, 0.0, 0.0 },
};

double[][] wardrobe =
{
    new double[] { 0.0, 0.0, 1.0, 0.0 }, // same for the
    new double[] { 0.1, 0.0, 1.0, 0.1 }, // wardrobe word.
    new double[] { 0.0, 0.1, 1.0, 0.0 },
    new double[] { 0.1, 0.0, 1.0, 0.1 },
};

// Here, please note that a real-world example would involve *lots*
// of samples for each word. Here, we are considering just one from
// each class which is clearly sub-optimal and should _never_ be done
// on practice. For example purposes, however, please disregard this.

// Those are the words we have in our vocabulary:
// 
double[][][] words = { hello, car, wardrobe }; 

// Now, let's associate integer labels with them. This is needed
// for the case where there are multiple samples for each word.
// 
int[] labels = { 0, 1, 2 };


// We will create our classifiers assuming an independent
// Gaussian distribution for each component in our feature
// vectors (like assuming a Naive Bayes assumption).

var initial = new Independent<NormalDistribution>
(
    new NormalDistribution(0, 1), 
    new NormalDistribution(0, 1), 
    new NormalDistribution(0, 1), 
    new NormalDistribution(0, 1)  
);


// Now, we can proceed and create our classifier. 
// 
int numberOfWords = 3;  // we are trying to distinguish between 3 words
int numberOfStates = 5; // this value can be found by trial-and-error

var hmm = new HiddenMarkovClassifier<Independent<NormalDistribution>>
(
    classes: numberOfWords, 
    topology: new Forward(numberOfStates), // word classifiers should use a forward topology
    initial: initial
);

// Create a new learning algorithm to train the sequence classifier
var teacher = new HiddenMarkovClassifierLearning<Independent<NormalDistribution>>(hmm,

    // Train each model until the log-likelihood changes less than 0.001
    modelIndex => new BaumWelchLearning<Independent<NormalDistribution>>(hmm.Models[modelIndex])
    {
        Tolerance = 0.001,
        Iterations = 100,

        // This is necessary so the code doesn't blow up when it realize
        // there is only one sample per word class. But this could also be
        // needed in normal situations as well.
        // 
        FittingOptions = new IndependentOptions()
        {
            InnerOption = new NormalOptions() { Regularization = 1e-5 }
        }
    }
);

// Finally, we can run the learning algorithm!
double logLikelihood = teacher.Run(words, labels);

// At this point, the classifier should be successfully 
// able to distinguish between our three word classes:
// 
int tc1 = hmm.Compute(hello);    // should be 0
int tc2 = hmm.Compute(car);      // should be 1
int tc3 = hmm.Compute(wardrobe); // should be 2


// Now, we can use the Markov classifier to initialize a HCRF
var function = new MarkovMultivariateFunction(hmm);
var hcrf = new HiddenConditionalRandomField<double[]>(function);

// We can check that both are equivalent, although they have
// formulations that can be learned with different methods
// 
for (int i = 0; i < words.Length; i++)
{
    // Should be the same
    int expected = hmm.Compute(words[i]);
    int actual = hcrf.Compute(words[i]);

    // Should be the same
    double h0 = hmm.LogLikelihood(words[i], 0);
    double c0 = hcrf.LogLikelihood(words[i], 0);

    double h1 = hmm.LogLikelihood(words[i], 1);
    double c1 = hcrf.LogLikelihood(words[i], 1);

    double h2 = hmm.LogLikelihood(words[i], 2);
    double c2 = hcrf.LogLikelihood(words[i], 2);
}


// Now we can learn the HCRF using one of the best learning
// algorithms available, Resilient Backpropagation learning:

// Create a learning algorithm
var rprop = new HiddenResilientGradientLearning<double[]>(hcrf)
{
    Iterations = 50,
    Tolerance = 1e-5
};

// Run the algorithm and learn the models
double error = rprop.Run(words, labels);

// At this point, the HCRF should be successfully 
// able to distinguish between our three word classes:
// 
int hc1 = hcrf.Compute(hello);    // Should be 0
int hc2 = hcrf.Compute(car);      // Should be 1
int hc3 = hcrf.Compute(wardrobe); // Should be 2

In order to see how this HCRF can be trained to the data, please take a look at the HiddenResilientGradientLearningT page. Resilient Propagation is one of the best algorithms for HCRF training.

See Also