Как сериализовать / десериализовать сети pybrain? - PullRequest
9 голосов
/ 02 декабря 2010

PyBrain - это библиотека python, которая предоставляет (среди прочего) простые в использовании искусственные нейронные сети.

Мне не удается правильно сериализовать / десериализовать сети PyBrain, используя pickle или cPickle.

См. Следующий пример:

from pybrain.datasets            import SupervisedDataSet
from pybrain.tools.shortcuts     import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer
import cPickle as pickle
import numpy as np 

#generate some data
np.random.seed(93939393)
data = SupervisedDataSet(2, 1)
for x in xrange(10):
    y = x * 3
    z = x + y + 0.2 * np.random.randn()  
    data.addSample((x, y), (z,))

#build a network and train it    

net1 = buildNetwork( data.indim, 2, data.outdim )
trainer1 = BackpropTrainer(net1, dataset=data, verbose=True)
for i in xrange(4):
    trainer1.trainEpochs(1)
    print '\tvalue after %d epochs: %.2f'%(i, net1.activate((1, 4))[0])

Это вывод вышеуказанного кода:

Total error: 201.501998476
    value after 0 epochs: 2.79
Total error: 152.487616382
    value after 1 epochs: 5.44
Total error: 120.48092561
    value after 2 epochs: 7.56
Total error: 97.9884043452
    value after 3 epochs: 8.41

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

Теперь мы выполним аналогичное упражнение, но включим сериализацию / десериализацию:

print 'creating net2'
net2 = buildNetwork(data.indim, 2, data.outdim)
trainer2 = BackpropTrainer(net2, dataset=data, verbose=True)
trainer2.trainEpochs(1)
print '\tvalue after %d epochs: %.2f'%(1, net2.activate((1, 4))[0])

#So far, so good. Let's test pickle
pickle.dump(net2, open('testNetwork.dump', 'w'))
net2 = pickle.load(open('testNetwork.dump'))
trainer2 = BackpropTrainer(net2, dataset=data, verbose=True)
print 'loaded net2 using pickle, continue training'
for i in xrange(1, 4):
        trainer2.trainEpochs(1)
        print '\tvalue after %d epochs: %.2f'%(i, net2.activate((1, 4))[0])

Это вывод этого блока:

creating net2
Total error: 176.339378639
    value after 1 epochs: 5.45
loaded net2 using pickle, continue training
Total error: 123.392181859
    value after 1 epochs: 5.45
Total error: 94.2867637623
    value after 2 epochs: 5.45
Total error: 78.076711114
    value after 3 epochs: 5.45

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

Есть ли какой-нибудь механизм кэширования, о котором мне нужно знать, который вызывает это ошибочное поведение? Есть ли лучшие способы сериализации / десериализации сетей Pybrain?

Соответствующие номера версий:

  • Python 2.6.5 (r265: 79096, 19 марта 2010 г., 21:48:26) [MSC v.1500 32 бит (Intel)]
  • Numpy 1.5.1
  • cPickle 1,71
  • Pybrain 0,3

P.S. Я создал отчет об ошибке на сайте проекта и буду обновлять как SO, так и трекер ошибокj

1 Ответ

11 голосов
/ 02 декабря 2010

Причина

Механизмом, вызывающим такое поведение, является обработка параметров (.params) и производных (.derivs) в модулях PyBrain: фактически все сетевые параметрыхранятся в одном массиве, но отдельные Module или Connection объекты имеют доступ к «своим» .params, которые, тем не менее, представляют собой только вид на фрагмент общего массива.Это позволяет выполнять как локальные, так и общесетевые операции записи и считывания в одну и ту же структуру данных.

По-видимому, эта связь с просмотром фрагмента теряется из-за травления-разблокировки.

Решение

Вставьте

net2.sorted = False
net2.sortModules()

после загрузки из файла (который воссоздает этот общий доступ), и он должен работать.

...