Задать вопрос
@byulent

Что не так с перцептроном?

Пишу простой линейный перцептрон с обучением с учителем. Нужно по координатам точки в пространстве определить, к какому октанту она относится.
Вроде бы всё сделал по инструкции:
под катом
class Program
    {
        private static void Teach(double[] x, double[,] w, double alpha, double theta, int octant)
        {
            double[] net = new double[8];
            double[] o = new double[8];
            double[] target = new double[8];
            double[] error = new double[8];
            for (int j = 0; j < 8; j++)
            {
                net[j] = 0;
                for (int i = 0; i < 3; i++)
                {
                    net[j] += x[i] * w[i, j];
                }
            }
            for (int j = 0; j < 8; j++) 
            { 
                if (net[j] > theta) o[j] = 1;
                else o[j] = 0;
                if (j == octant - 1) target[j] = 1;
                else target[j] = 0;
                error[j] = target[j] - o[j];
            }
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    w[i, j] += alpha * x[i] * error[j];
                }
            }
        }
        static int Recognize (double[] x, double[,] w, double theta)
        {
            int res = -1;
            double max = -999;
            double[] net = new double[8];
            double[] o = new double[8];
            for (int j = 0; j < 8; j++)
            {
                net[j] = 0;
                for (int i = 0; i < 3; i++)
                {
                    net[j] += x[i] * w[i, j];
                }
            }
            for (int j = 0; j < 8; j++)
            { 
                if (net[j] > max)
                {
                    max = net[j];
                    res = j + 1;
                }
            }
            return res;
        }
        static void Main(string[] args)
        {
            int n, octant;
            double[] x = new double[3];
            double[,] w = new double[3, 8]; //веса
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 8; j++) w[i, j] = 0.1;
            double alpha = 1; //скорость обучения
            double theta = 0; //общий порог для всех нейронов
            string[] lines = File.ReadAllLines("teach.txt");
            foreach (string s in lines)
            {
                string[] nums = s.Split(' ');
                for (int i = 0; i < 3; i++) x[i] = Convert.ToDouble(nums[i]);
                octant = Convert.ToInt32(nums[3]);
                Teach(x, w, alpha, theta, octant);
            }
            Console.WriteLine("Обучение завершено");
            Console.WriteLine("Введите строку для распознавания");
            lines = Console.ReadLine().Split(' ');
            for (int i=0; i<3; i++)
            {
                x[i] = Convert.ToDouble(lines[i]);
            }
            int r = Recognize(x, w, theta);
            Console.WriteLine("Октант: " + r);
            }
        }

Файл teach.txt: pastebin

Однако всё распознаётся неправильно: все точки определяются не тем октантом, и каждый раз по-разному. В чём ошибка и что нужно поменять?
  • Вопрос задан
  • 605 просмотров
Подписаться 2 Оценить 9 комментариев
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы