I am currently trying to develop a simple bayesian classifier. I run approximately (generally I have a couple of function that break the inference process in small steps- db object is a simple interface to the database that return int[] on all functions mentioned here ) the following code:
Variable<Vector> modelClassDistribution;
VariableArray<Vector>[] modelParams;
int tmp; // Infer.NET range for classes. Range modelClassRange = new Range(this.db.getClassCount()); // Put a Dirichlet prior on the class distribution. arrClassDist = this.db.getClassDistribution(this.trainDataset); for (tmp = 0; tmp < arrClassDist.Length; tmp++) arrClassDist[tmp] += 1.0; modelClassDistribution = Variable.Dirichlet(modelClassRange, arrClassDist); for (int i = 0; i < this.INT_FIELDS.Length; i++) { this.modelParams[ i ] = Variable.Array<Vector>(modelClassRange); arrFeatDist = this.db.getScalarFeatureDistribution(this.trainDataset, i); dir = new Dirichlet[arrFeatDist.Length]; for (tmp = 0; tmp < arrFeatDist.Length; tmp++) { for (j = 0; j < arrFeatDist[tmp].Length; j++) arrFeatDist[tmp][j] += 1.0; dir[tmp] = new Dirichlet(arrFeatDist[tmp]); prior = Variable.Constant(dir, modelClassRange); } using (Variable.ForEach(modelClassRange)) { this.modelParams[ i ][modelClassRange] = Variable.Random<Vector, Dirichlet>(prior[modelClassRange]); } }
int numTestpoints = 10;
// Infer.NET range for the datapoints. Range testDataRange = new Range(numTestpoints); VariableArray<int> testClasses = Variable.Array<int>(testDataRange); VariableArray<int>[] testFeat = new VariableArray<int>[this.INT_FIELDS.Length]; for (i = 0; i < this.INT_FIELDS.Length; i++) { testFeat[ i ] = Variable.Array<int>(testDataRange); }
// Infer.NET variable array for the labels. using (Variable.ForEach(testDataRange)) { testClasses[testDataRange] = Variable.Discrete(modelClassDistribution); }
for (i = 0; i < this.INT_FIELDS.Length; i++) { using (Variable.ForEach(testDataRange)) { using (Variable.Switch(testClasses[testDataRange])) { testFeat[ i ][testDataRange] = Variable.Discrete(this.modelParams[ i ][testClasses[testDataRange]]); } } }
for (i = 0; i < this.field_count; i++) { testFeat[ i ].ObservedValue = this.db.getFeatureData(i); } dist = ie.Infer<Discrete[]>(testClasses);
And I get the following error:
Compiling model...** (simpleBayes/bin/Debug/simpleBayes.exe:28682): WARNING **: Missing method System.Collections.Generic.ICollection`1.Contains in assembly /auto/homes/cr409/workspace/FlowClassifier/simpleBayes/simpleBayes/bin/Debug/Infer.Compiler.dll token a00007eUnhandled Exception: System.TypeLoadException: A type load exception has occurred. at #Bd.#QS.ConvertExpressionStatement (IBlockStatement bs, IExpressionStatement ies) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.DoConvertStatement (IBlockStatement bs, IStatement ist) [0x00000] at #Bd.#QS.DoConvertStatement (IBlockStatement bs, IStatement ist) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertStatement (IBlockStatement bs, IStatement ist, System.Object key) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertBlock (IBlockStatement outputBlock, IBlockStatement inputBlock, System.Object key) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertMethodBody (IMethodDeclaration md, IMethodDeclaration imd) [0x00000] at #Bd.#QS.ConvertMethodBody (IMethodDeclaration md, IMethodDeclaration imd) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertMethod (IMethodDeclaration md, IMethodDeclaration imd) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.DoConvertMethod (IMethodDeclaration imd, System.Object key) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertMethods (ITypeDeclaration td, ITypeDeclaration itd) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.ConvertType (System.Object owner, ITypeDeclaration td, ITypeDeclaration itd) [0x00000] at MicrosoftResearch.Transforms.CopyTransform.Transform (ITypeDeclaration itd) [0x00000] at MicrosoftResearch.Transforms.CodeTransformer.TransformToDeclaration (ITypeDeclaration typeDecl) [0x00000] at MicrosoftResearch.Transforms.TransformerChain.TransformToDeclaration (ITypeDeclaration itd, MicrosoftResearch.Transforms.AttributeRegistry`2 inputAttributes) [0x00000] at MicrosoftResearch.Infer.ModelCompiler.CompileWithoutParams (ITypeDeclaration itd, System.Reflection.MethodBase method, MicrosoftResearch.Transforms.AttributeRegistry`2 inputAttributes) [0x00000] at MicrosoftResearch.Infer.Models.ModelBuilder.Compile (MicrosoftResearch.Infer.InferenceEngine engine, Boolean checkParamsAreSet) [0x00000] at MicrosoftResearch.Infer.InferenceEngine.GetCompiledInferenceAlgorithm (IEnumerable`1 vars, Boolean checkParamsAreSet, Boolean inferOnlySpecifiedVars) [0x00000] at MicrosoftResearch.Infer.InferenceEngine.InferAll (Boolean inferOnlySpecifiedVars, IEnumerable`1 vars) [0x00000] at MicrosoftResearch.Infer.InferenceEngine.Infer (IVariable var) [0x00000] at MicrosoftResearch.Infer.InferenceEngine.Infer[Object] (IVariable var) [0x00000] at simpleBayes.Program.testModel () [0x00000] at simpleBayes.Program.run () [0x00000] at simpleBayes.Program.Main (System.String[] args) [0x00000]
Does this error comes from my code or is it an error on mono? The same code ruyns perfectly on Visual Studio, but I need to run this program on a linux platform.
Hi hrotsos,
this is a variant of the Mono bug detailed in the user guide: https://bugzilla.novell.com/show_bug.cgi?id=439125 generic methods where constraints have generic parameters.
When Infer is called using Discrete[] as the Generic parameter.
However, the following both work in Mono
var dist = ie.Infer<DistributionArray<Discrete, int>>(testClasses);
var dist = ie.Infer(testClasses);
Hope this helps. It's the best work around until the Mono bug is fixed,
cheers,
Elise
problem solved finally by using the latest version of mono for the svn. Fedora distributions seems to have a very bad support for mono. Thank you for the help.