01 / 本课学习路线
本课学习路线
汇总与分类 25 分钟 · 订正案例 25 分钟 · 修复与独立重写 75 分钟 · 收尾与进阶 30 分钟
02 / 订正流程与完成条件
订正不是重做一遍:四个动作,每道错题各走一次
「再做一遍」不是修复。订正的定义是:说清第一次错在哪一类、用一个最小用例复现它、改掉它、证明改对了、再不看旧代码重写一次。前五个模块的错题订正已经走过五遍,本课把同一套流程用在本模块的数值计算、聚类、训练与评估题上。
| 动作 | 做什么 | 产出 | 对应正文 |
|---|---|---|---|
| ① 分类 | 按第一次出错的原因归到六类之一 | 登记表的「首次错误类型」一栏 | 第 03 节 |
| ② 定位并修复 | 找到导致错误的那几行代码或那条被漏读的规则,改掉 | 登记表的「错误原因」「修复动作」 | 第 03、04 节 |
| ③ 最小验证 | 构造一个只触发该错误的输入,修复前失败、修复后通过 | 登记表的「触发用例」「最小验证」 | 第 04、05 节 |
| ④ 独立重写 | 不看旧代码从空文件重写整题,用复测清单验证后提交 | 登记表的「独立重写」 | 第 06 节 |
完成条件:本课没有新的必做题;下面的「重做任务」是复习题,用于独立重写,不计入完成状态。本课算完成 = 页面下方「学习完成检查」四条全部勾选,其中「未通过的在线题目已独立重写并通过」这一条要等你真的重写并通过后才能勾。暂时订正不了的题:在登记表里写明具体问题,可以先继续学模块 7,但本课保持未完成,解决并独立重写通过后再回来勾选。先用触发原错误的输入检查修改,再验证边界和题面样例;这些检查通过后,再独立重写并提交。
| 来源 | 题号 | 判题结果 | 先猜的错误类型 | 订正状态 |
|---|---|---|---|---|
| 阶段测验第 1 题 | P2471 | 答案错误(WA) / 运行错误(RE) / 未完成 / 通过(AC) | — | 未开始 |
| 阶段测验第 2 题 | P2477 | 同上 | — | 未开始 |
| 阶段测验第 3 题 | P2509 | 同上 | — | 未开始 |
| 第 1~5 课 未通过或看提示才通过的必做题 / 进阶题 | 逐题填 | 填判题结果 | — | 未开始 |
「先猜的错误类型」在第 03 节按判定信号确认后再改;AC 的题只登记曾经改过的具体问题,不进入订正流程。看提示才通过的题按「未通过」处理——提示告诉你的那一步,就是要独立重写验证的那一步。
03 / 六类错误的判定与定位
判定信号、定位步骤、修复动作、最小用例怎么构造(本模块版)
分类不靠感觉,靠信号:先看判题结果是哪一种,再用下面的问题逐个排除。本模块的题多了「数值对不对」这一层——取整方式、-0.0000、分母为 0、同步更新——定位工具是各课正文里现成的手动推演:矩阵四格、softmax 三步、K-Means 两轮、梯度下降三轮、四格与三档阈值。程序输出与预期不一致时,把中间量逐步打印出来与推演的值对照,第一处分歧点就是错误所在。
| 类型 | 判定信号 | 定位步骤 | 修复动作 | 最小用例怎么构造 |
|---|---|---|---|---|
| 读题 | 样例能过、某些用例 WA;对「整数部分」「字典序最小」「并列取小编号」「分母为 0 按 0」的理解与题目页不一致 | 重新写题目要求清单:取整方式、并列规则、特殊值规则;逐条对照代码 | 按那一条改一处 | 构造恰好落在规则上的输入(案例 A:diff 恰好等于 30) |
| 建模 | 所有用例都错或大面积错;说不清距离怎么定义、一轮的两个动作、fit 只读谁 | 写出方法一句话,用课里的推演检验(第 3 课 的六点两轮、第 4 课 的前三轮、第 5 课 的三档阈值) | 换距离定义 / 先全部分配再更新 / fit 只用训练集 | 取课里现成的推演(案例 B:查询 20 落在训练集范围 [0, 10] 之外) |
| 边界 | 只有特定输入错:n = 1、常数列、空簇、t = 0、下标越界 | 列出四类边界输入逐个手算 | 补上判断(常数列归 0、空簇沿用、t = 0 直接输出、下标先判范围) | 就是那个边界输入本身(案例 C:三个中心只有一个分到样本) |
| 复杂度 | 超时(TLE),且不是读入问题 | 估算最坏次数:每轮重算最小值最大值、对每个阈值重数四格、AI024 每轮对每个点重扫全部已选中心 | 训练集只归一化一次 / 排序后一次扫描 / 增量更新 | 构造最大规模输入计时 |
| 语言 | 运行错误(RE)或结果对不上却找不到逻辑错 | 写 3 行小实验:int(-3.6)、f"{-0.0004:.2f}"、负下标、round(0.5) | 换成明确的写法 | 触发该语言行为的最短输入 |
| 输出格式 | 答案错误(WA)或格式错误(PE),数字都对 | 把自己的输出与期望输出逐字节对比 | 改位数、-0.0000、分隔符、大小写 | 题面示例 |
数值定位三步(示例)
现象:AI002 输出对不上,题面示例 2 1 2 1 / 0.1 / 0 1 / 10 3 / 0 / 10 得到 0.2000 / 0.3500,期望 0.4000 / 0.7000 检查:逐轮打印梯度和权重,与第 4 课 第 04 节前三轮表对照 → 第 1 轮就对不上:正确 b=0.4、w=0.3,实际 b=0.2、w=0.15,正好差一半 定位:梯度公式里少了 2/n 的 2(写成了 1/n) 修正:把系数改回 2/n,复测题面示例得 0.4000 / 0.7000;提交前删除调试输出(额外输出会使结果不符合题目要求)
登记时的一条硬要求:「错误原因」必须具体到能据此直接改代码——「粗心」「没注意」不符合要求,「空簇的新中心写成了零向量,第 2 轮起靠近原点的样本被这个假中心抢走」符合。写不出具体原因,说明还没定位到,回到定位步骤。
04 / 三个完整订正案例
失败用例 → 定位 → 修改前后对照 → 复测
三个案例都来自本模块第 1、4、3 课 必做题里真实会出现的错误,每个都走完整流程;你的错题按同样的格式处理。
案例 A · 读题类:P2475 中间段的端点写成了 30 < diff
判题结果: 答案错误(WA);题面示例能过(diff = 190,落在第一段) 失败用例: 10 10 10 / 10 40 10 / 10 10 10 期望 10 10 10 / 10 13 10 / 10 10 10 实际 10 10 10 / 10 40 10 / 10 10 10 定位: 重写题目要求清单 → 「30 ≤ diff ≤ 50 用 9 个的整体均值」,端点 30 属于中间段;代码写成 30 < diff,diff 恰好等于 30 时掉进「不变」 修复: 中间段条件改成 30 <= diff <= 50(见下方前后对照) 复测: 上面的用例 → 中心 13 ✓ 10 10 10 / 10 39 10 / 10 10 10 → 中心 39 ✓(diff = 29,不变) 题面示例 10 10 10 / 10 200 10 / 10 10 10 → 中心 10 ✓
案例 A 修改前(片段)
Python# P2475:中间段的左端点写成了「大于」——题面是 30 ≤ diff ≤ 50,端点 30 属于中间段
if diff > 50:
mat[1][1] = floor(around + 0.5)
elif 30 < diff <= 50: # diff 恰好等于 30 时掉进「不变」
mat[1][1] = floor((total + mat[1][1]) / 9 + 0.5)案例 A 修改后(片段)
Python# P2475:端点按题面收进中间段
if diff > 50:
mat[1][1] = floor(around + 0.5) # 四舍五入:加 0.5 向下取整,不用 round()
elif 30 <= diff <= 50:
mat[1][1] = floor((total + mat[1][1]) / 9 + 0.5) # 9 个元素的整体均值只改了一处;完整程序在第 1 课 第 08 节展开区,三段规则的逐例表在第 1 课 第 07 节。修改前后各跑一次三个复测用例,修改前第一个用例失败、修改后全部通过——这才是「修复生效」。
案例 B · 建模类:AI002 的 fit 把查询也算了进去
判题结果: 答案错误(WA);题面示例能过(两个查询 0、10 都落在训练集范围内) 失败用例: 2 1 2 2 / 0.1 / 0 0 / 10 10 / 20 / -10 期望 5.3000 / -0.1000 实际 2.9296 / 1.7333 定位: 用第 4 课 第 05 节的题面示例逐步表检验:fit 只读训练集,每列最小值、最大值应是 0、10;代码把查询也放进去,算成 −10、20,跨度为 30,训练样本被归一化到 0.33、0.67,后面每一轮都跟着错 修复: 最小值、最大值只在训练集上算,查询只经过 transform(见下方前后对照) 复测: 上面的用例 → 5.3000 / -0.1000 ✓ 2 1 1 2 / 0.1 / 0 0 / 10 10 / 5 → 2.6000 ✓(查询在范围内,两种写法结果相同) 题面示例 2 1 2 1 / 0.1 / 0 1 / 10 3 / 0 / 10 → 0.4000 / 0.7000 ✓
案例 B 修改前(片段)
Python# AI002:fit 把查询也算了进去——训练集的归一化尺度被查询改变
mins = [min(row[j] for row in xs + queries) for j in range(d)]
maxs = [max(row[j] for row in xs + queries) for j in range(d)]案例 B 修改后(片段)
Python# AI002:fit 只用训练集算每列最小值与最大值;查询只经过 transform,超出范围不截断
mins = [min(row[j] for row in xs) for j in range(d)]
maxs = [max(row[j] for row in xs) for j in range(d)]建模类错误的定位工具是课里现成的推演:题面示例逐步表的第一行就是「每列最小值、最大值」,一对就知道 fit 读了谁。完整程序在第 4 课 第 08 节展开区。
案例 C · 边界类:AI001 空簇的新中心写成了零向量
判题结果: 答案错误(WA);每轮每个簇都分到样本的用例能过 失败用例: 4 2 3 4 / 0 0 / 100 100 / -100 -100 / 0 0 / 1 1 / 0 1 / 1 0 期望 0.50 0.50 / 100.00 100.00 / -100.00 -100.00 实际 0.67 0.67 / 0.00 0.00 / 0.00 0.00 定位: 四个样本第 1 轮全部分给中心 1,中心 2、3 是空簇;题面规定空簇沿用旧中心,代码把它们写成 (0,0)——第 2 轮起样本 (0,0) 被这个假中心抢走,中心 1 只剩三个点,均值变成 0.67 修复: 空簇一律 new_centers.append(centers[c])(见下方前后对照) 复测: 上面的用例 → 0.50 0.50 / 100.00 100.00 / -100.00 -100.00 ✓ 题面示例 4 2 2 2 / 0 0 / 8 8 / 1 1 / 2 2 / 8 9 / 9 8 → 1.50 1.50 / 8.50 8.50 ✓ 2 2 2 0 / 0 0 / 5 5 / 1 1 / 4 4 → 0.00 0.00 / 5.00 5.00 ✓(t = 0 直接输出初始中心)
案例 C 修改前(片段)
Python# AI001:空簇的新中心写成了零向量
for c in range(k): # ② 再统一更新
g = groups[c]
if not g:
new_centers.append([0.0] * d) # 空簇:写成零向量——第 2 轮起它会抢走靠近原点的样本
else:
new_centers.append([sum(p[j] for p in g) / len(g) for j in range(d)])案例 C 修改后(片段)
Python# AI001:空簇沿用旧中心(题面规则)
for c in range(k): # ② 再统一更新
g = groups[c]
if not g:
new_centers.append(centers[c]) # 空簇:沿用旧中心
else:
new_centers.append([sum(p[j] for p in g) / len(g) for j in range(d)])边界类错误的最小用例就是那个边界输入本身:三个中心、四个样本挤在一个中心旁边就够。完整程序在第 3 课 第 07 节展开区,空簇规则见第 3 课 第 05 节的补充材料。
05 / 错题登记与最小验证
登记模板、填好的示例、最小用例的三个要求
登记表是订正的账本:每道错题一条,订正完把「独立重写」一栏改成「通过」。下面先给空模板,再给案例 C 填好的样子。
错题登记模板(每题一条)
Python# 错题登记(每题一条;订正完把「独立重写」改成「通过」)
# 题号:
# 来源: 阶段测验第_题 / 课_ 必做 / 课_ 进阶
# 判题结果: WA / RE / TLE / PE
# 首次错误类型: 读题 / 建模 / 边界 / 复杂度 / 语言 / 输出格式
# 触发用例: 输入=____ 期望=____ 实际=____
# 错误原因: (具体到能据此直接改代码)
# 修复动作:
# 最小验证: (至少三条:触发错误的、边界另一侧的、题面示例)
# 独立重写: 未做 / 通过 / 再错(类型=__)复制进你的错题本,每订正一项填一条;如果暂时无法准确描述错误原因,请结合失败用例和代码位置进一步检查,再回到六类错误原因重新分类。
填好的示例(案例 C)
Python# 题号: AI001
# 来源: 第 3 课 必做
# 判题结果: WA
# 首次错误类型: 边界
# 触发用例: 输入=4 2 3 4 / 0 0 / 100 100 / -100 -100 / 0 0 / 1 1 / 0 1 / 1 0 期望=0.50 0.50 / 100.00 100.00 / -100.00 -100.00 实际=0.67 0.67 / 0.00 0.00 / 0.00 0.00
# 错误原因: 第 1 轮中心 2、3 没分到样本,空簇的新中心写成了零向量;第 2 轮起样本 (0,0) 被 (0,0) 这个假中心抢走,
# 中心 1 只剩三个点,均值变成 0.67
# 修复动作: 空簇一律沿用旧中心:new_centers.append(centers[c])
# 最小验证: 上面的输入 → 0.50 0.50 / 100.00 100.00 / -100.00 -100.00 ✓ 4 2 2 2 / 0 0 / 8 8 / 1 1 / 2 2 / 8 9 / 9 8 → 1.50 1.50 / 8.50 8.50 ✓(题面示例,没有空簇) 2 2 2 0 / 0 0 / 5 5 / 1 1 / 4 4 → 0.00 0.00 / 5.00 5.00 ✓(t = 0 直接输出初始中心)
# 独立重写: 通过「触发用例」写明期望与实际;「错误原因」写到能直接改代码;「最小验证」至少三条:触发错误的、边界另一侧的、题面示例。
| 要求 | 含义 | 反例 |
|---|---|---|
| 只触发这一类错误 | 修复前失败、修复后通过,且不涉及其它规则 | 拿 500 条训练样本验证「常数列归 0」 |
| 尽量短 | 手算能在 1 分钟内得到期望输出 | 用 2000 条样本验证「空簇沿用旧中心」 |
| 带期望输出 | 登记时写清期望与实际 | 只写「输入 10 10 10 / 10 40 10 / 10 10 10」不写期望 |
每订正一项做一次最小验证:不要直接重交原题,先跑最小用例确认修复真的生效,再独立重写整题。本模块每课的错误做法表都是现成的最小用例来源。
06 / 独立重写与复测清单
不看旧代码从空文件重写,用清单验证后再提交
独立重写检验的是「离开旧代码还能不能写对」。重写前只允许看题目页和自己的方法一句话注释,不看旧代码、不看参考程序。
| 题目 | 题面示例 | 边界用例 | 错误专项用例 |
|---|---|---|---|
| AI001 多维样本聚类器 | 4 2 2 2 / 0 0 / 8 8 / 1 1 / 2 2 / 8 9 / 9 8 → 1.50 1.50 / 8.50 8.50 | 3 2 2 0 / … → 直接输出初始中心;4 1 1 3 / 100 / -5 -2 4 9 → 1.50 | 5 2 3 2 / 0 0 / 0 0 / 10 10 / 0 0 / 1 1 / -1 -1 / 9 9 / 11 11 → 0.00 0.00 / 0.00 0.00 / 10.00 10.00(边分配边更新会得 0.50 0.50 / -1.00 -1.00 / …) |
| AI005 分类阈值优化器 | 0.9 1 / 0.8 0 / 0.7 1 / 0.4 0 → 0.7000 0.800000 | 3 / 0.9 0 / 0.1 0 / -0.2 0 → 0.9000 0.000000 | 3 / 0.8 1 / 0.8 0 / 0.2 0 → 0.8000 0.666667(同分逐条结算会得 1.000000) |
| P2471 新学校选址 | 题面示例(题目页给出输入与输出) | 1 / 20(只有一户);2 / 0 20(偶数户) | 3 / 0 1 100(三户分布不均)——期望输出以交卷后的测验解析为准 |
| P2477 最佳信号覆盖 | 题面示例(题目页给出输入与输出) | 1 1 / 1 1 9(单个 AP) | 2 1 / 1 1 5 / 3 1 5(两个 AP 信号强度相同)——期望输出以交卷后的测验解析为准 |
| P2509 不等式组 | 题面示例(题目页给出输入与输出) | 差全为小数的一组 | …;2,3,7,0,0;12.5,1,7;<=,>=,=(差有正有负)——期望输出以交卷后的测验解析为准 |
清单里给出的输出与各课正文的推演一致;阶段测验三题的期望输出以交卷后的测验解析为准。重写后先跑清单再提交;提交通过后把登记表的「独立重写」改成「通过」。
重写仍未通过怎么办:对比两次失败用例和代码位置——如果是同一个用例失败,说明错误原因没定位准,回到第 03 节重新分类;如果是新的用例失败,登记一条新的错题。两次都不过也不算失败,登记表里写明具体问题,带着它进下一模块——但本课「未通过的在线题目已独立重写并通过」那一条先不勾,解决后再回来勾。
07 / 迁移练习、进阶自测与没有错题的同学做什么
分类练习、找错练习、三套推演复现,以及进阶方向
每题先自己做,再展开答案。
练习 1(分类):下面五个失败描述各属于六类中的哪一类?① AI002 在常数列用例上抛出除以零;② AI011 在 4 1 4 1 / 0 4 / 2 1 / 10 4 / 12 1 / 6 上输出 4(期望 1);③ AI001 n = 2000、t = 20 超时,代码每轮重新读一遍样本列表并转成浮点;④ AI010 输出 0.0900 0.2447 0.6652 后交叉熵一行打印成 0.4076;⑤ AI003 在题面示例 2 上抛出除以零。
展开练习 1 答案
① 边界(常数列归 0 没处理);② 读题(票数并列取类别小的);③ 复杂度(重复转换是实现常数,属于复杂度一类);④ 输出格式(交叉熵要六位小数);⑤ 边界(缺失列权重为 0 要输出 NA)。判定依据:①⑤只有特定输入错且是运行错误;②数字全对只在并列上错;③超时;④数字对、位数不对。
练习 2(找错并写最小用例):一位同学的 AI002 把查询归一化写成「超出 [0,1] 就截到 0 或 1」。写出它的错误类型、一个最小用例(含期望与实际表现)和修复动作。
展开练习 2 答案
类型:读题(题面写明不截断)。最小用例:2 1 2 2 / 0.1 / 0 0 / 10 10 / 20 / -10——正确 5.3000 / -0.1000,截断后 3.5000 / 1.7000。修复:transform 只做 (x − min)/(max − min),不加 min(1, max(0, ·))。复测:题面示例 → 0.4000 / 0.7000 仍通过。
练习 3(三套推演复现):不看资料,各在纸上复现一遍并与正文核对——① 第 3 课 的六点两中心第 1 轮分配表;② 第 4 课 的两样本前三轮参数与损失;③ 第 5 课 的 10 条预测在阈值 0.60 下的四格。
展开练习 3 答案
① 第 3 课 第 05 节第一张表(C1 只分配到 P5);② 第 4 课 第 04 节第二张表(0.300 / 0.400 / 2.8250 起);③ 第 5 课 第 04 节第一张表(TP 4、FP 2、FN 1、TN 3)。复现后与正文对照,差异处就是要再练的点。
练习 4(没有错题的同学):把本模块印象最浅的一道必做题不看旧代码独立重写并用第 06 节的清单复测;然后按兴趣选一个进阶方向起步:数值梯度校验(下面的进阶自测)、反向传播(第 4 课 第 07 节)、随机森林(第 5 课 第 06 节的补充学习)——这部分不计入本课时长,也不是必做,阶段测验与模拟考试不依赖它们。
08 / 复习入口与完成条件
订正完成之后做什么
订正只针对本模块;每类错误对应的课入口如下,订正完成后按顺序进入模块 7。
| 错误类型 | 回到哪里 | 重点看什么 |
|---|---|---|
| 读题(取整方式、并列规则、特殊值) | 浮点精度与稳定 softmax、分类指标、阈值选择与决策树 | 第 2 课 的取整规则、第 5 课 第 05 节的并列表 |
| 建模(距离定义、一轮两个动作、fit 只读训练集) | 特征归一化、KNN 与 K-Means、线性回归与梯度下降 | 第 3 课 第 04、05 节,第 4 课 第 04、05 节 |
| 边界(常数列、空簇、t = 0、下标越界) | 矩阵维度与矩阵乘法、特征归一化、KNN 与 K-Means | 各课错误做法表里的边界行;上一课第 02~04 节的边界例 |
| 复杂度 / 语言(重复归一化、每个阈值重数、截断与四舍五入) | 线性回归与梯度下降、分类指标、阈值选择与决策树 | 第 4 课 第 09 节复杂度表、第 5 课 第 09 节复杂度表 |
| 输出格式(位数、-0.0000、大小写、分隔符) | 浮点精度与稳定 softmax | 格式化函数 fmt 与 -0.0000 的处理 |
完成条件:本课算完成 = 勾选全部学习完成检查,其中「未通过的在线题目已独立重写并通过」要等真的重写通过才能勾;两道重做任务是复习题,不计入完成状态;订正不了的题写明具体问题后可以先继续学,本课保持未完成。错题订正完成后,先把本模块最没把握的必做题独立重写一次;还有余力,再做进阶自测。仍然不加新的必做题——模块 7 的内容在后面。
09 / 练习
按顺序完成本课的任务
5 项自测任务,完成情况由你自己核对
错题登记:每题一条,逐条订正
代码自测自主练习练习重点:上一课「模块 6 · 阶段测验」的三题 + 本模块未通过的题,逐题按六类错误原因登记,写清触发用例与错误原因;预计用时:15 分钟
完成标准:错误原因记录表能直接指出本课要回到哪一课复习
需要时查看提示
分不清「建模」还是「边界」时问自己:思路对了只错在特例,是边界;思路本身不成立,是建模。若无法确定类别,先记录具体出错位置,订正后再重新判断类别。登记模板与填好的示例见第 05 节。
模块 6 知识关系回顾
必做任务 1自主练习练习重点:说明矩阵维度、输出规则、距离与聚类、损失与梯度、评估与阈值之间的关系;预计用时:15 分钟
完成标准:能不看笔记完整讲出本周五个主题的连接关系
需要时查看提示
可按以下关系组织回顾:矩阵表示数据,输出要求是评分标准,距离和梯度是两种「学习」方式,评估指标用于比较结果。若某一关系无法清楚说明,把对应主题加入复习清单。
AI001 多维样本聚类器 · 独立重写
重做任务 1自主练习练习重点:先全部分配再统一更新、并列取小编号、空簇沿用旧中心、两位小数与 -0.00;预计用时:25 分钟
完成标准:从空文件写到通过全部测试,并记录本次用时供后续比较
需要时查看提示
独立重写时遇到困难超过 10 分钟:先暂停编码,把模块 6 · 第 3 课 第 05 节的六点两轮表在纸上重新推演一遍再继续。用第 06 节清单里「边分配边更新」的用例验证;提交入口是模块 6 · 第 3 课 的 AI001 任务卡。
AI005 分类阈值优化器 · 同类强化
重做任务 2自主练习练习重点:同分一起跨过阈值、F1 并列取更大阈值、一次线性扫描;预计用时:20 分钟
完成标准:每个分支都能指出对应的题目规则
需要时查看提示
这是模块 6 · 第 5 课 做过的题,本课重做它,重点不在通过,而在核对每条题目规则都有对应实现。用第 06 节清单里「同分逐条结算」的用例验证;提交入口是模块 6 · 第 5 课 的 AI005 任务卡。
进阶练习:中心差分数值梯度与小网络复核
进阶练习 1进阶练习自主练习练习重点:实现数值梯度函数(numeric_grad),先核对标量例子,再逐参数复核模块 6 · 第 4 课 的 2→2→1 小网络的 9 个解析梯度;预计用时:20 分钟
完成标准:标量与 9 个网络参数的相对误差都小于 1e-6;未激活 ReLU 名下的 3 个梯度与全零初始化的 6 个梯度都为 0
需要时查看提示
中心差分 (f(w+h)−f(w−h))/(2h) 比前向差分精度高一个量级;比较用相对误差,绝对误差在大梯度下会误报。小网络的前向(forward)、损失(loss)、反向(backward)三个函数用你在模块 6 · 第 4 课 写的版本。
自测代码(复制到你的代码文件中运行,检查输出是否一致)
def numeric_grad(f, w, h=1e-5):
# 待完成:中心差分 (f(w+h) - f(w-h)) / (2h)
...
# 1) 标量:f(w) = w²,在 w=3 处解析梯度 2w = 6
assert abs(numeric_grad(lambda w: w * w, 3.0) - 6.0) < 1e-4
# 解析梯度有误时,两者的相对误差会明显偏大——比较用相对误差
def rel_err(a, b):
return abs(a - b) / max(1.0, abs(a), abs(b))
assert rel_err(numeric_grad(lambda w: w * w, 3.0), 6.0) < 1e-6
# 2) 复核模块 6 · 第 4 课 的 2→2→1 小网络:把你写的 forward / loss / backward 粘到上方,再逐参数核对
params = [0.5, 0.25, 0.0, -1.0, 0.25, 0.0, 1.0, -0.5, 0.5]
x, t = (1.0, 2.0), 1.0
grads = backward(params, x, t)
for i in range(9):
def loss_i(v, i=i):
p = params[:]
p[i] = v
return loss(p, x, t)
assert rel_err(numeric_grad(loss_i, params[i]), grads[i]) < 1e-6
# 3) 两个边界:未激活的 ReLU(z2 = -0.5)名下梯度为 0;全零初始化时隐藏层 6 个梯度全为 0
assert grads[3:6] == [0.0, 0.0, 0.0]
assert backward([0.0] * 9, x, t)[:6] == [0.0] * 6自评状态
提交结果说明与处理方法
- WA
答案错误
独立重写仍未通过:对比两次失败用例和代码位置,重新检查错误原因并更新登记表(第 06 节末段);数值题回到对应课的手动推演,逐步对照中间量
- PE
格式错误
输出要求再过一遍:位数、取整、-0.0000、行尾、大小写
- RE
运行错误
语言类错题:写 3 行小实验验证(
int(-3.6)、负下标、除以零);根据错误信息构造相同维度和边界的输入,在本地复现后定位原因- TLE
超时
每轮重算最小值最大值是无意义的重复;对每个阈值重数四格把 O(n) 变成 O(n²);AI024 每轮重扫全部已选中心把 O(k·n·d) 变成 O(k²·n·d)——记成复杂度类错题,改成只归一化一次 / 一次扫描 / 增量更新
- AC
通过
在登记表中将这条错题标记为已完成;所有错题完成修改、通过验证并更新状态后,本课的订正任务完成
10 / 学习完成检查
本课学习完成检查
完成本课需要:没有新的必做题,勾选全部学习完成检查即算完成。登录后,勾选记录会保存到账号,并更新课程总览的完成状态。