大家好~本课程为“深度学习基础班”的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序
线上课程资料:
本节课录像回放
加QQ群,获得ppt等资料,与群主交流讨论:106047770
本系列文章为线上课程的复盘,每上完一节课就会同步发布对应的文章
本课程系列文章可进入索引查看:
深度学习基础课系列文章索引
主问题:如何加快多分类的训练速度?
- “识别手写数字“属于单分类还是多分类?
答:多分类
- “识别手写数字“是否能使用单分类中的交叉熵损失函数?
答:不能
- 为什么?
答:
dEdwkj=δkaj=dEdykdf(netk)dnetkaj
因为目前的交叉熵损失函数是在单分类下推导的。
而在多分类下,由于原有的激活函数不再适合,需要更换新的激活函数,导致上面公式中的df(netk)dnetk发生了变化,导致损失函数E也需要改变,
所以需要新的损失函数
- 输出层原来的sigmoid激活函数是否适用于多分类的情况?
答:不适用
- 输出层需要新的激活函数
- 如何设计新的激活函数?
- 我们现在用a表示激活函数的输出值
- 激活函数要满足什么条件?
答: ak∈[0.0,1.0]以及∑nk=1ak=1
- 你能设计一个满足该条件的激活函数吗?
答:ak=tk∑iti且ti(包括tk)>0.0
- 我们使用softmax激活函数,它的公式为:
答: ak=enetk∑ni=1eneti
为什么tk使用ek这种函数呢?这可能是因为它大于0.0;并且由于是非线性的所以值的间隔拉的比较开,从而能适应更多的变化
- softmax是否满足条件?
答:满足
- 我们现在用y表示真实值(即标签)
- 如何计算loss?
答:−−→loss=−−→a输出层−→y
- 如何参考设计单分类误差项公式的思路来设计多分类误差项的公式,使其满足loss与误差项成正比?
答:−−→δ输出层=−−→loss=−−→a输出层−→y
- 我们需要将单分类的交叉熵损失函数修改一下,使其满足什么公式?
答:为了简单,我们暂时不考虑误差项向量,而只考虑单个神经元的误差项。所以应该满足下面的公式:
E=?从而∑ni=1dEdaidaidnetk=δk=ak−yk
(注意:因为每个a的计算都有所有的net参加,所以要使用全导数公式进行累加)
- 现在直接给出修改后的交叉熵损失函数的公式: E=−∑nj=1yjlnaj
- 请根据修改后的损失函数和softmax激活函数公式,推导误差项,看下是否为设计的公式: δk=∑ni=1dEdaidaidnetk=?(应该为ak−yk)
答:
∵
dEdai=d−∑nj=1yjlnajdai=−yiai
∴
δk=n∑i=1dEdaidaidnetk=−n∑i=1yiaidaidnetk
因为只能有一个真实值为1,所以假设yj=1,其它yi=0,则
δk=−1ajdajdnetk
现在需要推导dajdnetk,推导过程如下:
因为aj可以看作是netj的复合函数:
aj=enetj∑nm=1enetm=f(enetj,∑menetm)
所以:
dajdnetk=dajdenetkdenetkdnetk+dajd∑menetmd∑menetmdnetk
现在分两种情况:
dajdnetk=dajdnetj=dajdenetjdenetjdnetj+dajd∑menetmd∑menetmdnetj
∵
dajdenetj=1∑jenetjdenetjdnetj=enetjdajd∑menetm=−enetj(∑menetm)2d∑menetmdnetk=d∑menetmdenetkdenetkdnetk=enetk
∴
dajdnetk=dajdnetj=aj(1−aj)
dajdnetk=dajdenetkdenetkdnetk+dajd∑menetmd∑menetmdnetk
∵
dajdenetk=0dajd∑menetm=−enetj(∑menetm)2d∑menetmdnetk=enetk
∴
dajdnetk=−ajak
经过上面的推导后,写成向量的形式就是:
−−→δ输出层=⎡⎢
⎢
⎢
⎢
⎢
⎢
⎢
⎢
⎢
⎢⎣−1aj⋅(−aja1)⋮−1aj⋅(aj(1−aj))⋮−1aj⋅(−ajan)⎤⎥
⎥
⎥
⎥
⎥
⎥
⎥
⎥
⎥
⎥⎦=⎡⎢
⎢
⎢
⎢
⎢
⎢
⎢
⎢⎣a1⋮aj−1⋮an⎤⎥
⎥
⎥
⎥
⎥
⎥
⎥
⎥⎦=−−→a输出层−→y
结学
- 如何加快多分类的训练速度?
- 根据交叉熵损失函数和softmax,推导误差项的过程是什么?
任务:识别手写数字使用交叉熵损失函数和softmax激活函数
- 请在“识别手写数字Demo”中使用交叉熵损失函数和softmax激活函数,并且加入“通过打印loss来判断收敛”
答:待实现的代码为:NewCross_softmax,实现后的代码为:NewCross_softmax_answer
- 请每个同学运行代码
- 刚开始训练时,有什么警告?
答:如下图所示:有“输出层梯度过大”的警告

- 注释掉警告代码后,看下loss的训练速度与之前的代码相比是否明显加快?
答:没有
任务:改进代码
- 找到发生警告的原因?
答:
因为输出层加权和没有做缩小处理,所以加权和比较大(范围为[10.0,15.0]左右)。
通过上图(softmax的图像)可知,该范围内的梯度很大,所以报“梯度爆炸”的警告
- 如何改进代码?
答:将输出层的学习率变小为0.1
- 将输出层的学习率分别变小为1.0、0.1,运行代码,看是否解决了警告,并提升了训练速度?
答:变小为0.1后运行代码的结果如下图所示:

我们看到只需要四轮训练既达到95%的正确率
那么为什么在正确率到88%后会开始报输出层的一些梯度值过小的警告呢?这是因为此时loss小,所以梯度也小了
总结
参考资料
谢谢你~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?