Search code examples
c++neural-networkfann

C++ FANN fann_run always produce same output


I am using the FANN Library to build neural networks to proceed a regression problem. The thing is, once the networks has been trained on the relevant training set (which seems to work quite well), every single test output the exact same output. In other words, given any state of my 16 predictive variables, my predicted output, according the the ANN, is the same.

My guess would be that the network is correctly computing the first line of the calculation, then always outputs this result on other calculations, no matter what I feed it (as it seems to do very well on the first training example, giving an accurate prediction).

For instance, my first training example variables are:

1 1 13.5 13.5 13.5 14.5 14.4 14.3 14.3 14.2 14.5 13 11.7 12.2 12.2 11.3 

My target output is 14.5, and on each test, the network outputs something between 14.69 and 14.7 (due to small calculation times and as I am only playing with the package, I train it each time I run the code). So, this output seems completely legitimate with that set of data.

The thing is, when I try to run it on several other inputs, I always get that same 14.69/14.7 (identical output on even the smallest digit).

Since the network seems to be correctly processing the training example, learning the relationship and calculatting correctly on ONE new test example, I tend to believe that all the training part is correct. Since there is no reason the network would always output the same value, my guess is that my way of testing it is not correct.

My question is: what is the exact syntax to test a FANN neural network on a new dataset? and, how do I print/save the corresponding outputs?

Here is the current state of my code:

fann_type *calc_out;
fann_type input[16];

for (int i = 0; i < 20; i++)
{
    if (!rowHasNA(timeSerie, i))
    {
        cout << "Input : ";
        for (int j = 1; j < 17; j++)
        {
            input[j - 1] = timeSerie(i, j);
            cout << input[j - 1] << " ";
        }
        cout << endl;
        calc_out = fann_run(ann, input);
        cout << "Input " << i << " gives : " << calc_out[0] << endl;
    }
}

Where:

  • rowHasNA is a custom function I used to determine whether my example has at least one NA
  • ann is a fann* which has already been trained
  • timeSerie is a matrix<double> where each line is a test example

I am still a bit confused on how the FANN package works, since I have found no really clear documentation on how to train networks and test them. I struggle to understand how the fann_type works.

Thank you in advance.


Solution

  • To whom it may concern.

    The code which is written above is correct: in a case where the network has been properly trained, it manages to output different values for different inputs.

    The main problem was to train the network. As it gave me a correct answer (14.7, which was very close to the expected 14.5), I assumed it had been properly trained. Actually, it was not, and was kind of giving the "best mean value" corresponding to the training targets. As my training set has very little variance, always outputting the same value, no matter what input is fed, was giving a decent MSE (though, way worse than what I had in R and Octave, but as I never had used FANN I did not know what to expect).

    The solution is simple, and I should have thought about it earlier : feature scaling.

    I assumed that the package was proceeding to feature scaling on its own, given some litterature I had came accross on the Internet. With the most basic code to train networks, feature scaling is not applied to training sets.

    I recommand a feature scaling between 0 and 1 (x - min / max - min).