Advertisement
TShiva

Untitled

Jan 14th, 2021
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.58 KB | None | 0 0
  1. #include <windows.h>
  2. #include <math.h>
  3. #include <random>
  4. #include <iostream>
  5. #include <vector>
  6. #include <cmath>
  7. #include <ctime>
  8. using namespace std;
  9.  
  10. #define pi 3.14
  11.  
  12. int function = 1;
  13.  
  14. double scale;
  15. double scale2;
  16.  
  17. const int countOfNeurons = 20;//кол-во нейронов
  18.  
  19. int present = 10;
  20. //int distribution = 1;
  21. double mistake = 0.4;//велинична, на сколько максимально может отклонится точки от графика
  22.  
  23. double step = 0.0005;//шаг
  24.  
  25.  
  26. inline double tan(double x)//функция активации
  27. {
  28.     return tanh(3.5*x);
  29. }
  30.  
  31. inline double diff(double x)
  32. {
  33.     return 3.5*(1 - x * x);
  34. }
  35.  
  36. inline double sinfunc(double x)
  37. {
  38.     return sin(2 * pi*x / scale)*x / scale;
  39. }
  40.  
  41. inline double cube(double x){
  42.     auto cock = (pow(x/ 120, 3) + x/scale2 + 5);
  43.     return cock/scale2;
  44. }
  45.  
  46.  
  47. double cosfunc(double x)
  48. {
  49.     return cos(2 * pi*x / scale);
  50. }
  51.  
  52.  
  53. double parabola(double x)
  54. {
  55.     return pow(x / scale, 2.0);
  56.  
  57. }
  58.  
  59. double y;
  60.  
  61.  
  62. double WhatFunction(int f, double scale, double i)
  63. {
  64.     if (f == 1)
  65.         return scale * cosfunc(i);
  66.     if (f == 2)
  67.         return scale * sinfunc(i);
  68.     if (f == 3)
  69.         return scale * parabola(i);
  70.     if (f == 4)
  71.         return scale * cube(i);
  72. }
  73.  
  74.  
  75.  
  76.  
  77.  
  78. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  79.  
  80. void NeuralNetCalc(double& f, double w0, double* z, int r, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges);
  81.  
  82. void PaintResult(double& f, const HDC& hdc, int r, HPEN& hPen, double w0, double* z, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges);
  83.  
  84. void NetworkTrain(double* z, double* xx, double* inputEdges, double* weightsOfMovedPerceptrons, double& f, double* weightsOutputEdges, double& w0, double& delta, double* yy, double* delta_w, double* delta_v, double* delta_v0);
  85.  
  86. void ChangeEdgesInNetwork(double& delta, double f, double* yy, int h, double& w0, double* delta_w, double* z, double* delta_v, double* weightsOutputEdges, double* xx, double* delta_v0, double* inputEdges, double* weightsOfMovedPerceptrons);
  87.  
  88. void CalculateOutputFunction(double& f, double* weightsOutputEdges, double* z, double w0);
  89.  
  90. void genParams(int& i, int r, const HDC& hdc, double* xx, std::uniform_real_distribution<>& distr, std::mt19937& gen, double* yy, HPEN& hPen, HPEN& hPenOld, HBRUSH& hBrush, HBRUSH& hBrushOld);
  91.  
  92.  
  93. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  94.     PSTR szCmdLine, int iCmdShow)
  95. {
  96.     static TCHAR szAppName[] = TEXT("SineWave");
  97.     HWND hwnd;
  98.     MSG msg;
  99.  
  100.     WNDCLASSEX wndclass;
  101.     wndclass.cbSize = sizeof(wndclass);
  102.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  103.     wndclass.lpfnWndProc = WndProc;
  104.     wndclass.cbClsExtra = 0;
  105.     wndclass.cbWndExtra = 0;
  106.     wndclass.hInstance = hInstance;
  107.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  108.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  109.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  110.     wndclass.lpszMenuName = TEXT("MYMENU");
  111.     wndclass.lpszClassName = (szAppName);
  112.     wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  113.     RegisterClassEx(&wndclass);
  114.     hwnd = CreateWindow(szAppName, TEXT("Нейронная сеть"),
  115.         WS_OVERLAPPEDWINDOW,
  116.         CW_USEDEFAULT, CW_USEDEFAULT,
  117.         1000, 750,
  118.         NULL, NULL, hInstance, NULL);
  119.     ShowWindow(hwnd, iCmdShow);
  120.     UpdateWindow(hwnd);
  121.     while (GetMessage(&msg, NULL, 0, 0))
  122.     {
  123.         TranslateMessage(&msg);
  124.         DispatchMessage(&msg);
  125.     }
  126.     return msg.wParam;
  127. }
  128.  
  129.  
  130. LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  131. {
  132.     srand(time(NULL));
  133.     static int cxClient, cyClient;
  134.     HDC hdc;
  135.     PAINTSTRUCT ps;
  136.     int i, r;
  137.     HPEN hPen, hPenOld;
  138.     HBRUSH hBrush, hBrushOld;
  139.  
  140.     mt19937 gen(1529);
  141.  
  142.     uniform_real_distribution<> distr(-mistake, mistake);
  143.  
  144.     switch (iMsg)
  145.     {
  146.  
  147.     case WM_CREATE:
  148.         break;
  149.  
  150.     case WM_SIZE:
  151.         cxClient = LOWORD(lParam);
  152.         cyClient = HIWORD(lParam);
  153.         break;
  154.  
  155.     case WM_PAINT:
  156.     {
  157.  
  158.         double *xx = new double[countOfNeurons];
  159.         double *yy = new double[countOfNeurons];
  160.  
  161.         hdc = BeginPaint(hwnd, &ps);
  162.  
  163.         SetMapMode(hdc, MM_ISOTROPIC);
  164.         SetWindowExtEx(hdc, cxClient, cyClient, 0);
  165.         SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, 0);
  166.         SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, 0);
  167.  
  168.         MoveToEx(hdc, -cxClient, 0, NULL);
  169.         LineTo(hdc, cxClient, 0);
  170.         MoveToEx(hdc, 0, -cyClient, NULL);
  171.         LineTo(hdc, 0, cyClient);
  172.  
  173.         scale = cxClient;
  174.         scale2 = cyClient / 2;
  175.         r = cxClient;
  176.  
  177.         hPen = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
  178.         SelectObject(hdc, hPen);
  179.  
  180.         MoveToEx(hdc, -r, WhatFunction(function, scale2, -r), NULL);
  181.  
  182.  
  183.         genParams(i, r, hdc, xx, distr, gen, yy, hPen, hPenOld, hBrush, hBrushOld);
  184.  
  185.         for (int t = 0; t < 5; t++)//эпохи
  186.         {
  187.             double* inputEdges = new double[countOfNeurons];//веса для дуг от входных нейронов
  188.             double* weightsOutputEdges = new double[countOfNeurons];//веса для дуг к выходным нейронам
  189.             double* weightsOfMovedPerceptrons = new double[countOfNeurons];//веса нейронов смещения
  190.             double* z = new double[countOfNeurons];//хранение промежуточных значений
  191.             double* delta_v = new double[countOfNeurons];//ошибки для соответствующих дуг
  192.             double* delta_w = new double[countOfNeurons];
  193.             double* delta_v0 = new double[countOfNeurons];
  194.             double w0;//нейрон смещения для выхода
  195.             double delta;//ошибка
  196.             double f;//выходное значение
  197.  
  198.             for (int i = 0; i < countOfNeurons; i++)
  199.             {
  200.                 inputEdges[i] = (rand() % r * 2 - r) / scale;
  201.                 weightsOutputEdges[i] = (rand() % r * 2 - r) / scale;//назначения весов дуг графа случайными значениями
  202.                 weightsOfMovedPerceptrons[i] = (rand() % r * 2 - r) / scale;
  203.             }
  204.             w0 = (rand() % r * 2 - r) / scale;
  205.  
  206.             NetworkTrain(z, xx, inputEdges, weightsOfMovedPerceptrons, f, weightsOutputEdges, w0, delta, yy, delta_w, delta_v, delta_v0);
  207.  
  208.             NeuralNetCalc(f, w0, z, r, inputEdges, weightsOfMovedPerceptrons, weightsOutputEdges);
  209.  
  210.             PaintResult(f, hdc, r, hPen, w0, z, inputEdges, weightsOfMovedPerceptrons, weightsOutputEdges);
  211.         }
  212.         return 0;
  213.     }
  214.     case WM_DESTROY:
  215.         PostQuitMessage(0);
  216.         return 0;
  217.     }
  218.     return DefWindowProc(hwnd, iMsg, wParam, lParam);
  219.  
  220.  
  221. }
  222.  
  223. void NeuralNetCalc(double& f, double w0, double* z, int r, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges)
  224. {
  225.     f = w0;
  226.     for (int i = 0; i < countOfNeurons; i++)
  227.     {
  228.         z[i] = (-r / scale) * inputEdges[i] + weightsOfMovedPerceptrons[i];
  229.         z[i] = tan(z[i]);
  230.     }
  231.     for (int i = 0; i < countOfNeurons; i++)
  232.         f += z[i] * weightsOutputEdges[i];
  233.     f = tan(f);
  234.  
  235. }
  236.  
  237. void PaintResult(double& f, const HDC& hdc, int r, HPEN& hPen, double w0, double* z, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges)
  238. {
  239.     f *= scale2;//поправка для отрисовки
  240.  
  241.     MoveToEx(hdc, -r, f, NULL);
  242.  
  243.  
  244.     hPen = CreatePen(PS_SOLID, 0, RGB(30, 225, 0));
  245.     SelectObject(hdc, hPen);
  246.  
  247.     for (int j = -r; j <= r; j++)//отрисовка
  248.     {
  249.         f = w0;
  250.         for (int i = 0; i < countOfNeurons; i++)
  251.         {
  252.             z[i] = (j / scale) * inputEdges[i] + weightsOfMovedPerceptrons[i];
  253.             z[i] = tan(z[i]);
  254.         }
  255.         for (int i = 0; i < countOfNeurons; i++)
  256.             f += z[i] * weightsOutputEdges[i];
  257.         f = tan(f);
  258.         f *= scale2;
  259.         LineTo(hdc, j, (int)f);
  260.     }
  261. }
  262.  
  263. void NetworkTrain(double* z, double* xx, double* inputEdges, double* weightsOfMovedPerceptrons, double& f, double* weightsOutputEdges, double& w0, double& delta, double* yy, double* delta_w, double* delta_v, double* delta_v0)
  264. {
  265.     for (int u = 0; u < 10000; u++)//итерации для тренировки
  266.     {
  267.         for (int h = 0; h < countOfNeurons; h++)//для каждого элемента выборки, для каждой точке
  268.         {
  269.             for (int i = 0; i < countOfNeurons; i++)
  270.             {
  271.                 z[i] = xx[h] * inputEdges[i] + weightsOfMovedPerceptrons[i];//преобразование задаваемое нейронной сетью
  272.                 z[i] = tan(z[i]);
  273.             }
  274.             CalculateOutputFunction(f, weightsOutputEdges, z, w0);
  275.             ChangeEdgesInNetwork(delta, f, yy, h, w0, delta_w, z, delta_v, weightsOutputEdges, xx, delta_v0, inputEdges, weightsOfMovedPerceptrons);
  276.         }
  277.     }
  278. }
  279.  
  280. void ChangeEdgesInNetwork(double& delta, double f, double* yy, int h, double& w0, double* delta_w, double* z, double* delta_v, double* weightsOutputEdges, double* xx, double* delta_v0, double* inputEdges, double* weightsOfMovedPerceptrons)
  281. {
  282.     delta = (f - yy[h]) * diff(f);
  283.  
  284.     w0 -= step * delta;//меня дугу для выходного нейрона смещения
  285.     for (int i = 0; i < countOfNeurons; i++)
  286.     {
  287.         delta_w[i] = -step * delta * z[i];//считаем дельты для весов дуг между выходом и внутренним слоем
  288.         delta_v[i] = -step * delta * weightsOutputEdges[i] * xx[h] * diff(z[i]);//между входом и внутренним слоем
  289.         delta_v0[i] = -step * delta * weightsOutputEdges[i] * diff(z[i]);//для нейронов смещения
  290.     }
  291.  
  292.     for (int i = 0; i < countOfNeurons; i++)
  293.     {
  294.         inputEdges[i] += delta_v[i];//изменение весов дуг
  295.         weightsOutputEdges[i] += delta_w[i];
  296.         weightsOfMovedPerceptrons[i] += delta_v0[i];
  297.     }
  298.  
  299. }
  300.  
  301. void CalculateOutputFunction(double& f, double* weightsOutputEdges, double* z, double w0)
  302. {
  303.     f = 0;
  304.     for (int i = 0; i < countOfNeurons; i++) {
  305.         f += weightsOutputEdges[i] * z[i];//суммируем значения в выходном нейроне
  306.     }
  307.     f += w0;
  308.     f = tan(f);
  309. }
  310.  
  311. void genParams(int& i, int r, const HDC& hdc, double* xx, std::uniform_real_distribution<>& distr, std::mt19937& gen, double* yy, HPEN& hPen, HPEN& hPenOld, HBRUSH& hBrush, HBRUSH& hBrushOld)
  312. {
  313.  
  314.     for (i = -r; i < r; i++)
  315.     {
  316.         y = WhatFunction(function, scale2, i);
  317.         LineTo(hdc, i, (int)y);
  318.     }
  319.  
  320.     // заселение параметров
  321.     for (int i = 0; i < countOfNeurons; i++)
  322.     {
  323.         xx[i] = rand() % r * 2 - r; // сдвигаемся по x
  324.  
  325.         mistake = 0;
  326.  
  327.         if (rand() % 100 < present)
  328.         {
  329.             mistake = distr(gen); // диапазон ошибки
  330.         }
  331.  
  332.         yy[i] = WhatFunction(function, scale2, xx[i]) + scale2 * mistake;
  333.  
  334.         hPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 255));
  335.         hPenOld = (HPEN)SelectObject(hdc, hPen);
  336.  
  337.         hBrush = CreateSolidBrush(RGB(0, 0, 255));
  338.         hBrushOld = (HBRUSH)SelectObject(hdc, hBrush);
  339.  
  340.         Ellipse(hdc, xx[i] - 4.0, yy[i] - 4.0, xx[i] + 4.0, yy[i] + 4.0);
  341.  
  342.         xx[i] /= scale;
  343.         yy[i] /= scale2;
  344.  
  345.         SelectObject(hdc, hBrushOld);
  346.         DeleteObject(hBrush);
  347.  
  348.         SelectObject(hdc, hPenOld);
  349.         DeleteObject(hPen);
  350.  
  351.     }
  352. }
  353.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement