Рыночный этикет или правила хорошего тона на минном поле - страница 16

 
paralocus писал(а) >>

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

Я вам очень благодарен!

Ok.

 
Neutron >>:

Ok.

Здравтсвуйте Neutron. Вот, сваял кое-что.

Для алгоритма ОРО я слепил вот такую маленькую сетку:



Собственно, вот код самой сетки (это заголовочный файл Neyro_test.mqh):

extern int neyrons = 3;
extern int in = 5;

double Data[3][5] = {0.0,0.0,0.0,0.0,1.0,
0.0,0.0,0.0,0.0,1.0,
0.0,0.0,0.0,0.0,1.0 };

double W[4][5] = {-0.786, 0.359,-0.186, 0.891, 0.238,
0.711,-0.923, 0.088, 0.417,-0.112,
-0.867,-0.229, 0.321, 0.921,-0.941,
0.995,-0.712, 0.012,-0.625, 0.0 };

//----------------------------
double OUT(int bar = 1)
{
int i;
double res = 0.0;

GetInd(bar);
res = W[3,0]*RSI_1() + W[3,1]*RSI_2() + W[3,2]*RSI_3() + W[3,3];

return(res);
}

double RSI_1()
{
int i;
double res = 0.0;

for(i = 0; i < 5; i++)
res += W[0,i] * Data[0,i];

return(th(res));
}

double RSI_2()
{
int i;
double res = 0.0;

for(i = 0; i < 5; i++)
res += W[1,i] * Data[0,i];

return(th(res));
}

double RSI_3()
{
int i;
double res = 0.0;

for(i = 0; i < 5; i++)
res += W[2,i] * Data[0,i];

return(th(res));
}

//----------

void OPO(double de)
{
int i;
for(i = 0; i < 4; i++)
W[3,i] += de;
}

//---------------------------------------------------------------------

void GetInd(int i)
{
int dt = 7,per = 14, prc = 0;
double ue_in = 0.02,kf = 3.0;

Data[0,0] = th((iRSI(NULL,0,per,prc,i)*ue_in - 1.0)*kf);
Data[0,1] = th((iRSI(NULL,0,per,prc,i+dt)*ue_in - 1.0)*kf);
Data[0,2] = th((iRSI(NULL,0,per,prc,i+dt*2)*ue_in - 1.0)*kf);
Data[0,3] = th((iRSI(NULL,0,per,prc,i+dt*3)*ue_in - 1.0)*kf);
}
//-------------------------------------------

double th(double x)
{
double sh,ch;
sh = MathExp(x) - MathExp(-x);
ch = MathExp(x) + MathExp(-x);
return(sh/ch);
}



А вот как я её пытался учить в пустом советнике:

extern int cikl = 10;
static int prevtime = 0;


#include <Neyro_test.mqh>
//-----------------------------------
int init()
{
return(0);
}

int deinit()
{
return(0);
}
//-------------------------------------
int start()
{
static double test, control;

if(Time[0] == prevtime)
return(0);
prevtime = Time[0];

int pr = 14, pc = 0, i;
double in = 0.02, k = 3.0;


for(i = cikl; i > 2; i--)
{
test = OUT(i);
control = th((iRSI(NULL,0,pr,pc,i-1)*in - 1.0)*k);
OPO(test - control);
}

Comment("\r\n ВЕСА ВЫХОДНОГО НЕЙРОНА : ",W[3,0],", ",W[3,1],", ",W[3,2],", ",W[3,3]);
return(0);

}



Вобщем, эта сетка идет "вразнос". Весовые коэффициенты возрастают до неприличия уже после 10 шагов(баров). Долго искал ошибку в коде - оказалось, что код работает как и должен.

Т.е. если просто прибавлять полученную на выходе сетки ошибку ко всем весовым коэффициентам выходного слоя, то енти коэффициенты имеют свойство слишком быстро расти.

Зашкалиметр невыдерживает... -:) Пока что я пытался распространять ошибку только на веса выходного слоя.

Вопрос первый: Что я сделал не так?

Вопрос второй:

Вот я хотел бы получать на выходе сетки вероятность успешной покупки/продажи, или рекомендацию курить бамбук. А сетка эта обучается предсказывать значение RSI на n+1 баре...

А что мне с него?

 

в функции ОРО веса модифицируются неправильно

прочитайте теорию, хотя бы тут 

 
maxfade >>:

в функции ОРО веса модифицируются неправильно

прочитайте теорию, хотя бы тут

Благодарю, но я там ничего не понимаю

 

ошибка в выходном слое должна вычисляться по формуле e=OUT*(1-OUT)*(TEST-OUT) (это для логистической передаточной функции, для гиперболического тангенса вроде формула будет немного другой, но тоже не сильно сложной)

вес нейрона должен модифицироваться по формуле w+=nju*e*OUT, где nju - шаг обучения

если шаг слишком большой - сеть будет неустойчивой и будет наблюдаться бесконечное увеличение значения весов (как в вашем случае, вы используете (TEST-OUT) без всех остальных множителей)

если слишком маленький - сеть будет слишком долго учиться и может попасть в локальный минимум

 
maxfade >>:

ошибка в выходном слое должна вычисляться по формуле e=OUT*(1-OUT)*(TEST-OUT) (это для логистической передаточной функции, для гиперболического тангенса вроде формула будет немного другой, но тоже не сильно сложной)

вес нейрона должен модифицироваться по формуле w+=nju*e*OUT, где nju - шаг обучения

если шаг слишком большой - сеть будет неустойчивой и будет наблюдаться бесконечное увеличение значения весов (как в вашем случае, вы используете (TEST-OUT) без всех остальных множителей)

если слишком маленький - сеть будет слишком долго учиться и может попасть в локальный минимум


Спасибо, сейчас попробую

 
maxfade >>:

если шаг слишком большой - сеть будет неустойчивой и будет наблюдаться бесконечное увеличение значения весов (как в вашем случае, вы используете (TEST-OUT) без всех остальных множителей)

если слишком маленький - сеть будет слишком долго учиться и может попасть в локальный минимум


Меня, немного смущает то, что в результате модификации "относительное положение" весов остается неизменным. Это происходит потому, что все входящие веса, в реезультате модификации изменяются на одну и ту же величину. При этом изначальное соотношение весов было заданно случайным образом. Разве так должно быть?

 

Привет, paralocus .

Давай, по-порядку. У тебя имеется обучающий вектор длиной n-отсчётов, и нам необходимо сформировать вектор ошибок для корекции всех весов Сети. Понятно, что длина вектора будет равняться числу весов w считая веса постоянного уровня. Вектор ошибок будет сформирован только к концу первой (второй, третьей и т.п.) эпохи обучения. Метод его формирования следущий:

1. На первом шаге обучения (их всего n в каждой эпохе), формируем индивидуальную ошибку для каждого веса и не корректируем веса. Затем, на втором шаге, сформировав аналогичную коррекцию, складываем её с предыдущй и т.д. n-раз. Получаем суммарную коррекцию (с учётом знака каждого члена) по каждому весу. Теперь, важный момент. Эту итоговую коррекцию использовать нельзя - веса пойдут в разнос! Нужно, поделить её на норму вектора коррекции. Для этого, необходимо для каждого веса отдельно считать сумму квадратов каждой коррекции в пределах одной эпохи обучения. Как только мы закончили очередную эпоху (n-циклов в её пределах), извлекакм корень квадратный из суммы квадратов для каждого веса отдельно, и персонально делим на эту норму, каждую коррекцию. Корректируем каждый вес.

2. Таких эпох обучения будет от 10 до 1000 в зависимости от целей обучения (знак или амплитуда). Всё проделываем аналогично. Важный момент: переходя от эпохе к эпохе, необходимо строго следить за монотонным снижением амплитуды коррекции весов. Делать это нужно для того, что бы Сетка не ленилась искать всё более и более глубокий минимум в потенциале функции ошибки. Реализуется это просто. Необходимо, в конце эпохи, перед коррекцией веса, умножить корректор на величину 1-j/N, где N - число эпох обучения, j - текущий номер эпохи.

3. Для предотвращения неизбежного эффекта насыщения некоторых весов СЕти в процессе её обучения, необходимо сразу после очередной коррекции весов, воздействовать на все веса гиперболическим тангенсом. Эта процедура не очевидна, но крайне эффективна. Из-за гладкости и монотонности используемой ФА, все веса всегда будут оставаться в диапазоне +/-1 и сам акт воздействия не вызывает "истереку" у девушки.

Пока всё. Переваривай и задавай вопросы.

Что касается, вопроса о том, как от RSI перейти к Buy/Sell, то это, скорее, вопрос к тебе - ведь ты сам придумал этот ход. Я к примеру, то что прогнозирую, то и на вход подаю (а прогнозирую я именно Buy/Sell). Поэтому и противоречия нет. А ты пытаешься по цвету обоев в произвольной квартире, предсказывать цвет машины перед окном кухни этой квартиры...

 

Поскольку крапал пост вспоминая детали реализации, возникли неточности.

Глянул код, получается, что воздействие ФА на веса я производил один раз при переходе на новый прогноз, т.е. не каждую эпоху, а при необходимости дообучить сеть при поступлении новых данных.

И ещё. Коррекция веса, это произведение ошибки с выхода нейрона на производную ФА и на выход нейрона (амплитуду с учётом знака) с которого заводится сигнал.

Вот, как это выглядит для одного персептрона с нелинейным выходом (для примера):

Тут эпохи нумеруются по индексу L. Специально показываю черех MathCad, так нагляднее. In - число входов, х - входной вектор. Остальное вроде понятно.

 
Neutron >>:

Что касается, вопроса о том, как от RSI перейти к Buy/Sell, то это, скорее, вопрос к тебе - ведь ты сам придумал этот ход. Я к примеру, то что прогнозирую, то и на вход подаю (а прогнозирую я именно Buy/Sell). Поэтому и противоречия нет. А ты пытаешься по цвету обоев в произвольной квартире, предсказывать цвет машины перед окном кухни этой квартиры...

Привет, Neutron.

С тем, что ты написал я сейчас разбираюсь. Просто в мою башку математитка лезет с большим скрипом. Программирование чуть полегче. А насчет обоев - ты абсолютно прав - но я пока не знаю, что сетке на вход запихивать, окромя все тех же обоев, но другой фабрики(думаю, результат будет тем же). Здесь на форуме прочел вот эту статью, с неё и начался мой интерес к нейросеткам. А в той статье, как ты знаешь, на вход одного несчастного перцептрона, умные дядьки с форума пихают индюк АО (или АС - я их путаю постоянно), а чтобы было чего смотреть, они его на "кластеры" делят разноской входов оного перцептрона по графику упомянутого индюка(dt/dl ). Называется все это "НЕЙРОСЕТЬЮ" или даже "ТОРГОВЛЕЙ С НЕТРАДИЦИОННОЙ О... (нет, эт я чегой-то не туда загнул) АВТОМАТИЗАЦИЕЙ СЛИВА". Нехилые бабки чуваки гребут... в тестере.

Ну ладно... это было лирическое отступление.

Так вот после той статьи и еще пары ей подобных(по ссылкам с нее же) я стал перцептронами экспериментировать всяко. Вобщем, все как в той песне:

"Сидит Ванька на скамейке, долбит хреном три копейки.

Хочет сделать три рубля - Не выходит ничего!"

Однако же, интерес к неросеткам с целью их использования в торговле у меня остался и со временем даже вырос. То что я ничего лучшего, чем кластеризация RSI придумать пока не могу - это не дядек вина, но "палка о двух концах". Т.е. чтобы знать что и как запихнуть на вход сетки, мне нужно знать, как эти сетки устроены и не только знать, но и уметь их делать. Хотя бы в каких-то не очень сложных видах, но достаточных для устойчивой работы на реале. Вот поэтому я к тебе и обратился.


P.S. Ничего, что я на "ты" перешел? Так как-то душевней.