tutorial neural network learning example code and matlab neural-network

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:

  1. Inicialización inicial de la red neuronal.
  2. Normalización de datos
  3. 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.