amir.nazarizadeh Ответов: 2

Что не так с моим NN-кодом?


Привет
Я новичок в программировании
Я хочу, чтобы реализовать простой игры madaline для XOR-функции в нейронной сети
Я использовал этот алгоритм(см. ссылку ниже)
но это не дает мне правильного ответа
он должен дать правильный ответ через 4 эпохи
что не так с моим кодом?
спасибо.../

это ссылка:
алгоритм
.....

Что я уже пробовал:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace xxxxxxx
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] x = new int[,] { { 1, 1 }, { 1, -1 }, { -1, 1 } };
            int[] t = new int[] { -1, 1, 1 };
            double[,] w = new double[,] { { 0.05, 0.1 }, { 0.2, 0.2 }, { 0.5, 0.5 } };
            double[] b = new double[] { 0.3, 0.15, 0.5 };
            bool ep = true;
            int x1;
            int x2;
            double zin1;
            double zin2;
            int z1;
            int z2;
            double yin;
            int y;
            while (ep)
            {
                ep = false;
                for (int j = 0; j < 3; j = j + 1)
                {
                    x1 = x[j, 0];
                    x2 = x[j, 1];
                    zin1 = b[0] + (x1 * w[0, 0]) + (x2 * w[1, 0]);
                    zin2 = b[1] + (x1 * w[0, 1]) + (x2 * w[1, 1]);
                    z1 = f(zin1);
                    z2 = f(zin2);
                    yin = b[2] + z1 * w[2, 0] + z2 * w[2, 1];
                    y = f(yin);
                    if (y != t[j])
                    {
                        ep = true;
                        if (t[j] == 1)
                        {
                            if (Math.Abs(zin1) < Math.Abs(zin2))
                            {
                                b[0] = b[0] + 0.5 * (1 - zin1);
                                w[0, 0] = w[0, 0] + 0.5 * (1 - zin1) * x1;
                                w[1, 0] = w[1, 0] + 0.5 * (1 - zin1) * x2;
                            }
                            else
                            {
                                b[1] = b[1] + 0.5 * (1 - zin2);
                                w[0, 1] = w[0, 1] + 0.5 * (1 - zin2) * x1;
                                w[1, 1] = w[1, 1] + 0.5 * (1 - zin2) * x2;
                            }
                        }
                        else if(t[j] == -1)
                        {
                            if (zin1 > 0 && zin2 > 0)
                            {
                                b[0] = b[0] + 0.5 * (-1 - zin1);
                                w[0, 0] = w[0, 0] + 0.5 * (-1 - zin1) * x1;
                                w[1, 0] = w[1, 0] + 0.5 * (-1 - zin1) * x2;
                                b[1] = b[1] + 0.5 * (-1 - zin2);
                                w[0, 1] = w[0, 1] + 0.5 * (-1 - zin2) * x1;
                                w[1, 1] = w[1, 1] + 0.5 * (-1 - zin2) * x2;
                            }
                            else if (zin1 > 0 && zin2 <= 0)
                            {
                                b[0] = b[0] + 0.5 * (-1 - zin1);
                                w[0, 0] = w[0, 0] + 0.5 * (-1 - zin1) * x1;
                                w[1, 0] = w[1, 0] + 0.5 * (-1 - zin1) * x2;
                            }
                            else if (zin1 < 0 && zin2 > 0)
                            {
                                b[1] = b[1] + 0.5 * (-1 - zin2);
                                w[0, 1] = w[0, 1] + 0.5 * (-1 - zin2) * x1;
                                w[1, 1] = w[1, 1] + 0.5 * (-1 - zin2) * x2;
                            }
                        }
                    }
                }
            }

            Console.WriteLine("b1:{0} , b2:{1} , b3:{2} \n w00:{3} , w10:{4} , w01:{5}, w11:{6}", b[0], b[1], b[2], w[0, 0], w[1, 0], w[0, 1], w[1, 1]);

            int[,] test = new int[,] { { -1, -1 } };
            x1 = test[0, 0];
            x2 = test[0, 1];
            zin1 = b[0] + (x1 * w[0, 0]) + (x2 * w[1, 0]);
            zin2 = b[1] + (x1 * w[0, 1]) + (x2 * w[1, 1]);
            z1 = f(zin1);
            z2 = f(zin2);
            yin = b[2] + z1 * w[2, 0] + z2 * w[2, 1];
            y = f(yin);
            if (y == 1)
            {
                Console.WriteLine("1");
            }
            else
            {
                Console.WriteLine("-1");
            }
            Console.ReadLine();
        }

  private static int f(double zin)
        {
            return (zin >= 0) ? 1 : -1;
        }
    }
}

BillWoodruff

Установите точки останова, один шаг через код, наблюдая, что происходит и что отличается от ваших ожиданий, и вам нужно понять, что делает алгоритм в dertail.

2 Ответов

Рейтинг:
1

Patrice T

Цитата:
но это не дает мне правильного ответа

Вы забыли сказать нам, какие результаты вы ожидаете и какие результаты вы на самом деле получаете.
Без этих сведений невозможно дать вам реальные ответы.

Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя отладчик Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик-Википедия, свободная энциклопедия[^]
Отладка кода C# в Visual Studio-YouTube[^]
Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.


Рейтинг:
0

OriginalGriff

Поскольку вы перепечатали вопрос, я перепечатаю решение...


Несколько вещей:
1) Не используйте односимвольные имена переменных: их легко ввести, но невозможно прочитать и понять, что происходит. Используйте имена, которые описывают, что делают переменные, особенно если вы хотите, чтобы какой-нибудь другой бедняга попытался прочитать их.

2)Если вы не делаете (1) выше, документируйте свой код. На самом деле, документируйте свой код в любом случае. Я совершенно не представляю, что должен делать код, а тем более то, что он делает или не делает, что вы считаете "неправильным", или как я должен проверить его, чтобы выяснить.

3) компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании письма: успешная компиляция означает, что вы написали письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

Итак, теперь вы входите во вторую стадию разработки (на самом деле это четвертая или пятая, но к более ранним стадиям вы придете позже): тестирование и отладка.

Начните с рассмотрения того, что он делает и чем это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а он удваивает его и печатает ответ, то если ввод / вывод был таким:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его-он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он где-то здесь:
private int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поставить точку останова на строке:
while (pp < 15)

и запустите свое приложение. Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она на самом деле делала, когда вы использовали кнопку "шаг вперед" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?

Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он совершенствуется только при использовании!