Обсуждение статьи "Нейросети — это просто (Часть 51): Актер-критик, управляемый поведением (BAC)"

 

Опубликована статья Нейросети — это просто (Часть 51): Актер-критик, управляемый поведением (BAC):

В последних двух статьях рассматривался алгоритм Soft Actor-Critic, который включает энтропийную регуляризацию в функцию вознаграждения. Этот подход позволяет балансировать исследование среды и эксплуатацию модели, но он применим только к стохастическим моделям. В данной статье рассматривается альтернативный подход, который применим как для стохастических, так и для детерминированных моделей.

Вначале давайте порассуждаем о необходимости исследования окружающей среды в целом. Думаю, все согласны с необходимостью данного процесса. Но для чего конкретно и на какой стадии?

Начнем с простого примера. Мы впервые попадаем в некую комнату с 3 одинаковыми дверями и нам нужен выход на улицу. Что мы делаем? Поочередно открываем двери, пока не найдем нужную. Попадая повторно в эту же комнату для выхода на улицу, мы уже не будем открывать все двери, а сразу направимся к уже известному выходу. Если же в этой ситуации у нас будет другая задача, то тут возможны варианты. Мы можем снова открывать все двери, кроме уже известного нам выхода, и искать нужную. А можем сначала вспомнить какие мы двери открывали ранее при поиске выхода и была ли среди них нужная нам. Если мы помним нужную дверь, то направляемся к ней. В противном случае проверяем двери, которые не открывали ранее.

Вывод: исследование окружающей среды нам необходимо в незнаком состоянии для выбора правильного действия. После нахождения необходимого маршрута дополнительное исследование окружающей среды может только мешать.


Однако, при изменении задачи в известном состоянии нам может потребоваться дополнительное исследование окружающей среды. Сюда можно отнести и поиск более оптимального маршрута. В приведенном выше примере, если для выхода нам потребовалось пройти ещё несколько помещений или вышли не с той стороны здания.

Следовательно, нам нужен такой алгоритм, который позволяет усиливать исследование окружающей среды в неизученных состояниях и минимизировать в ранее исследованных.

Автор: Dmitriy Gizlyk

 
#Enjoy! <3 

Thanks Sir @Dmitriy

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CreateDescriptions(CArrayObj *actor, CArrayObj *critic, CArrayObj *autoencoder)
{
--- Smart print statement for debugging
   Print("Creating layer descriptions...");
   CLayerDescription *descr;
int layerNumber = 0; To keep track of layer numbers
--- Check and initialize input arrays if they are null
   if (!actor)
      {
         actor = new CArrayObj();
         if (!actor)
            return false;
      }
   if (!critic)
      {
         critic = new CArrayObj();
         if (!critic)
            return false;
      }
   if (!autoencoder)
      {
         autoencoder = new CArrayObj();
         if (!autoencoder)
            return false;
      }
--- Actor
actor. Clear();
--- Layer 1: Input layer
   layerNumber++;
   Print("Creating actor - Input Layer ", layerNumber, ": Input layer");
if (!( descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   int prev_count = descr.count = (HistoryBars * BarDescr);
   descr.activation = None;
   descr.optimization = ADAM;
if (!actor. Add(descr))
      {
         delete descr;
         return false;
      }
--- Layer 2
   layerNumber++;
   Print("Creating actor - Batch Normalization Layer ", layerNumber);
if (!( descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBatchNormOCL;
   descr.count = prev_count;
   descr.batch = 1000;
   descr.activation = None;
   descr.optimization = ADAM;
if (!actor. Add(descr))
      {
         delete descr;
         return false;
      }
--- Layer 3
   layerNumber++;
   Print("Creating actor - Convolutional Layer ", 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.activation = LReLU;
   descr.optimization = ADAM;
if (!actor. Add(descr))
      {
         delete descr;
         return false;
      }
--- Layer 4
   layerNumber++;
   Print("Creating actor - Convolutional Layer ", layerNumber);
if (!( 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.optimization = ADAM;
if (!actor. Add(descr))
      {
         delete descr;
         return false;
      }
--- Layer 5
   layerNumber++;
   Print("Creating actor - Dense/Base Layer ", layerNumber);
if (!( descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 2048;
   descr.optimization = ADAM;
   descr.activation = LReLU;
if (!actor. Add(descr))
      {
         delete descr;
         return false;
      }
--- Layer 6
   layerNumber++;
   Print("Creating actor - Dense/Base Layer ", layerNumber);
if (!( descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = 1024;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 7
   layerNumber++;
   Print("Creating actor - SoftMax Layer ", layerNumber);
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSoftMaxOCL;
   prev_count = descr.count = prev_count / 16;
   descr.step = 16;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 8 Multilayer Multi-Head Attention Layer
   layerNumber++;
   Print("Creating actor - Multilayer Multi-Head Attention Layer ", 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.layers = 3;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 9
   layerNumber++;
   Print("Creating actor - Concatenate Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronConcatenate;
   descr.count = LatentCount;
   descr.window = prev_count;
   descr.step = AccountDescr;
   descr.optimization = ADAM;
   descr.activation = SIGMOID;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 10
   layerNumber++;
   Print("Creating actor - SoftMax Layer ", layerNumber);
   if(!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronSoftMaxOCL;
   prev_count = descr.count = prev_count / 16;
   descr.step = 16;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 11 Multilayer Multi-Head Attention Layer
   layerNumber++;
   Print("Creating actor - Multilayer Multi-Head Attention Layer ", 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.layers = 3;
   descr.optimization = ADAM;
   descr.activation = None;
   if(!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 12
   layerNumber++;
   Print("Creating actor - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 2048;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 13
   layerNumber++;
   Print("Creating actor - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 2048;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 14
   layerNumber++;
   Print("Creating actor - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 2 * NActions;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 15
   layerNumber++;
   Print("Creating actor - VAE Output Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronVAEOCL;
   descr.count = NActions;
   descr.optimization = ADAM;
   if (!actor.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Critic
   critic.Clear();
//--- Layer 1: Input layer
   layerNumber++;
   Print("Creating critic - Input Layer ", layerNumber, ": Input layer");
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = LatentCount;
   descr.activation = None;
   descr.optimization = ADAM;
   if (!critic.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 2
   layerNumber++;
   Print("Creating critic - Concatenate Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronConcatenate;
   descr.count = LatentCount;
   descr.window = prev_count;
   descr.step = NActions;
   descr.optimization = ADAM;
   descr.activation = LReLU;
   if (!critic.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 3
   layerNumber++;
   Print("Creating critic - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = LatentCount;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!critic.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 4
   layerNumber++;
   Print("Creating critic - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = LatentCount;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!critic.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 5
   layerNumber++;
   Print("Creating critic - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   descr.count = 1;
   descr.optimization = ADAM;
   descr.activation = None;
   if (!critic.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Autoencoder
   autoencoder.Clear();
//--- Layer 1: Input layer
   layerNumber++;
   Print("Creating autoencoder - Dense/Base Layer ", layerNumber, ": Input layer");
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = LatentCount;
   descr.activation = None;
   descr.optimization = ADAM;
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 2
   layerNumber++;
   Print("Creating autoencoder - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = prev_count / 2;
   descr.optimization = ADAM;
   descr.activation = LReLU;
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 3
   layerNumber++;
   Print("Creating autoencoder - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = prev_count / 2;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 4
   layerNumber++;
   Print("Creating autoencoder - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   descr.type = defNeuronBaseOCL;
   prev_count = descr.count = 20;
   descr.count = LatentCount;
   descr.activation = LReLU;
   descr.optimization = ADAM;
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 5
   layerNumber++;
   Print("Creating autoencoder - Dense/Base Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   if (!(descr.Copy(autoencoder.At(2))))
      {
         delete descr;
         return false;
      }
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 6
   layerNumber++;
   Print("Creating autoencoder - Output Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   if (!(descr.Copy(autoencoder.At(1))))
      {
         delete descr;
         return false;
      }
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Layer 7
   layerNumber++;
   Print("Creating autoencoder - Output Layer ", layerNumber);
   if (!(descr = new CLayerDescription()))
      return false;
   if (!(descr.Copy(autoencoder.At(0))))
      {
         delete descr;
         return false;
      }
   if (!autoencoder.Add(descr))
      {
         delete descr;
         return false;
      }
//--- Smart print statement for debugging
   Print("Layer descriptions created successfully!");
   return true;
}

 
Здравствуйте. Опять не удается вывести  Research в зеленую зону. Отрицательный MinProfit не помогает. Довел значение до -10000. Вообще это странно как то. Если первоначальные значения параметров выбираются случайным образом, то хоть некоторые из них должны были выводить в плюс. Но этого и близко не наблюдается.
 

Всем здравствуйте. У меня данная версия примерно после 3-4 цикла (сбор БД - обучение - тест) стала давать просто прямую линию на тестах. Сделки не открывает. Обучение делал все разы по 500 000 итераций. Ещё интересный момент - в определённый момент ошибка одного из критиков стала сначала очень большой, а потом постепенно снизились ошибки обоих критиков до 0. И уже 2-3 цикла ошибки обоих критиков стоят на 0. И на тестах Test.mqh выдаётся прямая линия и отсутствие сделок. В проходах  Research.mqh бывают проходы с отрицательной прибылью и сделками. Так же есть проходы с отсутствием сделок и нулевым исходом. С положительным исходом било только 5 проходов в одном из циклов.

Вообще как-то странно. Я выполнял обучение строго по инструкции Дмитрия во всех статьях, и ни с одной статьи не получилось получить результат. Я не понимаю что я делаю не так...

Причина обращения: