/// <summary> /// Constructs a multi-component Bayes Point Machine using shared variables for chunking data /// </summary> /// <param name="nClass">Number of components (classes)</param> /// <param name="nFeatures">Number of features</param> /// <param name="noisePrec">Noise precision</param> /// <param name="trainChunkSize">Chunk size for training</param> /// <param name="testChunkSize">Chunk size for testing</param> public BPM_Shared(int nClass, int nFeatures, double noisePrec, int trainChunkSize, int testChunkSize) { this.nClass = nClass; this.nFeatures = nFeatures; this.trainChunkSize = trainChunkSize; this.testChunkSize = testChunkSize; NoisePrec = noisePrec; feature = new Range(nFeatures).Named("feature"); // The set of weight vectors (one for each component) are shared between all data chunks w = new SharedVariable<Vector>[nClass]; VectorGaussian wPrior0 = VectorGaussian.PointMass(Vector.Zero(nFeatures)); VectorGaussian wPrior = VectorGaussian.FromMeanAndPrecision(Vector.Zero(nFeatures), PositiveDefiniteMatrix.Identity(nFeatures)); for (int c = 0; c < nClass; c++) { w[c] = (c == 0) ? SharedVariable<Vector>.Random(VectorGaussian.PointMass(Vector.Zero(nFeatures))).Named("w_" + c) : SharedVariable<Vector>.Random(wPrior).Named("w_" + c); } trainModel = SpecifyTrainModel("_train", trainChunkSize); testModel = SpecifyTestModel("_test", testChunkSize); }
/// <summary> /// Specify the training model /// </summary> /// <param name="s">The name of the training model</param> /// <param name="nChunks">The number of chunks</param> /// <returns>A <see cref="BPMVarsModelForTrain"/> instance</returns> private BPMVarsModelForTrain SpecifyTrainModel(string s, int nChunks) { // An array of feature vectors - their observed values will be // set by the calling program VariableArray<Vector>[] xValues = new VariableArray<Vector>[nClass]; // The number of items for each component Variable<int>[] nItem = new Variable<int>[nClass]; // Ranges over the items for each component Range[] item = new Range[nClass]; // The model identifier for the shared variables Model model = new Model(nChunks).Named("model" + s); // The weight vector within a submodel Variable<Vector>[] wModel = new Variable<Vector>[nClass]; for (int c = 0; c < nClass; c++) { // Get a copy of the shared weight vector variable for the submodel wModel[c] = w[c].GetCopyFor(model).Named("wModel_" + c + s); } // Loop over the components for (int c = 0; c < nClass; c++) { // The number of items for each component - set by the calling program nItem[c] = Variable.New<int>().Named("nItem_" + c + s); // The item range for each component item[c] = new Range(nItem[c]).Named("item_" + c + s); // The items for each component - set by the calling program xValues[c] = Variable.Array<Vector>(item[c]); using (Variable.ForEach(item[c])) { // The score for this item across all components Variable<double>[] score = BPMUtils.ComputeClassScores(wModel, xValues[c][item[c]], NoisePrec); // The constraint imposed by the observed component BPMUtils.ConstrainArgMax(c, score); } } // Store the variables BPMVarsModelForTrain bpmVar = new BPMVarsModelForTrain(); bpmVar.ie = new InferenceEngine(); bpmVar.xValues = xValues; bpmVar.nItems = nItem; bpmVar.model = model; return bpmVar; }