Discussão do artigo "Redes neurais de maneira fácil (Parte 51): ator-crítico comportamental (BAC)"

 

Novo artigo Redes neurais de maneira fácil (Parte 51): ator-crítico comportamental (BAC) foi publicado:

Nos últimos dois artigos, discutimos o algoritmo Soft Actor-Critic, que incorpora regularização de entropia na função de recompensa. Essa abordagem permite equilibrar a exploração do ambiente e a exploração do modelo, mas é aplicável apenas a modelos estocásticos. Neste artigo, exploraremos uma abordagem alternativa que é aplicável tanto a modelos estocásticos quanto determinísticos.

Vamos começar discutindo a necessidade de explorar o ambiente em geral. Acredito que todos concordamos com a importância desse processo. Mas para que serve especificamente e em que estágio?

Comecemos com um exemplo simples. Estamos entrando em uma sala com 3 portas idênticas e precisamos encontrar a saída para a rua. O que fazemos? Abrimos as portas uma a uma até encontrarmos a saída. Se voltarmos a entrar na mesma sala para sair novamente, não abriremos todas as portas, iremos direto para a saída conhecida. No entanto, se tivermos uma tarefa diferente, existem opções. Podemos abrir todas as portas novamente, exceto aquela que já sabemos ser a saída, e procurar a que precisamos. Ou podemos primeiro lembrar quais portas abrimos anteriormente ao procurar a saída e verificar se a que precisamos estava entre elas. Se lembrarmos da porta necessária, seguimos em direção a ela. Caso contrário, verificamos as portas que não foram abertas anteriormente.

Conclusão: A exploração do ambiente é necessária quando estamos em um estado desconhecido para escolher a ação correta. Após encontrar a rota necessária, a exploração adicional do ambiente pode apenas atrapalhar.


No entanto, ao alterar a tarefa em um estado conhecido, pode ser necessário explorar o ambiente adicionalmente. Isso inclui a busca por uma rota mais otimizada. No exemplo acima, se precisarmos passar por mais salas para sair ou sair do lado errado do prédio.

Portanto, precisamos de um algoritmo que permita intensificar a exploração do ambiente em estados não explorados e minimizar em estados previamente explorados.

Autor: Dmitriy Gizlyk

 
#Enjoy! <3

Obrigado, senhor @Dmitriy

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CreateDescriptions(CArrayObj *actor, CArrayObj *critic, CArrayObj *autoencoder)
{
--- Declaração de impressão inteligente para depuração
Print("Criando descrições de camadas...");
CLayerDescription *descr;
int layerNumber = 0; Para manter o controle dos números das camadas
--- Verifique e inicialize as matrizes de entrada se elas forem nulas
se (!ator)
{
ator = new CArrayObj();
se (!ator)
return false;
}
if (!critic)
{
critic = new CArrayObj();
se (!crítico)
return false;
}
se (!autoencoder)
{
autoencoder = new CArrayObj();
se (!autoencoder)
return false;
}
--- Ator
ator. Clear();
--- Camada 1: camada de entrada
layerNumber++;
Print("Criando ator - Camada de entrada ", layerNumber, ": Camada de entrada");
se (!( 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))
{
excluir descr;
return false;
}
--- Camada 2
layerNumber++;
Print("Criando ator - Camada de normalização em lote ", layerNumber);
se (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBatchNormOCL;
descr.count = prev_count;
descr.batch = 1000;
descr.activation = None;
descr.otimização = ADAM;
se (!actor. Add(descr))
{
excluir descr;
return false;
}
--- Camada 3
layerNumber++;
Imprimir ("Criando ator - Camada convolucional ", layerNumber);
se (!( 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.activation = LReLU;
descr.otimização = ADAM;
se (!actor. Add(descr))
{
excluir descr;
return false;
}
--- Camada 4
layerNumber++;
Imprimir ("Criando ator - Camada convolucional ", layerNumber);
se (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronConvOCL;
prev_count = descr.count = prev_count;
descr.window = 8;
descr.step = 8;
descr.window_out = 8;
descr.activation = LReLU;
descr.otimização = ADAM;
se (!actor. Add(descr))
{
excluir descr;
return false;
}
--- Camada 5
layerNumber++;
Imprimir ("Criando ator - Camada densa/base ", layerNumber);
se (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.optimisation = ADAM;
descr.activation = LReLU;
Se (!actor. Add(descr))
{
excluir descr;
return false;
}
--- Camada 6
layerNumber++;
Imprimir ("Criando ator - Camada densa/base ", layerNumber);
se (!( descr = new CLayerDescription())))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = 1024;
descr.activation = LReLU;
descr.otimização = ADAM;
se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 7
layerNumber++;
Imprimir ("Criando ator - Camada SoftMax ", layerNumber);
se(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronSoftMaxOCL;
prev_count = descr.count = prev_count / 16;
descr.step = 16;
descr.optimisation = ADAM;
descr.activation = None;
se(!ator.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 8 Camada de atenção multicamada com várias cabeças
layerNumber++;
Print("Criando ator - Camada de atenção multicabeça multicamadas ", layerNumber);
se(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronMLMHAttentionOCL;
descr.count = prev_count;
descr.window = 16;
descr.window_out = 8;
descr.step = 4;
descr.layers = 3;
descr.optimisation = ADAM;
descr.activation = None;
se(!ator.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 9
layerNumber++;
Imprimir ("Criando ator - Concatenar camada ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronConcatenate;
descr.count = LatentCount;
descr.window = prev_count;
descr.step = AccountDescr;
descr.optimisation = ADAM;
descr.activation = SIGMOID;
se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 10
layerNumber++;
Imprimir ("Criando ator - Camada SoftMax ", layerNumber);
se(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronSoftMaxOCL;
prev_count = descr.count = prev_count / 16;
descr.step = 16;
descr.optimisation = ADAM;
descr.activation = None;
se(!ator.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 11 Camada de atenção multicamada com várias cabeças
layerNumber++;
Print("Criando ator - Camada de atenção multicabeça multicamadas ", layerNumber);
se(!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronMLMHAttentionOCL;
descr.count = prev_count;
descr.window = 16;
descr.window_out = 8;
descr.step = 4;
descr.layers = 3;
descr.optimisation = ADAM;
descr.activation = None;
se(!ator.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 12
layerNumber++;
Imprimir ("Criando ator - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.activation = LReLU;
descr.otimização = ADAM;
Se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 13
layerNumber++;
Print("Criando ator - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2048;
descr.activation = LReLU;
descr.otimização = ADAM;
se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 14
layerNumber++;
Imprimir ("Criando ator - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 2 * NActions;
descr.activation = LReLU;
descr.otimização = ADAM;
se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 15
layerNumber++;
Print("Criando ator - Camada de saída VAE ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronVAEOCL;
descr.count = NActions;
descr.optimise = ADAM;
se (!actor.Add(descr))
{
excluir descr;
return false;
}
//--- Crítico
critic.Clear();
//--- Camada 1: camada de entrada
layerNumber++;
Print("Criando crítico - Camada de entrada ", layerNumber, ": Camada de entrada");
Se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = LatentCount;
descr.activation = None;
descr.optimisation = ADAM;
se (!critic.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 2
layerNumber++;
Imprimir ("Criando crítico - Concatenar camada ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronConcatenate;
descr.count = LatentCount;
descr.window = prev_count;
descr.step = NActions;
descr.optimisation = ADAM;
descr.activation = LReLU;
se (!critic.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 3
layerNumber++;
Imprimir ("Criando crítico - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = LatentCount;
descr.activation = LReLU;
descr.optimisation = ADAM;
se (!critic.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 4
layerNumber++;
Imprimir ("Criando crítico - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = LatentCount;
descr.activation = LReLU;
descr.optimisation = ADAM;
se (!critic.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 5
layerNumber++;
Imprimir ("Criando crítico - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
descr.count = 1;
descr.optimisation = ADAM;
descr.activation = None;
se (!critic.Add(descr))
{
excluir descr;
return false;
}
//--- Autocodificador
autoencoder.Clear();
//--- Camada 1: camada de entrada
layerNumber++;
Imprimir ("Criando autoencoder - Camada densa/base ", layerNumber, ": Camada de entrada");
Se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = LatentCount;
descr.activation = None;
descr.optimisation = ADAM;
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 2
layerNumber++;
Imprimir ("Criando autoencoder - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = prev_count / 2;
descr.optimisation = ADAM;
descr.activation = LReLU;
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 3
layerNumber++;
Imprimir ("Criando autoencoder - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = prev_count / 2;
descr.activation = LReLU;
descr.optimisation = ADAM;
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 4
layerNumber++;
Imprimir ("Criando autoencoder - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
descr.type = defNeuronBaseOCL;
prev_count = descr.count = 20;
descr.count = LatentCount;
descr.activation = LReLU;
descr.otimização = ADAM;
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 5
layerNumber++;
Imprimir ("Criando autoencoder - Camada densa/base ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
se (!(descr.Copy(autoencoder.At(2))))
{
delete descr;
return false;
}
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 6
layerNumber++;
Print("Criando autoencoder - Camada de saída ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
se (!(descr.Copy(autoencoder.At(1))))
{
delete descr;
return false;
}
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Camada 7
layerNumber++;
Print("Criando autoencoder - Camada de saída ", layerNumber);
se (!(descr = new CLayerDescription()))
return false;
se (!(descr.Copy(autoencoder.At(0))))
{
delete descr;
return false;
}
se (!autoencoder.Add(descr))
{
excluir descr;
return false;
}
//--- Declaração de impressão inteligente para depuração
Imprimir ("Descrições de camadas criadas com sucesso!");
return true;
}

 
Olá. A pesquisa está novamente falhando em entrar na zona verde. O MinProfit negativo não ajuda. Eu levei o valor para -10000. Em geral, isso é estranho. Se os valores iniciais dos parâmetros forem escolhidos aleatoriamente, pelo menos alguns deles deveriam ter levado a uma vantagem. Mas isso não está nem perto de ser observado.
 

Olá a todos. Eu tenho esta versão, depois de cerca de 3-4 ciclos (coleta de banco de dados - treinamento - teste) começou a dar apenas uma linha reta nos testes. Os negócios não abrem. O treinamento fez todas as vezes 500.000 iterações. Outro ponto interessante - em um determinado momento, o erro de um dos críticos se tornou muito grande no início e, depois, gradualmente, os erros de ambos os críticos diminuíram para 0. E, por 2 a 3 ciclos, os erros de ambos os críticos estão em 0. E, nos testes, o Test.mqh apresenta uma linha reta e nenhuma transação. Nos passes do Research.mqh, há passes com lucro e negócios negativos. Também há passagens sem transações e com resultado zero. Houve apenas 5 passagens com um resultado positivo em um dos ciclos.

Em geral, isso é estranho. Tenho treinado estritamente de acordo com as instruções de Dmitry em todos os artigos e não consegui obter um resultado de nenhum artigo. Não entendo o que estou fazendo de errado....

 

Baixei a pasta zipada, mas haviam muitas outras pastas dentro.

Se possível gostaria que explicasse como implantar e treinar.

Parabens pelo ótimo trabalho!

Agradeço e muito obrigado