neural - Simular defaultnet con feedforwardnet en Matlab?
neural network toolbox matlab download (2)
Como suele ser habitual, la red no se comporta de forma absolutamente igual en cada entrenamiento. Puede depender de tres (es decir, sé tres) razones:
- Inicialización inicial de la red neuronal.
- Normalización de datos
- Escalado de datos
Si hablar sobre (1) la red se configura inicialmente con pesos aleatorios, en un rango pequeño con diferentes signos. Por ejemplo, una neurona con 6 entradas puede obtener pesos iniciales como este: 0.1, -0.3, 0.16, -0.23, 0.015, -0.0005. Y esto puede conducir a un poco más de otro resultado de entrenamiento. Si hablar sobre (2) si su normalización se realiza de manera deficiente, el algoritmo de aprendizaje converge a mínimos locales y no puede salirse de él. Lo mismo se aplica al caso (3) si sus datos necesitan escalado, y usted no lo hizo.
Obtuve una eficiencia de entrenamiento muy diferente con la siguiente red
net = patternnet(hiddenLayerSize);
y el siguiente
net = feedforwardnet(hiddenLayerSize, ''trainscg'');
net.layers{1}.transferFcn = ''tansig'';
net.layers{2}.transferFcn = ''softmax'';
net.performFcn = ''crossentropy'';
en los mismos datos.
Pensaba que las redes deberían ser iguales.
¿Qué cosa olvidé?
ACTUALIZAR
El siguiente código demuestra que el comportamiento de la red depende exclusivamente de la función de creación de red.
Cada tipo de red se ejecutó dos veces. Esto excluye problemas de generador aleatorio o algo así. Los datos son iguales.
hiddenLayerSize = 10;
% pass 1, with patternnet
net = patternnet(hiddenLayerSize);
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
[net,tr] = train(net,x,t);
y = net(x);
performance = perform(net,t,y);
fprintf(''pass 1, patternnet, performance: %f/n'', performance);
fprintf(''num_epochs: %d, stop: %s/n'', tr.num_epochs, tr.stop);
% pass 2, with feedforwardnet
net = feedforwardnet(hiddenLayerSize, ''trainscg'');
net.layers{1}.transferFcn = ''tansig'';
net.layers{2}.transferFcn = ''softmax'';
net.performFcn = ''crossentropy'';
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
[net,tr] = train(net,x,t);
y = net(x);
performance = perform(net,t,y);
fprintf(''pass 2, feedforwardnet, performance: %f/n'', performance);
fprintf(''num_epochs: %d, stop: %s/n'', tr.num_epochs, tr.stop);
% pass 1, with patternnet
net = patternnet(hiddenLayerSize);
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
[net,tr] = train(net,x,t);
y = net(x);
performance = perform(net,t,y);
fprintf(''pass 3, patternnet, performance: %f/n'', performance);
fprintf(''num_epochs: %d, stop: %s/n'', tr.num_epochs, tr.stop);
% pass 2, with feedforwardnet
net = feedforwardnet(hiddenLayerSize, ''trainscg'');
net.layers{1}.transferFcn = ''tansig'';
net.layers{2}.transferFcn = ''softmax'';
net.performFcn = ''crossentropy'';
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
[net,tr] = train(net,x,t);
y = net(x);
performance = perform(net,t,y);
fprintf(''pass 4, feedforwardnet, performance: %f/n'', performance);
fprintf(''num_epochs: %d, stop: %s/n'', tr.num_epochs, tr.stop);
La salida sigue:
pass 1, patternnet, performance: 0.116445
num_epochs: 353, stop: Validation stop.
pass 2, feedforwardnet, performance: 0.693561
num_epochs: 260, stop: Validation stop.
pass 3, patternnet, performance: 0.116445
num_epochs: 353, stop: Validation stop.
pass 4, feedforwardnet, performance: 0.693561
num_epochs: 260, stop: Validation stop.
Parece que esos dos no son lo mismo:
>> net = patternnet(hiddenLayerSize);
>> net2 = feedforwardnet(hiddenLayerSize,''trainscg'');
>> net.outputs{2}.processParams{2}
ans =
ymin: 0
ymax: 1
>> net2.outputs{2}.processParams{2}
ans =
ymin: -1
ymax: 1
El net.outputs{2}.processFcns{2}
es mapminmax
así que mapminmax
que uno de estos es volver a escalar su salida para que coincida mejor con el rango de salida de sus datos reales.
Para referencia futura, puede hacer cosas desagradables y sucias como comparar las estructuras de datos interiores al enviar a struct. Entonces hice algo como
n = struct(net); n2 = struct(net2);
for fn=fieldnames(n)'';
if(~isequaln(n.(fn{1}),n2.(fn{1})))
fprintf(''fields %s differ/n'', fn{1});
end
end
para ayudar a identificar las diferencias.