简介吴恩达深度学习课程的课后作业答案与总结整理成压缩包。面向深度学习初学者以及正在系统学习该课程的学生内容覆盖神经网络基础、深层网络优化、卷积神经网络、序列模型与结构化机器学习项目等核心模块。包内共七十个文件以五十五个ipynb笔记文件为主体逐题呈现解答过程与要点总结另有七个py脚本用于复现训练与推理六个png图片辅助理解网络结构和结果两个htm页面便于索引浏览整体大小三十二点八二MB目录按课程周次清晰分层。这份材料不仅提供作业正确代码还结合实例提炼前向传播、反向传播、梯度下降、正则化、注意力机制等关键知识点并针对CNN、RNN、LSTM等模型给出实现与调参思路帮助读者将理论真正落地。已有千余人下载学习适合课后自查、面试复习与项目参考。1. 这套深度学习公开课的课后作业值得逐题精做吗如果你搜过深度学习 课后作业 答案大概率见过这样的资源一个压缩包里按周数排好的 Notebook代码几乎填完运行一遍直接出图。很多人的第一反应是下载、跑通、截几张 loss 曲线然后存进已学完文件夹。但真实情况是过两周让你自己从零手写一个前向传播或者调一下初始化方式看效果脑子里还是一团浆糊。问题不在资源本身而在使用方式答案应该是用来对照和复盘的标准件不是用来替代思考的成品。这套深度学习公开课的课后作业最珍贵的地方在于它是半成品实验不是成品项目。它把网络结构、损失函数、梯度传播拆成了一个个需要你亲手补全的空洞填完的过程才是真正的学习过程。我见过不少同学用一周刷完所有答案也见过有人用一个月慢慢磨完五个作业半年后前者的代码能力几乎原地踏步后者已经能用同样的套路去迁移到自己的数据集上。这篇文章想聊的并不是哪里有完整答案而是拿到这类资源后怎么把抄答案变成练手把别人整理好的总结变成自己的技术资产。2. 先别急着找答案这套课后作业到底在训练什么能力2.1 作业的三层递进手推、手写、手调这套课程作业的设计思路和市面上很多直接给完整工程的教程完全不同。第一个作业通常要求你手动实现线性回归或逻辑回归正向传播、反向传播、梯度更新全部用最基础的 NumPy 完成不允许直接调用现成深度学习框架。到了第二个作业才开始用框架搭多层感知机但关键的前向和反向代码段依然是空白的。再往后是卷积网络、循环网络、人脸识别、神经风格迁移每一周都会引入一个新的任务类型但核心逻辑依旧要你亲手补全。这种递进关系值得认真对待因为它的目的是把你从调包侠变成理解者。手推公式解决的是数学直觉问题你至少要知道 softmax 之后为什么是交叉熵而不是什么函数都敢往 loss 里塞手写 NumPy 代码解决的是实现细节问题你会真正看到形状不匹配、维度广播、初始化为零这些坑长什么样框架调用解决的是工程效率问题你才会理解为什么别人说批量归一化能加速训练。删掉那段已经写好的 forward 函数自己重新补一遍比刷十遍课程视频都管用。我一般会建议同学做两层工作第一层把官方给的 skeleton 代码当成考试题目先不看答案独立完成第二层完成后再去找一份高质量参考实现做逐行差异对比。这里的高质量不是指能跑通就行而是指注释清晰、没有删掉关键检查步骤的版本。跑通只是及格线能说清楚每一行为什么那样写才算真正吸收了这份作业的价值。2.2 什么是有效的答案差异对照比全文粘贴重要得多很多人拿到答案后习惯从头到尾看一遍看得懂就觉得自己会了这是典型的眼睛会了手不会。有效使用答案的方式是把答案当裁判而不是当课本。你把作业自己写完之后运行报错或者结果达不到预期这时打开别人的实现只做差异分析。差异越具体收获越大。比如你的准确率只有 82%参考实现是 91%你要找的不是复制对方的网络定义而是比较激活函数、初始化方式、学习率调度这些细节。这里有一个非常实用的技巧不要复制答案文件而是把两份 Notebook 放在同一个仓库的不同目录下用版本对比工具从函数级别去看差异。我自己常用的做法是保留自己失败的版本和后来修复的版本这样每次翻车都有记录。常见做法是在装好代码托管仓库环境下执行 diff 命令输出每一处改动再针对每个改动回答三个问题为什么要改、改成这样数学上有什么好处、有没有副作用。这种复盘效率远高于对着别人代码抄一遍。有效答案的一个重要特征是可验证性。如果一个答案运行后 loss 曲线有明显震荡或者 final test accuracy 远低于正常范围那它不叫答案叫反面教材。判断一份答案是否靠谱先看它的关键指标是否与课程评分标准吻合再看代码里有没有嵌入检查步骤。课程作业通常会附带一些 sanity check比如梯度检查、形状检查、损失下降检查这些检查被保留的答案通常质量更高因为作者自己真的是跑完才发出来的。那些把检查代码都删掉、只留最终模型的答案往往只是为了截图好看反而丢了最重要的学习要素。2.3 一份合格总结的四个要素网上搜到的答案与总结资源很多但大部分总结其实是代码注释集锦不是真正的总结。我认为一份能打的技术总结至少要包含四个要素缺了任何一块到复现时都会卡住。第一是公式与代码的对应关系。只贴代码、不写公式你理解不了反向传播里那个链式法则为什么和代码里的循环一一对应。第二是损失和指标曲线的解读。至少要写出训练收敛到什么量级、验证集表现、有没有发生过拟合或欠拟合。第三是参数的关键取值列表。包括学习率、优化器参数、批大小、迭代轮数这些是复现实验的最低信息量。第四是踩坑记录。比如数据预处理里有个归一化顺序错了会导致训练发散这种记录比任何理论分析都更有迁移价值。有了这四要素总结才算从操作手册升级为技术文档。你下次遇到类似问题时查自己的总结比重新翻整套课程视频快得多。所以我常和身边的朋友说刷这套作业的正确顺序是独立完成、对照差异、补实验、写总结。这四步走下来你对深度学习的理解深度会明显超出只刷视频的人。3. 把作业与总结做成可复现工程环境、目录与自动化导出3.1 为每一课建一个干净的独立环境课程作业涉及不同时期的依赖库如果全装在一个环境里很容易出现第几章的包版本互相打架的情况。网络上的常规做法是使用 conda 创建按章节隔离的虚拟环境而不是直接在全局 Python 环境里 pip install。这样做的好处是环境可携带、可复现、挂掉了随时重建不会因为某一个包升级把之前跑通的实验弄崩。# 为第1周作业创建环境Python版本锁定到课程常见的稳定版本 conda create -n dl_week1 python3.7 -y # 激活环境后安装核心依赖numpy/scikit-learn装固定版本避免未来接口变动 conda activate dl_week1 pip install numpy1.18.5 scikit-learn0.22.2 matplotlib3.2.1 ipykernel5.3.0 # 把环境注册为Jupyter内核切换Notebook内核时才能选对Python环境 python -m ipykernel install --user --name dl_week1 --display-name DL Week1这段命令里python3.7的锁定是刻意的。很多旧版作业代码对高版本 NumPy 的随机数 API 或数据类型推断不兼容比如 NumPy 1.19 之后对浮点类型转换的警告变严格可能导致某些损失函数数值溢出。--user参数只对当前用户注册内核不会污染系统级配置重装环境时也不容易残留旧配置。Notebook 首次运行时记得点右上角内核菜单选择刚注册的DL Week1否则命令行创建环境就白做了。这种按章节建环境的模式前期会花一些时间但后续收益非常明显。它相当于给每个实验拍了快照哪一周的依赖出了问题就单独重建哪一周的环境完全不需要从零开始折腾全局环境。如果你的磁盘空间紧张官方有--clone和--copy这类子命令可以联动也可以用一个requirements.txt批量重建多个章节环境只要在文件里按周切分注释块即可。3.2 作业目录组织与命名规范可检索、可回溯刷作业最忌讳的是把文件都放在downloads或桌面下文件名还叫final_final_v3。推荐按课程结构组织目录像管理一个真实项目一样管理作业代码。下面这张表是我个人常用的目录规范适合绝大多数按课程章节推进的学习场景路径存放内容说明exercises/01_week1/01_my自己独立完成的原始版本保留首次实现不修改exercises/01_week1/02_ref参考实现及来源说明用于差异对比exercises/01_week1/03_notes对比后的复盘笔记补充公式和踩坑记录exercises/01_week1/data/weights训练好的权重文件避免重复训练envs/week1_requirements.txt该周环境依赖清单重建环境用这个结构解决了一个核心问题每个版本都有明确归宿不会覆盖自己之前的失败记录。写复盘笔记时如果发现一个很奇怪的现象比如加入正则化后验证集指标不升反降就把当时的现象、猜测、验证结果写进03_notes。这类记录比最终正确代码更有价值因为它是你独立思考和排查的过程。命名规范上我习惯用数字前缀比如01_data_load.py、02_model.py、03_train.py保证按字典序排序时执行顺序就是阅读顺序。Notebook 本身则保留课程原始命名比如week1_assignment.ipynb这样在不同章节间对比代码时文件命名保持一致。代码托管方面我通常会在一个本地 Git 仓库里维护这个目录每次实验成功或修复一个 bug 就提交一次。这样如果某天把某个文件改坏可以回退到上一个可用版本不用靠手动备份文件。3.3 Notebook 自动导出为 Markdown 与 PDF课程作业本身的载体是 Notebook但很多总结场景下Markdown 更利于检索和做笔记PDF 更适合归档分享。手动一个个导出很繁琐可以用命令行批量完成# 批量导出当前目录所有ipynb为Markdown保留输出结果 jupyter nbconvert --to markdown *.ipynb --output-dir ./export_md # 导出PDF需要额外依赖Missing字体时先装好TeX不加--execute则保留现有输出 jupyter nbconvert --to pdf *.ipynb --output-dir ./export_pdf这两条命令里--to markdown会把代码块、Markdown 说明、输出结果拆分开生成同名.md文件和一个文件夹文件夹内存放图片--to pdf走的是 LaTeX 路线所以机器上没有 TeX 发行版时会直接报错。如果你不想为了导出 PDF 专门安装大型 TeX 包更轻量的替代方案是导出为 HTML 后再通过浏览器打印为 PDF。这个导出流程适合当作收尾动作每次完成一个作业就把 Notebook 快照导出、提交到仓库养成习惯后你的知识库是按周自动增长的。3.4 用命令行批量跑作业并记录指标作业刷到最后你可能会想要一个统一的实验记录而不是每次运行完看一眼输出就关掉。可以利用 shell 重定向和 Python 的日志模块把每次训练的关键指标汇总到一个 CSV 里。这种方式能让你在刷完五个作业后横向对比不同章节模型的行为差异。# train_summary.py批量跑作业并记录关键指标 import json, csv, time from pathlib import Path results [] for nb_path in Path(exercises).glob(*/train.py): start time.time() acc run_training(nb_path) # 此处为示意实际需要引入训练入口 results.append({ task: nb_path.parent.name, acc: acc, cost_sec: round(time.time() - start, 2), }) with open(summary.csv, w, newline) as f: writer csv.DictWriter(f, fieldnamesresults[0].keys()) writer.writeheader() writer.writerows(results)上面这段代码是一个结构示例核心思想是把训练入口统一封装让所有作业共用同一个输出格式。实际使用时要根据自己的训练脚本改写run_training内部逻辑目标是每个章节的作业都产出一条包含任务名、精度、耗时的记录。这样你积累的不再是散落的 Notebook而是一张可检索的实验表格。这个习惯对后续做项目帮助很大因为真实工程中的实验管理基本也是这个套路只是工具换得更复杂一点。4. 避坑刷这套作业最常翻车的五个细节4.1 梯度检查不通过问题不在代码在阈值理解现象参考实现里跑得好好的梯度检查自己动手实现后一测就报错或者返回的误差在0.01量级怎么看都不对。原因梯度检查的原理是数值法解梯度和解析法梯度的差异比对通常要求一范数误差小于1e-7。但很多人会忽略两点——一是输入数据没有归一化数值梯度计算时步长太大导致误差偏大二是网络中存在 ReLU 这种分段线性激活函数时如果在拐点附近采样数值法与解析法天然会出现偏差不是代码算错了。解决先检查网络输入是不是已经做了标准化尤其是作业里经常把像素值直接除以 255这一步不能省。再把梯度检查模式设置为只在少数随机参数上做检查而不是对全网络做避免某些无关参数干扰观察。如果误差在1e-5量级但训练还是收敛得不错可以先记录现象再继续推进但要在总结里写明梯度检查未完全通过可能来自 ReLU 拐点。4.2 数据集路径写死导致换环境就崩现象作业代码在自己电脑跑过一次后隔两周打开就报错FileNotFoundError或者换到另外一台机器上直接眼前一黑。原因很多示例实现里会写data_path ./datasets/train_catvnoncat.h5这种相对路径但你的实际运行目录和写代码时的目录不是同一个一旦移动位置路径全部失效。这个问题在课程作业里特别常见因为数据文件往往很大大家喜欢只拷贝代码不拷贝数据结果路径自然对不上。解决在所有需要读取文件的地方统一改成基于当前文件目录来定位的绝对路径写法# 用pathlib基于当前文件位置定位避免运行时目录不同导致找不到数据 from pathlib import Path PROJECT_ROOT Path(__file__).resolve().parents[1] data_path PROJECT_ROOT / data / train_catvnoncat.h5Path(__file__).resolve()拿到的路径不受启动目录影响parents[1]可以往上跳两级到你的项目根目录。这样只要整个作业目录结构完整在任何机器上都能直接运行。换机器时还要确认数据文件确实存在可以在代码开头加一个if not data_path.exists(): raise FileNotFoundError早失败比运行到一半再报错容易排查得多。4.3 不同章节依赖版本冲突现象刷完第 1 周作业后安装第 2 周需要的新包某天打开旧 Notebook发现之前运行正常的结果再重新执行就报错比如 NumPy 函数参数变化或 PyTorch 接口改名。原因全局环境被升级了旧代码依赖的旧接口行为发生改变。这类事故不是课程内容难而是环境管理没跟上我见过最夸张的情况是有人为了装一个新版本框架把整个 Python 从 3.7 升到 3.9结果之前所有作业全跑不动。解决严格按照 3.1 节的做法按章节隔离环境。如果你已经在一个环境里装了所有作业的依赖那么补救办法是记录每个包版本并重新创建环境# 导出当前环境所有依赖版本清单用于后续重建 conda list --export requirements_export.txt # 按章节新建环境并安装指定版本依赖 conda create -n dl_week2 python3.7 -y conda install --name dl_week2 --file requirements_export.txt上面第一行的导出会记录精确版本号比手写 requirements.txt 更可靠。重建后一定要检查内核是否指向新环境这是很多人重建完仍旧踩坑的原因——Notebook 左上角内核还是旧环境。遇到这类问题我的习惯是把环境信息写进该周总结的开头标明本周使用 Python 3.7 NumPy 1.18.5下次环境崩了直接照抄命令重建。4.4 照抄参考实现跑通就以为学会了现象参考实现拿来直接运行几分钟出结果准确率还很高顿时很有成就感。但过两天让你不看资料写一个类似的数据加载函数只能写出个大概细节漏洞很多。原因人脑对看一遍别人写好的代码的记忆深度远低于从零写到跑通。把别人的代码复制过来运行本质上只是验证了对方代码可用你自己并没有从中建立任何条件反射。解决强制要求自己写第一遍时完全不看参考代码遇到卡住可以先看原理部分再看别人的一句话提示例如注意数组形状是 (m, n) 不是 (n, m)最后完成后再看完整参考实现做差异对比。如果你发现自己第一遍写得支离破碎那说明这个知识点还没有真正掌握这个信号是有价值的。相反如果你能独立写出一个跑通的版本哪怕准确率低一点再对照参考实现看差在哪往往能记住很长时间。4.5 总结写了但公式与代码对不上现象总结里公式写得头头是道但代码里变量的实现顺序和公式不一致比如公式里的乘法是矩阵乘代码里却用的是逐元素乘结果还能跑只是指标莫名其妙低一截。原因写总结时只复述了课程讲义里的理论公式没有对照自己实际写的代码去校验让总结变成了抄讲义而不是总结实验。这种总结最大的危害是会误导未来的自己你下次按总结复现时会陷入明显的矛盾。解决每写一个公式在旁边标注代码里的对应函数名和关键变量名比如公式 3 对应linear_forward里的Z np.dot(W, A_prev) b。做梯度检查时顺手把数值梯度与解析梯度的差异值记录下来不要只写通过。这一步也算是最廉价的验证手段——如果公式里的每个变量都能在代码里找到真实载体并且维度对得上那总结和实现就是一致的。如果对不上说明要么总结写错要么代码写歪了都需要当场修正。5. 把课后作业变成自己的复现资产我现在的固定收尾动作到了这个阶段你手上已经积累了不少作业代码和笔记但它们还处于散装状态需要做一次统一的封装。我会给每个作业的模型类接一个通用接口比如train()、evaluate()、predict()并在每个类的 docstring 里写明输入输出形状和关键参数。这样一来每个作业本质上都是一行可以反复调用的模块未来迁移到自己的模拟项目里时可以直接复用而不需要重新读一遍 Notebook。我还习惯在每周作业完全结束前做一个最小复现测试只保留核心代码和最小数据集从零跑一遍检查有没有隐藏的路径依赖、环境依赖或顺序依赖。这个测试的通过标准是在干净环境里只运行一个入口命令能在一分钟内看到一条合理下降的 loss 曲线。这个习惯曾经在一次闲聊面试中救过我被问到你是真的做过反向传播还是只调过框架时我当场在白板上画出了代码和公式的对应关系并用具体参数说明曲线为什么那样收敛对方很快就放弃了追问。至于总结我现在的做法不是写一大篇读后感而是把每一个作业的变量、超参数、异常现象整理成一个可检索的条目。比如NaN loss、准确率卡在 70%、训练集 loss 下降但验证集不下降每个条目都关联到具体代码行和解法。这些内容在之后做自己的小实验时价值极高因为你会发现真实业务里遇到的 80% 问题都和作业里的某些现象同源。这套流程走完后你面对的不再是一堆别人的代码而是一个属于你自己的、有标记、有验证、可复现的深度学习实验库。希望帮到你。本文还有配套的精品资源点击获取