Количество скрытых слоев, единиц в скрытых слоях и эпох до тех пор, пока нейронная сеть не начнет вести себя приемлемо на данных обучения

Я пытаюсь решить эту проблему Kaggle, используя Neural Networks. Я использую библиотеку Pybrain Python.

Это классическая контролируемая проблема обучения. В следующем коде: переменная "data" представляет собой массив numpy (892 * 8). 7 полей - мои функции, а 1 поле - мое выходное значение, которое может быть "0" или "1" .

from pybrain.datasets import ClassificationDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.shortcuts import buildNetwork

dataset = ClassificationDataSet(7,1)
for i in data:
    dataset.appendLinked(i[1:],i[0])
net = buildNetwork(7,9,7,1, bias = True,hiddenclass = SigmoidLayer, outclass = TanhLayer)
trainer = BackpropTrainer(net, learningrate = 0.04, momentum = 0.96, weightdecay = 0.02, verbose = True)
trainer.trainOnDataset(dataset, 8000)
trainer.testOnData(verbose = True)

После обучения моей нейронной сети, когда я тестирую ее на Training Data, она всегда дает один вывод для всех входных данных. Как:

Testing on data:
out:     [  0.075]
correct: [  1.000]
error:  0.42767858
out:     [  0.075]
correct: [  0.000]
error:  0.00283875
out:     [  0.075]
correct: [  1.000]
error:  0.42744569
out:     [  0.077]
correct: [  1.000]
error:  0.42616996
out:     [  0.076]
correct: [  0.000]
error:  0.00291185
out:     [  0.076]
correct: [  1.000]
error:  0.42664586
out:     [  0.075]
correct: [  1.000]
error:  0.42800026
out:     [  0.076]
correct: [  1.000]
error:  0.42719380
out:     [  0.076]
correct: [  0.000]
error:  0.00286796
out:     [  0.076]
correct: [  0.000]
error:  0.00286642
out:     [  0.076]
correct: [  1.000]
error:  0.42696969
out:     [  0.076]
correct: [  0.000]
error:  0.00292401
out:     [  0.074]
correct: [  0.000]
error:  0.00274975
out:     [  0.076]
correct: [  0.000]
error:  0.00286129

Я попробовал изменить learningRate, weightDecay, импульс, количество скрытых единиц, количество скрытых слоев, класс скрытых слоев, класс выходных слоев, чтобы решить его, но в каждом случае он дает одинаковый вывод для каждого входа, если вход происходит из данных обучения.

Я думаю, что я должен запускать его более 8000 раз, потому что, когда я строил Neural Network для "XOR" , потребовалось по крайней мере 700 итераций, прежде чем он начал давать ошибки в наномасштабном масштабе. Размер данных обучения на "XOR" был всего 4, тогда как в этом случае это 892. Таким образом, я выполнил 8000 итераций на 10% исходных данных (теперь размер данных обучения составляет 89), даже тогда он выдавал одинаковый результат для каждого входа в данных обучения. И поскольку я хочу классифицировать ввод в "0" или "1" , если я использую класс Output Layer для Softmax, он всегда дает "1" в качестве вывода.

Независимо от того, какую конфигурацию (количество скрытых единиц, класс выходного уровня, скорость обучения, класс скрытого слоя, импульс), я использовал в "XOR" , он более или менее начинал сходиться в каждом случае.

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

Я запустил его для 80 000 итераций (размер данных обучения - 89). Образец вывода:

Testing on data:
out:     [  0.340]
correct: [  0.000]
error:  0.05772102
out:     [  0.399]
correct: [  0.000]
error:  0.07954010
out:     [  0.478]
correct: [  1.000]
error:  0.13600274
out:     [  0.347]
correct: [  0.000]
error:  0.06013008
out:     [  0.500]
correct: [  0.000]
error:  0.12497886
out:     [  0.468]
correct: [  1.000]
error:  0.14177601
out:     [  0.377]
correct: [  0.000]
error:  0.07112816
out:     [  0.349]
correct: [  0.000]
error:  0.06100758
out:     [  0.380]
correct: [  1.000]
error:  0.19237095
out:     [  0.362]
correct: [  0.000]
error:  0.06557341
out:     [  0.335]
correct: [  0.000]
error:  0.05607577
out:     [  0.381]
correct: [  0.000]
error:  0.07247926
out:     [  0.355]
correct: [  1.000]
error:  0.20832669
out:     [  0.382]
correct: [  1.000]
error:  0.19116165
out:     [  0.440]
correct: [  0.000]
error:  0.09663233
out:     [  0.336]
correct: [  0.000]
error:  0.05632861

Средняя ошибка: 0.112558819082

('Максимальная ошибка:', 0.21803000849096299, 'Средняя ошибка:', 0.096632332865968451)

Он дает все выходы в пределах диапазона (0.33, 0.5).

Ответ 1

Существует еще одна метрика нейронной сети, о которой вы не отметили - количество адаптируемых весов. Я начинаю ответ от этого, потому что это связано с количеством скрытых слоев и единиц в них.

Для хорошего обобщения количество весов должно быть намного меньше Np/Ny, где Np - количество шаблонов, а Ny - количество сетевых выходов. Что такое "много", что можно обсудить, я предлагаю разницу в несколько раз, скажем 10. Для примерно 1000 шаблонов и 1 вывода в вашей задаче это будет означать 100 весов.

Не имеет смысла использовать 2 скрытых слоя. 1 достаточно для большинства задач, в которых задействована нелинейность. В вашем случае дополнительный скрытый слой делает только разницу, влияя на общую производительность. Поэтому, если используется 1 скрытый слой, количество нейронов в нем может быть аппроксимировано как количество весов, деленное на количество входов, то есть 100/7 = 14.

Я предлагаю использовать ту же самую функцию активации во всех нейронах, будь то Hypertanh или Sigmoid всюду. Ваши выходные значения на самом деле уже нормализованы для Sigmoid. Во всяком случае, вы можете улучшить производительность NN путем нормализации входных данных, чтобы поместиться в [0,1] во всех измерениях. Конечно, нормализуйте каждую функцию самостоятельно.

Если вы можете сделать это с помощью библиотеки Pybrain lib, начните учиться с большей скоростью обучения, а затем уменьшите ее плавно пропорционально текущему шагу (LR * (N - i)/N), где я - текущий шаг, N - предел, LR - начальная скорость обучения.

Как предположил @Junuxx, выводить текущую ошибку каждые M шагов (если это возможно), чтобы убедиться, что ваша программа работает должным образом. Остановите обучение, если разница в ошибках в последовательных шагах становится меньше порога. Только для начальной и грубой оценки правильных параметров NN, устанавливающих порог в 0,1-0,01 (нет необходимости в "наномасштабе" ).

Факт запуска сети по 89 шаблонам в 80000 шагах и получение результатов, которые у вас есть, странно. Пожалуйста, дважды проверьте, что вы передаете правильные данные в NN, и, пожалуйста, изучите, что означает значения ошибок, которые вы указали. Возможно, либо ошибки, либо выводимые данные берутся из неправильного места. Я думаю, 10000 шагов должны быть достаточно далеко, чтобы получить приемлемые результаты для 89 паттеров.

Что касается конкретной задачи, я думаю, что SOM net может быть другим вариантом (возможно, более подходящим, чем BP).

В качестве побочного элемента я не знаком с Pybrain, но закодировал некоторые NN на языках С++ и других языках, поэтому ваше время выглядит очень негативным.