学深度学习时,很多基础概念其实并不难理解,但一旦被框架封装起来,就很难直观看到它们具体是怎么工作的。

比如 Softmax 如何把输出变成类别概率、交叉熵损失为什么会下降、卷积之后图像尺寸为什么会变化,以及无监督聚类和有监督分类到底有什么区别。

前段时间我在 MoHub 上看到了一套**《深度学习综合教学案例库》**,其中“深度学习基础”模块正好用 5 个 Julia 案例分别演示这些问题:

  • SOM 无监督聚类
  • Softmax 与交叉熵分类
  • 深度学习算子可视化
  • 神经网络函数拟合
  • 鸢尾花模式识别分类

完整案例地址:

https://mohub.net/education/26291/summary

这几个案例都可以在 Syslab 的 Julia 环境中直接运行,主要依赖 TyDeepLearningTyImageProcessingTyPlot。按照案例目录中的 README 执行对应脚本即可,部分案例会读取配套的 CSV 数据文件。

下面直接看几个实际运行结果。

Softmax与交叉熵:损失从1.29降到0.038

Softmax 案例生成三类二维点云,每类 60 个样本,然后使用线性 Softmax 分类器配合交叉熵损失进行梯度下降训练。

主要参数为:

样本数:60 × 3
训练轮数:220
学习率:0.08

运行结果:

初始损失:1.2918
最终损失:0.0376
训练准确率:100%
图1:Softmax 交叉熵损失随迭代次数下降的曲线,纵轴为交叉熵损失,横轴为迭代次数

从损失曲线可以看到,训练前期下降较快,随后逐渐趋于平缓。

Softmax 会将模型输出的 logits 转换成各类别对应的概率,而交叉熵衡量的是预测概率与真实类别之间的差异。当模型对真实类别给出的概率越来越高时,交叉熵损失也会持续下降。

这个案例生成的三类二维数据本身具有比较明显的可分性,因此最终训练准确率达到 100%。

相比直接调用一个分类接口,这个例子更容易看清:

线性输出 → Softmax 概率 → 交叉熵损失 → 梯度下降 → 分类结果

这一整套多分类训练流程是怎样连接起来的。

函数拟合:隐藏节点数量会怎样影响结果?

函数拟合案例使用径向基特征加线性输出,对一组带噪声的非线性数据进行拟合。

默认使用 10 个隐藏节点,并按照约 7:1.5:1.5 的比例划分训练集、验证集和测试集。

运行结果:

训练 MSE:0.075759
验证 MSE:0.098399
测试 MSE:0.105056
图2:神经网络函数拟合效果,原始函数、带噪声样本与网络拟合曲线

从结果看,训练、验证和测试误差虽然依次略有升高,但整体处于比较接近的量级,没有出现训练误差很低、测试误差却明显增大的情况。

这个案例比较适合用来观察模型复杂度与拟合能力之间的关系

例如可以直接修改隐藏节点数量:

hiddenLayerSize

再重新运行。

隐藏节点较少时,模型表达能力有限,可能无法捕捉曲线中的复杂变化,容易出现欠拟合。

而随着隐藏节点增加,模型能够表达更复杂的函数,但如果复杂度过高,也可能逐渐开始贴合训练数据中的噪声。

所以“隐藏层节点越多,模型越好”并不成立。

相比单独看一张“欠拟合—正常拟合—过拟合”的示意图,直接修改参数再观察拟合曲线变化会直观很多。

鸢尾花分类:训练91%,测试87%

鸢尾花案例使用经典 Iris 数据完成三分类。

输入数据首先进行特征归一化,然后使用 tanh 随机特征和 Softmax 输出层进行训练,默认训练 300 轮。

运行结果:

训练准确率:91.43%
测试准确率:86.67%
图3:鸢尾花测试集混淆矩阵热力图,横轴为预测类别,纵轴为真实类别

如果只看 86.67% 的测试准确率,其实很难知道模型究竟错在什么地方。

混淆矩阵就能进一步把错误拆开。

从运行结果看,setosa 和 virginica 的测试样本都被正确识别,错误主要集中在 versicolor,其中有 6 个样本被预测成 virginica。

这也说明,评价一个分类模型时,只看 accuracy 往往还不够。

准确率回答的是:

“总共分对了多少?”

而混淆矩阵还能继续回答:

“哪些类别之间最容易混淆?”

这也是这个案例相比单纯输出一个准确率更有价值的地方。

SOM聚类:36个神经元中31个被命中

SOM 案例同样使用鸢尾花特征,但和前面的分类任务有一个很明显的区别:

训练过程中完全不使用样本标签。

标签只在训练结束后用于解释聚类结果,并不会参与网络权重更新。

默认参数为:

SOM 网格:6 × 6
神经元数量:36
训练轮数:200

运行后,36 个神经元中有 31 个被样本命中,也就是说有 5 个神经元为空。

图4:SOM 样本命中图与邻接距离图 U-Matrix

命中图可以看到不同样本最终集中映射到了哪些神经元。

而 U-Matrix 展示的是相邻神经元权重向量之间的距离。距离较大的区域,意味着相邻神经元所代表的特征差异更明显,可以辅助观察潜在的聚类边界。

这里出现少量空神经元并不奇怪。

SOM 网格大小是人为设定的,而样本在特征空间中的分布并不会恰好均匀覆盖整个 6×6 网格,因此部分节点没有样本命中属于正常现象。

这个案例也比较适合自己继续改参数,例如尝试:

4×4
5×5
6×6
8×8

观察不同网格规模下的样本命中情况和 U-Matrix 会有什么变化。

这样也能更直观地理解 SOM 中所谓的竞争学习和拓扑保持到底表现在哪里。

卷积算子可视化:32×32最后变成15×15

相比前面几个案例主要关注“训练”,这个案例更侧重于观察神经网络前向传播过程中发生了什么

程序首先读取一张混合图形图像,并将其缩放到:

32 × 32

然后依次执行:

3×3卷积
↓
ReLU
↓
2×2最大池化
↓
全连接
↓
Softmax

其中图像尺寸变化非常直观:

输入       32 × 32
卷积后     30 × 30
池化后     15 × 15
图5:深度学习算子前向传播可视化,依次为输入灰度图、卷积结果、ReLU结果、最大池化结果与Softmax概率

这里使用的是一个 3×3 卷积核,在没有 Padding 的情况下作用于 32×32 图像。

输出尺寸为:

32 - 3 + 1 = 30

因此卷积结果变成:

30 × 30

随后经过 2×2 最大池化:

30 / 2 = 15

最后得到:

15 × 15

运行得到的 Softmax 概率约为:

[0.2793, 0.3052, 0.4155]

其中第 3 个类别的概率最高,因此最终输出类别为 3。

不过这个案例真正值得看的其实不是“最后预测成了类别 3”,而是前面的整个变化过程。

输入图像经过卷积后提取局部特征,ReLU 去掉负响应,再经过最大池化进一步压缩尺寸,最后才进入全连接和 Softmax。

这样一来,卷积、激活函数和池化不再只是网络结构图里的几个方框,而是变成了具体的矩阵尺寸和数值变化。

对于后面继续学习 CNN,这种可视化会比较有帮助。

把5个案例放在一起看

这 5 个案例并不是为了搭建一个复杂的深度学习系统,而更像是把几个基础问题分别拆出来验证。

案例 主要观察内容
SOM 无监督聚类 没有标签时样本如何通过竞争学习形成聚类
Softmax 与交叉熵 多分类概率、损失函数和梯度下降之间的关系
算子可视化 卷积、ReLU、池化如何改变图像和特征尺寸
函数拟合 模型复杂度如何影响非线性拟合效果
鸢尾花分类 多分类模型如何训练,并通过混淆矩阵分析错误

我觉得这类小案例比较适合作为深度学习入门阶段的配套练习。

原因在于,它们没有一开始就把所有过程封装进复杂框架中。

Softmax、SOM、函数拟合和鸢尾花分类中的核心计算过程都比较容易跟踪,卷积、池化等部分则借助 TyDeepLearning 的基础算子完成。

这样可以先把单个概念看清楚,再去学习 CNN、RNN、LSTM 等更复杂的网络结构。

这些案例也有明显的边界

当然,这几个案例的定位主要是原理演示和教学练习,并不是生产级深度学习任务。

首先,数据规模都比较小。

鸢尾花只有 150 条数据,函数拟合也只是百余个采样点,因此这里的训练速度、准确率和误差水平不能直接类比真实的大规模深度学习任务。

其次,随机初始化和数据划分会影响最终指标。

如果修改随机种子,训练准确率、测试准确率或者 MSE 都可能出现一定变化,因此没有必要过度关注小数点后的具体数值。

另外,算子可视化案例中的全连接权重采用固定构造,最终得到的 Softmax 概率主要用于演示完整的前向传播过程,并没有进行真正意义上的网络训练。

所以这套案例更值得关注的是:

算法是怎么一步步运行的,而不是最后的准确率有多高。

小结

如果准备开始学习 CNN、RNN、LSTM 等更复杂的网络,我觉得可以先把几个基础问题弄明白:

  • Softmax 怎样把 logits 转换成类别概率?

  • 交叉熵为什么可以作为多分类损失函数?

  • 损失值是怎样通过训练逐渐下降的?

  • 卷积之后特征图尺寸怎么算?

  • ReLU 和池化分别改变了什么?

  • 无监督聚类和有监督分类究竟差在哪里?

  • 隐藏节点数量为什么会影响拟合能力?

  • 除了准确率,还能怎样分析模型的分类结果?

这 5 个 Julia 案例基本都能找到对应的动手实验。

如果只是想快速调用一个现成模型,它们可能显得有些基础;但如果想在继续学习复杂网络之前,把 Softmax、交叉熵、卷积、聚类、拟合这些概念真正跑一遍,这套案例还是比较合适的。

完整脚本、数据素材和说明文件可以在这里获取:

深度学习综合教学案例库

https://mohub.net/education/26291/summary

更多推荐