В предыдущих статьях мы рассмотрели принципы работы и различные структуры нейронных сетей, которые можно применить при анализе рыночных ситуаций. Для закрепления пройденного материала напишем программу на языке MQL, которая будет анализировать рыночную ситуацию, используя нейронные сети двух типов -многослойный перцептрон, и
самоорганизующуюся карту Кохонена.
Как было отмечено ранее, возможности языка MQL сильно ограничены, поэтому выполнять нейросетевые вычисления необходимо во внешней среде, например, при использовании библиотеки, которая может быть реализована на языке C+ + .
Обучение многослойного перцептрона будет проводиться по генетическому алгоритму, который для простоты реализации напишем на языке MQL. Библиотеку работы с самоорганизующейся картой Кохонена сгенерируем при помощи программы NeuroShell2, которая была описана во второй статье.
Давайте начнем с описания многослойного перцептрона, который имеет следующие параметры:
int INPUTLAYER = 10; int HIDDENLAYER = 10; int HIDDENLAYER2 = 10; int OUTPUTLAYER = 10; int MAXPOP =100;
int MAXWITCH = (INPUTLAYER 4 HIDDENLAYER2) * HIDDENLAYER 4 OUTPUTLAYER * HIDDENLAYER2 + OUTPUTLAYER + 1 double ww [ ];
Функция расчета нейронной сети представлена ниже:
double neuralnetMLP (double W[], double x[])
(
int i, j, k = 0;
//веса нейронов в слоях double ww ih[,];
ArrayResize(ww_ih, INPUTLAYER, HIDDENLAYER ); double ww_hh [, ];
ArrayResize(ww_hh, HIDDENLAYER, HIDDENLAYER2); double ww ho[,];
ArrayResiz e(ww_hh, HIDDENLAYE R2, OUT PUT LAYE R};
//выходы нейронов double out in [,];
ArrayResize(out_ih, HIDDENLAYER); double out_hh[,];
ArrayResize(out_hh, HIDDENLAYER2}; double out ho[,];
ArrayResize(out_ih, OUTPUTLAYER);
double out layer = 0;
for (i = 0; i INPUTLAYER; i+4)
for (j = 0; j HIDDENLAYER; j4+)
{
WW_ih[i, j] = W[j + І * HIDDENLAYER];
}
for (І = 0; І HIDDENLAYER; І44)
for (j = 0; j HIDDENLAYER2; j++)
{
ww_hh[i, j] = W[j + i * HIDDENLAYER2 4 INPUTLAYER^HIDDENLAYER];
}
for (І = 0; І HIDDENLAYER2; І44)
for (j = 0; j OUTPUTLAYER; j44)
{
ww_hc[i, j] = W[j 4 i * OUTPUTLAYER 4 INPUTLAYER * HIDDENLAYER 4 HIDDENLAYER*HIDDENLAYER2]
}
for (1=0; 1 HIDDENLAYER; 1++)
{
for (j = 0; j INPUTLAYER; j++)
{
out_ih[i] += x[j] * ww_ih[j, x];
I
out_ih[i] = tanh(out_ih[i]};
)
for (i = 0; i HIDDENLAYER2; i++)
{
for (j = 0; j HIDDENLAYER; j++)
{
outhh[i; -= aut_ih[j] * wwhh[j, i];
)
outhh[i] = tanh(outhh[i]); l
for (i = 0; i OUTPUTLAYER; i++)
{
for (j = 0; ; HIDDENLAYER2; j++)
{
out_ho[i] += out_hh[j] * w_ho [ j, i]; I
outho[i] = tanh(out_ho[i]};
for (i = 0; i OUTPUTLAYER; i++)
{
outlayer += out_ho[i] * W[i + INPUTLAYER * HIDDENLAYER + HIDDENLAYER * HIDDENLAYER2 + HIDDENLAYER2 * OUTPUTLAYERI; l
out_layer = tanh(out_layer);
return (tanh(out_layer * И[INPUTLAYER * HIDDENLAYER + HIDDENLAYER*HIDDENLAYER2 + HIDDENLAYER2 * OUTPUTLAYER + OUTPUTLAYER]));
Функция tanh(x) есть гиперболический тангенс - передаточная функция нейрона. Нейронная сеть принимает нормированные значения входов x[], и в соответствии с массивом весов W[], которые необходимо подстроить при обучении, выдает значение, или отклик.
Для подстройки весов многослойной нейронной сети можно использовать алгоритм обратного распространения ошибки, но в этом примере будет реализован несложный генетический алгоритм, который работает по следующему принципу. В начале обучения создаются MAXPOP массивов (особи), каждый из которых имеет размерность MAXWITCH (количество весов нейронов многослойной нейронной сети).
Затем по заданному нами условию выбираются те веса, при которых оно выполняется наиболее качественно. После нахождения лучшей особи происходит передача части весов другим особям, и так происходит до тех пор, пока не будет найдено оптимальное решение.
inc GeneticAlgorithD() i
int individ = -1; int individ_last = -1;
for (int i = 0; i MAXPOP; i++)
{
for (int j = 0; 3 MAXWITCH; j++)
{
population(i, j] = (MathRandO % 200) / 100.0 - 1.0,
while ((iterations iterations total)) i
individ " CalculateFitness();
if ((individ != individ_last) || (условие условие+1)) {
iterations = 0; individ last = individ;
MutatePopulation(individ)
iterations++;
Totallterations++;
return (osob)
int CalculateFitness()
{
double[] gen = new double[MAXWITCH];
double max = -10000;
int Bestlndividlndex = -1;
for
{
(int i = 0; i MAXPOP; i++)
/выбирается популяция
SelectChromosome(i, double% gen[]); //рассчитывается результат стратегии
fitness[i] = расчета результата стратегии;
//выбирается оптимальная особь для стратегии
if (fitness[і] max)