基于Python实现三种不同类型BP网络及分析

三种不同类型BP网络及分析

一、mnist1.py分析

minist1.py是一个一层的神经网络。

1.1 对循环轮数进行分析

轮数 在测试集的准确率
1 0.0648
40 0.1361
360 0.2215
720 0.2936
1024 0.3538
1600 0.4604
2000 0.5251
2400 0.5787
2800 0.6226
3200 0.6561
3600 0.6848
4000 0.7068

绘制图形 得出一个分析结论

可以看到 在测试集的准确率随着训练轮数的增加而增加,并且随着训练轮数的增加,增加的幅度在减弱。

进一步分析 在程序中记录每轮后在测试集上的分数 用matplotlib绘制轮数与正确率的关系图 。

可以看出虽然在局部随着训练轮数的增加,正确率有起伏,但整体的趋势是增加的,并且增加趋势与上图一致。

在搭建模型的过程中,一开始循环轮数设为40,正确率只有0.13,后来用一个比较大的数4000作为循环轮数后,模型得到了明显改善,争取率达到0.7068,并且根据上图可以大胆预测,将循环轮数设为更大的数如10000或15000,正确率还能提高!

1.2 改变学习率

尝试不同学习率对模型的影响(循环轮数设置为4000)

学习率 在测试集的准确率
0.5 nan
0.1 0.8539
0.01 0.7068
0.001 0.2297

一开始使用的学习率为0.01 在循环4000轮后正确率为0.7068 然而当学习率提升为0.1时,正确率提升至0.85 结合上面的分析,当循环轮数增加时,正确率呈上升趋势 这也表明当前的学习率略低,模型始终在拟合,还远未到最优解附近,因而提升学习率之后,正确率得到了提升。

然而,当我把学习率改为0.5时,loss值不收敛了,这由于学习率设置的过大,越过最低点,无法达到最低点。

当学习率改为0.001时,争取率只有0.2297,是由于学习率太慢,经过4000轮迭代仍然远远未达到最优解附近。

1.3 改变损失函数

观察不同损失函数对于模型的影响(学习率0.1)

损失函数 循环轮数 在测试集的准确率
均方误差 4000 0.8539
交叉熵 200 0.88
交叉熵 400 0.894
交叉熵 600 0.886
交叉熵 800 0.926
交叉熵 1000 0.935
交叉熵 1200 0.931
交叉熵 1400 0.932

对比可得,当使用交叉熵时,只需迭代200轮,在测试集的准确率就超过了使用均方误差时循环4000轮的准确率。这表明,交叉熵时比均方误差更适用的损失函数。

1.4 改变随机种子

改变对权的初始化,观察对模型影响(循环4000轮,学习率0.1,梯度下降优化器)

随机种子 在测试集的准确率
42 0.7065
1 0.7118
12345 0.7225

随机种子的选择会影响权值的初始化,进而影响模型。但是分别选择比较小的随机种子1和比较大种子12345,对模型的影响差别并不大。

二、mnist2.py分析

mnist2.py构建了一个三层的BP网络,使用了正则化优化技术,使用Adma优化器。

2.1 改变节点个数

第一层节点数 第二层节点数 第三层节点数 在测试集上的准确率
1000 200 10 0.9621
5000 2000 10 0.9546
30 20 10 0.9452
100000000 20 10 无法运行
1000000 20 10 无法运行
100000 20 10 无法运行
10000 20 10 0.2567
  • 尝试使用大的中间层节点数,5000和2000;尝试使用很小的中间层节点数 30和20;均未对准确率产生比较大的变化,但是中间层节点数大的时候,程序运行需要更久的时间
  • 尝试第一层节点数特别大(一亿),第二层的很小,程序无法运行
  • 尝试第一层节点数特别大(一百万),第二层的很小,程序无法运行
  • 尝试第一层节点数特别大(十万),第二层的很小,程序无法运行
  • 尝试第一层节点数特别大(一万),第二层的很小时程序运行结果准确率只有0.2567;说明提高隐藏层的节点个数并不能确定的提高准确率

2.2 改变学习率(节点个数1000和200)

学习率 在测试集的准确率
0.5 0.1135
0.1 0.1028
0.01 0.9621
0.001 0.2375

表明学习率设置过大或者过小都不能提高正确率

2.3 选择不同优化器(节点个数1000和200)

优化器 在测试集的准确率
梯度下降 0.8093
Adam 0.9621
Momentum 冲量(0.9) 0.878
Momentum 冲量(0.5) 0.6487
Momentum 冲量(0.1) 0.8148
Momentum 冲量(0.001) 0.7849

在本网络中,Adam优化器表现最好。

2.4 更改激活函数

激活函数 在测试集的准确率
relu 0.9621
sigmod 0.8384
swish 0.9381
tanh 0.9417

更换不同的激活函数对正确率有影响,其中最优的还是relu

三、mnist3.py分析

mnist3.py构建了一个五层的BP网络,使用了可变的学习率来优化网络,使用sigmod激活器,使用Momentum优化器

3.1 最初学习率对模型影响

最初学习率 在测试集的准确率
0.01 0.4272
0.1 0.7359
0.9 0.1135
0.0001 0.0859

搭建网络时一开始并没有用可变衰减率,后来加上可变学习率,初始学习率设为0.01,结果准确率在百分之40,后来改为0.1,正确率达到百分之70。

  • 尝试使用很大的最初学习率---0.9
  • 尝试使用很小的最初学习率---0.0001

最初学习率选择不能过大也不能过小,过大则会 使开始时学习步幅多大,无法达到最优点,最初学习率过小则会导致学习速度过慢。

3.2 改变激活函数

激活函数 在测试集的准确率
relu 0.098
sigmod 0.7359
swish 0.098
tanh 0.1135

一开始使用的是sigmod激活函数,准确率0.7359,改用激活函数后,准确率都下降的非常低;通过观察最后的w1和b1发现,最后很多w1和b1都是nan。

3.3 改变优化器

优化器 在测试集的准确率
梯度下降 0.4343
Adam 0.1135
Momentum 冲量(0.9) 0.7359
Momentum 冲量(0.5) 0.5251
Momentum 冲量(0.1) 0.457
Momentum 冲量(0.001) 0.4371

Adam优化器表现很差,梯度下降优化器表现一般,Momentum优化器在冲量0.9时表现较好,但随着冲量减小,正确率也在减小。

3.4 改变BATCH_SIZE

BATCH_SIZE 在测试集的准确率
1000 0.7315
100 0.7407
10000 0.6896

当BATCH_SIZE为100时,在14轮之后,学习率变为了0。

四、总分析

主要使用mnist2.py。做了三种不同结构的网络,其中第二种三层网络在测试集上的表现最好,但这可能由于第二种做的比较完善,但是可以去推想,即使增加模型隐藏层层数,并不一定能提高模型在测试集上的表现,根据前面更改节点个数,同样得出,增加节点个数不一定能提高正确率,但是增加节点数会增长程序运行时间!

通过对前面的探究,初步得出,对模型影响比较大的两个因素 学习率和损失函数。

学习率不可设置的过大或过小,要根据实际情况选择。

损失函数选择非常重要,不同的损失函数对模型影响很大,若选择不好,有可能导致loss不收敛,或模型表现非常差!

相关推荐
不7夜宵7 分钟前
Golang 反射
开发语言·后端·golang
瑞雪流年11 分钟前
conda 创建环境失败故障解决记录
开发语言·python·conda
山山而川粤17 分钟前
大连环保公益管理系统|Java|SSM|Vue| 前后端分离
java·开发语言·后端·学习·mysql
尘浮生24 分钟前
Java项目实战II基于SpringBoot前后端分离的网吧管理系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·小程序
codists34 分钟前
《Django 5 By Example》阅读笔记:p237-p338
python·django
小白也有IT梦38 分钟前
Python 虚拟环境使用指南
python
晚安,cheems43 分钟前
c++(入门)
开发语言·c++
小乖兽技术44 分钟前
C#13新特性介绍:LINQ 的优化设计
开发语言·c#·linq
Mcworld8571 小时前
C语言:strcpy
c语言·开发语言
知识鱼丸1 小时前
【数据结构】一图介绍python数据结构
数据结构·python