Обсуждение статьи "Нейросети — это просто (Часть 5): Многопоточные вычисления в OpenCL" - страница 4

 
Можно ли сделать LSTM-сеть c OpenCL? Если да, то с какой версией NeuroNet.mqh лучше? С версией из этой статьи выдается ошибка "Error of execution kernel CaclOutputGradient: 0". А с версией из статьи 7 похоже вообще OpenCL не используется, если создавать нейроны defNeuronLSTM. А  defNeuronLSTMOCL не реализован.
Нейросети — это просто (Часть 7): Адаптивные методы оптимизации
Нейросети — это просто (Часть 7): Адаптивные методы оптимизации
  • www.mql5.com
В предыдущих статьях мы рассмотрели разные типы нейронов, но всегда использовали метод стохастического градиентного спуска для обучения нейронной сети. Данный метод, наверное, можно назвать базовым и различные его вариации очень часто используются на практике. Тем не менее, он не единственный и существует целый ряд других методов для обучения...
 
Ivan Titov:
Можно ли сделать LSTM-сеть c OpenCL? Если да, то с какой версией NeuroNet.mqh лучше? С версией из этой статьи выдается ошибка "Error of execution kernel CaclOutputGradient: 0". А с версией из статьи 7 похоже вообще OpenCL не используется, если создавать нейроны defNeuronLSTM. А  defNeuronLSTMOCL не реализован.
На данный момент LSTM ещё не переведен в OpenCL. Планирую сделать в ближайшем будущем.
 
Ясно, спасибо. Просьба также уточнить: recentAverageSmoothingFactor = 10000 - задано жестко. Надо ли менять его на количество значений в обучающей выборке?
 
Ivan Titov:
Ясно, спасибо. Просьба также уточнить: recentAverageSmoothingFactor = 10000 - задано жестко. Надо ли менять его на количество значений в обучающей выборке?

Если выборка меньше, то нужно уменьшить. Увеличивать есть смысл, если Вы хотите видеть ошибку по всей выборке.
Я использую жесткое значение, чтобы оценивать работу сети в разных рыночных условиях.

 

Дмитрий, не могу понять, почему не происходит обновление значений в массиве. При этом никаких ошибок нет - выход из метода по false не происходит. Можете проверить это у себя?

bool CNeuronBaseOCL::calcOutputGradients(CArrayDouble *Target)
  {
   if(CheckPointer(OpenCL)==POINTER_INVALID || CheckPointer(Target)==POINTER_INVALID)
      return false;
   uint global_work_offset[1]= {0};
   uint global_work_size[1];
   global_work_size[0]=Target.Total();
   for(uint i=0; i<global_work_size[0]; i++)
     {
      double z=Target.At(i);                    //<--В массиве Target три значения (1,0;0.0;0.0)
      if(!Gradient.Update(i,Target.At(i)))
         return false;
     }
                                                //Проверяем значения в массиве Gradient после обновления
   double target[];                             
   if(getGradient(target)<Gradient.Total())     //<--В массиве target три значения (0,0;0.0;0.0)
      return false;
//---
   Gradient.BufferWrite();
......
 }
 
Aleksei Lesnikov:

Дмитрий, не могу понять, почему не происходит обновление значений в массиве. При этом никаких ошибок нет - выход из метода по false не происходит. Можете проверить это у себя?

Алексей, метод update наследуется от класса CArrayDouble и записывает данные в массив, но не передает их в буфер GPU.

if(!Gradient.Update(i,Target.At(i)))
         return false;

В тоже время, при вызове метода getGradient, происходит считывание данных с буфера GPU, что и перезатирает внесенные ранее изменения.

virtual int       getGradient(double &values[])    {  return Gradient.GetData(values);    }
.......
int CBufferDouble::GetData(double &values[])
  {
   if(!BufferRead())
      return false;
   return ArrayCopy(values,m_data,0,0,m_data_total);
  }
 
Dmitriy Gizlyk:

Алексей, метод update наследуется от класса CArrayDouble и записывает данные в массив, но не передает их в буфер GPU.

В тоже время, при вызове метода getGradient, происходит считывание данных с буфера GPU, что и перезатирает внесенные ранее изменения.

Действительно, что-то я сглупил. Спасибо.
 

Добрый день, Дмитрий! Большое спасибо за ваши публикации, которые мне очень помогли повысить свои знания в области разработки. Буду очень пизнателен за ваш совет. Сейчас изучаю статью про многопоточные вычисления (№5). Попробовал запустить из вложений уже скомпелированный файл, он не запускается и крашится весь терминал полностью. Попробовал пересобрать из исходников, итог получается тотже, что наталкивает на мысль, что это не из-за исходников. Попробовал погонять на тестере: крашится когда вызывается метод CNet::backPropOCL на строке 1486 (neuron.calcHiddenGradients(nextLayer.At(0));), а там уже на предопределённой функции из каталога OpenCL (CLExecute(kernel_handle,work_dim,work_offset,work_size)). Самое интересное, что в логах нет никакой ошибки просто тестер также крашится. Может подскажите из-за чего это может быть? Спасибо.

 
Aleksandr Seredin #:

Добрый день, Дмитрий! Большое спасибо за ваши публикации, которые мне очень помогли повысить свои знания в области разработки. Буду очень пизнателен за ваш совет. Сейчас изучаю статью про многопоточные вычисления (№5). Попробовал запустить из вложений уже скомпелированный файл, он не запускается и крашится весь терминал полностью. Попробовал пересобрать из исходников, итог получается тотже, что наталкивает на мысль, что это не из-за исходников. Попробовал погонять на тестере: крашится когда вызывается метод CNet::backPropOCL на строке 1486 (neuron.calcHiddenGradients(nextLayer.At(0));), а там уже на предопределённой функции из каталога OpenCL (CLExecute(kernel_handle,work_dim,work_offset,work_size)). Самое интересное, что в логах нет никакой ошибки просто тестер также крашится. Может подскажите из-за чего это может быть? Спасибо.

Добрый день, Александр.
Если я правильно понимаю, то крашится при выполнении OpenCL программы. Попробуйте запустить в режиме отладки и посмотреть на размеры передаваемых буферов. Возможно ошибка в выходе за пределы массива в OpenCL программе.
 

В методе "bool CNeuron::feedForward(CLayer *prevLayer)", файла "NeuroNet.mqh", есть строка:

"outputVal=activationFunction(MathMin(MathMax(sum,-18),18));"

непонятно почему результат активационной функции от -18 до 18, разве не должно быть от -1 до 1 или от 0 до 1?

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