问题描述
PyBrain 是一个python库,除其他功能外,它还提供了易于使用的人工神经网络.
PyBrain is a python library that provides (among other things) easy to use Artificial Neural Networks.
我无法使用pickle或cPickle正确地对PyBrain网络进行序列化/反序列化.
I fail to properly serialize/deserialize PyBrain networks using either pickle or 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.
As you can see, network total error decreases as the training progresses. You can also see that the predicted value approaches the expected value of 12.
现在我们将进行类似的练习,但是将包括序列化/反序列化:
Now we will do a similar exercise, but will include serialization/deserialization:
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
如您所见,训练似乎对网络有一定影响(报告的总错误值持续减少),但是网络的输出值冻结在与第一次训练迭代相关的值上.
As you can see, it seems that the training has some effect on the network (the reported total error value continues to decrease), however the output value of the network freezes on a value that was relevant for the first training iteration.
我是否需要了解任何导致这种错误行为的缓存机制?有没有更好的方法来对pybrain网络进行序列化/反序列化?
Is there any caching mechanism that I need to be aware of that causes this erroneous behaviour? Are there better ways to serialize/deserialize pybrain networks?
相关版本号:
- Python 2.6.5(r265:79096,2010年3月19日,21:48:26)[MSC v.1500 32位(Intel)]
- Numpy 1.5.1
- cPickle 1.71
- 人脑0.3
P.S.我已经在该项目的网站上创建了错误报告,并将同时保留SO和错误跟踪器已更新j
P.S. I have created a bug report on the project's site and will keep both SO and the bug tracker updatedj
推荐答案
原因
导致此行为的机制是PyBrain模块中参数(.params
)和派生类(.derivs
)的处理:实际上,所有网络参数都存储在一个数组中,但单独的Module
或Connection
对象可以访问它们自己的" .params
,但是,这只是整个数组中一部分的视图.这样一来,就可以在同一数据结构上进行本地和网络范围的写入和读出.
The mechanism that causes this behavior is the handling of parameters (.params
) and derivatives (.derivs
) in PyBrain modules: in fact, all network parameters are stored in one array, but the individual Module
or Connection
objects have access to "their own" .params
, which, however are just a view on a slice of the total array. This allows both local and network-wide writes and read-outs on the same data-structure.
显然,此切片视图链接由于酸洗/去酸洗而丢失.
Apparently this slice-view link gets lost by pickling-unpickling.
解决方案
插入
net2.sorted = False
net2.sortModules()
从文件加载后(重新创建此共享),它应该可以工作.
after loading from the file (which recreates this sharing), and it should work.
这篇关于如何序列化/反序列化pybrain网络?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!