Fit-DNN机理研究
# 问题
随着网络尺寸的增大,Fit-DNN的性能逐渐低于DNN,结果甚至出现发散现象,需要排查原因
# 解决历程
只使用固定学习率(lr=0.01),最简单的2层全连接层,经典网络。
- 使用Pytorch脚本的权重进行初始化,也会因为精度差异逐渐有了差距。这种差异从学习一个样本后的梯度更新就已经有了,所以一个epoch后,差异不容小视【🚩以后工作中的经典网络不可以用pytorch自建的,得用python手敲的】
utt_acc_pytorch=82.6667%, utt_acc_python=81.3333%
- Pytorch默认是float32,Python默认是float64
- loss在后期一直振荡,需要完善的学习率更新机制,否则如何作对比呢?
- 如果用Fit-DNN自带的权重,对结果有什么影响?
- 如果加上输入预处理myInput(),对于两层网络效果不行,四层网络可以
- 使用Pytorch脚本的权重进行初始化,也会因为精度差异逐渐有了差距。这种差异从学习一个样本后的梯度更新就已经有了,所以一个epoch后,差异不容小视【🚩以后工作中的经典网络不可以用pytorch自建的,得用python手敲的】
训练样本全部学习完再更新梯度会怎么样?
在Pytorch上进行测试,效果并不行,lr=0.1时,也不行
增加batch size对识别结果有什么影响?
当
batch_size=64,lr=0.1
时,识别率达到了91.3333%(Pytorch),随着batch的增大,学习率也应该适当提升batch_size learning_rate nepoch utt_acc(%) 64 0.05 50 90.6667 64 0.05 30 90 64 0.1 30 91.3333 能不能多个样本一起进行DDEs计算,即Fit-DNN前向传播也使用batch_size参数?
能不能批处理不重要,DNN单样本能达到的精度,Fit-DNN也应该达到啊
# 20220905
- 从Pytorch脚本下的训练集中划分出验证集
- 测试集计算帧组识别率与句子识别率合并
# 20220906
- 同昨天一样,对应调整Python脚本
# 20220907
⭐最佳模型:最佳验证集准确率所对应的模型
Pytorch下等宽DNN增加层数的效果?变宽DNN呢?
- 增加层数的同时,也需要节点数的增加
- 瓶颈层靠近输出层比较好
结构 学习率 bin_acc(%) utt_acc(%) [50, 50] 0.01 39.7986 88.6667 [50, 50, 50, 50] 0.01 37.7607 78.0000 [256, 256, 256, 256] 0.01 发散 发散 [256, 256, 256, 256] 0.0025 53.8000 98.0000
最稳定0.0075 52.1937 96.6667 [128, 256, 256, 256] 0.0025 52.6732 94.0000 0.0075 45.0012 87.3333
第六次迭代[256, 128, 256, 256] 0.0025 51.8581 95.3333 0.0075 45.0252 92.6667
第八次迭代[256, 256, 128, 256] 0.0025 54.8789 97.3333 0.0075 40.0144 87.3333 [256, 256, 256, 128] 0.0025 54.9269 96.0000 0.0075 51.4984 92.0000 - 为了摆脱对比实验中学习率设置的烦恼,初始学习率设置为0.01,根据验证集的效果实时调整!
- 唯一的缺点是,bin acc达标了,utt acc没有!!
Python下等宽DNN增加层数的效果?
- 使用自带的权重初始化,在第一轮
utt_acc
就达到了65.3333%,最佳模型:bin_acc=55.6461%
,utt_acc=98.6667%
- 使用Pytorch的权重初始化,第11轮迭代出现偏差,最佳模型:
bin_acc=53.9439%
,utt_acc=98.0000%
,还是自带的初始化方便
- 使用自带的权重初始化,在第一轮
Python下变宽DNN的表现?
结构 学习率 bin_acc(%) utt_acc(%) [256, 256, 256, 128] 0.0025 56.1017 99.3333 0.0075 51.5704 95.3333
过拟合了- 看来Python的权重初始化一直比Pytorch优秀
# 20220908~20220913
自适应学习率:Pytorch版本
- 原因:1)固定的学习率衰减无法判断瓶颈层结构的性能;2)无论何种版本,固定学习率衰减,准确率都很动荡,无法体验模型性能;
- 根据dev_acc调整,初始学习率均为0.01【不妥,自适应策略只是对学习率的微调,初始学习率还是决定了根基】
- 不保存最佳模型,人工查看
- Pytorch如何实现参数更新?copy到新字典进行修改后,重新load进来
找到一种网络结构,使得变宽的结果优于等宽:轻松找到!
初始学习率 衰减率 结构 bin_acc(%) utt_acc(%) 0.005 0.75 [256, 256, 256, 256] 53.1767 94.0000 [256, 256, 256, 128] 53.7521 96.0000 [256, 256, 128, 256] 52.6972 96.0000 - 现在弄Pytorch版本没有意义,需要在Fit-DNN上做实验!
自适应学习率:Python版本?完蛋了,学习率应该是后面再关注的事情,首要是解决局部耦合问题!!!
完成精简版Fit-DNN
# 20220914~20220915
主要任务:Python版本下DNN与Fit-DNN对比
自适应学习率应用至Python脚本
把衰减率作为超参数写进配置文件
DNN
结构 种子 初始学习率 衰减率 bin_acc(%) utt_acc(%) 备注 [50,50] 42 0.001 / 50.1798 85.3333 为啥这个bin acc这么好?
换个种子试试49.7722 90.6667 epoch=50 48.1419 91.3333 epoch=100 0.9 49.7243 93.3333 epoch=100,结果相当平稳 0.01 0.75 44.3539 91.3333 45.2409 94.0000 epoch=50 0.005 0.75 45.6006 94.6667 123 0.001 / 50.0852 88.6667 0.01 0.75 42.9788 91.3333 bin acc与utt acc还是失衡 0.005 0.75 45.2908 92.6667 换种子后结果也差不多
再换一个种子321 0.001 / 51.5943 87.3333 0.01 0.75 47.2508 94.6667 我不理解! 0.005 0.75 46.9244 90.0000 [50,50,50] 42 0.01 0.75 40.3261 91.3333 是因为节点数多了,没有充分学习吗? 0.02 0.75 38.1683 88.6667 [30,50,50] 42 0.01 0.75 42.1721 90.6667 靠近输入层好一些 [50,30,50] 42.6037 92.6667 [50,50,30] 39.1033 88.0000 [50,50,50,50] 42 0.01 0.75 44.0422 92.0000 这个结构无法证明瓶颈层的有效性 [30,50,50,50] 41.3810 88.0000 [50,30,50,50] 41.4049 86.0000 [50,50,30,50] 35.9386 78.0000 [50,50,50,30] 39.9664 86.0000 [256,256,256] 42 0.01 0.75 50.9470 94.0000 靠近输出层好些 [128,256,256] 49.2927 96.0000 [256,128,256] 49.4366 97.3333 [256,256,128] 51.1388 93.3333 [256,256,256,256] 42 0.01 0.75 47.3508 92.6667 靠近输入层好些 [128,256,256,256] 50.8991 92.6667 [256,128,256,256] 50.3956 97.3333 [256,256,128,256] 50.3237 94.0000 [256,256,256,128] 49.1009 92.0000 bin acc与utt acc差距也太大了!会不会准确率算法弄错了?应该不是,增加epoch行不行?也不行!
神经网络也太能造假了,初始学习率偏差也能造成结果的不同,算法还重要吗?
其实初始学习率设为0.001并不好,训练时间太长了
变宽DNN的优越性简单地用50个节点能不能验证?
不需要[50,50,50]效果比[50,50]好,只需要有了瓶颈层比没有瓶颈层效果好!
我不需要也不可能得到瓶颈层靠近哪里会比较好的结论,不同网络结构及识别任务都有不同的结论,只要证明有瓶颈层比没有瓶颈层好就行了
Fit-DNN
结构 种子 初始学习率 衰减率 bin_acc(%) utt_acc(%) 备注 [50,50] 42 0.001 / 47.4946 82.6667 学习速度及识别率远低于DNN
没有得到充分学习0.005 / 41.4529 87.3333 又是颠倒的识别率 0.01 0.75 47.9262 93.3333 完美压倒DNN [50,50,50] 42 0.01 0.75 39.2232 91.3333 !没有得到预期的效果 [30,50,50] 39.7986 84.6667 [50,30,50] 33.8528 78.0000 [50,50,30] 35.5071 85.3333 [50,50,50] 44.3059 92.6667 试试打乱操作放在循环内
结果也不行[30,50,50] 43.0352 85.3333 [50,30,50] 42.1002 84.6667 [50,50,30] 41.2371 86.0000 - 学习率需要使得Fit-DNN被充分训练,也能保持DNN性能不下降
# 20220916~20220918
打乱训练样本放在循环内还是循环外?之前都是放在循环外的
在循环内使用固定的随机种子,是不会打乱的,本质还是循环外
打乱训练样本放在循环内效果更佳
实验记录
结构 种子 初始学习率 衰减率 bin_acc utt_acc 备注 [50,50] 42 0.01 0.75 44.3539 91.3333 循环外 47.7583 96.0000 循环内 [50,50,50] 42 0.01 0.75 40.3261 91.3333 循环外 48.7653 93.3333 循环内
改写Python代码,分别写4个求解器,记得修改nHiddenNode和下面引用函数的输入参数
solver 求解说明 dde_ibp 在$[0,\theta]$区间内积分,求解步$h=\theta/N_h$
采用分段积分的修正梯形规则的半解析Heun法求解延迟微分方程dde_heun 在$[0,\theta]$区间内积分,求解步$h=\theta/N_h$
采用标准梯形规则通过半解析Heun法求解延迟微分方程network_decoupled 经典神经网络 network_coupled 在$[0,\theta]$区间内积分,求解步为$\theta$
从第二层起,忽略$\theta$的一阶小量,直接使用第一层的迭代式
# 20220919
四个求解器性能比较:初始学习率0.01,衰减率0.75,30次迭代
solver 结构 bin_acc(%) utt_acc(%) dde_ibp [50,50] 47.5665 95.3333 dde_heun [50,50] 46.8233 94.0000 [50,50,50] 43.7545 94.0000 network_decoupled[DNN] [50,50] 47.7583 96.0000 [256,256] 53.7281 96.6667 network_coupled [50,50] 48.2139 96.6667 [256,256] 53.6562 96.6667 为什么第一层明明有精确解,dde还要用求解步?
是解析解与数值解的关系,验证得到,结果一致
审阅代码,弄清楚求解步设置
可以发现,两个基于Heun法的DDEs求解,性能是略低于DNN的,而简单的network_coupled在小型网络中性能优于DNN,而较大网络中略低于DNN
🚩前向传播是模拟光学系统,更精细的仿真是有必要的,但是反向传播只能在传统计算机上进行,目前粗略的计算方法只能与network_coupled对应,因此存在前后向传播不一致的问题
# 20220920~20220924
[50,50,50]系列求解下,差距为何越来越大?
为什么正向传播的时候使用了比$\theta$更小的求解步,但是反向传播的时候只考虑间距$\theta$,为什么不用更小的求解步传递?
没想明白,打算用network_coupled做接下来的实验
可能是正向传播是光电系统的数值仿真,只能通过更小的时间步得到精细的模拟,但是反向传播本身只能在传统PC上做,保存的也只有那么些节点数据
在大求解步下,Fit-DNN是否等价于DNN?以network_coupled为例,网络结构为[50,50],其余参数同上,DNN识别率47.7583%及96.0000%
$\theta$ bin_acc(%) utt_acc(%) 2(default) 48.2139 96.6667 10 48.4296 96.0000 100 47.7583 96.0000 是的,可以做到完全一模一样!
对于没有连线的节点,计算误差阶段就无法传递,不必到计算梯度的时候才考虑?
计算误差阶段,对应的权重为0,连带着算上也无妨,因此,可以在梯度阶段再考虑非零元素的位置
瓶颈层的作用?network_coupled
seed theta 结构 bin_acc(%) utt_acc(%) 42 2 [50,50,50] 46.8473 94.6667 [30,50,50] 44.8094 93.3333 [50,30,50] 45.7684 94.0000 [50,50,30] 43.1072 91.3333 4 [50,50,50] 46.1280 90.6667 [30,50,50] 48.1899 90.6667 [50,30,50] 43.2990 90.0000 [50,50,30] 41.8844 88.6667 8 [50,50,50] 47.6624 94.0000 [30,50,50] 48.6214 94.6667 [50,30,50] 44.9532 93.3333 [50,50,30] 42.1961 88.6667 123 2 [50,50,50] 44.9258 90.6667 [30,50,50] 46.4103 92.0000 [50,30,50] 44.0983 92.6667 [50,50,30] 43.8306 91.3333 4 [50,50,50] 46.6294 94.6667 [30,50,50] 46.9701 90.6667 [50,30,50] 43.3439 92.0000 [50,50,30] 46.0453 91.3333 321 2 [50,50,50] 45.3929 88.6667 [30,50,50] 46.8491 92.0000 [50,30,50] 44.5142 91.3333 [50,50,30] 44.6899 90.0000 4 [50,50,50] 44.9159 90.6667 [30,50,50] 44.1376 89.3333 [50,30,50] 43.7359 92.6667 [50,50,30] 43.3342 84.6667 789 2 [50,50,50] 44.2331 88.6667 [30,50,50] 44.4770 82.0000 [50,30,50] 39.4050 82.0000 [50,50,30] 41.3802 85.3333 4 [50,50,50] 45.5743 90.0000 [30,50,50] 42.8920 84.6667 [50,30,50] 41.6728 86.0000 [50,50,30] 43.1602 92.6667 2 2 [50,50,50] 48.2268 88.0000 [30,50,50] 48.0769 93.3333 [50,30,50] 45.1548 87.3333 [50,50,30] 46.6034 83.3333 4 [50,50,50] 45.4296 87.3333 [30,50,50] 47.7772 94.0000 [50,30,50] 46.9530 92.0000 [50,50,30] 46.9031 92.0000 - 不需要与DNN的性能进行比较
- 更换随机种子,做多组实验,画出中位线
- 只要证明性能没有太大损失,甚至有时候优于无瓶颈层的状态,就可以了
- 但是瓶颈层放在别的层差距也太大了吧,那只能说是应该在适当位置加入瓶颈层
- $\theta=2$得到的优化太小了,用$\theta=4$重做实验,好像也不行
# 20220926
放大节点间距可以解决问题,但一味放大可不行,是否有别的抑制方法?
修改梯度:为局部连接部分的梯度幅值添加缩放因子,权衡局部连接与层间连接
网络 缩放因子 bin_acc utt_acc DNN[256,256] / 53.7281 96.6667 Fit-DNN[256,256] / 53.6562 96.6667 0.9 54.5843 97.3333 0.6 53.7438 96.0000 0.3 53.6378 96.6667 - 通过梯度抑制确实可以缓解net_coupled求解器下Fit-DNN与DNN的差距
- 前后向传播算法不一致依然是最大的问题,因为net_coupled求解器并不足以模拟光学时延系统,这也是物理芯片的通病
大型网络下,net_coupled方法在较大节点间隔下,是否可以与DNN等价?
对于两种dde方法,较大节点间隔是否依旧可行?
# To Be Continued...
# 经验总结
- 分析Fit-DNN时,应该与Python手敲的DNN作对比
- 换网络的时候,使用Pytorch脚本快速确定学习率
- bin acc与utt acc并没有必然的联系,这就使得某些时刻的性能提升没有说服力【数据集还是太小了,结果无法有一致性!】
- 梯度更新时使用的样本数越多,学习率需要相应向上调整
# 记忆容量
# 参考资料
- pytorch实现查看当前学习率_Python-考高分网 (kaotop.com) (opens new window)
- How is Pytorch’s Cross Entropy function related to softmax, log softmax, and NLL | by Yang Zhang | Medium (opens new window)
- 深度学习种 数据shuffle对模型性能的影响_loveliuzz的博客-CSDN博客 (opens new window)
- numpy设置输出精度_skyecs的博客-CSDN博客_numpy设置精度 (opens new window)
- Hinton:我终于想明白大脑怎么工作了!神经学家花三十年,寻找反向传播的生物机制 (cxyinfo.com) (opens new window)
- pytorch中state_dict()和named_parameters()的差别,以及model.buffer/model.parameter__illusion_的博客-CSDN博客 (opens new window)
- 深度学习延时系统solve_dde_ibp_qq_41093957的博客-CSDN博客 (opens new window)