尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

从零啃完鱼书代码,这些实操经验帮你避坑

发布时间:2026/9/7 12:04:38

资讯中心
01
ARTICLE

从零啃完鱼书代码,这些实操经验帮你避坑

从零啃完鱼书代码,这些实操经验帮你避坑
简介这套代码是《深度学习入门基于Python的理论与实现》一书的随书实现面向正在学习深度学习基础、希望用Python动手复现理论的读者。资源按原书章节组织覆盖第一章到第八章的主要示例包含神经网络前向与反向传播、梯度下降、MNIST手写数字识别、卷积神经网络、批量归一化、过拟合应对、超参数优化及深度网络训练等实验代码。压缩包共67个文件其中59个py源码为主体另配3个pkl预训练参数便于直接加载运行2个md说明文档和2个png图片辅助理解整体大小仅4.44MB。目前已有2489人学习浏览。通过逐章代码可配合书籍逐步调试理解损失函数、激活函数、优化器、权值初始化、Dropout与Batch Norm等核心机制还能学习常见模型构建与训练流程适合初学者对照阅读或作为课程实验参考。 从零啃完鱼书代码我想把这些经验都告诉你如果2024年还有人问深度学习入门该看什么书我大概率还是会推荐那本封面画着鱼的《深度学习入门基于Python的理论与实现》。国内读者习惯叫它“鱼书”斋藤康毅写的和另一本《动手学深度学习》花书并称两大入门神作。但这本书有个特点——很多人买回来翻了几十页就吃灰了。原因不是书写得不好而是书里的代码逻辑密集光看不敲根本跟不上。我自己当年也是断断续续摸了三遍从照着抄都报错到能完全不看源码把MNIST分类器实现出来中间踩了太多坑。这篇文章就围绕鱼书配套代码从一个“代码实操者”的角度把项目结构、环境配法、关键章节的复现要领、常见报错和排查方式都梳理一遍给正准备啃这本书的人一份“避坑地图”。1. 鱼书代码的整体认知与章节拆解1.1 这套代码解决了什么问题很多人学深度学习一上来就装TensorFlow或PyTorch调几行接口就能跑模型。但如果你问一个调包侠“反向传播到底在算什么东西”大概率是答不上来的。鱼书的价值恰恰在于它用NumPy从零实现了一个完整的神经网络手写前向传播、手写反向传播、手写SGD、手写卷积层、手写池化层。你看到的不是几十个封装好的API而是几百行能一步步断点调试的源码。配套代码仓库是书里每一章的实现集合本质上就是用最朴素的方式回答三个核心问题神经网络怎么算的、怎么学的、怎么用的。当你真正逐行理解这套代码之后再去看PyTorch源码或Transformer结构会感觉阻力小很多因为底层概念是相通的。1.2 代码文件之间的组织关系鱼书每一章的代码文件独立性很强这个设计对学习者非常友好。官方GitHub仓库的结构大致是这样的dataset/存放数据集下载脚本和已有的小型数据集如MNIST、螺旋状数据。mnist.py负责把MNIST的.idx格式解析成NumPy数组spiral.py生成用于双层神经网络分类实验的螺旋数据。ch01/Python基础语法示例和NumPy入门代码。ch02/感知机实现包含与门、与非门、或门、异或门的简单例子。perceptron.py只有几十行是全书最简单的代码文件。ch03/神经网络前向传播包含sigmoid函数、softmax函数、MNIST推理。这部分最重要的就是softmax的实现和批处理逻辑。ch04/损失函数与数值微分。gradient_simplenet.py演示了损失函数对参数求梯度的完整流程two_layer_net.py定义了一个最简单两层网络。ch05/误差反向传播法。这是全书最难啃的一章layer.py定义了乘法层、加法层、ReLU层、Sigmoid层、Affine层、SoftmaxWithLoss层每一个类的forward和backward方法都值得反复看。ch06/优化器与正则化。optimizer.py比较了SGD、Momentum、AdaGrad、Adam四种优化器在同一个问题上的表现weight_init_activation_histogram.py画出了不同初始权重下激活值的分布overfit_weight_decay.py和overfit_dropout.py演示了过拟合的抑制方法。ch07/卷积神经网络。simple_convnet.py实现了包含一个卷积层、一个池化层、两个全连接层的小型CNNtrain_convnet.py是训练入口。ch08/深度学习实战。deep_convnet.py是模仿VGG结构的深层网络半精度训练、分布式等概念也有提及。common/全书的公共模块包括functions.py、layers.py、gradient.py、optimizer.py、multi_layer_net.py、util.py等是最高频使用的目录。建议的学习路径是先花两周时间把ch02到ch04的代码全部手敲一遍再花一周突击ch05的每一层实现最后用ch06和ch07巩固。ch08可以先放着等前面都通了再看否则容易心态崩。2. 准备工作Python环境配置与依赖安装2.1 这个项目到底需要什么环境鱼书代码的核心依赖只有三个NumPy、Matplotlib以及可选的Pillow用于图像显示。不需要安装PyTorch或TensorFlow这对新手来说非常友好直接把环境复杂度降了一个数量级。Python版本建议用3.8到3.11之间太新的3.12、3.13在某些老版本库上可能会有兼容性提示虽然也能跑但没必要给自己加戏。我个人的推荐配置是使用Miniconda或venv建立一个干净的虚拟环境Python版本3.10NumPy装1.24或1.26都行Matplotlib任意较新版本。之所以用虚拟环境而不是直接装在系统环境里是因为后面你迟早会开始跑PyTorch项目到时候依赖冲突会很头疼。用鱼书的机会把虚拟环境这套流程练熟后续能省很多事。2.2 一步一步配置环境的操作流程用命令行操作整个过程大概需要十分钟# 创建虚拟环境文件名可以自己起 python -m venv fishbook_env # 激活环境 # Windows: fishbook_env\Scripts\activate # macOS/Linux: source fishbook_env/bin/activate # 安装依赖 pip install numpy matplotlib pillow # 验证是否装好 python -c import numpy, matplotlib; print(numpy.__version__)如果你用Miniconda命令会更简单conda create -n fishbook python3.10 conda activate fishbook conda install numpy matplotlib pillow配置完成后把鱼书代码克隆到本地或者直接在出版社官网下载压缩包解压。我建议直接在GitHub上clone官方仓库后续如果发现代码bug还能看到issue区的讨论git clone https://github.com/oreilly-japan/deep-learning-from-scratch.git这里说一个容易踩的坑书里的代码是基于当时Python 3的环境写的默认编码都是UTF-8。Windows用户如果在运行mnist.py时遇到UnicodeDecodeError多半是文件编码识别问题可以用文本编辑器把对应文件另存为UTF-8编码或者在代码头部加一行# -*- coding: utf-8 -*-声明。2.3 环境搭建时最常见的报错处理第一个常见报错是ModuleNotFoundError: No module named numpy。原因就是没在当前的虚拟环境里装依赖。很多人忘了激活环境就直接跑脚本结果调用了系统Python而不是虚拟环境里的Python。排查方式很简单运行which python或which pip看路径是不是指向你的虚拟环境目录。第二个常见报错是ImportError: numpy.core.multiarray failed to import。这种通常是因为环境中存在多个不兼容的NumPy版本或者是旧版本缓存导致的。解决方法就是强制重装pip uninstall numpy -y pip install --no-cache-dir numpy第三个是比较隐蔽的Matplotlib中文字体问题。你运行绘图代码时图表上的中文标签全部变成方框。这不算程序的错是Matplotlib默认字体不支持中文。解决办法是在代码里强制指定中文字体import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # Windows # 或者 macOS: # plt.rcParams[font.sans-serif] [Arial Unicode MS] plt.rcParams[axes.unicode_minus] False建议在一开始就把这段加到自己的公共工具文件里否则后面画loss曲线、权重分布图时每次都要改。3. 吃透核心代码从数值微分到误差反向传播3.1 数值微分和反向传播的根本区别全书最关键的一个转折点就是从ch04的“数值微分”切换到ch05的“误差反向传播”。数值微分的思路非常简单粗暴求某个权重对损失的影响就用(f(xh) - f(x-h)) / 2h这种近似公式算梯度。代码逻辑像这样def numerical_gradient(f, x): h 1e-4 grad np.zeros_like(x) for idx in range(x.size): tmp_val x[idx] x[idx] tmp_val h fxh1 f(x) x[idx] tmp_val - h fxh2 f(x) grad[idx] (fxh1 - fxh2) / (2 * h) x[idx] tmp_val return grad这种做法的优点是实现简单、不容易出错缺点是慢得离谱。MNIST这种784维输入、几万条样本的数据集用数值微分算一次梯度可能要跑很久。反向传播不一样它是利用链式法则把误差从输出层一层一层往回传每个参数的梯度只需要一次前向加一次反向就能算完速度是数量级的提升。鱼书ch05的巧妙之处在于它先用数值微分算梯度作为“标准答案”再用反向传播算梯度两者对照验证反向传播的实现是否正确——梯度确认gradient check这个习惯我一直保留到现在每次新写一个网络结构都会跑一遍非常推荐你也养成这个习惯。3.2 “层”的本质所有人都能用装修来理解ch05里最重要的概念是“层”。我感觉用装修来比喻特别合适一层ReLU就是一道工序比如刷漆数据经过它得到输出是“刷完的效果”反向传播时误差回流就是“发现刮痕后追溯是哪一步出的问题”。拿书中最经典的ReLU层代码举例class Relu: def __init__(self): self.mask None def forward(self, x): self.mask (x 0) out x.copy() out[self.mask] 0 return out def backward(self, dout): dout[self.mask] 0 dx dout return dxself.mask记录的就是前向传播时哪些位置的输入被置零了反向传播时只要把那些位置的梯度也置零就行。就是这么简单。Sigmoid层稍微复杂一点它把y 1 / (1 exp(-x))拆解成多个基础运算的组合每个运算都对应一个局部导数。乘法层的反向传播是交换两个输入再相乘这是全书最核心的一句话。理解了这个Affine层矩阵乘法层基本就是它的扩展版。3.3 一个权重更新迭代的完整故事我把两层网络的学习过程从头到尾讲一遍你就能把整个流程串起来了。第一步初始化。两层网络以MNIST为例输入784隐藏层50输出10会随机初始化两个权重矩阵W1 (784, 50)b1 (50,)W2 (50, 10)b2 (10,)。权重初始化方法在ch06里专门讲初始值不能太大也不能太小。第二步前向传播。数据从输入层进入经过AffineReLUAffineSoftmax得到最终10个类别的预测概率如上图。这一步做的就是矩阵乘法、激活函数变换、归一化指数代码都在common/functions.py里。第三步计算损失。书里用的是交叉熵误差def cross_entropy_error(y, t): delta 1e-7 return -np.sum(t * np.log(y delta)) / y.shape[0]如果预测分布和真实标签one-hot向量越接近损失越小。delta这个微小值是为了防止np.log(0)出现这个是实操里最常见的一个细节。第四步反向传播。从损失函数层开始SoftmaxWithLoss层的反向传播有一个非常优雅的结论它的梯度就是(y - t) / batch_size也就是预测概率与真实标签的差。这个差值反映了“我们有多大程度预测错了”然后它沿着Affine层、ReLU层一路传回去。第五步参数更新。用最简单SGD的例子来说W1 - learning_rate * dW1 b1 - learning_rate * db1学习率设成0.1还是0.01在三维空间里就是参数点走向最低点的步长调大跑得快但容易震荡调小稳但收敛慢。书里ch06会展示用grid search找学习率的方法这个思路和后来炼丹调参是一模一样的。整个循环跑1000个epoch损失曲线从最初的2.3左右10类随机猜测的熵一路下降到0.1以下准确率能到95%以上这套代码就跑通了。4. 实操中的常见问题排查与技巧实录4.1 训练时Loss不下降的几个典型原因这是新手最容易卡住的地方。我见过太多人在GitHub issue区问“为什么我的loss一直是2.3”总结下来主要有四种情况。权重初始值全设为0或全为同一个常数。如果初始权重相同那么同一层内所有神经元的输出也完全相同反向传播时梯度也相同这会导致所有隐藏单元都在学习同样的特征网络完全没有表达能力。解决办法是用随机初始化鱼书默认用的是np.random.randn高斯分布。学习率设置不合理。学习率太大loss可能直接变成nan因为参数震荡发散学习率太小loss下降慢到几乎看不到变化。一般先在0.001到0.1之间试观测loss曲线的形态再调整。数据预处理没做对。比如图像数据直接使用0到255的整数值没有归一化到0到1这会导致梯度量级不稳定。鱼书代码里normalizeTrue参数就是做这个事情的注意别漏。Softmax和交叉熵的数值稳定性没处理好。如果y里有0log(0)会得到负无穷整个loss全崩。鱼书用加delta的方式解决实际框架里会用log_softmax这种更稳定的数学等价格式。4.2 从零复现时值得养成的几个习惯第一个习惯是写代码前先想清楚变量形状。每定义一个矩阵或张量都随手标注一下形状。比如X (batch_size, 784)经过第一层后变成(batch_size, 50)再经过第二层变成(batch_size, 10)。形状不匹配是最常见的bug提前标注能省一半调试时间。第二个习惯是善用极小规模实验。比如只用100条数据、隐藏层设成2个神经元观察能否过拟合。如果在小规模数据上代码都跑不通那问题一定在代码逻辑而不是数据量。第三个习惯是打开断点调试。Python的pdb或IDE自带的调试器在forward和backward里打上断点亲眼看看梯度是怎么回传的。这一步对理解ch05特别重要比看十篇博客都管用。第四个习惯是遇到书里代码和你的运行结果不一致时优先检查NumPy版本差异。鱼书代码用的是np.dot做矩阵乘法注意和np.multiply逐元素乘严格区分。这是个特别容易眼花的点我当年就因为这个少算了一维导致loss不降。4.3 从“会跑”到“懂原理”的进阶思路很多读者跑完书里的代码成就感满满但一个月后回想起来只记得“我跑过能出结果”原理全忘了。我推荐一个进阶做法把每章代码的核心函数改成你自己的版本扔掉官方文件重新实现一遍。比如不看two_layer_net.py自己写一个MyTwoLayerNet类包含predict和loss方法。然后不看layers.py自己实现一个Affine层类。最后用数值微分验证反向传播的梯度和自己手推的梯度一致。这个过程走完你对反向传播的理解就是真正的理解而不是“看懂了别人代码的理解”。另外一个思路是读图扩展把ch07的CNN换成不同的卷积核尺寸观察output shape的变化把ch06的不同优化器在同一个损失曲面上可视化看SGD、Momentum、Adam的路径差异。这些都是鱼书代码之外的“小实验”价值极高。5. 从鱼书到真实项目现代深度学习框架映射5.1 用鱼书思路看懂PyTorch代码很多人学完鱼书发现PyTorch的代码完全另一个风格感到脱节。其实鱼书的代码非常接近PyTorch的底层设计理念——在PyTorch里nn.Linear就是鱼书的Affine层nn.ReLU就是鱼书的Relu层nn.CrossEntropyLoss对应鱼书的SoftmaxWithLoss。你在鱼书里手写的每一个层都在PyTorch里有对应的模块。所以学完鱼书再学PyTorch相当于你已经会手写积木了现在只是换了一箱更高级的乐高套装而已。建议先自己把鱼书的两层网络改成PyTorch版本结构对比着看这样过渡非常平滑。5.2 深度学习常用视觉库和扩展方向鱼书这个阶段基本只用了NumPy和Matplotlib但你在真实项目中一定会遇到几个更常用的库OpenCV用于图像读取和预处理Pillow处理简单图像操作scikit-learn用于数据集切分和评价指标以及后面的PyTorch、TensorFlow这类深度学习框架。关于视觉检测方向的扩展鱼书ch07的CNN和deep_convnet.py已经帮你把卷积、池化、卷积、全连接这套基础盘得很清楚了。后续如果你想往目标检测方向走就可以理解YOLO、Faster R-CNN这些结构都包含了CNN的骨架阅读其代码时的阻力会小很多。对于环境配置建议在学习完鱼书之后顺手把PyTorch的CPU版也装上跑一个简单的CNN分类MNIST和鱼书的纯NumPy实现做对比。然后你去查“深度学习环境配置”相关的资料就都有了抓手。6. 写在最后我的几个真实体会鱼书这套代码我前前后后摸了很多遍最大的感受是它不是一套简单的示例代码而是一份可以反复消化、每次都有新收获的教材。第一次照着抄还吃力第二次能独立复现第三次再看会惊讶于“原来这里的设计是为了这个”。几点建议刚开始跑不通代码不要焦虑几乎所有人都会在一个小报错上卡很久这不是你不行是这套代码信息密度真的高。一定要改代码不要只是复制粘贴。哪怕是把隐藏层从50改成100这种小改动运行之后对比结果差异都会比纯看代码收获大得多。多利用GitHub的issue区。鱼书仓库至今还有人在提交issue很多问题你遇到的别人早就遇到过了。搜索关键词通常能直接找到答案这个习惯对往后自学非常有帮助。最后分享一个小技巧你在学完鱼书后可以试着把权重的初始值换成交叉验证选择或者把输入数据加一点噪声看看鲁棒性会有什么变化。这种“留出好奇心”的玩法会把知识真正变成自己的。祝您学习顺利。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。