hamish
hamish

Reputation: 455

Execution error when calling Matlab compiled function from c#

I am using Matlab 2015a and have developed, trained and tested a classification ensemble (boosted tree) and saved the best trained model (.mat file).

As I wish to use this model in a .Net C# application I have create a .m file to load the .mat file containing the trained classifier and use it to predict an outcome based upon the features passed in (see code for .m file below).

function [ypredict score] = fnTrainedClassifer( input_args )
  load ('trainedClassifier.mat');
  [ypredict score] = predict(trainedClassifier,input_args);
end

I then used the Matlab compiler to create a .Net assembly and made sure to include the .mat file in the section for files required for your library to run. All good so far... I then created a quick C# console app to test the library (see code of the app below) and ran it.

using System;
using MathWorks.MATLAB.NET.Arrays;
using TrainedClassifierComp;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MLTestClass theModel = null;   /* Stores deployment class instance */
            MWStructArray inputs = null;   /* Sample input data */
            MWArray[] result = null;       /* Stores the result */
            MWNumericArray prediction = null;  /* Ouptut data extracted from result */
            MWNumericArray score = null;  /* Ouptut data extracted from result */

            /* Create the new deployment object */
            theModel = new MLTestClass();

            /* Create an MWStructArray */
            String[] myFieldNames = { "1", "2", "3", "4", "5", "6", "7", "8" };
            inputs = new MWStructArray(1, 8, myFieldNames);

            /* Populate struct with some sample inputs  */
            inputs["1", 1] = 1;
            inputs["2", 2] = 2;
            inputs["3", 3] = 3;
            inputs["4", 4] = 4;
            inputs["5", 5] = 5;
            inputs["6", 6] = 6;
            inputs["7", 7] = 7;
            inputs["8", 8] = 8;

            /* Show some of the sample data */
            Console.WriteLine("Inputs: ");
            Console.WriteLine(inputs.ToString());

            /* Pass it to a MATLAB function */
            result = theModel.fnTrainedClassifier(1, inputs);
            prediction = (MWNumericArray) result[0];
            score = (MWNumericArray)result[1];

            /* Show the results */
            Console.WriteLine("Prediction: ");
            Console.WriteLine(prediction.ToString());
            Console.WriteLine("Score: ");
            Console.WriteLine(prediction.ToString());
        }
    }
}

Unfortunately i come up with the following execution time error, which searching on Google bears no useful results:

Warning: Variable 'trainedClassifier' originally saved as a classreg.learning.classif.ClassificationEnsemble cannot be instantiated as an object and will be read in as a uint32. In fnTrainedClassifier (line 4) Error using predict (line 84) Systems of uint32 class cannot be used with the "predict" command. Convert the system to an identified model first, such as by using the "idss" command. Error in fnTrainedClassifier (line 5)

Any guidance on how to resolve this issue info on how you were able to achieve something similar would be greatly appreciated.

Additional Info: I have tried a couple of other AI systems e.g. neural network and I am having the same problem. It seems to me that I am not approaching this correctly - is there another way of using Matlab functions in external compiled languages such as c#?

Upvotes: 2

Views: 699

Answers (1)

Memin
Memin

Reputation: 4090

It has been a while the question asked, but I faced the same problem. I hope the following solution helps some to save some time. So, when a class object is loaded from a .mat file it seems Matlab compiler reads the class types but does not load the class itself. Therefore, somehow we need to add the class definition of instantiated object.

To force the compiler to load the required classes, I created an empty object of the class, then I loaded object from the .mat file and assigned it to the empty object. Your mat code should be something like following;

function [ypredict score] = fnTrainedClassifer( input_args )
     trainedClassifier = classreg.learning.classif.ClassificationEnsemble.empty; % only this line is added.
     load ('trainedClassifier.mat');
     [ypredict score] = predict(trainedClassifier,input_args);
end

Upvotes: 1

Related Questions