AI深度学习系列(2):亲手搭第一个网络

AI深度学习系列(2):亲手搭第一个网络
ai深度学习系列2亲手搭第一个神经网络

简单说:第一个神经网络别自己发明,抄一个最小版本跑通,再逐个改参数看变化。我搭的两层网络总共六十行代码,第一次报了七个错。改学习率比改网络结构见效快得多。

ai深度学习系列2来了。第一篇讲概念(想补课的搜"AI深度学习是什么,看完这篇你就能跟人聊明白"),后台就有读者催更:道理都懂了,手痒,想真的搭一个出来。这篇就是我搭第一个网络的完整流水账——从抄代码、报错、修错、到跑通后做的三组小实验。

丑话说前面:这篇没有高深内容。

它的价值恰恰在于足够笨。网上不缺教程,缺的是把"从报错到跑通"这段狼狈过程原样记录下来的参考。新手最怕的不是难,是以为只有自己卡住。

任务和弹药:六十行代码搭个什么

原子答案:任务是从零搭一个两层全连接网络,识别手写数字(MNIST数据集),只用PyTorch的基础张量运算,不调用现成的nn.Sequential堆模块。整个网络连注释六十行,训练五分钟能出结果。

为什么选这个任务?三个理由。数据集是现成的,六万张28乘28像素的灰度图,不用自己找数据;任务目标简单,把图片分成十类(数字0到9),做对做错一眼可判;最关键的是——它麻雀虽小,前向传播、损失函数、反向传播、参数更新四件套一个不少,改动任何一处都有肉眼可见的反馈。

环境方面我用的老笔记本,CPU跑,没显卡。这个任务模型小,CPU完全够用,一轮训练约四十秒。框架选PyTorch不选TensorFlow纯属个人偏好,TensorFlow搭同样的东西也可以,PyTorch官方教程的60分钟入门那篇我是对照着抄的。数据集MNIST的原始出处是Yann LeCun的页面,现在一般直接用框架内置的下载接口,省事。

网络结构画出来就一行字:784个输入(28乘28展开)→128个神经元(ReLU激活)→10个输出。

就这么点东西。

第一晚的七个报错,逐个复盘

原子答案:七个错里五个是形状对不上,两个是数据类型问题,没有一个是"数学不会"。新手阶段的深度学习代码报错,九成是张量形状和类型这类工程细节,不是智商问题。

挨个列出来,你可能全都会撞上:

第一个错,矩阵维度不匹配。输入忘了把图片展开成一维向量,直接把形状为64乘28乘28的张量喂给了期待784维输入的层。报错信息最后一行写着expected input size匹配失败。修法一行代码:reshape成64乘784。

第二个错,CrossEntropyLoss重复套softmax。我在网络最后一层手贱加了softmax,而这个损失函数内部自带一遍。模型死活不收敛,损失在2.3附近横盘——这个数字我记到现在,log(10)约等于2.3,等于模型在瞎猜。删掉那行softmax,损失立刻开始掉。

第三个和第四个错是复制粘贴手滑:一个把学习率的0.1敲成了01(Python里这是合法的整数1,不报错但训练飞了),一个变量名写错大小写。第五个是忘了zero_grad,梯度累积导致训练曲线抖成心电图。第六个,DataLoader的num_workers参数在Windows上报错,这是个老坑,Windows下多进程加载数据得套main保护。第七个纯属玄学,Anaconda环境冲突,pandas和numpy版本打架,重开了一个干净环境了事。

老实讲,第一个晚上我就卡在这七个错上,进度为零,气得下楼跑了两圈。回来重读报错信息,发现每个错的最后一行其实都把答案写脸上了。深度学习新手的报错,读最后三行,够了。

ai深度学习系列2实战:跑通之后改参数比看十篇教程涨知识

原子答案:网络跑通后我做三组对照实验:调学习率、调隐藏层宽度、调训练轮数,每组只动一个变量。实验一晚上做完,结论是学习率对结果影响最大,隐藏层从128加到512提升微弱。

基础配置下(学习率0.1、隐藏层128个神经元、跑5轮),测试集准确率约97.1%。然后开始瞎改。先说三组实验的数据:

改动项原值改后测试准确率我的判断
学习率0.10.5跌到约89%,损失剧烈震荡步子太大,直接崩
学习率0.10.01约96.5%,收敛变慢稳但慢,不划算
隐藏层宽度128512约97.3%,提升0.2个点收益太薄,不值当
训练轮数515约97.6%,但训练耗时三倍边际递减明显
批大小6416约97.2%,训练变慢小任务上无感

这张表最扎心的发现是隐藏层那行。参数翻了四倍,准确率才涨0.2个点。当时我对着屏幕愣了几秒,第一次直观理解了什么叫"模型容量不是越大越好"——任务太简单,大网络杀鸡用牛刀,牛刀还贵。

学习率0.5那组最有戏剧性。损失曲线像坐过山车,忽上忽下,最后稳定在一个很差的水平。这个画面比任何教材里"学习率过大会导致震荡"那句话都生动。看一百遍定义,不如亲手把损失曲线抖一次。

这次实战教会我的三件事

原子答案:一,形状错误是新手第一大坑,打印张量形状的习惯能救命;二,损失值卡在2.3这种"奇怪的平台期"往往藏着逻辑错误而非超参数问题;三,实验记录必须当场写,事隔三天全忘。

第一件事展开说说。我现在的习惯是每次数据进网络前都print一下shape,几十行的脚本里塞了七八个print。看着蠢,救过我无数次。深度学习代码的bug大多不报语法错误,形状悄悄错了照样能跑,结果就是不对,这种沉默的错最耗时。新手怎么避坑,我踩过的那些入口级陷阱都记在AI入门学习的五大误区里,这篇算是它的代码版续集。

第二件事,那个2.3的教训后来被我用上了。同事的模型损失一直卡在某个值不动,我瞄了一眼数字就问:是不是损失函数和输出层重复处理了?他查了十分钟,果然。这种"数字指纹"的直觉只能从自己的坑里长出来。

第三件事是我的实验记录本。三组实验当晚全靠随手记在一个文本文件里,包括每次改动的准确率和耗时。上周翻回去看,如果没有那份记录,0.2个点的提升差异我绝对记不准。写下来,比记住靠谱。

如果这个系列的第一篇你还没看过,建议先补:AI深度学习是什么?一个例子讲透底层原理,概念和实操配着消化最快。

话说回来,搭完这个网络我有三天没碰深度学习。原因是膨胀——觉得全连接网络不过如此,直接去抄了个ResNet,然后被批归一化层和残差连接的组合按在地上摩擦了整晚。冷静下来才明白,六十行的两层网络和工业级的残差网络之间,隔着的是几百个我这种夜晚。

下一步的台阶怎么上,路线我规划过一版,按"先动手再补原理"的顺序排:人工智能AI技术学习顺序。慢就是快,这话是我被ResNet毒打之后才真信的。

常见问题

完全零基础能直接照这篇搭吗?

需要先会一点Python,能看懂函数、循环和列表就行,大概两周的入门量。数学不设门槛,这个网络用到的求导知识看不懂也不影响跑通,回头补得上。

没有显卡怎么办?

这个任务不需要。CPU跑一轮约四十秒,五轮三分多钟,完全可以接受。真到了要训大模型的阶段,用云端免费算力顶上,具体白嫖姿势我写过一篇实操记录,搜AI云计算跑机器学习就能找到。

为什么要手写网络而不用现成库?

练手阶段的手写是有价值的重复劳动——你会在报错里被迫理解每一行在干嘛。跑通之后就该用高级接口了,工程里没人手写这些。学习的顺序和干活的习惯,得分开对待。

准确率97%算什么水平?

对MNIST这个任务来说只是及格线。人类准确率约99.7%,卷积网络能到99%以上。但第一个网络的97%比数字本身重要,它证明整条链路在你手里是通的。

ai深度学习系列2到这里收尾。下一篇打算写卷积:同样的手写数字任务,换CNN能再涨两个点,改动量其实只有十几行。第一个网络的代码和实验记录我都留着,需要参考的可以照文中的结构自己敲一遍——敲一遍,你就懂了这整篇文章在说什么。觉得有用的话,转给那个总说"想学深度学习但不知从哪下手"的朋友,这篇就是给他准备的起跑线。