Discusión sobre el artículo "Redes neuronales: así de sencillo (Parte 51): Actor-crítico conductual (BAC)"

 

Artículo publicado Redes neuronales: así de sencillo (Parte 51): Actor-crítico conductual (BAC):

Los dos últimos artículos han considerado el algoritmo SAC (Soft Actor-Critic), que incorpora la regularización de la entropía en la función de la recompensa. Este enfoque equilibra la exploración del entorno y la explotación del modelo, pero solo es aplicable a modelos estocásticos. El presente material analizará un enfoque alternativo aplicable tanto a modelos estocásticos como deterministas.

En primer lugar, reflexionaremos sobre la necesidad de la exploración del entorno en general. Creo que todo el mundo estará de acuerdo con la necesidad de este proceso, pero, ¿para qué en concreto y en qué fase?

Empezaremos con un ejemplo sencillo. Imaginemos que entramos por primera vez en una especie de habitación con 3 puertas idénticas y necesitamos hallar la salida a la calle. ¿Qué hacemos? Abriremos las puertas una a una hasta encontrar la correcta. Cuando volvamos a entrar en la misma habitación, para salir al exterior ya no abriremos todas las puertas, sino que iremos directamente a la salida, que ya conocemos. Si en esta situación tenemos una tarea diferente, entonces existirán varias opciones. Podemos volver a abrir todas las puertas, salvo la salida, que ya conocemos, y buscar la correcta. O bien podemos recordar qué puertas hemos abierto antes al buscar la salida y pensar si entre ellas estaba la correcta. Si recordamos la puerta correcta, nos dirigiremos a ella. En caso contrario, comprobaremos las puertas que no se hayan abierto antes.

Conclusión: la exploración del entorno es necesaria para, en un estado desconocido, seleccionar la acción correcta. Una vez hayamos encontrado la ruta necesaria, la exploración adicional del entorno solo podrá entorpecer el camino.

No obstante, puede que necesitemos investigar más el entorno cuando cambiemos la tarea en un estado conocido. Aquí se podría incluir la búsqueda de una ruta mejor: por ejemplo, en el caso de atravesar algunas habitaciones más para salir en la historia anterior, o si saliéramos por el lado equivocado del edificio.

De ahí que necesitemos un algoritmo que aumente la exploración del entorno en los estados inexplorados y la minimice en los estados previamente explorados.

Autor: Dmitriy Gizlyk

 
#¡Disfruta! <3

Gracias Señor @Dmitriy

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CreateDescriptions(CArrayObj *actor, CArrayObj *critic, CArrayObj *autoencoder)
{
--- Declaración de impresión inteligente para depuración
Print("Creando descripciones de capa...");
CLayerDescription *descr;
int layerNumber = 0; Para llevar la cuenta de los números de capa
--- Comprobar e inicializar las matrices de entrada si son nulas
if (!actor)
{
actor = new CArrayObj();
si (!actor)
return false;
}
if (!critic)
{
critic = new CArrayObj();
if (!critic)
return false;
}
if (!autoencoder)
{
autoencoder = new CArrayObj();
if (!autoencoder)
return false;
}
--- Actor
actor. Clear();
--- Capa 1: Capa de entrada
layerNumber++;
Print("Creando actor - Capa de entrada ", layerNumber, ": Capa de entrada");
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBaseOCL;
int prev_count = descr.count = (HistoryBars * BarDescr);
descr.activation = None
descr.optimisation = ADAM;
if (!actor. Add(descr))
{
borrar descr;
return false;
}
--- Capa 2
layerNumber++;
Print("Creando actor - Capa de normalización por lotes ", layerNumber);
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBatchNormOCL;
descr.count = prev_count;
descr.batch = 1000;
descr.activation = None
descr.optimización = ADAM;
if (!actor. Add(descr))
{
borrar descr;
return false;
}
--- Capa 3
layerNumber++;
Print("Creando actor - Capa Convolucional ", layerNumber);
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronConvOCL;
prev_count = descr.count = prev_count - 1;
descr.window = 2;
descr.step = 1;
descr.window_out = 8;
descr.activación = LReLU;
descr.optimización = ADAM;
si (!actor. Add(descr))
{
borrar descr;
return false;
}
--- Capa 4
layerNumber++;
Print("Creando actor - Capa Convolucional ", layerNumber);
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronConvOCL;
prev_count = descr.count = prev_count;
descr.window = 8;
descr.paso = 8
descr.window_out = 8;
descr.activación = LReLU;
descr.optimización = ADAM;
si (!actor. Add(descr))
{
borrar descr;
return false;
}
--- Capa 5
layerNumber++;
Print("Creando actor - Capa Densa/Base ", layerNumber);
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.optimización = ADAM;
descr.activation = LReLU;
if (!actor. Add(descr))
{
borrar descr;
return false;
}
--- Capa 6
layerNumber++;
Print("Creando actor - Capa Densa/Base ", layerNumber);
if (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = 1024;
descr.activación = LReLU;
descr.optimisation = ADAM;
if (!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 7
layerNumber++;
Print("Creando actor - Capa SoftMax ", layerNumber);
if(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronSoftMaxOCL;
prev_count = descr.count = prev_count / 16;
descr.paso = 16;
descr.optimización = ADAM;
descr.activation = None;
if(!actor.Add(descr))
{
elimina descr;
return false;
}
//--- Capa de atención multicapa 8
layerNumber++;
Print("Creando actor - Capa de Atención Multicapa ", layerNumber);
if(!(descr = new CLayerDescription()))
return false
descr.type = defNeuronMLMHAttentionOCL;
descr.count = prev_count;
descr.window = 16
descr.window_out = 8;
descr.step = 4
descr.capas = 3;
descr.optimización = ADAM;
descr.activación = None;
if(!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 9
layerNumber++;
Print("Creando actor - Concatenar capa ", layerNumber);
if (!(descr = new CLayerDescription()))
return false
descr.type = defNeuronConcatenate;
descr.count = LatentCount;
descr.ventana = recuento_previo;
descr.paso = AccountDescr;
descr.optimización = ADAM;
descr.activación = SIGMOID;
if (!actor.Add(descr))
{
elimina descr;
return false;
}
//--- Capa 10
layerNumber++;
Print("Creando actor - Capa SoftMax ", layerNumber);
if(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronSoftMaxOCL;
prev_count = descr.count = prev_count / 16;
descr.paso = 16;
descr.optimización = ADAM;
descr.activation = None;
if(!actor.Add(descr))
{
elimina descr;
return false;
}
//--- Capa de Atención Multicapa 11
layerNumber++;
Print("Creando actor - Capa de Atención Multicapa ", layerNumber);
if(!(descr = new CLayerDescription()))
return false
descr.type = defNeuronMLMHAttentionOCL;
descr.count = prev_count;
descr.window = 16
descr.window_out = 8;
descr.step = 4
descr.capas = 3;
descr.optimización = ADAM;
descr.activación = None;
if(!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 12
layerNumber++;
Print("Creando actor - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.activación = LReLU;
optimización descr.= ADAM;
if (!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 13
layerNumber++;
Print("Creando actor - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.activación = LReLU;
optimización descr.= ADAM;
if (!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 14
layerNumber++;
Print("Creando actor - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2 * NActions;
descr.activación = LReLU;
descr.optimización = ADAM;
if (!actor.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 15
layerNumber++;
Print("Creando actor - Capa de salida VAE ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronVAEOCL;
descr.count = NActions;
descr.optimise = ADAM;
if (!actor.Add(descr))
{
elimina descr;
return false;
}
//--- Critic
critic.Clear();
//--- Capa 1: Capa de entrada
layerNumber++;
Print("Creando crítico - Capa de entrada ", layerNumber, ": Capa de entrada");
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = LatentCount;
descr.activation = None
descr.optimización = ADAM;
if (!critic.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 2
layerNumber++;
Print("Creando crítico - Concatenar capa ", layerNumber);
if (!(descr = new CLayerDescription()))
return false
descr.type = defNeuronConcatenate;
descr.count = LatentCount;
descr.window = recuento_previo;
descr.paso = NActions;
descr.optimización = ADAM;
descr.activación = LReLU;
if (!critic.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 3
layerNumber++;
Print("Creando crítico - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = LatentCount;
descr.activación = LReLU;
descr.optimización = ADAM;
if (!critic.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 4
layerNumber++;
Print("Creando crítico - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = LatentCount;
descr.activación = LReLU;
descr.optimización = ADAM;
if (!critic.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 5
layerNumber++;
Print("Creando crítico - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 1;
descr.optimización = ADAM;
descr.activation = None;
if (!critic.Add(descr))
{
borrar descr;
return false;
}
//--- Autoencoder
autoencoder.Clear();
//--- Capa 1: Capa de entrada
layerNumber++;
Print("Creando autoencoder - Capa Densa/Base ", layerNumber, ": Capa de entrada");
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = LatentCount;
descr.activation = None
descr.optimisation = ADAM;
if (!autoencoder.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 2
layerNumber++;
Print("Creando autocodificador - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = prev_count / 2;
descr.optimización = ADAM;
descr.activation = LReLU;
if (!autoencoder.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 3
layerNumber++;
Print("Creando autocodificador - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = prev_count / 2;
descr.activación = LReLU;
descr.optimisation = ADAM;
if (!autoencoder.Add(descr))
{
elimina descr;
return false;
}
//--- Capa 4
layerNumber++;
Print("Creando autocodificador - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = 20;
descr.count = LatentCount;
descr.activación = LReLU;
descr.optimisation = ADAM;
if (!autoencoder.Add(descr))
{
elimina descr;
return false;
}
//--- Capa 5
layerNumber++;
Print("Creando autocodificador - Capa Densa/Base ", layerNumber);
if (!(descr = new CLayerDescription()))
return false
if (!(descr.Copy(autoencoder.At(2))))
{
borrar descr;
return false;
}
if (!autoencoder.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 6
layerNumber++;
Print("Creando autocodificador - Capa de salida ", layerNumber);
if (!(descr = new CLayerDescription()))
return false
if (!(descr.Copy(autoencoder.At(1))))
{
borrar descr;
return false;
}
if (!autoencoder.Add(descr))
{
borrar descr;
return false;
}
//--- Capa 7
layerNumber++;
Print("Creando autocodificador - Capa de salida ", layerNumber);
if (!(descr = new CLayerDescription()))
return false
if (!(descr.Copy(autoencoder.At(0))))
{
borrar descr;
return false;
}
if (!autoencoder.Add(descr))
{
borrar descr;
return false;
}
//--- Declaración de impresión inteligente para depuración
Print("¡Descripciones de capa creadas con éxito!");
return true;
}

 
Hola. La investigación está fallando de nuevo para entrar en la zona verde. MinProfit negativo no ayuda. He llevado el valor a -10000. En general, es extraño. Si los valores iniciales de los parámetros se eligen al azar, entonces al menos algunos de ellos deberían haber llevado a un plus. Pero esto no es ni siquiera cerca de ser observado.
 

Hola a todos. Tengo esta versión después de unos 3-4 ciclos (colección de base de datos - formación - prueba) comenzó a dar sólo una línea recta en las pruebas. Las ofertas no se abren. Formación hizo todas las veces 500 000 iteraciones. Otro punto interesante - en un momento dado el error de uno de los críticos se hizo muy grande al principio, y luego poco a poco los errores de ambos críticos disminuyó a 0. Y durante 2-3 ciclos de los errores de ambos críticos están en 0. Y en las pruebas Test.mqh da una línea recta y no hay ofertas. En los pases de Research.mqh hay pases con ganancias y tratos negativos. También hay pases sin tratos y resultado cero. Sólo hubo 5 pases con resultado positivo en uno de los ciclos.

En general, es extraño. He estado entrenando estrictamente de acuerdo con las instrucciones de Dmitry en todos los artículos, y no he sido capaz de obtener un resultado de cualquier artículo. No entiendo lo que hago mal....

 
MetaQuotes:

Nuevo artículo Neural networks made easy (Part 51): behavioural actor-criticism (BAC ) ha sido publicado:

Autor: Dmitriy Gizlyk

He descargado la carpeta comprimida, pero dentro había muchas otras carpetas.

Si es posible me gustaría que me explicaras como desplegar y entrenar.

Enhorabuena por el gran trabajo.

Muchas gracias