Многослойный персептрон (нейронная сеть) - что мне не хватает? - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь реализовать свой собственный многослойный персептрон, к сожалению, я делаю ошибку, которую не могу найти. Ссылка на полную программу находится здесь (это легкое, простое консольное приложение на c #). Я учусь из этой книги , код, который я пытаюсь переписать из партии в последовательную форму, находится в этом github .

Ссылка на мой мой проект здесь (github). Сам перцептрон находится здесь .

Мои тестовые входы - это функция Xor и функция или функция и некоторая случайная функция с небольшим шумом.

Мои вопросы:

1) Прежде, чем я покрыл весь мой код проверками бесконечности (для двойного переполнения), все мои результаты (и веса) очень быстро (более 100 итераций) сходились к некоторым сверхвысоким значениям, и результаты стали NaN. После добавления чеков я только что получил double.MaxValue. Интересно то, что если я запустил одну и ту же программу около 5 раз, я получу правильные результаты (в зависимости от количества итераций). Единственной случайной величиной являются веса, которые инициализируются с использованием случайных чисел (в диапазоне -1/sqrt(n) < x < 1/sqrt(n), где n - число нейронов в скрытом слое). Что может быть причиной этого?

2) Я тренируюсь и проверяю один и тот же набор данных (потому что сейчас это не имеет значения), и, поскольку это последовательный алгоритм, я перетасовываю учебные материалы и цели ВНУТРИ моего класса.

public void Train(int iterations, double eta)
{
    _lastHiddenUpdates = new double[_hiddenWeights.RowLength(), _hiddenWeights.ColumnLength() + 1];
    _lastOutputUpdates = new double[_outputWeights.Length];
    for (int i = 0; i < iterations; i++)
    {
        ShuffleRows(); // <---- ShuffleRows is a private method without any ref parameter!
        this._currentIteration = i;
        var result = ForwardPhase(_trainingInput);
        BackwardsPhase(result.OutputResult, result.HiddenValues, eta);
    }
}

Это класс MultiLayerPerceptron. Дело в том, что после обучения исходный массив double[] также перемешивается! массив double является структурой, а структуры передаются по значению, а не по ссылке, а исходный массив находится в program.cs. Почему это изменилось за пределами области видимости? Я что-то пропустил? Теперь я просто клонирую целевые массивы.

3)

Это супер уродливо

var infinity = deltasHs[i, j];
if (double.IsNegativeInfinity(infinity))
{
    deltasHs[i, j] = double.MinValue;
}
else if (double.IsPositiveInfinity(infinity))
{
    deltasHs[i, j] = double.MaxValue;
}

Как я могу это просто?

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

...