preview
Rede neural na prática: Reta Secante

Rede neural na prática: Reta Secante

MetaTrader 5Aprendizado de máquina | 7 março 2024, 17:10
165 0
Daniel Jose
Daniel Jose

Introdução

Bem vindos meus caros leitores, a um assunto que não irei tratar como uma série de artigos.

Apesar de muitos imaginarem que seria melhor termos uma série de artigos sobre o tema de inteligência artificial. Não vejo como fazer isto. Já que a maior parte de fato não tem a mínima noção do real objetivo de redes neurais e por consequência as chamadas inteligências artificiais.

Aqui não iremos tratar do tema, focando em um ou outro objetivo final. Por tanto, você poderá ler meus artigos sobre o tema em qualquer ordem que desejar. Podendo apenas focar em um ou outro. Já que irei abordar o tema de redes neurais e inteligência artificial, da maneira o mais ampla possível. O objetivo aqui, não será criar um sistema voltado para operar no mercado, ou para algum propósito específico. O objetivo aqui será explicar, mas principalmente mostrar. Por que e como um programa de computador consegue fazer o que a mídia vem mostrando. E que tanto fascínio gerou em tanta gente. A ponto de muitos acreditarem que redes neurais ou inteligência artificial, pode ter algum nível de consciência.

Para mim existe uma diferença entre redes neurais e inteligência artificial. Mas isto é na minha visão. Ao logo dos artigos, você irá notar que, uma inteligência artificial ou mesmo uma rede neural. Não tem nada de especial. Apenas trata-se de um programa bem elaborado e pensado de maneira a se conseguir um determinado objetivo. Mas não tenha pressa. Vamos passar por diversas etapas de desenvolvimento, para que você de fato consiga compreender como e por que as coisas funcionam. Não iremos usar nada que não seja o MQL5 puro.

Este será o meu desafio pessoal. Mas você irá ver que se tivermos os conceitos certos e o real conhecimento de como as coisas funcionam. Poderá usar qualquer linguagem para produzir o que será visto aqui. Então tenham todos uma excelente leitura e que estes artigos sejam divertidos e lhes tragam algum conhecimento sobre o tema.


A regressão linear

Como foi explicado na parte teórica. Precisamos usar regressões lineares e derivadas, quando o assunto é rede neural. Mas por que ?!?! O motivo disto, é que a regressão linear é uma das fórmulas mais simples que existe. Basicamente uma regressão linear, é apenas uma função afim. Porém quando falamos em rede neural, não estamos interessados na reta, que a regressão linear cria. Estamos interessados é na equação que gera tal reta. A reta gerada pouco importa. Mas a fórmula é a parte que interessa.

Para entender, vamos criar um pequeno indicador, como mostrado no código abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property indicator_chart_window
04. #property indicator_plots 0
05. //+------------------------------------------------------------------+
06. #include <Canvas\Canvas.mqh>
07. //+------------------------------------------------------------------+
08. CCanvas canvas;
09. //+------------------------------------------------------------------+
10. void Func_01(const int x, const int y)
11. {
12.     int A[] {
13.                 -100,  150,
14.                  -80,   50,
15.                   30,  -80,
16.                  100, -120
17.             };
18. 
19.     canvas.LineVertical(x, y - 200, y + 200, ColorToARGB(clrRoyalBlue, 255));
20.     canvas.LineHorizontal(x - 200, x + 200, y, ColorToARGB(clrRoyalBlue, 255));
21. 
22.     for (uint c0 = 0, c1 = 0; c1 < A.Size(); c0++)
23.         canvas.FillCircle(x + A[c1++], y + A[c1++], 5, ColorToARGB(clrRed, 255));
24. }
25. //+------------------------------------------------------------------+
26. int OnInit()
27. {    
28.     int px, py;
29.     
30.     px = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0);
31.     py = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0);
32. 
33.     canvas.CreateBitmapLabel("BL", 0, 0, px, py, COLOR_FORMAT_ARGB_NORMALIZE);
34.     canvas.Erase(ColorToARGB(clrWhite, 255));
35.         
36.     Func_01(px / 2, py / 2);
37. 
38.     canvas.Update(true);
39.     
40.     return INIT_SUCCEEDED;
41. }
42. //+------------------------------------------------------------------+
43. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
44. {
45.     return rates_total;
46. }
47. //+------------------------------------------------------------------+
48. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
49. {
50. }
51. //+------------------------------------------------------------------+
52. void OnDeinit(const int reason)
53. {
54.     canvas.Destroy();
55. }
56. //+------------------------------------------------------------------+

Ao executar este código, você verá a seguinte imagem, mostrada logo abaixo.


Muito bem, neste exato momento, vamos começar a entender, por que de usar regressão linear e derivadas, quando o assunto é rede neural. Os pontos vermelhos representam informações presentes dentro da rede neural. Ou seja, a inteligência artificial, foi treinada, e contem as informações que são vistas como pontos vermelhos. As linhas em azul são os eixos de coordenadas. A pergunta é: Qual equação matemática melhor descreve este conjunto de dados ?!?! Ou melhor dizendo. Se tivéssemos de resumir o conhecimento mostrado na imagem acima. Qual fórmula matemática, melhor representaria este mesmo conhecimento ?!?! Olhando para a distribuição dos pontos, você diria que seria uma reta. Então, pensaria na equação de uma reta, que é uma função afim. Esta tem o formado mostrado na imagem abaixo.


Ok, esta função serve para que venhamos a criar uma reta. Então voltando a questão principal. Quais os valores para A e B, que deveremos usar a fim de que a reta seja criada da melhor maneira possível. Bem, muitos poderiam dizer, que poderíamos buscar estes valores na base da tentativa e erro. De fato, porém, vamos simplificar um pouco as coisas. Para isto, assumiremos que B é igual a zero. Ou seja, a reta passará pela origem do eixo de coordenadas. Faremos isto neste primeiro momento, apenas para simplificar inicialmente as coisas. A fim de que você, meu caro leitor, possa compreender a matemática usada na rede neural.

Fazendo desta maneira, tudo que nos resta é procurar um valor para a constante A. Agora vem uma nova pergunta: Como você pretende achar este valor para A. Você pode colocar qualquer valor. Mas dependendo do valor usado, a fórmula, não estará de fato otimizada. Mesmo para uma quantidade tão pequena de conhecimento dentro da nossa rede neural. Não é adequado, que este conhecimento seja perdido. Por isto, não usamos, ou não podemos usar qualquer valor. Precisamos procurar um valor em que A seja o melhor valor possível.

E é neste ponto em que a máquina começa a aprender. Ou que surge o tal termo: Aprendizagem de máquina, ou do inglês: Machine Learning. Muita gente usa este termo, sem de fato entender o que ele quer dizer. A ideia aqui, é justamente isto. Criar uma equação matemática, que melhor representa os pontos de conhecimento dentro da rede. Fazer isto manualmente é uma das tarefas mais complicadas e difíceis que existe. Porém usando, de manipulações matemáticas, podemos fazer com que a máquina gere uma equação para nos. E isto é o tal sistema de aprendizagem de máquina. Força de alguma forma que o computador, crie uma equação matemática de forma automática.

Muito bem, agora você começou a entender como uma máquina aprende. Esta é uma das maneiras de se fazer isto. Existem outras. Porém neste momento, vamos focar nesta maneira. Assim, já temos o que precisamos fazer. Bolar alguma maneira de encontrar o melhor valor para a constante A na equação afim mostrada acima.

Neste ponto, você pode pensar o seguinte: Podemos criar um laço, que varrerá todos os valores dentro de um dado range. Isto de fato funcionaria. Porém não seria eficiente em termos de computação. Para entender, pense no seguinte: Este exemplo que estamos usando, precisa de apenas um único valor, que é a constante A. Isto por que estamos considerando o valor da constante B como sendo zero. Mas na prática, B muito provavelmente não será zero. Então esta solução de varrer um range de valores, não atende a todas as situações possíveis. E precisamos de fato, construir algo que consiga atender a todas a situações possíveis. Mesmo quanto tivermos de ajustar o valor da constante B.

Entendido este ponto, podemos começar a pensar em como resolver esta questão. Para que as coisas fiquem mais agradáveis de serem compreendidas. Vamos mudar um pouco o programa original, a fim de termos uma visualização melhor do que será feito, em termos de matemática. Com isto o novo código pode ser visto abaixo:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property indicator_chart_window
04. #property indicator_plots 0
05. //+------------------------------------------------------------------+
06. #include <Canvas\Canvas.mqh>
07. //+------------------------------------------------------------------+
08. #define _ToRadians(A) (A * (M_PI / 180.0))
09. #define _SizeLine 200
10. //+------------------------------------------------------------------+
11. CCanvas canvas;
12. //+------------------------------------------------------------------+
13. struct st_00
14. {
15.     int     x,
16.             y;
17.     double  Angle;
18. }global;
19. //+------------------------------------------------------------------+
20. void Func_01(void)
21. {
22.     int A[] {
23.                   -100,  150,
24.                    -80,   50,
25.                     30,  -80,
26.                    100, -120
27.             };
28. 
29.     canvas.LineVertical(global.x, global.y - _SizeLine, global.y + _SizeLine, ColorToARGB(clrRoyalBlue, 255));
30.     canvas.LineHorizontal(global.x - _SizeLine, global.x + _SizeLine, global.y, ColorToARGB(clrRoyalBlue, 255));
31. 
32.     for (uint c0 = 0, c1 = 0; c1 < A.Size(); c0++)
33.         canvas.FillCircle(global.x + A[c1++], global.y + A[c1++], 5, ColorToARGB(clrRed, 255));
34. }
35. //+------------------------------------------------------------------+
36. void NewAngle(const char direct, const double step = 1)
37. {
38.     canvas.Erase(ColorToARGB(clrWhite, 255));
39.     Func_01();
40. 
41.     global.Angle = (MathAbs(global.Angle + (step * direct)) <= 90 ? global.Angle + (step * direct) : global.Angle);
42.     canvas.TextOut(global.x + 250, global.y, StringFormat("%.2f", global.Angle), ColorToARGB(clrBlack));
43.     canvas.Line(
44.                 global.x - (int)(_SizeLine * cos(_ToRadians(global.Angle))), 
45.                 global.y - (int)(_SizeLine * sin(_ToRadians(global.Angle))), 
46.                 global.x + (int)(_SizeLine * cos(_ToRadians(global.Angle))), 
47.                 global.y + (int)(_SizeLine * sin(_ToRadians(global.Angle))), 
48.                 ColorToARGB(clrForestGreen)
49.             );
50.     canvas.Update(true);
51. }
52. //+------------------------------------------------------------------+
53. int OnInit()
54. {    
55.     global.Angle = 0;
56.     global.x = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0);
57.     global.y = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0);
58. 
59.     canvas.CreateBitmapLabel("BL", 0, 0, global.x, global.y, COLOR_FORMAT_ARGB_NORMALIZE);
60.     global.x /= 2;
61.     global.y /= 2;
62.         
63.     NewAngle(0);
64. 
65.     canvas.Update(true);
66.     
67.     return INIT_SUCCEEDED;
68. }
69. //+------------------------------------------------------------------+
70. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
71. {
72.     return rates_total;
73. }
74. //+------------------------------------------------------------------+
75. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
76. {
77.     switch (id)
78.     {
79.         case CHARTEVENT_KEYDOWN:
80.             if (TerminalInfoInteger(TERMINAL_KEYSTATE_LEFT))
81.                 NewAngle(-1);
82.             if (TerminalInfoInteger(TERMINAL_KEYSTATE_RIGHT))
83.                 NewAngle(1);
84.             break;
85.     }
86. }
87. //+------------------------------------------------------------------+
88. void OnDeinit(const int reason)
89. {
90.     canvas.Destroy();
91. }
92. //+------------------------------------------------------------------+

Muito bem, o que temos aqui é visto na animação abaixo:


Ou seja, podemos gerar uma equação afim, onde o valor da constante A pode ser ajustada, gerando o que seria um possível equação de regressão linear. Isto de forma a tentar conservar o conhecimento existente. Ou seja, os pontos em vermelho. A equação no caso, que você pensaria ser a correta. Seria a equação mostrada na imagem abaixo. Onde o ângulo informado, é exatamente o que você nota, ao usar as setas para a esquerda ou direita.


Ou seja, você imaginaria que a tal constante que estaríamos procurando, poderia ser o seno do ângulo. Criando assim nossa equação. Porém, você estaria errado. Não por imaginar que a constante não estaria ligada ao ângulo. Pois de fato ela está ligada ao ângulo. Mas você estaria errado por pensar que deveria usar o seno ou cosseno. No entanto, este método, não é a melhor forma geral de expressar as coisas. Normalmente você não verá uma equação afim, sendo escrita fazendo uso de funções trigonométrica. Não que seja errado, porém é incomum. Porém ainda neste artigo, iremos ver como poderemos usar o ângulo a fim de obter a tal constante. Mas vamos devagar, por que ainda é preciso explicar outras coisas antes disto. Mas mudando um pouco mais o código, como mostrado no fragmento abaixo, podemos verificar algo, que seria um pouco mais, como realmente seria normalmente a equação correta da reta mostrada na animação. Ou seja, agora a constante de fato utiliza o termo correto.

35. //+------------------------------------------------------------------+
36. void NewAngle(const char direct, const double step = 1)
37. {
38.     canvas.Erase(ColorToARGB(clrWhite, 255));
39.     Func_01();
40. 
41.     global.Angle = (MathAbs(global.Angle + (step * direct)) < 90 ? global.Angle + (step * direct) : global.Angle);
42.     canvas.TextOut(global.x + _SizeLine + 50, global.y, StringFormat("%.2f", MathAbs(global.Angle)), ColorToARGB(clrBlack));
43.     canvas.TextOut(global.x, global.y + _SizeLine + 50, StringFormat("f(x) = %.2fx", -MathTan(_ToRadians(global.Angle))), ColorToARGB(clrBlack));
44.     canvas.Line(
45.                 global.x - (int)(_SizeLine * cos(_ToRadians(global.Angle))), 
46.                 global.y - (int)(_SizeLine * sin(_ToRadians(global.Angle))), 
47.                 global.x + (int)(_SizeLine * cos(_ToRadians(global.Angle))), 
48.                 global.y + (int)(_SizeLine * sin(_ToRadians(global.Angle))), 
49.                 ColorToARGB(clrForestGreen)
50.             );
51.     canvas.Update(true);
52. }
53. //+------------------------------------------------------------------+

O resultado da execução pode ser visto na animação imediatamente abaixo.


Observe que agora, temos, por conta da linha 43, algo bem próximo ao que seria uma equação de reta. Perceba, que para criar a fórmula, usaremos a tangente do ângulo, e não o seno ou o cosseno que muitos poderiam imaginar ser o correto. Mas isto é apenas uma tentativa de gerar o valor mais adequado. Porém apesar de estamos conseguindo gerar uma equação. Você pode notar que não é simples de acertar o melhor valor de inclinação da reta. Ou seja, o ângulo do sistema. Você pode até tentar fazer isto de maneira manual. No entanto, tal tarefa, é extremamente complicada de ser feita. Apesar de toda a dificuldade gerada para conseguir uma equação, que nos daria uma regressão linear. Você deve notar, que estamos trabalhando, neste momento, com apenas e somente uma única variável neste sistema. Esta é justamente o valor que precisamos encontrar, como mostrado na animação acima.

Mas a matemática, se devidamente utilizada nos permitirá encontrar algo que seria o valor mais adequado para o ângulo de inclinação. E para fazer isto, precisaremos usar derivadas no nosso sistema. Assim como também, para entender, por que a tangente é a função trigonométrica que melhor indica a constante a ser usada na equação. Mas para que você, meu caro leitor, consiga entender isto. Vamos abrir um novo tópico, a fim de não tornar as coisas confusas para você.


Fazendo uso de derivadas

Neste ponto é que a matemática, começa a ficar um tanto quanto confusa para muitos. Porém, não é motivo para desespero, medo, ou aflição nos corações. O que precisaremos fazer, é simplesmente dizer ao nosso código, como ele pode encontrar o melhor valor para ângulo. Isto para que a equação, nos permita ter acesso aos valores já conhecidos. Ou nos aproximar o máximo possível deles. Assim a equação, terá como constantes os valores mais próximos possíveis dos valores ideais. Isto fará com que o conhecimento presente no gráfico, seja minimamente conservado em um formato de equação, que no caso seria uma equação linear.

O fato de usarmos e procurarmos uma equação linear. Que muitas das vezes se parece com uma regressão linear. É devido ao fato, de que calcular as constantes necessárias é mais simples neste tipo de equação. Não é por conta que ela é a melhor escolha, representando melhor os valores no gráfico. Mas simplesmente por ela ser mais simples de calcular. E mesmo assim, em alguns casos, o tempo de processamento pode ser bem grande. Mas isto será tema para um outro momento futuro.

Desta forma, para podermos calcular a tal equação, precisaremos de alguns artifícios matemáticos. Já que uma função afim, que é uma função de reta, não nos permite gerar uma derivada. Isto por que uma derivada, é justamente uma reta que passa em um dado ponto, que é conseguido usando uma equação qualquer. Muitos fazem uma baita de uma confusão, para explicar isto. Mas em essência, uma derivada nada mais é do que uma reta tangente em um ponto qualquer de uma função. Esta reta tangente é traçada justamente em um ponto pertencente a uma equação, que normalmente criará uma curva no gráfico. Ou seja, como a função afim é uma reta tangente. Por isto a tangente representa tão bem, o valor da constante que multiplica a parte desconhecida, nos fornecendo assim a equação daquela reta específica. Por conta disto, não temos como traçar uma segunda reta tangente fazendo uso desta equação original. Precisamos de algum artifício para fazer isto. Resumindo, independente do ponto que venhamos a tentar utilizar para gerar a derivada. NÃO É POSSÍVEL CRIAR UMA DERIVADA EM UMA FUNÇÃO AFIM.

Porém existem algumas forma de tornar a criação da derivada possível. E é isto que começaremos a ver neste tópico. Bem, para entender como faremos isto, primeiro é preciso que você, meu caro leitor, entenda definitivamente o que é esta tal derivada. Isto mesmo antes de entender o método que utilizaremos para gerar a tal derivada e assim conseguir criar a função afim, que descreveria a reta minimamente ideal. Para fazer isto, vamos utilizar uma função que permita traçar uma derivada. Sendo a mais simples delas, a função quadrática. Para quem não conhece, a tal função tem a seguinte fórmula vista abaixo.


Note o fato, de termos um expoente dois nesta equação. O simples motivo de isto acontecer, já nos permite explicar uma derivada no sistema derivada. Mas poderíamos usar qualquer função para gerar a curva. Poderia ser até mesmo uma função log. Porém a função Log não faria sentido, no momento em que formos visualizar outra coisa, que precisaremos fazer depois. Então, por este motivo e para simplificar ao máximo as coisas, vamos usar esta equação quadrática. Assim quando você utiliza a fórmula mostrada acima, conseguirá o gráfico visto abaixo.


Este gráfico é conseguido, ao usarmos o valor de A como sendo um, e tornando os valores tanto de B como de C iguais a zero. Porém este fato não importa muito. O que realmente nos importa é a curva que pode ser vista no gráfico. Está sim, que nos interessa.

Agora preste bastante atenção, pois o que será explicado é importante para entender o que será feito lá no nosso programa, para que ele consiga encontrar a tal equação que tanto desejamos.

Com base no gráfico visto acima, vamos supor, e desde momento em diante, entender estas suposições é importante. Que você queira saber o valor da derivada para a posição onde X é igual a quarto. Bem para fazer isto, você deverá traçar uma reta tangente, que deverá passar obrigatoriamente e exatamente no ponto onde X é igual a quatro. Parece ser fácil de fazer tal coisa, você pega uma régua, marca o ponto igual a quatro na coordenada X. E ali tenta fazer uma reta que tangencia aquele ponto na curva. Hum, mas será que você de fato conseguirá traçar a reta tangente fazendo isto ?!?! Bem, isto é pouco provável. Sendo bem mais provável que você crie uma reta, que não será a reta tangente.

Por conta disto, é preciso que usemos alguns cálculos. E é aqui que a coisa começa a complicar. Mas para não tornar a coisa complicada, sem a devida necessidade. Não vou entrar nos detalhes do cálculo em si, neste momento. Vou pressupor que você saiba qual é a fórmula da derivada de uma equação quadrática. Depois explicarei como esta fórmula é obtida, isto para aqueles que desconhecem tal fato. Pois a forma como as equações de derivadas são conseguidas. É de suma importância para nos. A fórmula final, pouco importa. Mas a fórmula que conseguir a derivada, está é importante. Mas então vamos continuar.

A derivada de uma equação quadrática, é conseguida usando a fórmula vista logo abaixo.


Aqui estou mostrando ambas notações mais comuns. Você pode usar a da direita, ou da esquerda. Isto não importa. O que nos interessa, neste momento, é a fórmula em sim. Que é justamente dois que multiplica X. Esta fórmula nos dá um valor. que para nosso exemplo é oito, já que o ponto de origem é quatro. Se você sabe o que este valor oito, significa já será capaz de traçar a reta tangente no ponto onde X vale quatro. Porém caso você não saiba o que este valor oito significa, precisará de uma segunda fórmula para traça a reta tangente. 

Se você não entendeu por que o valor é oito. Veja a imagem abaixo, onde queremos a derivada no X igual a quatro. Para isto, calculamos o valor nesta posição. Como é mostrado abaixo.


Ok, mas antes de vermos outros cálculos, vamos entender o que este oito significa. Este valor significa que se avançarmos uma posição no eixo X, precisaremos avançar oito no eixo Y. Isto nos permite traçar a reta tangente. Talvez você não esteja acreditando, e precise ver isto acontecendo de fato. Se este for o seu caso, existe um fórmula que permite criar a equação desta reta tangente. Tal equação pode ser vista abaixo.


Parece algo assustador. Mas é muito mais simples do que parece. Porém esta fórmula é bastante especial. Ela nos permite criar a equação da reta tangente da derivada. Se bem que a derivada em última instância será uma reta tangente. Mas isto é apenas um fato que estou mencionado como uma curiosidade. Não é algo do qual você precisará se preocupar. Muito bem, como já conhecemos grande parte dos valores a serem usados. Podemos fazer as substituições para encontrar a fórmula da equação da reta tangente. Isto pode ser visto logo abaixo.


Aqui, é onde muitos acabam se complicando. Mas vamos entender de onde vieram os valores mostrado aqui. O valor 16 é o resultado da equação original. Ou seja, colocamos na equação quadrática o valor de X que estamos usando na derivada, ou seja quatro. O valor oito, vem do cálculo efetuado na função derivada. Novamente o X vale quatro, e isto também se aplica na função de derivada. O valor quatro que vemos aqui, é o valor de X inicial, que estamos usando em todas as demais equações. Efetuamos os cálculos, chegamos a seguinte fórmula da reta tangente, que é vista logo abaixo.


Legal, agora podemos finalmente traçar a reta tangente com base na equação vista acima. A reta traçada, pode ser vista na imagem abaixo em vermelho.


Este gráfico, acima foi feito usando o SCILAB. Para quem desejar observar com mais atenção. O código a ser usado no SCILAB, para gerar esta figura acima é visto logo abaixo.

x = [-10:.2:10];
y = x ^ 2;

plot(x, y, 'b-');
plot(4, 16, 'ro');

x = [2:.2:10];
y = 8 * x - 16;

plot(x, y, 'r-');

Estou adicionando isto, para que você, meu caro leitor, perceba, que não é só aprender a usar um ou outro programa. Esta ou aquela linguagem que vai lhe tornar alguém realmente capacitado. Muitas das vezes, precisamos recorrer a diversos programas diferentes, para conseguir analisar de forma clara as coisas. Por isto é importante sempre estar estudando. Não importa o qual bom você se imagina ser. Sempre haverá alguém um pouco mais capacitado do que você em alguma área de atuação. Por isto estude sempre.

Muito bem, agora já temos todo o conhecimento do qual precisaremos. Mas o que esta reta tangente quer nos dizer ?!?! E por que ela é tão especial para quem trabalha com redes neurais ?!?! O motivo é que esta reta nos diz para onde devemos ir. Ou melhor, para onde nosso programa, deverá ir a fim de conseguir gerar a tal equação de regressão linear.

Mas não é só isto, esta reta nos explica como devemos calcular os desvios. E é neste cálculo que mora a magia das redes neurais. Você não consegue ver isto ?!?! Ou não entende como isto é possível de ser feito ?!?! Bem, para entender é preciso entender o que gera o cálculo da derivada, que informei a pouco para você. Pois apesar de no final usarmos uma reta tangente, o cálculo não nasce de uma reta tangente. Ele surge de uma outra função trigonométrica. E é ali onde mora a mágica do sistema. E esta mágica nos permite criar uma solução genérica, para todos os casos possíveis e imagináveis a fim de que a rede neural funcione. Então vamos entender isto em um outro tópico. Para deixar as coisas bem separadas.


A Reta Secante

Apesar de todos quando falam de rede neurais, apenas falarem de derivadas. Não é na derivada ou na reta tangente que está o segredo. Mas sim em uma outra reta. A reta secante. Por isto havia uma certa resignação da minha parte em escrever sobre este tema, que é o de rede neurais. Mesmo com algumas pessoas me pedindo para explicar sobre o tema. A grande verdade, é que apesar de muitos dizerem algo sobre redes neurais. Poucos de fato conseguem entender como elas de fato funcionam. Isto olhando pelo ponto de vista matemático da coisa. A programação é a parte fácil, a matemática é a parte complicada. Grande parte acreditam que é preciso usar esta ou aquela biblioteca. Esta ou aquela linguagem de programação. Mas no bem da verdade, podemos usar qualquer linguagem, desde é claro, você entenda como a parte matemática funciona. Não estou aqui para falar mal de ninguém, tão pouco, dizer que estão errados na forma como explicam ou dizem as coisas. Cada um é livre para entender as coisas como bem desejar. Porém, minha vontade, é de fato explicar como as coisas funcionam. Não quero que você, meu caro leitor, seja mais um escravo de uma linguagem ou biblioteca. Quero que você aprenda e entenda, como as coisas funcionam por dentro. Por isto, decidi criar estes artigos, para falar sobre o tema.

A ideia por trás, da derivada, é justamente procurar o valor da reta tangente. Isto por que a reta tangente nos diz, qual a inclinação que a função está tendo. Ou melhor dizendo. Qual o erro que está acontecendo na regressão linear, isto quando ela está sendo usada em uma rede neural. Então quando a reta tangente começar a alcançar o ângulo de zero graus, o erro começará a se aproximar de zero. Ou seja, a equação que gera a regressão linear sobre os valores já existentes no banco de dados, começa a se aproximar dos valores ideias. Isto para aquele caso específico e valores específicos.

Porém quando vamos, de fato fazer os cálculos, não usamos a reta tangente. Usamos de fato a reta secante. Pouco importa o tipo de rede neural implementada. Se está sendo feito um cálculo ali, ele não é usando a reta tangente, mas sim a reta secante. Você pode estar pensando que isto parece muito mais complicado. Mas se você pensou assim, significa que não sabe como a reta tangente da derivada de fato é conseguida. Ou pior, como a fórmula da derivada é obtida. Decorar fórmulas não está com nada. O correto é entender por que da fórmula ter aquele e não este formato. Lembra dos cálculos vistos no tópico anterior ?!?! Você sabe de onde eles vieram ?!?!. Se não, veja o seguinte gráfico mostrado abaixo.


A linha em vermelho neste gráfico é a reta secante. Se antes você estava pretendo atenção. Agora quero que você redobre a sua atenção. Pois isto daqui será ainda mais importante, do que qualquer outra coisa que você possa vir a ler ou ouvir sobre redes neurais.

Aqui estou usando o mesmo ponto X que foi usado no tópico anterior, ou seja, o valor quatro. Isto para que você consiga realmente entender o que desejo explicar.

Observe que é impossível gerar a reta tangente, não importa o que você pense, ou o que imagine. NÃO DÁ PARA GERAR UMA RETA TANGENTE A PARTIR DE UMA CURVA NO GRÁFICO. Porém se usarmos a reta secante podemos conseguir a reta tangente. Como ?!?! Simples. Veja que f(x + h) é f(x) deslocado em uma distância h. Então se h tender a zero, o resultado será que a reta secante tenderá a se tornar a reta tangente. E quando h for exatamente zero. a reta secante, vista na imagem, será exatamente a reta tangente. Ou seja, neste ponto, a reta tangente nos dará a inclinação da derivada da função, naquele ponto. Ok, mas ainda não entendi. Bem, meu caro leitor, vamos colocar o que é visto acima, de uma forma que fique um pouco menos poluído. Assim, talvez fique mais claro.


Nesta imagem acima, temos exatamente o que é visto na imagem anterior. Assim acredito que ficará mais claro, a ideia de usar a secante. E por que diferente do que todos afirma, que usamos a reta tangente, ou derivadas. Quando usamos uma rede neural, na verdade usamos a reta secante, para que a máquina consiga gerar a equação correta.

Se você reduzir o valor de h, começará a se aproximar do f(x), porém este h nunca será de fato zero. Isto quando estamos usando redes neurais. Ele pode ser um valor bem pequeno. O quanto este valor será pequeno dependerá de uma coisa, que veremos mais para frente. Tal coisa é conhecida como: Loucura da rede neural. Quanto menor este h for, menos louca será a rede neural, porém quanto maior ele for, mais louca ela será. Mas por que ?!?! O motivo é a convergência. Durante os cálculos que veremos depois, você perceberá que esta convergência, tende ao valor de h. Isto fará com que a equação gerada no final, tenda a variar dentro desta convergência. Por isto este h é importante. Parece complicado falando assim, mas você verá que é bem mais simples na prática. Mas ainda não cheguei no ponto em que quero mostrar. Se você, então jogar esta imagem acima, em uma fórmula, irá ter o seguinte cálculo sendo feito.


Esta fórmula, nos diz o quanto a reta secante está distante da reta tangente. Mas o cálculo realmente usado é o que pode ser visto na imagem abaixo.


É esta equação que explica tudo que você precisa saber sobre redes neurais. E é aqui o motivo de dizerem que redes neurais usam derivadas. Pois esta equação é a que gera aqueles cálculos que muitos simplesmente decoram. Que são as fórmulas das tais derivadas. Pronto. Não existe mais nada a ser explicado ou falado. Pois tudo que precisamos é desta equação mostrada acima. Com isto posso encerrar e seguir a minha vida tranquilamente.


Considerações finais

Mas espere um pouco ai. Você não explicou como esta equação da reta secante é usada, e por que ela explica tudo. Como assim não tem mais nada a explicar ?!?! "Tú tá de sacanagem ?!?!" De fato meu caro leitor. Aqui apenas comecei a introduzir a questão. Porém quero que você estude este artigo com bastante calma. No próximo artigo sobre redes neurais, mostrarei como usar o conhecimento mostrado aqui a fim de conseguir gerar a equação correta.


Arquivos anexados |
Anexo_01.mq5 (3.49 KB)
Teoria das Categorias em MQL5 (Parte 22): Outra Perspectiva sobre Médias Móveis Teoria das Categorias em MQL5 (Parte 22): Outra Perspectiva sobre Médias Móveis
Neste artigo, tentaremos simplificar a descrição dos conceitos discutidos nesta série, focando apenas em um indicador, o mais comum e, provavelmente, o mais fácil de entender. Estamos falando da média móvel. Também examinaremos o significado e as possíveis aplicações das transformações naturais verticais.
Algoritmos de otimização populacionais: Algoritmo de evolução da mente (Mind Evolutionary Computation, MEC) Algoritmos de otimização populacionais: Algoritmo de evolução da mente (Mind Evolutionary Computation, MEC)
Este artigo discute um algoritmo da família MEC, denominado algoritmo simples de evolução da mente (Simple MEC, SMEC). O algoritmo se destaca pela beleza da ideia subjacente e pela simplicidade de implementação.
Interface Gráfico: Dicas e recomendações para criar uma biblioteca gráfica no MQL Interface Gráfico: Dicas e recomendações para criar uma biblioteca gráfica no MQL
Vamos explorar os fundamentos das bibliotecas de interface gráfica para que você possa entender como elas funcionam ou até mesmo começar a criar as suas próprias.
Modelos prontos para integrar indicadores nos Expert Advisors (Parte 3): Indicadores de tendência Modelos prontos para integrar indicadores nos Expert Advisors (Parte 3): Indicadores de tendência
Neste artigo de referência, vamos dar uma olhada nos indicadores padrão da categoria Indicadores de tendência. Criaremos modelos prontos a serem usados em Expert Advisors, modelos esses que incluirão: declaração e configuração de parâmetros, inicialização/desinicialização de indicadores e recuperação de dados/sinais a partir de buffers de indicador em EAs.