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 <fstream>
- #include <sstream>
- #include <vector>
- #include <cmath>
- #include <ctime>
- using namespace std;
- #define Pi 3.14
- #define isFunction 1 // выбор функции, 1 = cos(2*pi*x), 2 = pow(x,3)*5.0+pow(x,2)+5.0, 3 = sin(2*pi*x)*x
- double coef_x;
- double coef_y;
- int points = 10;//кол-во нейронов во внутреннем слое
- double mis;
- //int present = 10;
- double mistake = 0.25;// модуль максимального значения ошибки
- int typeOfError = 1;//тип ошибки: равномерная =1 или нормальная =2.
- double step = 0.0005;//шаг
- double currentError = 0.;
- std::mt19937 gen(time(0));
- std::uniform_real_distribution<> uid(0, 1);
- inline double tan(double x)//функция активации
- {
- return tanh(x*3.5);
- }
- inline double diff(double x)//тупо производная гиперболического тангенса через формулу тейлора
- {
- return 3.5*(1 - pow(x ,2)+2*pow(x,4)/3);
- }
- inline double cosinus(double x) {
- return cos(2 * Pi*x / coef_x);
- }
- inline double cube(double x) {//не подогнал
- double cock = pow(x / coef_x, 3)*5.0 + pow(x / coef_x, 2) + 5.0 / coef_x;
- return cock;
- }
- inline double sinus(double x) {
- double cock = sin(2.0 * Pi*x / coef_x)*x / coef_x;
- return cock;
- }
- double WhatTheFunction(int f, double coef_y, int i)
- {
- if (f == 1)
- return coef_y * cosinus(i);
- if (f == 2)
- return coef_y * cube(i);
- if (f == 3)
- return coef_y * sinus(i);
- }
- double NormalErr(double mistake) {
- double ksi = 0, randomNumber;
- for (int i = 0; i< 12; i++) {
- randomNumber = uid(gen);
- ksi += randomNumber;//сумма 12 случайно распределённых числел
- }
- double etha = ksi - 6;//Etha принадлежит отрезку от 0 до 1
- randomNumber = uid(gen);
- double randomValue = mistake * (2 * randomNumber - 1);
- return etha * randomValue;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- static int cxClient, cyClient;
- HDC hdc;
- PAINTSTRUCT ps;
- HPEN hPen, hPenOld;
- HBRUSH hBrush, hBrushOld;
- switch (iMsg)
- {
- case WM_CREATE:
- break;
- case WM_SIZE:
- cxClient = LOWORD(lParam);//ширина
- cyClient = HIWORD(lParam);//высота
- break;
- case WM_PAINT:
- {
- double *xx = new double[points];
- double *yy = new double[points];
- double *tt = new double[points];
- 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, nullptr);//переместили курсор
- LineTo(hdc, cxClient, 0);//нарисовали одну ось
- MoveToEx(hdc, 0, -cyClient, nullptr);
- LineTo(hdc, 0, cyClient);//нарисовали другую
- hPen = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
- SelectObject(hdc, hPen);
- coef_x = cxClient;
- coef_y = cyClient/ 2;
- MoveToEx(hdc, -cxClient, static_cast<int>(WhatTheFunction(isFunction, coef_y, -coef_x)), nullptr);//устанавливаем начальную позицию
- for (int i = -cxClient; i < cxClient; i++)//рисуем график функции
- {
- double y = static_cast<int>(WhatTheFunction(isFunction, coef_y, i));
- LineTo(hdc, i, (int)y);
- }
- for (int i = 0; i < points; i++)
- {
- // вычисление равномерного распределённого вектора X
- //генерируем точки для метода
- xx[i] = uid(gen)*coef_x * 2 - coef_x;// генерация элемента выборки, из отрезка [0,1] -> [-cxClient,cxClient]
- yy[i] = WhatTheFunction(isFunction, coef_y, xx[i]);
- //находим t[i] в зависимости от вида распределения ошибки
- if (typeOfError == 1)//имеет равномерное распределение
- {
- currentError = uid(gen) * 2 * mistake*coef_y - mistake * coef_y;
- //домножение на коэффициент (coef_y) оправдано
- tt[i] = yy[i] + currentError;
- }
- if (typeOfError == 2)//имеет нормальное распределение
- {
- currentError = NormalErr(mistake*coef_y);
- tt[i] = yy[i] + currentError;
- }
- 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] - 5, tt[i] - 5, xx[i] + 5, tt[i] + 5);
- xx[i] /= coef_x;
- yy[i] /= coef_y;
- tt[i] /= coef_y;
- SelectObject(hdc, hBrushOld);
- DeleteObject(hBrush);
- SelectObject(hdc, hPenOld);
- DeleteObject(hPen);
- }
- for (int t = 0; t < 100; t++)//эпохи
- {
- double* v = new double[points]; //веса для дуг от входного нейрона
- double* w = new double[points]; //веса для дуг к выходному нейрону
- double* v0 = new double[points]; //веса нейронов смещения
- double* z = new double[points]; //хранение промежуточных значений
- double* a = new double[points];
- double* delta_v = new double[points]; //ошибки для соответствующих дуг
- double* delta_w = new double[points];
- double* delta_v0 = new double[points];
- double w0; //нейрон смещения для выхода
- double delta; //ошибка - градиент?
- double f; //выходное значение
- for (int i = 0; i < points; i++)
- {
- v[i] = uid(gen)* 2 - 1;
- w[i] = uid(gen) * 2 - 1;//назначения весов дуг графа случайными значениями
- v0[i] = uid(gen) * 2 - 1;
- }
- w0 = uid(gen) * 2 - 1;
- for (int u = 0; u < 10000; u++)//итерации для тренировки
- {
- //прямое распространение, ищем a[i] и z[i] для внутреннего и последнего слоя
- for (int h = 0; h < points; h++)//для каждого элемента выборки, их не обязательно должно быть столько же, сколько нейронов, просто я так реализовал это
- {
- for (int i = 0; i < points; i++)
- {
- a[i] = xx[h] * v[i] + v0[i];//преобразование задаваемое нейронной сетью
- z[i] = tan(a[i]);//функция активации
- }
- f = 0;
- for (int i = 0; i < points; i++)
- f += w[i] * z[i];//суммируем значения в выходном нейроне
- f += w0;
- f = tan(f);
- //обратное распространение
- delta = (f - tt[h])*diff(f);// вычисление градиента функции ошибки
- w0 -= step * delta;//меняем дугу для выходного нейрона смещения
- for (int i = 0; i < points; i++)
- {
- delta_w[i] = -step * delta*z[i];//считаем дельты для весов дуг между выходом и внутренним слоем
- delta_v[i] = -step * delta*w[i] * xx[h] * diff(z[i]);//между входом и внутренним слоем
- delta_v0[i] = -step * delta*w[i] * diff(z[i]);//для нейронов смещения
- }
- for (int i = 0; i < points; i++)
- {
- v[i] += delta_v[i];//изменение весов дуг
- w[i] += delta_w[i];
- v0[i] += delta_v0[i];
- }
- }
- }
- f = w0;
- for (int i = 0; i < points; i++)
- {
- a[i] = (-coef_x)*v[i] + v0[i];
- z[i] = tan(a[i]);
- }
- for (int i = 0; i < points; i++)
- f += z[i] * w[i];
- f = tan(f);
- f *= coef_y;//поправка для отрисовки
- MoveToEx(hdc, -coef_x, f, NULL);
- hPen = CreatePen(PS_SOLID, 0, RGB(30, 225, 0));
- SelectObject(hdc, hPen);
- for (int j = -coef_x; j <= coef_x; j++)//отрисовка
- {
- f = w0;
- for (int i = 0; i < points; i++)
- {
- a[i] = (j / coef_x)*v[i] + v0[i];
- z[i] = tan(a[i]);
- }
- for (int i = 0; i < points; i++)
- f += z[i] * w[i];
- f = tan(f);
- f *= coef_y;
- LineTo(hdc, j, (int)f);
- }
- }
- return 0;
- }
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, iMsg, wParam, lParam);
- }
- 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(nullptr, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(nullptr, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = TEXT("MYMENU");
- wndclass.lpszClassName = (szAppName);
- wndclass.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
- RegisterClassEx(&wndclass);
- hwnd = CreateWindow(szAppName, TEXT("Нейронная сеть"),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 1000, 750,
- nullptr, nullptr, hInstance, nullptr);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- while (GetMessage(&msg, nullptr, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement