【问题标题】:How to serialize/deserialized pybrain networks?如何序列化/反序列化 pybrain 网络?
【发布时间】:2010-12-02 12:25:35
【问题描述】:

PyBrain 是一个 Python 库,它提供(除其他外)易于使用的人工神经网络。

我无法使用 pickle 或 cPickle 正确序列化/反序列化 PyBrain 网络。

请看下面的例子:

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,2010 年 3 月 19 日,21:48:26)[MSC v.1500 32 位(英特尔)]
  • Numpy 1.5.1
  • cPickle 1.71
  • pybrain 0.3

附:我在项目网站上创建了a bug report,并将保持 SO 和错误跟踪器更新j

【问题讨论】:

  • 你确定不应该在你重新加载net2之后再做trainer2 = BackpropTrainer(net2, dataset=data, verbose=True)吗?
  • @Seth Johnson 当然,我愿意,但这样做并不能解决问题。实际上,我的测试代码包含该行,但我在粘贴时错误地提交了它。现已修复

标签: python serialization neural-network pickle


【解决方案1】:

原因

导致这种行为的机制是 PyBrain 模块中对参数 (.params) 和导数 (.derivs) 的处理:实际上,所有网络参数都存储在一个数组中,但单独的 Module 或 @ 987654324@ 对象可以访问“他们自己的”.params,但这只是整个数组的一部分的视图。这允许在同一数据结构上进行本地和网络范围的写入和读取。

显然这个切片视图链接会因酸洗-解酸而丢失。

解决方案

插入

net2.sorted = False
net2.sortModules()

从文件加载后(重新创建此共享),它应该可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多