用Pybrain库进行神经网络拟合
转自:http://www.zengmingxia.com/use-pybrain-to-fit-neural-networks/
Pybrain号称最好用的Python神经网络库。其实Scikit-Learn号称Python上最好用的机器学习库,但是它偏偏就没有神经网络这块,所以就与我无缘了。
之前也看过一些提到Neurolab这个库的,打算之后尝试一下(好像支持的神经网络不太一样)。
Pybrain的文档传说中写得不错,但是我需要的例子它并没有。官方文档给的例子是用于分类的,而不是数据拟合(预测,或者叫做回归问题)。
另外,官方文档的函数(方法)说明并不全,有一些需要自己通过help函数在python shell里调用,或者直接阅读源代码。
好了言归正传。大概分为以下这几步。
- 构造神经网络
- 构造数据集
- 训练神经网络
- 结果可视化
- 验证与分析
构造神经网络
可以采用快速建立神经网络的模式,也可以自己设定神经网络。这里采用第二种做法,建立的是前馈神经网络。
from pybrain.structure import * # 建立神经网络fnn fnn = FeedForwardNetwork() # 设立三层,一层输入层(3个神经元,别名为inLayer),一层隐藏层,一层输出层 inLayer = LinearLayer(3, name='inLayer') hiddenLayer = SigmoidLayer(7, name='hiddenLayer0') outLayer = LinearLayer(1, name='outLayer') # 将三层都加入神经网络(即加入神经元) fnn.addInputModule(inLayer) fnn.addModule(hiddenLayer) fnn.addOutputModule(outLayer) # 建立三层之间的连接 in_to_hidden = FullConnection(inLayer, hiddenLayer) hidden_to_out = FullConnection(hiddenLayer, outLayer) # 将连接加入神经网络 fnn.addConnection(in_to_hidden) fnn.addConnection(hidden_to_out) # 让神经网络可用 fnn.sortModules()
构造数据集
在构造数据集的时候,我用的是SupervisedDataset,即监督数据集。也可以试一试别的。
from pybrain.supervised.trainers import BackpropTrainer # 定义数据集的格式是三维输入,一维输出 DS = SupervisedDataSet(3,1) # 往数据集内加样本点 # 假设x1,x2,x3是输入的三个维度向量,y是输出向量,并且它们的长度相同 for i in len(y): DS.addSample([x1[i], x2[i], x3[i]], [y[i]]) # 如果要获得里面的输入/输出时,可以用 X = DS['input'] Y = DS['target'] # 如果要把数据集切分成训练集和测试集,可以用下面的语句,训练集:测试集=8:2 # 为了方便之后的调用,可以把输入和输出拎出来 dataTrain, dataTest = DS.splitWithProportion(0.8) xTrain, yTrain = dataTrain['input'], dataTrain['target'] xTest, yTest = dataTest['input'], dataTest['target']
构造数据集部分就这样告一段落了。
训练神经网络
俗话说得好,80%的工作往往是20%的部分完成的。嗯哼,其实最重要的代码就是如下这几行啦。
不过调用的是别人的东西,也不知道内部的实现比例,就是开个玩笑。
from pybrain.supervised.trainers import BackpropTrainer # 训练器采用BP算法 # verbose = True即训练时会把Total error打印出来,库里默认训练集和验证集的比例为4:1,可以在括号里更改 trainer = BackpropTrainer(fnn, dataTrain, verbose = True, learningrate=0.01) # maxEpochs即你需要的最大收敛迭代次数,这里采用的方法是训练至收敛,我一般设为1000 trainer.trainUntilConvergence(maxEpochs=1000)
结果可视化
数据可视化就不提了,基本上用的是Pylab来进行数据可视化,具体可见这篇博文:
Python的一些画图函数 。
验证与分析
- 首先,我们可以挑一个随机数据来看看结果。
import random # c为从0到xTest的长度(包括0,不包括长度)之间的随机值 c = random.randint(0, xTest.shape[0]) # X2为xTest的一个随机样本点 X2 = xTest[c,:] # activate函数即神经网络训练后,预测的X2的输出值 prediction = fnn.activate(X2) # 可以将其打印出来 print('true number is: ' + str(yTest[c]), 'prediction number is:' + str(prediction), 'error:' + str((prediction-yTest[c])/yTest[c]))
- 我们可以把神经网络打印出来,此处的代码是在stackoverflow里找到的,出处忘了,感谢那个哥们的轮子。
这样就可以看各条连接的权重了。
for mod in fnn.modules: print "Module:", mod.name if mod.paramdim > 0: print "--parameters:", mod.params for conn in fnn.connections[mod]: print "-connection to", conn.outmod.name if conn.paramdim > 0: print "- parameters", conn.params if hasattr(fnn, "recurrentConns"): print "Recurrent connections" for conn in fnn.recurrentConns: print "-", conn.inmod.name, " to", conn.outmod.name if conn.paramdim > 0: print "- parameters", conn.params
- 我们可以调用一个计时器来看程序的运行时间,判断性能
import time # 在需要计时的代码前调用这个 start = time.clock() # 在需要计时的代码后再调用一次clock函数 elapsed = (time.clock()-start) print("Time used:" + str(elapsed))
- 如果需要一些统计数据的话,可以自己写一些统计类的函数,或者找包里的
tools
模块,有一些统计函数,比如均方误差(MSE)等。