利用matlab中patternnet函数进行目标分类过程中遇到的奇葩问题

这几天在用matlab中patternnet函数进行目标分类试验的过程中,遇到了一个很奇葩的问题。为这个问题我苦苦纠缠了差不多两天的时间,终于在坚持不懈的调试后,找到了问题所在。下面对这个问题及解决问题的全过程进行描述,防止以后重蹈覆辙。

在模型训练的过程中我将已有数据集按5:3:2的比例分为训练集、验证集和测试集,得到如下的训练结果,可以看出训练得到的模型的分类效果还是比较理想的。

于是将该模型保存下来,然后迫不及待地将这个模型应用于另外收集的测试数据集中,信心满满地等待一个赏心悦目的结果。需要注意的是我采用的两级分类架构,第一级分类器(不是基于神经网络的分类器)能够正确分类一部分目标,第一级分类器无法分类的目标才送到神经网络分类器进行进一步分类,也就是说上述保存下来的模型被用到了第二级分类器中。分类结果让我大失所望,居然糟到了我都不忍直视的地步。于是我郁闷了,到底是哪一个地方出现了问题。模型过拟合?提取的特征无效?matlab patternnet训练得到的模型不支持离线保存后再应用?。。。。。一个个可能的原因终于还是在我绞尽脑汁的验证下一一否定掉了。在测试的过程中发现一个很奇怪的现象,如果我拿全部的测试数据集里面的数据进行处理,得到的效果很好,但是只对第一个分类器分类剩下的数据进行分类,结果就是不行。而第一个分类器并不会对数据进行修改。于是我就屏蔽了第一个分类器,然后随机从数据集中选择部分的数据进行测试以模拟第一个分类器的效果,发现这个随机挑选的结果有时候好,有时候坏,但是坏的结果坏得实在太离谱了,它分类错误的数量甚至远远大于在全部数据集上分类错误的数量,如下图所示,左边是选择整体数据集的一部分数据进行测试的结果,以第三类目标为例,第三类目标被错误分成第一类目标的数量就达到1587个,而右图是用全部数据集进行处理的结果,它第三类目标被错误分成第一类目标的数量只有5个,这显然是不可思议的,难道这个模型在分类的时候不是一个一个样本进行分类,而是与输入样本整体的情况有关?我甚至怀疑这是matlab库函数的一个bug,于是我单步调试进入库函数内部,想弄清它到底怎么根据现有模型对新的数据进行预测的,不过单步调试几步之后发现它最核心部分的代码时屏蔽着的,所以没有办法一探究竟。此路不通,只能另找出路了,静下心来认真分析,首先排除matlab库函数的问题,人家毕竟身经百战,这库函数被无数人验证过,有问题怎么轮得到我这个神经网络小白去发现呢,肯定是在某一步的处理过程中,将该网络的输入样本变化了。又是一顿艰辛的操作,终于定位了问题所在,问题出现在样本归一化函数mapminmax的应用上面。

我们知道不同特征的取值范围可能相差很大,所以一般需要将所有样本的所有特征都归一化到相同的取值范围内,比如全部归一化到[-1,1]之间,再将归一化后的样本作为神经网络的输入样本。matlab提供了归一化的函数mapminmax,它的表达式是

,  分别是归一化前后的数据的取值范围。在神经网络的归一化中要求测试集归一化时需要和训练集归一化保持同样的基准,即测试集的归一化需要用到训练集归一化时的上述两个取值范围。而自己所犯的错误正是没有遵循这一原则,对全部测试数据一起进行处理时,它的归一化范围与训练集的归一化范围比较接近,所以此时归一化是有效的,而采用某些部分测试数据进行处理时,它的归一化范围和训练集归一化的取值范围相去甚远,所以此时归一化是无效的,导致了上述不好的结果。所以我们需要将训练集归一化过程的某些信息保存下来,用于后续测试集的归一化,mapminmax函数正好提供了这一功能。对训练集的归一化过程我们按如下形式使用该函数[y,ps]=mapminmax(x,x_min,x_max)其中x是训练集数据,[x_min,x_max]是训练集要求归一化的范围,y是训练集归一化后的结果,ps就保存了归一化过程中的一些重要信息,后续测试集归一化需要用到。对测试集进行归一化时需要采用如下形式y=mapminmax('apply',x,ps)才能保证测试集的归一化和训练集具有相同的参考基准。

 

猜你喜欢

转载自www.cnblogs.com/PHZWJ/p/13208287.html