Intentar simular una red neuronal en MATLAB por mí mismo

I tried to create a neural network to estimate y = x ^ 2. So I created a fitting neural network and gave it some samples for input and output. I tried to build this network in C++. But the result is different than I expected.

With the following inputs:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71

and the following outputs:

0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841 900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841 900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041

I used fitting tool network. with matrix rows. Training is 70%, validation is 15% and testing is 15% as well. The number of hidden neurons is two. Then in command lines I wrote this:

purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})

Otra información :

My net.b[1] is: -1.16610230053776 1.16667147712026

My net.b[2] is: 51.3266249426358

And net.IW(1) is: 0.344272596370387 0.344111217766824

net.LW(2) is: 31.7635369693519 -31.8082184881063

When my inputTest is 3, the result of this command is 16, while it should be about 9. Have I made an error somewhere?

I found the Stack Overflow post Red neuronal en MATLAB that contains a problem like my problem, but there is a little difference, and the differences is in that problem the ranges of input and output are same, but in my problem is no. That solution says I need to scale out the results, but how can I scale out my result?

preguntado el 31 de julio de 12 a las 13:07

@Georg : thank you for your response. as i told the question is when i write purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2}) the result should be 9. becuase "inputTest" is 9. but the result that i get is 16. my question is why this happened? beaucuse i try to approximate y = x ^ 2 -

Have you tried increasing the number of hidden nodes? -

i think you did'nt understand my question correctly. if i write net(inputTest) the result is near 9 like 9.03. but when i try to simulate the events that matlab do ( by that command : purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2}) ) the result is diffrent and i don't know why. -

i found the link ingrese la descripción del enlace aquí that contains a problem like my problem but there is a little diffrence, and the diffrences is in that problem the ranges of input and output are same but in my problem is no. That solution sais i need to scaled out results but i dont know how to scaled out my result. any idea? -

1 Respuestas

You are right about scaling. As was mentioned in the respuesta vinculada, the neural network by default scales the input and output to the range [-1,1]. This can be seen in the network processing functions configuration:

>> net = fitnet(2);

>> net.inputs{1}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

>> net.outputs{2}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

The second preprocessing function applied to both input/output is mapminmax con los siguientes parámetros:

>> net.inputs{1}.processParams{2}
ans =
    ymin: -1
    ymax: 1

>> net.outputs{2}.processParams{2}
ans =
    ymin: -1
    ymax: 1

to map both into the range [-1,1] (antes to training).

This means that the trained network expects input values in this range, and outputs values also in the same range. If you want to manually feed input to the network, and compute the output yourself, you have to scale the data at input, and reverse the mapping at the output.

One last thing to remember is that each time you train the ANN, you will get different weights. If you want reproducible results, you need to fix the state of the random number generator (initialize it with the same seed each time). Read the documentation on functions like rng y RandStream.

You also have to pay attention that if you are dividing the data into training/testing/validation sets, you must use the same split each time (probably also affected by the randomness aspect I mentioned).


Here is an example to illustrate the idea (adapted from otra publicación mía):

%%# data
x = linspace(-71,71,200);            %# 1D input
y_model = x.^2;                      %# model
y = y_model + 10*randn(size(x)).*x;  %# add some noise

%%# create ANN, train, simulate
net = fitnet(2);                     %# one hidden layer with 2 nodes
net.divideFcn = 'dividerand';
net.trainParam.epochs = 50;
net = train(net,x,y);
y_hat = net(x);

%%# plot
plot(x, y, 'b.'), hold on
plot(x, x.^2, 'Color','g', 'LineWidth',2)
plot(x, y_hat, 'Color','r', 'LineWidth',2)
legend({'data (noisy)','model (x^2)','fitted'})
hold off, grid on

%%# manually simulate network
%# map input to [-1,1] range
[~,inMap] = mapminmax(x, -1, 1);
in = mapminmax('apply', x, inMap);

%# propagate values to get output (scaled to [-1,1])
hid = tansig( bsxfun(@plus, net.IW{1}*in, net.b{1}) ); %# hidden layer
outLayerOut = purelin( net.LW{2}*hid + net.b{2} );     %# output layer

%# reverse mapping from [-1,1] to original data scale
[~,outMap] = mapminmax(y, -1, 1);
out = mapminmax('reverse', outLayerOut, outMap);

%# compare against MATLAB output
max( abs(out - y_hat) )        %# this should be zero (or in the order of `eps`)

Opté por usar el mapminmax function, but you could have done that manually as well. The formula is a pretty simply linear mapping:

y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;

Captura de pantalla

Respondido 15 Oct 21, 16:10

One comment, if you use the nftool GUI, you should choose the samples shape as "matrix columns" not "matrix rows" (each column is a sample) - Amro

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.