L'étiquette du marché ou les bonnes manières dans un champ de mines - page 16

 
paralocus писал(а) >>

Neutron, je vais prendre un petit temps mort. Je dois à nouveau tout repenser et le mettre en code pour au moins un neurone. Bref, un jour ou deux, et ensuite nous continuerons.

Je l'apprécie vraiment !

Ok.

 
Neutron >> :

Ok.

Bonjour Neutron. Tiens, j'ai fait quelque chose.

J'ai fait une grille si petite pour l'algorithme ORO :



En fait, voici le code de la grille elle-même (il s'agit du fichier d'en-tête 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);
}



Voici comment j'ai essayé de l'enseigner dans un Expert Advisor vide :

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);

}



En gros, cette grille est "déréglée". Les coefficients de pondération deviennent ridiculement élevés après 10 étapes (barres). J'ai longtemps cherché une erreur dans le code et j'ai découvert qu'il fonctionne comme il le devrait.

C'est-à-dire que si nous ajoutons simplement une erreur obtenue à la sortie de la grille à tous les poids de la couche de sortie, alors ces coefficients ont tendance à croître trop rapidement.

Le scalimètre ne peut pas tenir... - :) Jusqu'à présent, j'ai seulement essayé de propager l'erreur aux poids de la couche de sortie.

Première question : qu'est-ce que j'ai fait de mal ?

Deuxième question :

Je veux obtenir la probabilité de réussite d'un achat/vente dans la sortie de la grille ou une recommandation pour fumer du bambou. Mais cette grille est formée pour prédire la valeur du RSI à n+1 barres...

Qu'est-ce que j'y gagne ?

 

dans la fonction ORO, les poids ne sont pas modifiés correctement

Lisez la théorie, au moins ici

 
maxfade >> :

dans la fonction ORO, les poids ne sont pas modifiés correctement

lire la théorie, au moins ici

Merci, mais je n'y comprends rien.

 

l'erreur dans la couche de sortie doit être calculée en utilisant la formule e=OUT*(1-OUT)*(TEST-OUT) (ceci est pour la fonction de transfert logistique, pour la tangente hyperbolique la formule semble être un peu différente, mais aussi pas trop compliquée)

le poids des neurones doit être modifié selon la formule w+=nju*e*OUT, où nju est un pas d'apprentissage

si le pas est trop grand, le réseau sera instable et il y aura une augmentation infinie des poids (comme dans votre cas, vous utilisez (TEST-OUT) sans tous les autres multiplicateurs).

S'il est trop petit, le réseau mettra trop de temps à apprendre et risque d'atteindre un minimum local.

 
maxfade >> :

l'erreur dans la couche de sortie doit être calculée en utilisant la formule e=OUT*(1-OUT)*(TEST-OUT) (ceci est pour la fonction de transfert logistique, pour la tangente hyperbolique la formule semble être un peu différente, mais aussi pas trop compliquée)

le poids des neurones doit être modifié selon la formule w+=nju*e*OUT, où nju est un pas d'apprentissage

si le pas est trop grand, le réseau sera instable et il y aura une augmentation infinie des poids (comme dans votre cas, vous utilisez (TEST-OUT) sans tous les autres multiplicateurs).

S'il est trop petit, il mettra trop de temps à apprendre et risque d'atteindre un minimum local.


Merci, je vais essayer maintenant.

 
maxfade >> :

Si le pas est trop grand, le réseau sera instable et il y aura une augmentation infinie des poids (comme dans votre cas, vous utilisez (TEST-OUT) sans tous les autres multiplicateurs).

S'il est trop petit, il mettra trop de temps à apprendre et risque d'atteindre un minimum local.


Je suis légèrement confus par le fait que la modification a pour résultat que la "position relative" des poids reste inchangée. Cela est dû au fait que tous les poids entrants, à la suite de la modification, changent de la même quantité. Dans ce cas, le rapport original des poids a été fixé de manière aléatoire. Cela devrait-il être le cas ?

 

Bonjour, paralocus.

Faisons un pas à la fois. Vous disposez d'un vecteur d'apprentissage de longueur n-comptés, et nous devons générer un vecteur d'erreur pour corriger tous les poids du réseau. Il est clair que la longueur du vecteur sera égale au nombre de poids w en comptant les poids de niveau constant. Le vecteur d'erreur ne sera généré qu'à la fin de la première (deuxième, troisième, etc.) époque d'apprentissage. La méthode de sa formation est la suivante :

1. Lors de la première étape de l'apprentissage (il y a un total de n dans chaque époque), nous formons une erreur individuelle pour chaque poids et ne corrigeons pas les poids. Puis, à la deuxième étape, ayant formé une correction similaire, l'ajouter à la précédente, etc. n-times. Vous obtenez une correction totale (en tenant compte du signe de chaque terme) pour chaque poids. Voici un point important. Cette correction finale ne doit pas être utilisée - les poids vont s'effondrer ! Elle doit être divisée par la norme du vecteur de correction. Pour ce faire, comptez la somme des carrés de chaque correction dans une époque d'apprentissage pour chaque poids séparément. Dès que l'on termine une époque(n-cycles à l'intérieur de celle-ci), on prend la racine carrée de la somme des carrés pour chaque poids séparément, et on divise personnellement chaque correction par cette norme. Nous corrigeons chaque poids.

2. 10 à 1000 époques d'apprentissage, selon l'objectif de l'apprentissage (signe ou amplitude). Procédez de la même manière. Point important : en passant d'une époque à l'autre, il faut strictement observer une diminution monotone de l'amplitude de la correction des poids. La Grille ne doit pas être paresseuse pour chercher un minimum de plus en plus profond dans le potentiel de la fonction d'erreur. Il est mis en œuvre simplement. A la fin d'une époque, avant la correction du poids, on multiplie le correcteur par la valeur 1-j/N, où N est le nombre d'époques d'apprentissage et j est le numéro de l'époque courante.

3. Pour éviter l'effet inévitable de saturation de certains poids du CETI pendant son apprentissage, il est nécessaire d'affecter tous les poids avec une tangente hyperbolique immédiatement après la prochaine correction des poids. Cette procédure n'est pas évidente, mais extrêmement efficace. En raison de la douceur et de la monotonie de la FA utilisée, tous les poids restent toujours dans la fourchette +/-1 et le fait d'agir ne provoque pas d'"hystérie" chez la jeune fille.

C'est tout pour le moment. Digérez et posez des questions.

Quant à la question de savoir comment passer du RSI à l'achat/vente, elle s'adresse plutôt à vous - après tout, c'est vous qui avez eu l'idée de ce mouvement. Par exemple, ce que je "prédis", je l'utilise également pour l'entrée (et je prévois exactement pour l'achat/la vente). C'est pourquoi il n'y a pas de contradiction. Et vous essayez de prédire la couleur du papier peint dans un appartement arbitraire par la couleur d'une voiture devant la fenêtre de sa cuisine...

 

En rédigeant le billet en me souvenant des détails de la mise en œuvre, j'ai relevé quelques inexactitudes.

J'ai regardé le code et il s'avère que j'influençais FA sur les poids une fois lors du passage à une nouvelle prévision, c'est-à-dire pas à chaque époque, mais lorsqu'il était nécessaire de réentraîner le réseau à l'arrivée de nouvelles données.

Une dernière chose. La correction du poids est le produit de l'erreur de la sortie du neurone par la dérivée FA et par la sortie du neurone (amplitude, en tenant compte du signe) d'où provient le signal.

Voici à quoi cela ressemble pour un perseptron avec une sortie non linéaire (par exemple) :

Ici, les époques sont numérotées par l'indice L. J'ai fait exprès de le montrer dans MathCad, c'est plus clair. In - nombre d'entrées, x - vecteur d'entrée. Le reste semble être clair.

 
Neutron >> :

Quant à la façon de passer du RSI à l'achat/vente, c'est plutôt une question pour vous - vous avez trouvé ce mouvement vous-même. Par exemple, ce que je prédis, je l'utilise aussi pour l'entrée (et je prédis exactement pour l'achat/la vente). C'est pourquoi il n'y a pas de contradiction. Et vous essayez de prédire la couleur du papier peint d'un appartement arbitraire en fonction de la couleur de la voiture qui se trouve devant la fenêtre de la cuisine de cet appartement...

Bonjour, Neutron.

Je fais face à ce que tu as écrit en ce moment. C'est juste que les maths grincent vraiment dans ma tête. La programmation est un peu plus facile. Et à propos du papier peint - vous avez tout à fait raison - mais je ne sais toujours pas quoi mettre dans la grille, à part le même papier peint, mais dans une autre usine (je pense que le résultat sera le même). Sur le forum, j'ai lu cet article qui a éveillé mon intérêt pour les réseaux neuronaux. Et dans cet article, comme vous le savez, sur une entrée du perceptron pauvre, des gars intelligents du forum poussent l'indice AO (ou AC - je les confonds constamment), et pour avoir quelque chose à regarder, ils l'ont divisé en "clusters" en partageant les entrées du perceptron sur le graphique de l'indice mentionné(dt/dl ). Ils appellent tout cela "NEUROSETTING" ou même "TRADING WITHIN THE NETHERLANDS O... (non, ce n'est pas ce que j'ai voulu dire) AUTOMATISATION DES SLIVE". C'est beaucoup d'argent... dans un testeur.

Très bien... C'était une digression.

Ainsi, après cet article et quelques autres similaires (grâce aux liens qu'il contient), j'ai commencé à expérimenter les perceptrons de différentes manières. Bref, c'est comme cette chanson :

"Vanka est assis sur le banc, en train de piler trois kopecks avec sa bite.

Il veut gagner trois roubles - Rien ne sort !"

Cependant, mon intérêt pour les non cultivateurs dans le but de les utiliser dans le cadre d'opérations commerciales est resté et s'est même accru au fil du temps. Que je n'ai pas encore trouvé mieux que le regroupement RSI - ce n'est pas la faute de mon oncle, mais c'est une "arme à double tranchant". C'est-à-dire que pour savoir quoi et comment mettre dans les mailles d'entrée, j'ai besoin de savoir comment ces mailles sont disposées et non seulement de savoir, mais aussi d'être capable de les faire. Au moins sous certaines formes pas très compliquées, mais suffisantes pour un travail stable sur le réel. C'est pourquoi je me suis tourné vers vous.


P.S. Rien que je sois allé sur un "vous" ? C'est plus gentil comme ça.