English Español Português
preview
Нейронная сеть на практике: Секущая прямая

Нейронная сеть на практике: Секущая прямая

MetaTrader 5Машинное обучение | 23 августа 2024, 08:18
139 0
Daniel Jose
Daniel Jose

Введение

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

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

Так что мы не будем здесь подробно рассматривать данную тему. Мы сосредоточимся на иных аспектах. Поэтому вы можете читать мои статьи на эту тему в любом порядке и сосредоточиться на нужном именно вам материале. Мы будем рассматривать тему нейронных сетей и искусственного интеллекта как можно шире. Здесь главное не в том, чтобы создать систему, ориентированную на рынок или на какую-то конкретную задачу. Наша цель объяснить и показать, каким образом компьютерная программа может выполнять то, что было показано в средствах массовой информации, и что настолько завораживает многих людей, заставляя их поверить, что нейронные сети или искусственный интеллект могут обладать определенным уровнем сознания.

Я вижу разницу между нейронными сетями и искусственным интеллектом, но это, конечно, только моё мнение. В данной серии статей вы увидите, что в искусственном интеллекте и нейронных сетях нет ничего особенного. Это просто хорошо продуманная программа, направленная на достижение конкретной цели. Но давайте пока не будем торопиться. Сначала мы должны пройти через различные этапы, чтобы понять, как всё работает. Мы не будем использовать ничего, кроме MQL5.

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


Линейная регрессия

Как уже объяснялось в теоретической части, при работе с нейронными сетями нам необходимо использовать линейные регрессии и производные. Но почему? Причина заключается в том, что линейная регрессия - одна из самых простых из существующих формул. На самом деле, линейная регрессия - это просто аффинная функция. Однако, когда мы говорим о нейронных сетях, нас не интересуют эффекты прямой линейной регрессии. Нас интересует уравнение, которое порождает данную прямую. Созданная прямая не имеет большого значения: нас интересует именно формула.

Чтобы понять это, давайте создадим небольшой индикатор, как показано в коде ниже.

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. //+------------------------------------------------------------------+

Когда этот код будет выполнен, на экране появится следующее изображение.


Именно в этот момент мы должны начать разбираться в том, зачем использовать линейную регрессию и производные при работе с нейронными сетями. Красные точки представляют информацию, присутствующую в нейронной сети, то есть искусственный интеллект был обучен и содержит информацию, которая отображается в виде красных точек. Синие линии - это координатные оси. Вопрос в том, какое математическое уравнение лучше всего описывает этот набор данных? Или, иными словами, если бы мы обобщили понятия, изображенные на картинке выше, какая математическая формула лучше всего представила бы данные понятия? Если посмотреть на распределение точек, можно сказать, что это прямая линия. Тогда мы могли бы подумать об уравнении линии, которое является аффинной функцией. Это происходит в формате, который показан на рисунке ниже.


Хорошо, эта функция используется для создания линии. Давайте вернемся к главному вопросу. Какие значения A и B мы должны использовать, чтобы создать линию наилучшим образом? Итак, многие могут сказать, что искать их нужно методом проб и ошибок. На самом деле стоит немного упростить ситуацию. Для этого мы будем считать, что B равен нулю. Т.е. линия будет проходить через начало координатной оси. Сначала мы сделаем это просто для упрощения, чтобы понять математику, используемую в нейронной сети.

Таким образом, остается только найти значение константы A. Теперь возникает еще один вопрос: как мы собираемся найти это значение для A? Можно поставить любое, но в зависимости от используемого значения, формула не будет по-настоящему оптимизированной. Даже для такого небольшого объема знаний, хранящихся в нашей нейронной сети, было бы нецелесообразно потерять их. По этой причине мы не используем (или не можем использовать) какое-либо значение. Нам нужно найти значение, при котором A было бы наилучшим возможным значением.

И именно в этот момент машина начинает обучаться. Здесь и возникает термин «машинное обучение» (Machine Learning, ML). Многие люди используют этот термин, не понимая его значения. Идея заключается именно в этом: составить математическое уравнение, которое наилучшим образом отражает точки знания внутри сети. Делать это вручную - одна из самых сложных задач. Однако с помощью математических манипуляций мы можем заставить машину создать для нас уравнение. А именно это и есть система машинного обучения. Идея заключается в том, чтобы каким-то образом заставить компьютер автоматически составить математическое уравнение.

Теперь мы начинаем понимать, как учится машина. Это лишь один из способов сделать это, но есть и другие. Однако сейчас мы остановимся именно на данном методе. Теперь у нас есть задача для выполнения. Мы должны рассчитать, каким образом можно найти оптимальное значение константы A в аффинном уравнении, показанном выше.

Сейчас можно подумать о следующем: Мы можем создать цикл, который перебирает все значения в заданном диапазоне. На самом деле это сработает, но не будет эффективным с точки зрения вычислений. Чтобы понять это, подумайте о следующем: В данном примере нам нужна только одна переменная - константа A. Это происходит таким образом, что мы считаем значение константы B равным нулю. Однако на практике, скорее всего, константа B не будет равна нулю. Поэтому данный метод обхода диапазона значений работает не во всех ситуациях. Нам нужно построить нечто, способное адаптироваться ко всем ситуациям, даже если нам придется изменять значение константы B.

Если этот момент понятен, то мы можем начать думать о том, как разрешить этот вопрос. Чтобы сделать всё более простым для понимания, мы немного изменим данный подход, чтобы лучше визуализировать математику, которая будет использоваться. Новый код показан ниже:

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. //+------------------------------------------------------------------+

В анимации ниже показано то, что получилось:


То есть мы можем составить аффинное уравнение, в котором можно изменить значение константы A, чтобы создать возможное уравнение линейной регрессии, стараясь сохранить существующие знания, то есть красные точки. В этом случае правильным будет уравнение, которое показано на рисунке ниже. Указанный угол - это угол, полученный с помощью стрелок влево или вправо.


То есть можно предположить, что искомая константа - это синус угла, и таким образом составить наше уравнение. Однако это не так. Не из-за того, что константа не связана с углом (на самом деле, она связана), а потому что вы бы подумали, что нужно использовать синус или косинус. Однако данный метод не является лучшим общим способом выражения идеи. Обычно мы не видим аффинного уравнения, записанного с помощью тригонометрических функций. Не то, чтобы неправильно, но необычно. Однако в этой статье мы рассмотрим, как можно использовать угол для получения данной константы. Но давайте не будем торопиться: сначала нам нужно объяснить еще кое-что. Если немного изменить код, как показано во фрагменте ниже, то можно убедиться в том, что будет больше похоже на правильное уравнение прямой, показанной в анимации. То есть константа теперь использует правильный термин.

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. //+------------------------------------------------------------------+

Результат выполнения можно посмотреть в анимации ниже.


Обратите внимание, что теперь, благодаря линии 43, мы имеем нечто очень приближенное к уравнению прямой линии. Мы видим, что для создания формулы мы будем использовать тангенс угла, а не синус или косинус, как можно себе представить. Но это всего лишь попытка сгенерировать наиболее подходящее значение. Однако, хотя нам и удается составить уравнение, можно понять, что не так-то просто угадать оптимальное значение наклона линии, то есть угла системы. Мы можем попытаться сделать это вручную, но это очень сложная задача. Несмотря на все сложности по составлению уравнения, которое порождает линейную регрессию, следует помнить, что в данный момент мы работаем только с одной переменной в этой системе. И это именно то значение, которое нам нужно найти, что показано на анимации выше.

Однако, если правильно использовать математику, она позволит нам найти наиболее подходящее значение угла наклона. Для этого нам понадобится использовать производные в нашей системе, для того, чтобы понять, почему тангенс - это тригонометрическая функция, которая лучше всего указывает на константу, которую нужно использовать в уравнении. Но для того, чтобы вы, дорогой читатель, поняли это, давайте начнем новую тему, чтобы не запутаться.


Используем производные

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

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

Чтобы вычислить такое уравнение, нам нужны некоторые математические ресурсы. Это связано с тем, что аффинная функция является линейной функцией и не позволяет получить производную. Дело в том, что производная - это прямая, проходящая через заданную точку и она получается из любого уравнения. Многие путаются в этих объяснениях, но, по сути, производная - это не что иное, как касательная прямая в данной точке функции. Касательная прямая проводится в точке, принадлежащей уравнению, которое обычно создает кривую на графике, то есть, поскольку аффинная функция - это касательная прямая, то касательная настолько хорошо отражает значение константы, на которую умножается неизвестная часть, что дает нам уравнение данной конкретной линии. По этой причине вторая касательная не может быть проведена с помощью этого исходного уравнения. Для этого нам нужен некий прием. Таким образом, не важно, какую точку мы пытаемся использовать для получения производной. НЕВОЗМОЖНО СОЗДАТЬ ПРОИЗВОДНУЮ В АФФИННОЙ ФУНКЦИИ.

Однако есть несколько приемов, которые обеспечивают создание производной. Именно это мы и начнем изучать сегодня. Чтобы понять, как мы это сделаем, необходимо понять, что такое производная, а также метод, который мы будем использовать для получения этой производной и, соответственно, для создания аффинной функции, описывающей минимально идеальную прямую. Для этого мы используем функцию, которая позволяет вывести производную. Самая простая из них - квадратичная функция. Если вы не знали, данная функция имеет следующую формулу:


Обратите внимание, что в этом уравнении присутствует вторая степень. Уже этот факт позволяет объяснить наличие производной в системе, однако мы можем использовать любую функцию для построения кривой. Это может быть даже логарифмическая функция, но она не будет иметь смысла, если мы представим себе что-то еще, что нам нужно будет сделать позже. По этой причине и для того, чтобы максимально упростить процесс, мы будем использовать квадратное уравнение. Таким образом, при использовании приведенной выше формулы, мы получим такой график.


Такой график будет получен, если принять значение A за единицу, а значения B и C сделать равными нулю. Однако данный факт не имеет большого значения, для нас действительно важна кривая, которую можно увидеть на графике. Она нам интересна.

Теперь будьте внимательны - это объяснение важно для понимания того, что мы будем реализовать в нашей программе, чтобы найти уравнение, которое нам так нужно.

Из приведенного выше графика следует, что с этого момента важно понимать эти предположения. Мы хотим узнать значение производной в точке, где икс равен четырем. Для этого нужно провести касательную прямую, которая должна точно проходить через точку, где X равен четырем. Это на первый взгляд просто: берем линейку и отмечаем на координате точку X, равную четырем. А затем попробуем построить линию, касательную к точке на кривой. Но сможем ли мы на самом деле провести касательную прямую, сделав это? Это маловероятно!

С большой долей вероятности мы создадим линию, которая не будет касательной. По этой причине необходимо произвести некоторые расчеты, и вот здесь всё становится сложнее. Но чтобы не усложнять ситуацию просто так, я не буду вдаваться в подробности самих расчетов на данном этапе. Я предполагаю, что читатель знает формулу производной квадратного уравнения. Для тех, кто не знает, позже будет объяснено, как получить эту формулу. Для нас очень важен способ получения производных уравнений. Конечный результат не столь важен, но важна формула, полученная из производной. Так что давайте продолжим.

Производную квадратного уравнения можно найти по следующей формуле.


Далее я покажу два наиболее распространенных обозначения. Можно использовать обозначение справа, или то, которое находится слева, это не имеет значения. Сейчас нас интересует сама формула, она равна 2 на Х. Данная формула дает нам значение равно восемь, которое в нашем примере является значением касательной прямой в точке, где Х равен четырем. Если вы знаете, что означает значение восемь, то можно провести касательную прямую в точке, где Х равен четырем. Однако если вы не знаете, что означает данное значение, вам понадобится вторая формула для построения касательной. 

Если вы не поняли, почему значение равно восьми, посмотрите на рисунок ниже, где мы хотим, чтобы производная по X была равна четырем. Для этого мы вычисляем значение в этой позиции так, как показано ниже.


Но прежде чем мы перейдем к другим расчетам, давайте разберемся, что означает данное значение восемь. Оно означает, что если мы продвигаемся на одну позицию по оси X, нам нужно продвинуться на восемь позиций по оси Y. И это позволит нам провести касательную прямую. Может быть вы не поверите в это, не увидев, как это происходит на самом деле. Если это ваш случай, есть формула, которая позволяет составить уравнение касательной прямой. Данное уравнение можно увидеть ниже.


Да, оно немного пугает, но всё гораздо проще, чем кажется. Хотя, без сомнения, эта формула довольно особенная. Она позволяет создать уравнение касательной к производной, хотя производная в конечном итоге будет касательной прямой. Но это просто факт, который я упоминаю как нечто интересное, не стоит беспокоиться. Итак, поскольку большинство значений нам уже известно, мы можем выполнить соответствующие подстановки, чтобы найти формулу для уравнения касательной прямой. Данный момент можно увидеть ниже.


Именно на этом этапе возникает множество сложностей, но давайте разберемся, откуда взялись приведенные здесь значения. Значение 16 является результатом исходного уравнения. Иными словами, мы подставили в квадратное уравнение то значение "X", которое используем в производной, то есть "четыре". Значение восемь получается как результат вычисления производной функции. Опять же, "X" равен четырем, и это также относится к производной функции. Значение 4, которое мы видим здесь, - это начальное значение X, используемое нами во всех остальных уравнениях. После проведенных вычислений мы получаем следующую формулу для касательной прямой.


Отлично, теперь мы можем провести касательную прямую на основе уравнения выше. Прорисованная линия видна на изображении ниже, она выделена красным цветом.


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

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

Я добавляю это для того, чтобы вы поняли, что дело не только в том, чтобы научиться пользоваться той или иной программой. Владение тем или иным языком - это не то, что дает вам настоящую квалификацию. Часто нам приходится прибегать к помощи различных программ, чтобы проанализировать ситуацию с точностью. По этой причине дальнейшее обучение имеет большое значение. И не важно, насколько хорошим вы себя считаете, всегда найдется кто-то более опытный, чем вы, в той или иной области. Поэтому всегда учитесь.

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

Но это еще не всё: в этой прямой объясняется, как рассчитать отклонения. Именно в этих расчетах и заключается «магия» нейронных сетей. Разве не видно? Или вы не понимаете, как это возможно? Чтобы понять это, нужно разобраться в том, что порождает расчет производной, о чем я рассказывал вам некоторое время назад. Несмотря на то, что мы используем касательную прямую в конце, вычисления не возникают из касательной прямой. Они возникают из другой тригонометрической функции. Именно здесь кроется волшебство системы. Эта «магия» позволяет нам создать общее решение для всех возможных и допустимых случаев, что и заставляет работать нейронную систему. Поэтому мы оставим это для другой темы, чтобы всё было раздельно.


Секущая прямая

Хотя, когда все говорят о нейронных сетях, упоминают только производные, секрет заключается не в производной и не в касательной прямой. Секрет заключается в другой прямой. И это секущая прямая. Поэтому с моей стороны было определенное нежелание писать на тему нейронных сетей. На самом деле, несколько человек просили меня рассказать об этом. Правда заключается в том, что многие люди говорят о нейронных сетях, но очень немногие действительно понимают, как они работают с математической точки зрения. Программирование - легкая часть, а сложная - это математика. Многие считают, что необходимо пользоваться той или иной библиотекой, тем или иным языком программирования. Но на самом деле мы можем использовать любой язык, если понимаем, как работает его математическое составляющее. Я не собираюсь говорить о ком-то в негативном ключе или утверждать, что кто-то ошибается в своих объяснениях. Каждый имеет право понимать всё так, как ему хочется. Однако мое желание по-настоящему объяснить, как всё устроено. Я не хочу, чтобы вы стали еще одним рабом языков или библиотек. Я хочу, чтобы вы поняли, как всё устроено изнутри. Именно поэтому я решил написать серию статей, чтобы поговорить на эту тему.

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

Однако, когда мы выполним вычисления, мы не будем использовать касательную прямую. На самом деле мы используем секущую прямую. Не имеет значения, какой вид нейронной сети реализован. Если производится вычисление, то используется не касательная, а секущая прямая. Вам может показаться, что это гораздо сложнее, но если вы так подумали, значит, вы не знаете, как на самом деле получается касательная прямая к производной. Или, что еще хуже, как получается формула для производной. Заучивание формул не имеет особого смысла. Правильнее всего будет понять, почему у формулы именно такой формат, а не другой. Помните расчеты, приведенные в предыдущей теме? Вы знаете, откуда они взялись? Если нет, давайте посмотрим на график ниже:


Красная линия на этом графике - это секущая прямая. Если вы были внимательны до этого, то теперь я хочу, чтобы вы удвоили свое внимание. Это будет даже важнее, чем всё остальное, что вы можете прочитать или услышать о нейронных сетях.

Здесь я использую ту же точку X, что и в предыдущей теме, то есть значение четыре. Тогда вы действительно сможете понять, что я объясняю.

Сгенерировать касательную прямую невозможно, что бы вы ни думали и ни представляли. НЕВОЗМОЖНО ПОСТРОИТЬ КАСАТЕЛЬНУЮ ПРЯМУЮ ИЗ КРИВОЙ НА ГРАФИКЕ.. Однако если использовать секущую прямую, то можно получить касательную. Как? Всё очень просто. Заметим, что f(x + h) - это f(x), сдвинутая на расстояние h. Тогда, если h стремится к нулю, секущая превратится в касательную. А когда h в точности равно нулю, секущая прямая, изображенная на рисунке, будет в точности совпадать с касательной. То есть в этой точке касательная прямая даст нам наклон производной функции в этой точке. Ладно, но я всё равно не понимаю. Что ж, дорогой читатель, давайте изложим то, что вы видите выше, в менее запутанной форме, пожалуй, это прояснит ситуацию.


На изображении выше показано то же самое, что и на предыдущем. Думаю, так идея использования секущей станет более понятной. И почему, в отличие от того, что все утверждают, будто мы используем касательную прямую или производные, когда используем нейронную сеть, на самом деле мы используем секущую прямую, чтобы компьютер мог сгенерировать правильное уравнение.

Если уменьшить значение h, то начнется приближение к f(x), но это h никогда не будет равно нулю. В этом случае мы используем нейронные сети. Это может быть очень маленькое значение; насколько меньше это значение, зависит от того, что мы увидим позже. Этот момент известен как: безумие нейронной сети. Чем меньше эта величина h, тем менее безумной будет нейронная сеть, но чем она больше, тем более безумной будет она. Но почему? Причина - конвергенция. В ходе вычислений, которые мы рассмотрим позже, можно будет заметить, что данная конвергенция стремится к значению h. Это приведет к тому, что уравнение, полученное в конце, будет иметь тенденцию к изменению в пределах этой конвергенции. По этой причине h очень важна. Объяснение кажется сложным, но на практике вы увидите, что всё гораздо проще. Однако мы еще не дошли до того момента, который мы хотим показать. Если вы примените данное изображение в формуле, то получите следующий расчет.


Эта формула показывает, на каком расстоянии находится секущая прямая от касательной. Однако на самом деле используется расчет, который показан на рисунке ниже.


Это уравнение объясняет всё, что вам нужно знать о нейронных сетях. Именно поэтому говорят, что нейронные сети пользуются производными. Ведь именно это уравнение генерирует те вычисления, которые многие просто заучивают: формулы производных. На этом закончим. Больше ничего не нужно объяснять и говорить. Всё, что нам нужно, - это уравнение, приведенное выше. Уже можно расслабиться.


Заключительные идеи

Но подождите минутку. Вы не объяснили, как пользоваться этим уравнением секущей прямой, и не объяснили, почему оно всё проясняет. Как это, "не объяснил"? Вы что, шутите? Дорогой читатель, на самом деле, мы только начали нашу работу с этим вопросом. Я хочу, чтобы вы сначала спокойно изучили данный материал. В следующей статье о нейронных сетях мы рассмотрим, как использовать представленные здесь знания для составления правильного уравнения.


Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/13656

Прикрепленные файлы |
Anexo_01.mq5 (3.49 KB)
Возможности Мастера MQL5, которые вам нужно знать (Часть 15): Метод опорных векторов с полиномом Ньютона Возможности Мастера MQL5, которые вам нужно знать (Часть 15): Метод опорных векторов с полиномом Ньютона
Метод опорных векторов (Support Vector Machines) классифицирует данные на основе предопределенных классов, исследуя эффекты увеличения их размерности. Это метод обучения с учителем, который довольно сложен, учитывая его потенциальную возможность работы с многомерными данными. В этой статье мы рассмотрим, как эффективнее реализовать базовую версию двумерных данных с помощью полинома Ньютона при классификации ценовых действий.
Циклы и Forex Циклы и Forex
Циклы имеют большое значение в нашей жизни. День и ночь, времена года, дни недели и множество других циклов разного характера и разной природы присутствуют в жизни любого человека. В этой статье мы попробуем рассмотреть циклы на финансовых рынках.
Разрабатываем мультивалютный советник (Часть 17): Дальнейшая подготовка к реальной торговле Разрабатываем мультивалютный советник (Часть 17): Дальнейшая подготовка к реальной торговле
Сейчас наш советник использует базу данных для получения строк инициализации одиночных экземпляров торговых стратегий. Однако база данных является достаточно объёмной и содержит много информации, ненужной при реальной работе советника. Попробуем обеспечить работоспособность советника без обязательного подключения к базе данных.
Нейросети в трейдинге: Универсальная модель генерации траекторий (UniTraj) Нейросети в трейдинге: Универсальная модель генерации траекторий (UniTraj)
Понимание поведения агентов важно в разных областях, но большинство методов фокусируются на одной задаче (понимание, удаление шума, прогнозирование), что снижает их эффективность в реальных сценариях. В данной статье я предлагаю познакомиться с моделью, которая способна адаптироваться к решению различных задач.