Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <math.h>
- #include <random>
- #include <iostream>
- #include <vector>
- #include <cmath>
- #include <ctime>
- using namespace std;
- #define pi 3.14
- int function = 1;
- double scale;
- double scale2;
- const int countOfNeurons = 20;//кол-во нейронов
- int present = 10;
- //int distribution = 1;
- double mistake = 0.4;//велинична, на сколько максимально может отклонится точки от графика
- double step = 0.0005;//шаг
- inline double tan(double x)//функция активации
- {
- return tanh(3.5*x);
- }
- inline double diff(double x)
- {
- return 3.5*(1 - x * x);
- }
- inline double sinfunc(double x)
- {
- return sin(2 * pi*x / scale)*x / scale;
- }
- inline double cube(double x){
- auto cock = (pow(x/ 120, 3) + x/scale2 + 5);
- return cock/scale2;
- }
- double cosfunc(double x)
- {
- return cos(2 * pi*x / scale);
- }
- double parabola(double x)
- {
- return pow(x / scale, 2.0);
- }
- double y;
- double WhatFunction(int f, double scale, double i)
- {
- if (f == 1)
- return scale * cosfunc(i);
- if (f == 2)
- return scale * sinfunc(i);
- if (f == 3)
- return scale * parabola(i);
- if (f == 4)
- return scale * cube(i);
- }
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- void NeuralNetCalc(double& f, double w0, double* z, int r, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges);
- void PaintResult(double& f, const HDC& hdc, int r, HPEN& hPen, double w0, double* z, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges);
- 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);
- 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);
- void CalculateOutputFunction(double& f, double* weightsOutputEdges, double* z, double w0);
- 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);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT("SineWave");
- HWND hwnd;
- MSG msg;
- WNDCLASSEX wndclass;
- wndclass.cbSize = sizeof(wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = TEXT("MYMENU");
- wndclass.lpszClassName = (szAppName);
- wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- RegisterClassEx(&wndclass);
- hwnd = CreateWindow(szAppName, TEXT("Нейронная сеть"),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 1000, 750,
- NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- srand(time(NULL));
- static int cxClient, cyClient;
- HDC hdc;
- PAINTSTRUCT ps;
- int i, r;
- HPEN hPen, hPenOld;
- HBRUSH hBrush, hBrushOld;
- mt19937 gen(1529);
- uniform_real_distribution<> distr(-mistake, mistake);
- switch (iMsg)
- {
- case WM_CREATE:
- break;
- case WM_SIZE:
- cxClient = LOWORD(lParam);
- cyClient = HIWORD(lParam);
- break;
- case WM_PAINT:
- {
- double *xx = new double[countOfNeurons];
- double *yy = new double[countOfNeurons];
- hdc = BeginPaint(hwnd, &ps);
- SetMapMode(hdc, MM_ISOTROPIC);
- SetWindowExtEx(hdc, cxClient, cyClient, 0);
- SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, 0);
- SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, 0);
- MoveToEx(hdc, -cxClient, 0, NULL);
- LineTo(hdc, cxClient, 0);
- MoveToEx(hdc, 0, -cyClient, NULL);
- LineTo(hdc, 0, cyClient);
- scale = cxClient;
- scale2 = cyClient / 2;
- r = cxClient;
- hPen = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
- SelectObject(hdc, hPen);
- MoveToEx(hdc, -r, WhatFunction(function, scale2, -r), NULL);
- genParams(i, r, hdc, xx, distr, gen, yy, hPen, hPenOld, hBrush, hBrushOld);
- for (int t = 0; t < 5; t++)//эпохи
- {
- double* inputEdges = new double[countOfNeurons];//веса для дуг от входных нейронов
- double* weightsOutputEdges = new double[countOfNeurons];//веса для дуг к выходным нейронам
- double* weightsOfMovedPerceptrons = new double[countOfNeurons];//веса нейронов смещения
- double* z = new double[countOfNeurons];//хранение промежуточных значений
- double* delta_v = new double[countOfNeurons];//ошибки для соответствующих дуг
- double* delta_w = new double[countOfNeurons];
- double* delta_v0 = new double[countOfNeurons];
- double w0;//нейрон смещения для выхода
- double delta;//ошибка
- double f;//выходное значение
- for (int i = 0; i < countOfNeurons; i++)
- {
- inputEdges[i] = (rand() % r * 2 - r) / scale;
- weightsOutputEdges[i] = (rand() % r * 2 - r) / scale;//назначения весов дуг графа случайными значениями
- weightsOfMovedPerceptrons[i] = (rand() % r * 2 - r) / scale;
- }
- w0 = (rand() % r * 2 - r) / scale;
- NetworkTrain(z, xx, inputEdges, weightsOfMovedPerceptrons, f, weightsOutputEdges, w0, delta, yy, delta_w, delta_v, delta_v0);
- NeuralNetCalc(f, w0, z, r, inputEdges, weightsOfMovedPerceptrons, weightsOutputEdges);
- PaintResult(f, hdc, r, hPen, w0, z, inputEdges, weightsOfMovedPerceptrons, weightsOutputEdges);
- }
- return 0;
- }
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, iMsg, wParam, lParam);
- }
- void NeuralNetCalc(double& f, double w0, double* z, int r, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges)
- {
- f = w0;
- for (int i = 0; i < countOfNeurons; i++)
- {
- z[i] = (-r / scale) * inputEdges[i] + weightsOfMovedPerceptrons[i];
- z[i] = tan(z[i]);
- }
- for (int i = 0; i < countOfNeurons; i++)
- f += z[i] * weightsOutputEdges[i];
- f = tan(f);
- }
- void PaintResult(double& f, const HDC& hdc, int r, HPEN& hPen, double w0, double* z, double* inputEdges, double* weightsOfMovedPerceptrons, double* weightsOutputEdges)
- {
- f *= scale2;//поправка для отрисовки
- MoveToEx(hdc, -r, f, NULL);
- hPen = CreatePen(PS_SOLID, 0, RGB(30, 225, 0));
- SelectObject(hdc, hPen);
- for (int j = -r; j <= r; j++)//отрисовка
- {
- f = w0;
- for (int i = 0; i < countOfNeurons; i++)
- {
- z[i] = (j / scale) * inputEdges[i] + weightsOfMovedPerceptrons[i];
- z[i] = tan(z[i]);
- }
- for (int i = 0; i < countOfNeurons; i++)
- f += z[i] * weightsOutputEdges[i];
- f = tan(f);
- f *= scale2;
- LineTo(hdc, j, (int)f);
- }
- }
- 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)
- {
- for (int u = 0; u < 10000; u++)//итерации для тренировки
- {
- for (int h = 0; h < countOfNeurons; h++)//для каждого элемента выборки, для каждой точке
- {
- for (int i = 0; i < countOfNeurons; i++)
- {
- z[i] = xx[h] * inputEdges[i] + weightsOfMovedPerceptrons[i];//преобразование задаваемое нейронной сетью
- z[i] = tan(z[i]);
- }
- CalculateOutputFunction(f, weightsOutputEdges, z, w0);
- ChangeEdgesInNetwork(delta, f, yy, h, w0, delta_w, z, delta_v, weightsOutputEdges, xx, delta_v0, inputEdges, weightsOfMovedPerceptrons);
- }
- }
- }
- 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)
- {
- delta = (f - yy[h]) * diff(f);
- w0 -= step * delta;//меня дугу для выходного нейрона смещения
- for (int i = 0; i < countOfNeurons; i++)
- {
- delta_w[i] = -step * delta * z[i];//считаем дельты для весов дуг между выходом и внутренним слоем
- delta_v[i] = -step * delta * weightsOutputEdges[i] * xx[h] * diff(z[i]);//между входом и внутренним слоем
- delta_v0[i] = -step * delta * weightsOutputEdges[i] * diff(z[i]);//для нейронов смещения
- }
- for (int i = 0; i < countOfNeurons; i++)
- {
- inputEdges[i] += delta_v[i];//изменение весов дуг
- weightsOutputEdges[i] += delta_w[i];
- weightsOfMovedPerceptrons[i] += delta_v0[i];
- }
- }
- void CalculateOutputFunction(double& f, double* weightsOutputEdges, double* z, double w0)
- {
- f = 0;
- for (int i = 0; i < countOfNeurons; i++) {
- f += weightsOutputEdges[i] * z[i];//суммируем значения в выходном нейроне
- }
- f += w0;
- f = tan(f);
- }
- 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)
- {
- for (i = -r; i < r; i++)
- {
- y = WhatFunction(function, scale2, i);
- LineTo(hdc, i, (int)y);
- }
- // заселение параметров
- for (int i = 0; i < countOfNeurons; i++)
- {
- xx[i] = rand() % r * 2 - r; // сдвигаемся по x
- mistake = 0;
- if (rand() % 100 < present)
- {
- mistake = distr(gen); // диапазон ошибки
- }
- yy[i] = WhatFunction(function, scale2, xx[i]) + scale2 * mistake;
- hPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 255));
- hPenOld = (HPEN)SelectObject(hdc, hPen);
- hBrush = CreateSolidBrush(RGB(0, 0, 255));
- hBrushOld = (HBRUSH)SelectObject(hdc, hBrush);
- Ellipse(hdc, xx[i] - 4.0, yy[i] - 4.0, xx[i] + 4.0, yy[i] + 4.0);
- xx[i] /= scale;
- yy[i] /= scale2;
- SelectObject(hdc, hBrushOld);
- DeleteObject(hBrush);
- SelectObject(hdc, hPenOld);
- DeleteObject(hPen);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement