整体思路:模型搭建--训练--测试--优化
搭建基本模型阶段:
step1:引入要用的包
step2:定义神经网络
step3:定义正向传播训练过程
step4:定义反向传播过程--更新权重
step5:查询网络--输入数据、返回输出
step6:设定各层数量和参数
模型训练阶段
模型测试阶段
模型准度计算以及后续优化
一、搭建基本模型阶段:
step1 导入后面需要用到的包:
![](https://img.haomeiwen.com/i2346922/d78d7e48516aafb2.png)
为了方便,numpy简记为np,scipy.special简记为ss
numpy包的各种用法:https://blog.csdn.net/cxmscb/article/details/54583415 (非常详细)
scipy包的知识:https://www.jianshu.com/p/6c742912047f
tqdm:Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息用法
step2:定义神经网络
![](https://img.haomeiwen.com/i2346922/8dfeef6030eca596.png)
解释:
涉及到属性的调用,详细知识点请移步:https://www.jianshu.com/writer#/notebooks/4844988/notes/58754235
inputNodes为输入层,hiddenNodes为隐层,outputNodes为输出层,learingRate为学习率
w_ih为输入层与隐层之间的权重; w_ho为隐层到输出层的权重
正态分布的随机数产生
numpy.random.normal(loc=0.0,scale=1.0, size=None)
loc:float 此概率分布的均值(对应着整个分布的中心centre)
scale:float 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints 输出的shape,默认为None,只输出一个值
pow() 方法返回 xy(x的y次方) 的值;
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
expit函数,也称为logistic sigmoid函数,定义为expit(x)= 1 /(1 + exp(-x))。 它是logit函数的反函数。
![](https://img.haomeiwen.com/i2346922/b34cd0b430a4d1c9.png)
step3:定义正向传播训练过程
![](https://img.haomeiwen.com/i2346922/2bac8d6b73c734a7.png)
解释:
inputs=np.array(inputlist,ndmin=2).T 初始输入值为输入列的二维矩阵数据。.T就是转置,简单来说将x和y值交换。后面targets同理。
hiddenInput=np.dot(self.w_ih,inputs) 隐藏层输入值为权重和初始输入值的矩阵积
numpy.dot用法详见:https://www.cnblogs.com/luhuan/p/7925790.html
self.activate 为激活函数方法的调用 ,每次输出时,符合阈值条件的将触发激活函数。
step4:定义反向传播过程--更新权重
![](https://img.haomeiwen.com/i2346922/8a26f1d5ce92abf7.png)
![](https://img.haomeiwen.com/i2346922/9a85ff4d67dde0b2.jpg)
step5:查询网络--输入数据、返回输出
![](https://img.haomeiwen.com/i2346922/78c50cfea55d2706.png)
这里就是实际输入数据了,然后根据数据得到模型预测出来的值。
step6:设定各层数量和参数
![](https://img.haomeiwen.com/i2346922/b6b04adfc91886d3.png)
神经网络由输入层、隐层、输出层、学习率四个参数构成
inputNodes: 输入层的数量,取决于输入图片(训练和识别)的像素,像素点的数量等于输入层的数量
hiddenNodes: 隐藏层的数量,一般比输入层少,但具体不确定,可根据准确率进行调整
outputNodes: 输出层的数量,等于需要分类的数量。
学习率越大,每次学习变化越大,改变的越多,但接近准确点时无法准确到达
学习率越小,每次学习更改的参数值就越小,只有大量的数据才能习得准确值
需要注意的是:在89个训练集和11个测试集下,inputNodes=307200才能跑。后续加大训练集和测试集,分别达到6万和2万的时候,inputNodes=784.
二、模型训练阶段
![](https://img.haomeiwen.com/i2346922/154c143e5d183a8e.png)
多次利用相同的数据训练:tqdm.tqdm一共5个,每次更新1个,一共更新5次
tqbar:遍历循环每个图片的数据矩阵,一共100个,每次更新1个,一共更新100次
图像处理为什么转换为double类型?详见:https://blog.csdn.net/mine_land/article/details/79947734
numpy.asfarrary用法详见:https://docs.scipy.org/doc/numpy/reference/generated/numpy.asfarray.html
numpy.zeros(outputNodes)返回一个给定形状和类型的用0填充的数组;详见:https://blog.csdn.net/qq_26948675/article/details/54318917
输入数据x设置为0-1,最正确的目标值y整数形式设置为0.99
三、模型测试阶段
![](https://img.haomeiwen.com/i2346922/58959e619d7a9d72.png)
测试图片用逗号分隔,输出的的识别答案就是Y值,即[0]的索引值。将测试输入转换为double的形式。将测试集数据输入查询网络中得到replyOutput.
numpy.argmax输出的是矩阵的最大值的索引值。如果预测值正确,则输出1,如果预测值不正确,则输出0.
四、优化阶段:
首先测试准确度:
![](https://img.haomeiwen.com/i2346922/cacfa3e31b86d350.png)
在以上的参数下,我们只能得到0.45的准确率,准确率如此之低,我们需要进行优化。
我的优化方方案如下
主要是调整:训练次数、隐层数量、测试集和训练集的数量、学习率
调试方法1 在其他条件不变的前提下,调整迭代次数和隐层数量
调试方法2 在其他条件不变的前提下,调整学习率和隐层数量
调试方法3 根据前面得到的最优组合进一步研究
调试方法4 将训练集和测试集扩大
调试方法1 在其他条件不变的前提下,调整迭代次数和隐层数量
![](https://img.haomeiwen.com/i2346922/ac1206a2149a71e1.png)
测试集为11,训练集为89,学习率为0.1
通过上图我们可以得到结论:在训练集和测试集较小的时候,搭配0.1的学习率,我们无论如何改变隐层数量和迭代数,都无法提升准确率。
有空白的原因:已经测了19次了,准确率仍然无法上升,提示着我们需要转换思路。
那么接下来提升准确率就将往:扩大训练集、测试集的数量或者改变学习率 这两个方面探索。
接下来我们先尝试改变学习率。
调试方法2 在其他条件不变的前提下,调整学习率和隐层数量
![](https://img.haomeiwen.com/i2346922/e425e2ef003afeac.png)
测试集为11,训练集为89,迭代次数为5
通过上图我们发现,在学习率为0.005的条件下,平均准度在所测范围内达到了最高。同时在0.001的学习率下,产生了目前最高的准确度0.82。并且这两者的平均准度也达到了0.6以上,已经较调试方法1的准确率有了0.2以上的增幅了。
综上,我们得到了两个比较合适的学习率:0.005和0.001。
同时,我们可以推测:在上述条件下,当层数达到150以上,准确度会有比较不错的表现
调试方法3 根据前面得到的最优组合进一步研究
我们选取隐层层数在200和300并且在0.001学习率的条件下,研究迭代数对于目前最优的参数组合影响大不大。(训练集为89,测试集为11)
![](https://img.haomeiwen.com/i2346922/8b6e853b0f3cbd93.png)
同时我们再回顾一下调试方法1的结果:
![](https://img.haomeiwen.com/i2346922/ac1206a2149a71e1.png)
从这两个表格,我们可以得出结论:学习率在0.001和0.1时,和训练集为89、测试集为11时,改变迭代次数对于准确率的影响不大。
我们可以推测:在测试集和训练集的数量较少的情况下,迭代数的增加对于准确度的提升帮助不大。
至此,学习率的影响、迭代数的影响、隐层层数的影响我们都已经讨论过了。那么接下来我们的方向是:改变训练集和测试集的数量大小。
调试方法4 将训练集和测试集扩大
前面的调试方法留给我们的疑问:
①当扩大了训练集和测试集后,迭代数的改变对于准确度的影响大不大?
②当扩大了训练集集和测试集后,学习率的改变和隐层数量的改变的影响又是如何?
在这里首先感谢刘继端同学提供的2万测试集和6万训练集。
疑问1解答:
![](https://img.haomeiwen.com/i2346922/e15fa1adea542b2d.png)
在扩大后的训练集和测试集下,迭代次数的变化对于准确度的变化影响在0.1之内。这对于找到0.99的准确度还是挺有帮助的,但对于0.9以下的准确率提升作用不大。
疑问2解答:
![](https://img.haomeiwen.com/i2346922/bebe60b7c46aa32b.png)
根据上表,我们可以看出在其他条件不变的情况下,隐层数量越多,准确度越高。同时,在充分大的训练集和测试集的前提下下,学习率越高(但不宜过高),准确度越高。
因此,在扩大了训练集和测试集之后,模型的准确度有了质的飞跃。另外,准确度在隐层数量300-400之间,学习率为0.05-0.1之间准确度会有比较不错的表现。
五、调试结果
通过多次测试,我们发现训练次数、隐层数量、测试集和训练集的数量、学习率这四个是影响准确率的主要因素。其中训练次数的影响力对比其他三个因素较小。训练集和测试集的数量影响最大。
总的来说:
①我们发现隐层的增加确实能增加准确率。但这需要合适的训练次数配合和学习率的配合。并不是隐层越多、学习率越大、训练次数越多就能增加准确率。
②充分大的训练集和测试集对于准确度的提升至关重要。
最终,基于以上调试方法,我调试的的最佳参数为:
![](https://img.haomeiwen.com/i2346922/d8795f88000cef5d.png)
![](https://img.haomeiwen.com/i2346922/c70cbc5ba417fe5c.png)
最优准确率为:
![](https://img.haomeiwen.com/i2346922/96cfdf51d235b740.png)
尽力了还是没能调试到0.99.
代码地址:https://gitee.com/kristina666/test.git
网友评论