nok / sklearn-porter

Transpile trained scikit-learn estimators to C, Java, JavaScript and others.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MLPClassifier does not reset network value producing wrong predictions when doing continuous prediction

julian-ramos opened this issue · comments

Hi, Great work with Porter really helpful!

The next is a small issue but one that took me a good time to debug so here I wanted to post as both a problem and a possible solution that seems to work for me.

I have been porting an MLPClassifier to android, everything seemed fine except that in java desktop tests the classifier worked fine but in android would usually produce not completely wrong but slightly off values. I kept running tests and found that the way MLPClassifier is implemented currently in Java stores the input values of the network in the object every time a prediction is made, what this means is that if the method .predict is run once any subsequent call will reuse values that were changed inside the network, with this I do not mean the weights but the actual input values and any subsequent estimations. This does not produce very different results but slightly off which makes it very hard to debug, initially, I thought this may have been just a rounding numbers issue. Also when running desktop tests you may run the suggested terminal test which inputs a single value, and hence this problem is impossible to catch that way as it only appears when you call .predict multiple times sequentially.

A way to fix this issue is by adding a method that resets the network values to zero.

public void reset(){
        //Cleans up the network values
        for (int i=0;i<this.network.length;i++){
            for (int i2=0;i2<this.network[i].length;i2++){
                this.network[i][i2]=0;
            }
        }
    }

The solution above has the caveat that it will assign a value of zero to the input values used in .predict since predict does not copy the values but instead uses a pointer.

Although deleting the MLPClassifier is another option or creating a new this.network is possible it may be much slower.

Hope this helps other people and if you have a better solution please let me know.

@julian-ramos, thanks a lot for sharing your insights and proposed solution.

And I quite agree. We should reset the internal conditions after each inference.