6.3 实际运行
现在可以获取我们的二元分类代码(5.3节),并在MNIST样本数据集上运行这段代码了。我们确实需要对这个分类代码进行一些调整,但是需要改变的部分很少。事实上,我们可以使用与前一章完全相同的函数,只需要对主代码进行一些更新即可,如下所示:
一行语句用于模型的训练,一行语句用于模型的测试。我们不需要加载和准备数据,因为MNIST库已经处理好了这个问题。
第一个图像分类器的输出如下所示:
有超过96%的样本预测被证明是准确的。我们的程序能够识别图像!
现在我们已经沉浸在这个数字的荣耀之中,然而我不得不扮演一个扫兴的角色。虽然96%准确率似乎很好,但这并不意味着我们的程序非常准确。想象一下,MNIST测试集中只有10%的数字是5。这意味着一个预测值总是为0(表示“这不是5”)的幼稚程序也能够以90%准确率命中目标。真扫兴。
公平地说,我们的程序的准确率是96%,比90%的基线要高。然而,很难衡量它到底有多好。为了直观地了解这个程序的准确性,必须扩展我们的代码来识别0~9的任何数字。让我们把胜利之舞留给下一章吧!
超参数调优
当为上面内容编写实际的“主”代码时,我必须为迭代次数和学习率lr寻找到适合这个新任务的取值。像往常一样,具体的搜索过程涉及一些反复的试验,我只是调整了那些超参数,直到对结果满意为止。
对于这个特定的应用实例,我发现lr值必须非常小。我选择了0.000 01。如果使用较大的lr值,程序会在计算S型函数和损失时溢出。这种溢出是使用指数运算和对数运算的副作用,它们可以很容易地产生很大的数值。此外,当我尝试一个稍微大一点的lr值时,程序就无法收敛,这是一种花哨的说法,意思是梯度下降的迭代计算过程一直在最小损失的附近打滑,而不是越来越接近最小损失。
稍后,我们将在第15章中具体讨论更多的关于超参数调优的内容。现在,让我们接受这样一个事实,每当我们改变算法或数据集时,都必须通过摸索确定超参数的取值。