Подтвердить что ты не робот

Обучение нейронной сети с PyBrain не сходится

У меня есть следующий код из учебника PyBrain:

from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure.modules import TanhLayer

ds = SupervisedDataSet(2, 1)
ds.addSample((0,0), (0,))
ds.addSample((0,1), (1,))
ds.addSample((1,0), (1,))
ds.addSample((1,1), (0,))

net     = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
trainer = BackpropTrainer(net, ds)

for inp, tar in ds:
     print [net.activate(inp), tar]

errors  = trainer.trainUntilConvergence()

for inp, tar in ds:
     print [net.activate(inp), tar]

Однако результатом является нейронная сеть, которая плохо обучена. При просмотре вывода ошибки сеть получает соответствующую подготовку, но использует аргумент 'continueEpochs' для обучения еще нескольких, и сеть снова работает хуже. Таким образом, сеть сходится, но нет возможности получить лучшую обучаемую сеть. Документация PyBrain подразумевает, что сеть возвращается, которая лучше всего обучена, однако возвращает Tuple ошибок.

Когда etting continueEpochs в 0, я получаю сообщение об ошибке (ValueError: max() arg - пустая последовательность), поэтому continueEpochs должен быть больше 0.

Действительно ли PyBrain поддерживается, потому что кажется, что существует большая разница в документации и коде.

4b9b3361

Ответ 1

После некоторого дополнительного копания я обнаружил, что пример в учебнике PyBrain совершенно неуместен.

Когда мы смотрим на подпись метода в исходном коде, мы находим:

def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):

Это означает, что для проверки используется 25% обучающего набора. Хотя это очень эффективный метод при подготовке сети к данным, которые вы не собираетесь делать, когда у вас есть полный набор возможностей в вашем распоряжении, а именно набор из 4-х рядов XOR 2-in-1-out. Когда вы хотите тренировать набор XOR и вы удаляете одну из строк для проверки, которая имеет непосредственное следствие, что вы получаете очень редкий набор тренировок, где одна из возможных комбинаций опущена, что автоматически получается в тех весах, которые не проходят обучение.

Обычно, когда вы опускаете 25% данных для проверки, вы делаете это, предполагая, что эти 25% покрывают "большую часть" пространства решений, с которым сеть уже столкнулась более или менее. В этом случае это неверно, и он охватывает 25% пространства решений, полностью неизвестного сети, поскольку вы удалили его для проверки.

Итак, тренер правильно тренировался в сети, но, не обращая внимания на 25% проблемы XOR, это приводит к плохо обученной сети.

Другой пример на веб-сайте PyBrain как быстрый запуск будет очень удобен, потому что этот пример просто неверен в этом конкретном случае XOR. Вы могли бы задаться вопросом, попробовали ли они сам пример, потому что он просто выводит случайно плохо обученные сети.

Ответ 2

Я взял отличный класс машинного обучения на Coursera, преподаваемый Andrew Ng, и одна часть класса покрыла обучение небольшой нейронной сетью распознать xor. Поэтому я был немного обеспокоен примером pybrain, основанным на частях quickstart, которые не сходились.

Я думаю, что есть много причин, в том числе выше, о том, что минимальный набор данных разделен на обучение и валидацию. В какой-то момент в курсе Андрей сказал: "Это не тот, у кого лучший алгоритм, который выигрывает, тот, у кого больше всего данных. И он продолжал объяснять, что взрыв в доступности данных в 2000 году является частью причины возрождение в ИИ, теперь называемое машинным обучением.

Итак, со всем этим я понял, что

  • набор проверок может содержать 4 выборки, поскольку это происходит после фазы обучения.
  • сети требуется только 2 узла в скрытом слое, как я узнал в классе,
  • скорость обучения в этом случае должна быть довольно маленькой, например 0,005, иначе тренировка иногда пропускает ответ (это важный момент из класса, который я подтвердил, играя с цифрами).
  • Чем меньше скорость обучения, тем меньше может быть maxEpochs. Небольшая скорость обучения означает, что сходимость занимает меньшие шаги вдоль градиента к минимизации. Если он больше, вам нужны большие maxEpochs, чтобы он подождал дольше, прежде чем решить, что он достиг минимального уровня.
  • Вам нужно предусмотреть смещение = True в сети (что добавляет константу 1 node к входным и скрытым слоям). Прочитайте ответы на этот вопрос о предвзятости.
  • Наконец, и самое главное, вам нужен большой набор тренировок. 1000 сходится в правильном ответе примерно в 75% случаев. Я подозреваю, что это связано с алгоритмом минимизации. Меньшие числа будут терпеть неудачу часто.

Итак, вот какой код работает:

from pybrain.datasets import SupervisedDataSet

dataModel = [
    [(0,0), (0,)],
    [(0,1), (1,)],
    [(1,0), (1,)],
    [(1,1), (0,)],
]

ds = SupervisedDataSet(2, 1)
for input, target in dataModel:
    ds.addSample(input, target)

# create a large random data set
import random
random.seed()
trainingSet = SupervisedDataSet(2, 1);
for ri in range(0,1000):
    input,target = dataModel[random.getrandbits(2)];
    trainingSet.addSample(input, target)

from pybrain.tools.shortcuts import buildNetwork
net = buildNetwork(2, 2, 1, bias=True)

from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(net, ds, learningrate = 0.001, momentum = 0.99)
trainer.trainUntilConvergence(verbose=True,
                              trainingData=trainingSet,
                              validationData=ds,
                              maxEpochs=10)

print '0,0->', net.activate([0,0])
print '0,1->', net.activate([0,1])
print '1,0->', net.activate([1,0])
print '1,1->', net.activate([1,1])

Ответ 3

trainer = BackpropTrainer(net, ds, learningrate = 0.9, momentum=0.0, weightdecay=0.0, verbose=True) 
trainer.trainEpochs(epochs=1000)

Этот путь может сходиться. если уровень обучения слишком мал (например, 0,01), он потерян в локальном минимуме. Поскольку я тестировал, обучаюсь в 0.3-30, он может сходиться.

Ответ 4

Следующее, похоже, последовательно дает правильные результаты:

from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure import TanhLayer
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer

#net = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
net = buildNetwork(2, 3, 1, bias=True)

ds = SupervisedDataSet(2, 1)
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))

trainer = BackpropTrainer(net, ds, learningrate=0.001, momentum=0.99)

trainer.trainUntilConvergence(verbose=True)

print net.activate([0,0])
print net.activate([0,1])
print net.activate([1,0])
print net.activate([1,1])