Pybrain学习笔记-4 基于前馈神经网络的分类器
来源:互联网 发布:c语言播放音乐linux 编辑:程序博客网 时间:2024/06/05 02:58
Pybrain学习笔记-4 基于前馈神经网络的分类器
引言:
通过前面的学习已经清楚了pybrain的基础模块功能,也学会了利用神经网络模型进行一些基本的数据操作,下面让我们正式实践一下,通过分类器深刻理解一下利用神经网络解决分类问题的整体流程。
分类器整体思路分析:
在给出代码前,有必要讲一下使用神经网络构造分类器的整体思路。
本次神经网络分类器目的,是给出一个二维空间点,我们可以将其读入训练好的神经网络模型,通过模型得到这个二维空间点的所属分类。因此,大致的流程如下:
先建立一个前馈神经网路,然后再建立满足分类要求的数据集,从数据集中采样出训练集对网络进行训练,使得网络达到所需精度。最后利用测试集进行测试,再实现输出结果的绘制。
注:有关网络的建立、数据集的建立、网络的训练方法可以参考我的前几篇博文。
构建神经网络分类器:
话不多说,直接上代码:
5.test_pybrian_5
#!usr/bin/env python#_*_coding:utf-8_*_'''Created on 2017年4月14日Topic:Classification with Feed-Forward Neural Networks@author: Stuart斯图尔特'''from pybrain.datasets import ClassificationDataSet #分类数据专用数据集工具包from pybrain.utilities import percentError #以列表和数组的形式返回误差的百分比工具包from pybrain.tools.shortcuts import buildNetworkfrom pybrain.supervised.trainers import BackpropTrainerfrom pybrain.structure.modules import SoftmaxLayer#下面是一些图形界面以及矩阵运算和随机数组运算的工具包,可暂时忽略具体应用,后续会讲到from pylab import ion , ioff , figure , draw , contourf , clf , show , hold , plotfrom scipy import diag , arange , meshgrid , wherefrom numpy.random import multivariate_normal#创建一个有二维空间点组成的列表means = [(-1,0),(2,4),(3,1)]#创建一个由对角矩阵形成的列表cov = [diag([1,1]), diag([0.5,1.2]), diag([1.5,0.7])]#ClassificationDataSet:Specialized data set for classification data. Classes are to be numbered from 0 to nb_classes-1. #定义数据集:输入目标是2维,目标的target的维数是1,数据可被分为3类alldata = ClassificationDataSet(2, 1, nb_classes=3)for n in xrange(400): #外层循环400次 for klass in range(3): #内层循环三次 input = multivariate_normal(means[klass],cov[klass]) #理解成把输入数据进行正态分布的处理,得到更好的数据集 alldata.addSample(input, [klass]) #得到二维输入数据#按照3:1的比例划分测试集和训练集 #tstdata, trndata = alldata.splitWithProportion( 0.25 )#报错:AttributeError: 'SupervisedDataSet' object has no attribute '_convertToOneOfMany'#将这条语句改成下面代码段:tstdata_temp, trndata_temp = alldata.splitWithProportion(0.25) #定义测试集,输入维度是2,target是1,有三类,均是2d向量tstdata = ClassificationDataSet(2, 1, nb_classes=3) for n in xrange(0, tstdata_temp.getLength()): tstdata.addSample( tstdata_temp.getSample(n)[0], tstdata_temp.getSample(n)[1] ) #定义训练集, 输入维度是2,target是1,有三类,均是2d向量trndata = ClassificationDataSet(2, 1, nb_classes=3) for n in xrange(0, trndata_temp.getLength()): trndata.addSample( trndata_temp.getSample(n)[0], trndata_temp.getSample(n)[1] ) #将target转化成一维的输出,注意网络的output有三层,在分类器中我们想得到的结果是某一明确的分类 #通过convertToOneOfMany()实现target的降维,并把'target'字段转存在'class'字段中trndata._convertToOneOfMany( )tstdata._convertToOneOfMany( )print "Number of training patterns: ", len(trndata) #Number of training patterns: 900print "Input and output dimensions: ", trndata.indim, trndata.outdim #Input and output dimensions: 2 3print "First sample (input, target, class):"print trndata['input'][0], trndata['target'][0], trndata['class'][0] #[ 0.7295122 0.37413538] [0 0 1] [2]#调用buildNetwork建立前馈神经网络,输入层是2,隐含层是5,输出层是3fnn = buildNetwork( trndata.indim, 5, trndata.outdim, outclass=SoftmaxLayer )#调用反向误差训练器trainer = BackpropTrainer( fnn, dataset=trndata, momentum=0.1, verbose=True, weightdecay=0.01)#这个网络已经可以进行测试了,但由于想做出一个漂亮易懂的分类器,因此下面将自定义数据范围,用训练好的网络进行分类并将分类结果可视化#下面为了把分类器控制在一个可绘制方格中,因此随机生成方格内的二维点#从-3到6建立一维数组,间隔为0.2,显然维度是60#生成矩阵X , Y,矩阵均为60*60的方阵ticks = arange(-3.,6.,0.2) X, Y = meshgrid(ticks, ticks) # need column vectors in dataset, not arrays 定义分类数据集并从X Y矩阵中采样griddata = ClassificationDataSet(2,1, nb_classes=3)for i in xrange(X.size): griddata.addSample([X.ravel()[i],Y.ravel()[i]], [0])#同样要把target映射成一维数据放到class实例中griddata._convertToOneOfMany() for i in range(20): trainer.trainEpochs( 1 ) #训练网络一次,之所以要训练一次是想得到每次的训练结果 trnresult = percentError( trainer.testOnClassData(),trndata['class'] ) tstresult = percentError( trainer.testOnClassData(dataset=tstdata ), tstdata['class'] ) #打印每次训练的错误率 print "epoch: %4d" % trainer.totalepochs, \ " train error: %5.2f%%" % trnresult, \ " test error: %5.2f%%" % tstresult out = fnn.activateOnDataset(griddata) #下面是输出可视化的分类结果,涉及pylab模块的使用,后续会讲到 out = out.argmax(axis=1) # the highest output activation gives the class out = out.reshape(X.shape) figure(1) ioff() # interactive graphics off clf() # clear the plot hold(True) # overplot on for c in [0,1,2]: here, _ = where(tstdata['class']==c) plot(tstdata['input'][here,0],tstdata['input'][here,1],'o') if out.max()!=out.min(): # safety check against flat field contourf(X, Y, out) # plot the contour ion() # interactive graphics on draw() # update the plotioff()show()
代码说明:有关代码的解释都已在注释中给出,下面主要对标记转化函数_convertToOneOfMany( )报出的AttributeError进行分析与解释
在官方的说明书中,训练集与测试集按照3:1划分,并将标记转化为一维输出,语句是:
tstdata, trndata = alldata.splitWithProportion( 0.25 )tstdata, trndata = alldata.splitWithProportion( 0.25 )trndata._convertToOneOfMany( )tstdata._convertToOneOfMany( )
但是在编译时报错如下:
AttributeError:'SuperviseDataSet' object has no attribute '_convertToOneOfMany'
按照错误提示,SuperviseDataSet类中不存在_convertToOneOfMany()这个方法。回头看,这很对啊,我之前建立的alldata是ClassificationDataSet类的一个实例,而通过查看源代码,我们使用的_convertToOneOfMany()方法也正好在ClassificationDataSet中,我们已经引好了各种数据集的工具包,引包调用,天经地义,可为什么报出找不到方法这样的错误呢?
找了很长时间的原因才发现问题所在,首先打开spiltWithProportion()方法的源码:
def splitWithProportion(self, proportion = 0.5): """Produce two new datasets, the first one containing the fraction given by `proportion` of the samples.""" indicies = random.permutation(len(self)) separator = int(len(self) * proportion) leftIndicies = indicies[:separator] rightIndicies = indicies[separator:] leftDs = SupervisedDataSet(inp=self['input'][leftIndicies].copy(), target=self['target'][leftIndicies].copy()) rightDs = SupervisedDataSet(inp=self['input'][rightIndicies].copy(), target=self['target'][rightIndicies].copy()) return leftDs, rightDs
有没有发现,spiltWithProportion()方法所返回的参数有两个,即leftDs和rightDs,整个源码函数的作用实际上是按照随机的一个比例,将所处理的数据集分成两个部分,并作为SupervisedDataSet类型的数据返回。因此Python在调用方法的时候实际上是在找SupervisedDataSet中的函数,也就找不到_convertToOneOfMany()了。
有关于后面的替换代码,是参考了stackoverflow论坛的解决方案,(传送门)。
好了,最后给出程序跑过一遍后的效果,参考一下:
控制台打印出了网络在训练20次过程中的细节,用错误分类的比率给出,然后打印出了分类的结果图。
我们发现分类的结果并不是十分的精确,这与训练数据和训练次数都有一定的关系,若想获得更精确的结果,可以建立更大的数据集,同时扩大训练次数。
至此,利用神经网络编写的分类器就实现了。
pybrain的强大之处就在于其具有强大的API来支撑神经网络进行各种数据的处理。从而极大地缩小了代码量,增强了代码的可移植性。然而官方的案例只针对于有监督数据。接下来将考虑将pybrain用于无监督数据集的处理问题,这也是我们学习pybrain的初衷,因为在NLP领域的很多问题都是针对于无监督的文本数据的分析与处理,可见仅在神经网络的路上,我们要走的路还长着呢。
后续我将从神经网络的具体算法入手,并结合pybrain的源码,进行实验与学习,road still long。
Ps:程序小猿,个人能力和表达能力有限,如有错误欢迎指正交流。码字不易,转载请注明出处(笔芯)。
- Pybrain学习笔记-4 基于前馈神经网络的分类器
- Pybrain学习笔记-3 使用Pybrain构建前馈神经网络
- Pybrain学习笔记-1 pybrain介绍
- Pybrain学习笔记-2 pybrain快速入门
- PyBrain-Python的人工神经网络
- 基于BP算法的前馈神经网络
- pybrain学习教程(一):创建神经网络
- pybrain学习教程(三):训练神经网络
- pybrain的神经网络文档部分翻译
- 深度学习-基于softmax神经网络分类的源码实现
- 【神经网络学习笔记】基于离散Hopfield神经网络的数字识别
- 基于PyTorch的深度学习入门教程(五)——训练神经网络分类器
- halcon基于mlp神经网络分类器的OCR字符识别
- 神经网络与机器学习笔记——贝叶斯分类器
- 小象学院深度学习笔记4(卷积神经网络-目标分类)
- 神经网络案例分析4-5-神经网络遗传算法函数极值寻优-基于BP_Adaboost 的强分类器设计
- 基于BP神经网络的数据分类
- 基于BP神经网络的数据分类
- Android NDK 开发(五)AndroidStudio 2.2 NDK的开发环境搭建
- c++(常量)
- 图像处理中的傅里叶变换
- MyBatis--查询缓存--增删改会清空一级缓存
- SwipeRefreshLayout的setColorSchemeColors没效果的原因
- Pybrain学习笔记-4 基于前馈神经网络的分类器
- C++(变量作用域)
- nyoj167 && zoj3305【DP位运算--枚举补集】
- reactjs 获取真实dom,并获取dom css 三种方法
- caffe设置正则化项
- HTML——标签——2
- CMakeList配置之编译多个.cpp文件
- 走迷宫
- caffe使用中的问题记录