Пример #1
0
        /// <summary>
        /// Метод вычисления состояния нижнего слоя нейронов выбранной нейросети.
        /// </summary>
        /// <param name="Neuronet">Указатель на нейросеть.</param>
        public static void ComputeNeuronet(ref StructureNeuronet Neuronet)
        {
            Int32 i = 0, j = 0, i0 = 0, j0 = 0, k, l;                                        // Переменные для четырех циклов.
            Int32 Square = 0;                                                                // Номер текущего квадратика.
            Int32 Side   = (Int32)Math.Sqrt(Neuronet.Pixel.Length / Neuronet.Neuron.Length); // Сторона квадратика, на которые разбиваем все изображение.
            float Excitation;

            // Основной цикл по квадратикам:
            while (i < (Int32)Math.Sqrt(Neuronet.Neuron.Length))
            {
                j  = 0;
                j0 = 0;
                while (j < (Int32)Math.Sqrt(Neuronet.Neuron.Length))
                {
                    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    Excitation = 0.0f;
                    for (k = 0; k < Side; k++)
                    {
                        for (l = 0; l < Side; l++)
                        {
                            Excitation += ColorToExcitation(ref Neuronet.Pixel[j0 + l, i0 + k]);
                        }
                    }
                    Neuronet.Neuron[Square] = Excitation;
                    Square++;
                    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    j0 += Side;
                    j++;
                }
                i0 += Side;
                i++;
            }
        }
Пример #2
0
        /// <summary>
        /// Метод переобучения нейросети с коэффициентом памяти (aka коэф.забывания).
        /// </summary>
        /// <param name="Destination">Указатель на принимающую нейросеть.</param>
        /// <param name="Source">Указатель на исходную нейросеть.</param>
        /// <param name="MemoryFactor">Коэффициент памяти.</param>
        public static void MemorizeNeuronet(ref StructureNeuronet Destination, ref StructureNeuronet Source, float MemoryFactor)
        {
            Int32 i, j, k = (Int32)Math.Sqrt(Source.Pixel.Length); // i, j - переменные для цыклов; k - размерность матрицы изображения.

            Destination.Name = Source.Name;
            // Копирование изображения:
            Destination.Pixel = new StructureColor[k, k];
            for (i = 0; i < k; i++)
            {
                for (j = 0; j < k; j++)
                {
                    Destination.Pixel[j, i] = Source.Pixel[j, i];
                }
            }
            // Копирование нижнего состояния нижнего слоя нейронов с учетом коэффициента памяти (aka коэф. забывания):
            if (MemoryFactor < 0.0f)
            {
                MemoryFactor = 0.0f;
            }
            if (MemoryFactor > 1.0f)
            {
                MemoryFactor = 1.0f;
            }
            Destination.Neuron = new float[Source.Neuron.Length];
            for (i = 0; i < Source.Neuron.Length; i++)
            {
                Destination.Neuron[i] = Destination.Neuron[i] * MemoryFactor + Source.Neuron[i] * (1.0f - MemoryFactor);
            }
        }
Пример #3
0
 /// <summary>
 /// Метод создания экземпляра образа.
 /// </summary>
 /// <param name="Name">Имя образа.</param>
 /// <param name="SideLength">Длина стороны образа.</param>
 /// <param name="BottomLayerLength">Длина нижнего слоя нейронов (количество нейронов в нижнем слое).</param>
 /// <returns>Указатель на созданный образ.</returns>
 public static void CreateNeuronet(ref StructureNeuronet Neuronet, String Name, Int32 PictureDimension, Int32 ImageDimension)
 {
     Neuronet        = new StructureNeuronet();
     Neuronet.Name   = Name;
     Neuronet.Pixel  = new StructureColor[PictureDimension, PictureDimension];
     Neuronet.Neuron = new float[ImageDimension];
 }
Пример #4
0
        /// <summary>
        /// Метод сравнения двух нейросетей. Именно нейросетей. Каждый образ поступает на чувствительные нейроны (верхний слой), далее
        /// возбуждает нижний слой. Вот в таком состоянии хранятся образы, в виде возбужденных нейросетей. Сравнивая состояние нейросетей,
        /// мы как бы сравниваем образы, вот и получается это самое распознавание изображений. На выходе этого метода получаем
        /// число, которое показывает степень отличия образов. Чем оно меньше, тем похожее образы.
        /// </summary>
        /// <param name="Neuronet1">Указатель на первую нейросеть.</param>
        /// <param name="Neuronet2">Указатель на вторую нейросеть.</param>
        /// <returns>Степень соответствия нейросетей (ну или образов, как хотите).</returns>
        public static Single CompareImages(ref StructureNeuronet Neuronet1, ref StructureNeuronet Neuronet2)
        {
            Single Result = 0.0f;
            Int32  Length = Math.Min(Neuronet1.Neuron.Length, Neuronet2.Neuron.Length);

            for (Int32 i = 0; i < Length; i++)
            {
                Result += (Single)Math.Pow((Single)(Neuronet1.Neuron[i] - Neuronet2.Neuron[i]), 2.0f);
            }
            return(Result / (Single)Length);
        }
Пример #5
0
        /// <summary>
        /// Метод копирования содержимого одного образа в другой.
        /// </summary>
        /// <param name="Destination">Принимающий образ.</param>
        /// <param name="Source">Исходный образ.</param>
        public static void CopyNeuronet(ref StructureNeuronet Destination, ref StructureNeuronet Source)
        {
            Int32 i, j, k = (Int32)Math.Sqrt(Source.Pixel.Length); // i, j - переменные для цыклов; k - размерность матрицы изображения.

            Destination.Name = Source.Name;
            // Копирование изображения:
            Destination.Pixel = new StructureColor[k, k];
            for (i = 0; i < k; i++)
            {
                for (j = 0; j < k; j++)
                {
                    Destination.Pixel[j, i] = Source.Pixel[j, i];
                }
            }
            // Копирование нижнего слоя нейронов:
            Destination.Neuron = new float[Source.Neuron.Length];
            for (i = 0; i < Source.Neuron.Length; i++)
            {
                Destination.Neuron[i] = Source.Neuron[i];
            }
        }
Пример #6
0
        /// <summary>
        /// Метод отрисовки диаграммы возбужденности нейронных слоев нейросети.
        /// </summary>
        /// <param name="Neuronet">Указатель на нейросеть.</param>
        /// <param name="Canvas">Графический буфер для рисования.</param>
        /// <param name="x">Координата по оси OX.</param>
        /// <param name="y">Координата по оси OY.</param>
        /// <param name="Angle">Угол поворота диаграммы.</param>
        public static void DrawNeuronet(ref StructureNeuronet Neuronet, Graphics Canvas, float x, float y, float Angle)
        {
            Pen   Pen = new Pen(Color.White, 45.0f); // Кисть с соответствующим цветом и размером.
            float Angl, dAngl, Excitation;           // Текущий угол; приращение кугла; цвет сектора диаграммы (пропорционален возбужденности блока нейронов).
            Int32 i = 0, i0 = 0, j, j0, k, l;        // Переменные цикла.
            Int32 c, s, Block, Side;                 // Переменные цикла; c - номер текущего нейрона в блоке; s - текущая часть блока (в данном случае всего 3 части в каждом блоке);

            // Block - количество нейронов в блоке; Side - сторона квадратика, см. ниже.
            // Рисуем верхний (чувствительный слой нейронов):
            Angl  = Angle;                                                            // Установка угла, под которым будем рисовать круговую диаграмму состояния нейросети.
            dAngl = 360.0f / (3 * Neuronet.Neuron.Length);                            // Установка приращения угла, в которое будет укладываться блок нейронов верхнего слоя.
            Side  = (Int32)Math.Sqrt(Neuronet.Pixel.Length / Neuronet.Neuron.Length); // Сторона квадратика, на которые разбиваем все изображение.
            Block = (Int32)(Math.Pow(Side, 2) / 3);                                   // Вычисление количества нейронов в блоке.
            while (i < (Int32)Math.Sqrt(Neuronet.Neuron.Length))                      // (Int32) используется для правильного округления и предотвращения выхода за границы массива.
            {
                j = 0;                                                                // Количество пройденных кубиков по горизонтали (необходимо для правильного вывода нестандартных нейросетей, т.е. у которых Side не целое число).
                       // i - по вертикали.
                j0 = 0;                                                               // Позиция (по горизонтали) в матрице с изображением.
                                                                                      // i0 - по вертикали.
                while (j < (Int32)Math.Sqrt(Neuronet.Neuron.Length))
                {
                    //MessageBox.Show(m_PictureDimension.ToString() + " " + j.ToString() + " " + i.ToString());
                    c          = 0; // Количество подсчитанных нейронов в блоке.
                    s          = 0; // Пройденное количество блоков.
                    Excitation = 0.0f;
                    for (k = 0; k < Side; k++)
                    {
                        for (l = 0; l < Side; l++)
                        {
                            Excitation += ColorToExcitation(ref Neuronet.Pixel[j0 + l, i0 + k]); // Ссумируем напряженность текущего нейрона.
                            c++;
                            if (c == Block)
                            {
                                s++;
                                c           = 0;
                                Excitation /= Block;                                                     // Смегчаем цвет для более приятного и информативного отображения на экране.
                                Pen.Color   = Color.FromArgb(0, ExcitationToByte(Excitation / 3.0f), 0); // Вычисляем цвет нейронного блока в зависимости от их возбужденности (делим для более приятного отображения на экране).
                                Canvas.DrawArc(Pen, x, y, 5 * Pen.Width, 5 * Pen.Width, -Angl, -dAngl);  // Отрисовка блока нейронов в 3-ех градусах диаграммы.
                                Angl += dAngl;                                                           // Переход на новый угол диаграммы.
                                if (s == 3)
                                {
                                    k = Side; // Принудительно завершаем третий цикл.
                                    break;    // И выхоим из текущего.
                                }
                            }
                        }
                    }
                    j0 += Side;
                    j++;
                }
                i0 += Side;
                i++;
            }
            // Рисуем нижний слой нейронов (образ):
            Angl  = Angle;                           // Установка угла, под которым будем рисовать круговую диаграмму состояния нейросети.
            dAngl = 360.0f / Neuronet.Neuron.Length; // Установка приращения угла, в которое будет укладываться блок нейронов верхнего слоя.
            for (i = 0; i < Neuronet.Neuron.Length; i++)
            {
                Pen.Color = Color.FromArgb(0, ExcitationToByte(Neuronet.Neuron[i] / 42.0f), 0);                 // Вычисляем цвет нейронного блока в зависимости от их возбужденности.
                Canvas.DrawArc(Pen, x + Pen.Width, y + Pen.Width, 3 * Pen.Width, 3 * Pen.Width, -Angl, -dAngl); // Отрисовка блока нейронов в 3-ех градусах диаграммы.
                Angl += dAngl;                                                                                  // Переход на новый угол диаграммы.
            }
        }