Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Drawing;
- using System.Windows.Forms;
- namespace NeuralNetworkPrediction
- {
- public class MainPanel : Panel
- {
- // Константы
- private const int N = 300;
- private const double TAU = 0.01;
- private const double TAU_STEP = 0.01;
- private const double D_H = 0.05;
- private const double ALPHA = 0.01;
- private const int R = 10;
- private const double START_X = -10.0;
- private const double END_X = 5.0;
- private const double A0 = 4.5;
- private const double A1 = 0.6;
- private const double A2 = -23.2;
- private const double A3 = 108.6;
- private const double A4 = -147.7;
- private const double A5 = 38;
- // Переменные нейросети
- private double c_x;
- private double[] u_t;
- private double[] u;
- private double[] u_n;
- private double[] g;
- private int n_t;
- private int step;
- private int err;
- private double learningPercentage;
- // Графические параметры
- private double graphW, graphH, graphDx, graphBx, graphRx;
- private Timer timer;
- public MainPanel()
- {
- // Инициализация переменных
- c_x = START_X;
- u_t = new double[N];
- u = new double[N];
- u_n = new double[N];
- g = new double[R];
- for (int i = 0; i < N; i++)
- {
- u[i] = 0.0;
- u_t[i] = 0.0;
- u_n[i] = 0.0;
- }
- for (int i = 0; i < R; i++)
- {
- g[i] = 0.0;
- }
- n_t = N / 2 + 1;
- step = 1;
- err = 0;
- learningPercentage = 0.0;
- // Настройка панели
- DoubleBuffered = true;
- // Запуск таймера
- timer = new Timer();
- timer.Interval = 1;
- timer.Tick += Timer_Tick;
- timer.Start();
- }
- private double Sign(double x)
- {
- if (x > 0) return 1.0;
- else if (x < 0) return -1.0;
- return 0.0;
- }
- private double F(double x)
- {
- return A0 * Math.Pow(x, 5) + A1 * Math.Pow(x, 4) + A2 * Math.Pow(x, 3)
- + A3 * Math.Pow(x, 2) + A4 * x + A5;
- }
- private void Teach(double[] u, double[] g, int n_t, double delta)
- {
- double[] delta_g = new double[R];
- for (int r = 0; r < R; r++)
- {
- double x_r = u[n_t - 1 - r];
- delta_g[r] = ALPHA * Sign(x_r) * Sign(delta);
- }
- for (int r = 0; r < R; r++)
- {
- g[r] += delta_g[r];
- }
- err++;
- }
- private void CalculateLearningPercentage()
- {
- double totalError = 0.0;
- double minVal = u[0], maxVal = u[0];
- for (int i = 0; i < N; i++)
- {
- totalError += Math.Abs(u_n[i] - u_t[i]);
- if (u[i] < minVal) minVal = u[i];
- if (u[i] > maxVal) maxVal = u[i];
- }
- double avgError = totalError / N;
- double range = maxVal - minVal;
- if (range < 1e-9) range = 1.0;
- learningPercentage = 100 * (1 - avgError / range);
- if (learningPercentage < 0) learningPercentage = 0;
- if (learningPercentage > 100) learningPercentage = 100;
- }
- private void NewStep()
- {
- for (int i = 0; i < N; i++)
- {
- u_n[i] = F(c_x + i * TAU);
- }
- c_x += TAU_STEP;
- if (c_x > END_X)
- {
- c_x = START_X;
- }
- for (int i = 0; i < N; i++)
- {
- u_t[i] = 0.0;
- }
- for (int i = R; i < N; i++)
- {
- for (int r = 0; r < R; r++)
- {
- u_t[i] += g[r] * u[i - 1 - r];
- }
- }
- for (int i = 0; i < R; i++)
- {
- u_t[i] = u[i];
- }
- double d_u = u_n[n_t] - u_t[n_t];
- if (d_u < -D_H || d_u > D_H)
- {
- Teach(u, g, n_t, d_u);
- }
- step++;
- }
- private void UpdateVars()
- {
- NewStep();
- for (int i = 0; i < N; i++)
- {
- u[i] = u_n[i];
- }
- CalculateLearningPercentage();
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- base.OnPaint(e);
- Graphics g2 = e.Graphics;
- // Инициализация графических параметров
- graphW = Width;
- graphH = Height;
- graphDx = graphW / N;
- graphBx = (graphW - graphDx * (N - 1)) / 2.0;
- graphRx = graphBx + (N - 1) * graphDx;
- // Масштабирование
- double minVal = u[0], maxVal = u[0];
- for (int i = 1; i < N; i++)
- {
- if (u[i] < minVal) minVal = u[i];
- if (u[i] > maxVal) maxVal = u[i];
- }
- double mid = (maxVal + minVal) / 2.0;
- double diff = maxVal - minVal;
- minVal = mid - diff * 1.5;
- maxVal = mid + diff * 1.5;
- if (Math.Abs(maxVal - minVal) < 1e-9)
- {
- minVal -= 1.0;
- maxVal += 1.0;
- }
- double localMtt = graphH / (maxVal - minVal);
- double y_c = localMtt * maxVal;
- // Рисуем оси
- using (Pen pen = new Pen(Color.Black))
- {
- g2.DrawLine(pen, (float)graphBx, 0, (float)graphBx, (float)graphH);
- g2.DrawLine(pen, (float)graphRx, 0, (float)graphRx, (float)graphH);
- g2.DrawLine(pen, (float)graphBx, 0, (float)graphRx, 0);
- g2.DrawLine(pen, (float)graphBx, (float)graphH, (float)graphRx, (float)graphH);
- g2.DrawLine(pen, (float)graphBx, (float)y_c, (float)graphRx, (float)y_c);
- for (int i = 1; i < N - 1; i++)
- {
- float x = (float)(graphBx + i * graphDx);
- g2.DrawLine(pen, x, (float)(y_c - 3), x, (float)(y_c + 3));
- }
- float x_nt = (float)(graphBx + (n_t - 1) * graphDx);
- g2.DrawLine(pen, x_nt, 0, x_nt, (float)graphH);
- }
- // Рисуем кривую u
- using (Pen greenPen = new Pen(Color.Green))
- {
- float oldX = (float)graphBx;
- float oldY = (float)(y_c - localMtt * u[0]);
- for (int i = 1; i < N; i++)
- {
- float x = (float)(graphBx + i * graphDx);
- float y = (float)(y_c - localMtt * u[i]);
- g2.DrawLine(greenPen, oldX, oldY, x, y);
- oldX = x;
- oldY = y;
- }
- }
- // Рисуем прогноз u_t
- using (Pen redPen = new Pen(Color.Red))
- {
- float oldX = (float)graphBx;
- float oldY = (float)(y_c - localMtt * u_t[0]);
- for (int i = 1; i < N; i++)
- {
- float x = (float)(graphBx + i * graphDx);
- float y = (float)(y_c - localMtt * u_t[i]);
- g2.DrawLine(redPen, oldX, oldY, x, y);
- oldX = x;
- oldY = y;
- }
- }
- // Рисуем текст
- using (Font font = new Font("Arial", 10))
- using (Brush brush = new SolidBrush(Color.Black))
- {
- float textX = 20;
- float textY = 20;
- g2.DrawString($"Step = {step}", font, brush, textX, textY); textY += 16;
- g2.DrawString($"dH = {D_H:F2}", font, brush, textX, textY); textY += 16;
- g2.DrawString($"dG = {ALPHA:F3}", font, brush, textX, textY); textY += 16;
- for (int i = 0; i < R; i++)
- {
- g2.DrawString($"G[{i}] = {g[i]:F3}", font, brush, textX, textY);
- textY += 16;
- }
- g2.DrawString($"Learning: {learningPercentage:F2}%", font, brush, textX, textY);
- textY += 16;
- g2.DrawString($"c_x = {c_x:F3}", font, brush, textX, textY);
- }
- }
- protected override Size DefaultSize => new Size(800, 600);
- private void Timer_Tick(object sender, EventArgs e)
- {
- UpdateVars();
- Invalidate();
- }
- [STAThread]
- static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Form form = new Form
- {
- Text = "Прогнозирование функции (нейросеть)",
- ClientSize = new Size(800, 600)
- };
- MainPanel panel = new MainPanel();
- form.Controls.Add(panel);
- panel.Dock = DockStyle.Fill;
- form.ShowDialog();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement