|
1989年,基于Yann LeCun在贝尔实验室把一张32×32的神经数字识别灰度图塞进一个叫LeNet的网络里,机器认出了邮局手写的网络邮政编码。那套东西的写体骨架,就是基于今天要聊的BP神经网络。它不新鲜,神经数字识别但管用。网络 手写体数字识别这件事,写体说白了就是基于让机器看图猜数。人看一眼就懂,神经数字识别机器不行。网络它看到的写体是一堆像素点,每个点取值0到255。基于28×28的神经数字识别MNIST图片,展开就是网络784个数字。BP神经网络干的事,是找一组权重和偏置,把这784个输入映射到10个输出上,哪个输出最大,就认成哪个数字。 网络长什么样 拿一个最朴素的版本说。输入层784个节点,对应每个像素。中间藏一层,比如128个神经元。输出层10个节点,对应0到9。层与层之间全连接,每个连接上有个权重。前向传播时,每个隐藏神经元收到784个输入加权求和,加偏置,过激活函数——常见的是ReLU或者Sigmoid。输出层再用Softmax把10个实数压成概率分布。 这中间有个细节容易被跳过。权重初始化不能全设成一样的值,否则所有神经元学到的特征完全相同,网络退化成一条直线。通常用高斯分布随机初始化,标准差控制在0.01到0.1之间。LeCun早期论文里提过,初始化方差要跟输入节点数挂钩,不然信号传几层就衰减没了。 反向传播在调什么 前向跑完,网络给出一个预测,比如它觉得图里是“3”的概率是0.7。真实标签是“3”,one-hot编码后对应[0,0,0,1,0,0,0,0,0,0]。损失函数用交叉熵,算出来一个标量。这个标量对每个权重的偏导数,就是反向传播要算的东西。链式法则一层层往回推,算出梯度,然后用梯度下降更新权重:w = w - lr * grad。 学习率这个参数很敏感。设0.1可能震荡不收敛,设0.0001又慢得让人想砸键盘。实践中常用Adam或者RMSProp这类自适应方法,它们对学习率没那么挑剔。MNIST上,一个784-128-10的网络,用Adam,学习率0.001,批量大小64,跑五六个epoch,测试集准确率能到97%以上。再往上提,就得靠卷积网络了。 几个实际会踩的坑 过拟合是第一个。训练集准确率99%,测试集只有92%,网络把训练样本背下来了。Dropout是常用手段,训练时随机让一部分神经元失活,逼网络学更鲁棒的特征。另一个是梯度消失,Sigmoid激活函数在饱和区导数接近零,反向传播时梯度越传越小,浅层几乎学不动。换ReLU能缓解,但ReLU也有自己的问题——神经元可能“死掉”,输出恒为零,梯度永远为零。 数据预处理别忽略。把像素值从0-255缩放到0-1,收敛快很多。不缩放也能跑,但训练时间可能翻倍。还有个经验:打乱训练数据顺序。MNIST原始数据按标签排过序,不shuffle的话,每个batch里全是同一个数字,梯度方向偏得离谱,网络根本学不好。 它为什么还值得讲 现在随便一个卷积网络在MNIST上都能刷到99.5%以上,BP神经网络看起来像古董。但它是理解深度学习的地基。卷积、池化、注意力机制,反向传播的数学框架没变。把784-128-10这个网络手写一遍,不用框架,只用numpy,梯度推导自己算,比调包跑一百个模型收获都大。我见过不少人能背出反向传播公式,但问他“偏置的梯度为什么是误差项直接求和”,答不上来。动手写一遍,这个问题就消失了。 MNIST本身也值得说一句。这个数据集从1998年发布到现在,被用烂了,但它干净、小、加载快,适合验证想法。不过别拿它当benchmark吹牛,97%和98%的差距,可能只是随机种子不同。真要评估模型,换Fashion-MNIST或者EMNIST,难度上来了,方法的好坏才看得出来。 |