01 / 本课学习路线
本课学习路线
阅读与推演约 110 分钟,练习约 70 分钟
02 / 学习目标与先修自测
学完本课你能做什么,以及开始前需要会什么
数值题的评分标准写在题面里:位数、取整规则、容差。本课把它们变成动手前的固定检查步骤,再解决 softmax 的上溢。
| 学完后能做的事 | 正文位置 | 检查方式 |
|---|---|---|
说出本语言默认 round 与「四舍五入」的差别和处理办法 | 第 04 节 | 自查第 2 条、练习 4 |
| 不看参考写出稳定 softmax:先减最大值再取指数 | 第 05 节 | 自查第 3 条、练习 5 |
| 解释为什么中间值不能提前舍入 | 第 07 节 | 自查第 4 条 |
| 输出前检查 -0.0000 并归成 0 | 第 07 节 | 自查第 5 条 |
| 两个自测断言全部通过,P2483 复习重做通过 | 第 08、11 节 | 自查第 1 条 |
先修自测:下面 5 题请先自己写答案,再展开对照。答不出的按括号里的位置补看再回来。本课假定你已完成模块 1 的「输入输出规则、数据范围与精度」。
| 题号 | 题目 | 补看位置 |
|---|---|---|
| 自测 1 | round(2.5)、round(3.5)、f"{0.125:.2f}" 各是什么? | 输入输出规则、数据范围与精度第 05 节 |
| 自测 2 | math.floor(2.5 + 0.5) 与 math.floor(-2.5 + 0.5) 各是多少? | 数字与运算符 |
| 自测 3 | math.exp(1000) 会怎样?math.exp(-1000) 呢? | 常用内置函数 |
| 自测 4 | 0.1 + 0.2 == 0.3 是真是假? | 数字与运算符 |
| 自测 5 | f"{x:.4f}" 里的 .4f 是什么意思?x = 3 时打印什么? | 字符串 |
展开先修自测答案
自测 1:2、4、0.12——Python 在正好一半时向偶数靠(银行家舍入)。题目说「四舍五入」时它们应是 3、4、0.13。
自测 2:3 与 −2。加 0.5 向下取整对正数是四舍五入;对负数 −2.5 会得 −2(向上),若题目要求「远离零」要先取绝对值再还原符号。
自测 3:抛出 OverflowError(上溢);math.exp(-1000) 得 0.0(下溢成 0,不报错)。softmax 先减最大值就是为了避开前者。
自测 4:假——0.1 + 0.2 是 0.30000000000000004。浮点数比较要按题目要求留容差(补充学习)。
自测 5:保留 4 位小数的定点格式;x = 3 打印 3.0000。位数以题目要求为准。
03 / 概念与术语
舍入规则、精度一半、上溢与下溢、log-sum-exp
两件事共用一个原则:数值行为以题目要求为准,不以语言默认为准。
| 术语 | 含义 | 代码里的位置 |
|---|---|---|
| 四舍五入(0.5 远离零) | 正好一半时向绝对值更大的方向取 | floor(abs(x) * scale + 0.5) / scale 再还原符号 |
| 银行家舍入(向偶数靠) | 正好一半时取偶数:2.5 → 2、3.5 → 4;Python 的 round 与 f-string 都这样 | 不要直接用它满足「四舍五入」 |
| 精度一半 | 保留 d 位时 0.5 × 10⁻ᵈ;绝对值小于它的值输出成 0 | if abs(x) < 0.5 / 10 ** digits: x = 0.0 |
| 上溢 / 下溢 | exp 的输入太大抛 OverflowError;太小得 0.0 | 先减最大值,输入 ≤ 0 |
| softmax | p_i = exp(z_i − m) / Σexp(z_j − m),m 为最大值 | stable_softmax |
| log-sum-exp | ln Σexp(z_j − m) + m;用它从原始分数直接算 −ln p | cross_entropy_from_logits |
补充学习(选学)softmax 的温度参数:控制分布的集中程度约 4 分钟比较三种温度参数下的概率分布,并说明其在大语言模型采样中的作用
分数 [2, 1, 0] 除以温度 T 再做 softmax
T = 1 : [0.665, 0.245, 0.090] T = 0.5: [0.867, 0.117, 0.016] (更集中,最大项占绝对多数) T = 2 : [0.506, 0.307, 0.186] (更平缓,小项也有机会)
大语言模型(LLM)生成每个 token(词元,模型处理文本的基本单位),就是对整张词表的分数做一次 softmax 再采样:温度先调整分布的集中程度,Top-K(只保留分数最高的 K 个候选)再截断候选。调整分布用的正是本课这个函数——模块 7 · 第 3 课(KV 缓存与束搜索)讲解码时会再用到它。
补充学习(选学)浮点比较为什么要留容差约 4 分钟浮点数表示误差及在线题目中的比较方法
双精度浮点是二进制小数,0.1、0.2 都存不精确:0.1 + 0.2 得 0.30000000000000004。所以浮点数的「相等」要按题目的要求来判:整数(比如 AI011 的整数平方距离)直接用 == 精确比较;浮点数看量级——量级在 1 附近用「差的绝对值小于给定误差容限(EPS)」,模块 6 · 第 3 课(特征归一化、KNN 与 K-Means) K-Means(K 均值聚类)的距离并列规则(1e-9 内算并列)就是这种;量级很大或很小时固定的绝对 EPS 会失真:10¹² 与 10¹²+1 只差 1,用 1e-9 的绝对容差判成「不相等」,可它们的相对差只有 10⁻¹²;10⁻¹² 与 2×10⁻¹² 差了整整一倍,同一个绝对容差却判成「相等」。所以量级偏离 1 很远时要改用相对误差,或绝对与相对取其一满足即可。非数值(NaN)与无穷值(inf)的规则不同,不能合在一起说:inf 参与的比较是有定义的,inf > 0、inf == inf 都为真,−inf < 任何有限数也为真;NaN 才是特殊的——它与任何值(包括它自己)比较都为假,因此 NaN != NaN 反而为真,判断一个数是不是 NaN 要用专门的判断函数(Python 里是 math.isnan)。题目里可能出现这两种值时,先按题目要求单独处理,再进入正常比较。
题目会通过输出格式或误差范围说明采用哪种比较方式:有的题要求输出完全一致(那就严格按位数格式化),有的题声明绝对/相对误差 1e-6 内算对(那就保证算法精度、位数打够)。读题时先看清是哪一种。
04 / 取整规则
同一组数、几种写法的对照:题目说「四舍五入」时用哪一种
下面每一格都可以自己在 Python 里复现。
| 输入 | Python round | f-string .2f / .0f | floor(x + 0.5) | round_half_up(本课) |
|---|---|---|---|---|
| 2.5 → 整数 | 2 | 2 | 3 | 3 |
| 3.5 → 整数 | 4 | 4 | 4 | 4 |
| −2.5 → 整数 | −2 | −2 | −2 | −3(远离零) |
| 0.125 → 两位 | 0.12 | 0.12 | 0.13 | 0.13 |
| 2.675 → 两位 | 2.67 | 2.67 | 2.68 | 2.68 |
前两行是「向偶数靠」与「四舍五入」的差别;第三行说明加 0.5 向下取整在负数上不是「远离零」;最后一行提醒:有些十进制小数在二进制里存不精确,2.675 实际存成 2.67499…,默认 round 与 f-string 按存储值得 2.67;而它乘以 100 后中间结果又被舍成恰好 267.5,加 0.5 向下取整得 2.68——同一个输入两类写法结果不同。1.005 则相反:1.005 × 100 = 100.49999…,两类写法都得 1.00(第 08 节断言)。若题目要求按十进制文本精确四舍五入,要用 Decimal 或整数计算,不能把这个浮点模板当成对任意十进制都精确的规则;题目若给了这类示例,以示例为准。
写法:floor(abs(x) * 10**d + 0.5) / 10**d,再把符号还原。对正数它就是「加 0.5 向下取整」(上一课 P2475 用的那条);对负数它按「远离零」处理。题目若明确要求别的规则(例如「向下取整」「向偶数靠」),按题目改。
05 / 稳定 softmax
减最大值、取指数、归一化:结果不变,不会上溢
softmax 把一组分数变成总和为 1 的概率:p_i = exp(z_i) / Σexp(z_j)。分数很大时 exp 直接上溢,所以先整体减去最大值。
| 步骤 | 计算 | 结果 |
|---|---|---|
| ① 减最大值 m = 1002 | [1000−1002, 1001−1002, 1002−1002] | [−2, −1, 0] |
| ② 取指数 | [e⁻², e⁻¹, e⁰] | [0.1353, 0.3679, 1.0000],和 S = 1.5032 |
| ③ 归一化 | 各项 ÷ S | [0.0900, 0.2447, 0.6652] |
不减最大值直接 math.exp(1000) 抛出 OverflowError。显示值合计 0.9999 是四位舍入所致;未舍入的概率之和严格为 1,不要去调整已格式化的概率让显示值凑成 1。
为什么减最大值不改变结果
每个分数减同一个常数 m,等于分子分母同乘 e 的负 m 次方——softmax 概率一个都不变。减完之后最大项是 0,指数函数(exp)的输入始终 ≤ 0,不会向上溢出。「先减最大值」是模块 7 每道注意力题的第一行代码。全同分 [3, 3, 3] 减完全是 0,指数全 1,得均匀分布 [1/3, 1/3, 1/3];单元素 [7] 得 [1.0]。
06 / log-sum-exp
从原始分数直接算交叉熵:−ln p = ln Σexp(z − m) − (z_label − m)
交叉熵损失是 −ln p_label。先算 p 再取对数有两个问题:p 可能下溢成 0(math.log(0.0) 抛 ValueError),也损失精度。把公式展开,直接用原始分数算。
| 标签 | 先算 p 再取 −ln | log-sum-exp:ln S − (z_label − m) | 结果 |
|---|---|---|---|
| 2 | −ln 0.6652 | ln 1.5032 − 0 | 0.4076 |
| 0 | −ln 0.0900 | ln 1.5032 − (−2) = 0.4076 + 2 | 2.4076 |
表里的概率是四位显示值,对数按未舍入的概率算——把 0.6652 直接送进 −ln 得 0.4077,与 0.4076 差在第四位。两种算法在这里结果相同;差别在极端输入:z = [0, −2000]、标签 1——先算 p 得 exp(−2000) 下溢成 0,取对数报错;log-sum-exp 得 ln(1 + e⁻²⁰⁰⁰) − (−2000) = 2000.0,正常。模块 7 的注意力题也用这个写法。
07 / 中间值与负零
中间值不提前舍入;绝对值小于精度一半的值按 0 输出
「保留两位」几乎总是指最终输出,中间量全程双精度,最后一步统一格式化。
| 做法 | 输入 | 得到 | 应为 |
|---|---|---|---|
| 中间值先舍入两位再相加 | 0.125 + 0.125 | 0.13 + 0.13 = 0.26(或 0.12 + 0.12 = 0.24) | 0.25 |
| 直接格式化一个极小负数 | −0.00004 保留四位 | -0.0000 | 0.0000 |
| 格式化前先归零 | 同上 | 0.0000 | 0.0000 |
判题逐字节比对:-0.0000 与 0.0000 不同。格式化函数里先判「绝对值小于精度一半」再格式化——第 08 节的 fmt。
08 / 从规则到程序
两份带断言的参考实现,每一步落在哪几行
先自己写完并跑断言,再展开对照。本课没有新的在线题目,两个代码自测就是要通过的东西。
| 规则 | 代码 |
|---|---|
| 四舍五入、远离零 | floor(abs(x) * scale + 0.5) / scale,负数还原符号 |
| 精度一半以内归零 | if abs(x) < 0.5 / 10 ** digits: x = 0.0 |
| 减最大值 | m = max(scores);math.exp(s - m) |
| 归一化 | e / total |
| 从原始分数算 −ln p | lse - (scores[label] - m) |
取整与格式化模板(round_half_up、fmt)
Pythondef round_half_up(x, digits):
# 待完成 1:实现「四舍五入、0.5 远离零」的取整规则,不直接使用语言默认的 round
# 提示:对正数可用 floor(x * 10**digits + 0.5) / 10**digits
...
def fmt(x, digits):
# 待完成 2:格式化输出,绝对值小于精度一半时输出 0.00…0,避免出现 -0.00
...格式化函数(fmt)里先判「绝对值小于精度一半」再格式化,可以避免输出 -0.0000;这两个函数在模块 6 与模块 7 会反复用。
展开参考实现 1:round_half_up 与 fmt(自带断言;先自己写完再对照)
round_half_up 与 fmt 的参考实现(自带断言)
Pythonfrom math import floor
def round_half_up(x, digits):
# 四舍五入、0.5 远离零:先取绝对值,加 0.5 向下取整,再还原符号
scale = 10 ** digits
v = floor(abs(x) * scale + 0.5) / scale
return -v if x < 0 else v
def fmt(x, digits):
# 绝对值小于精度一半的值按 0 输出,避免出现 -0.00…0
if abs(x) < 0.5 / 10 ** digits:
x = 0.0
return f"{round_half_up(x, digits):.{digits}f}"
assert round_half_up(0.125, 2) == 0.13 # Python 默认 f"{0.125:.2f}" 是 0.12
assert round_half_up(2.5, 0) == 3 and round_half_up(3.5, 0) == 4 # 默认 round(2.5) 是 2
assert round_half_up(-2.5, 0) == -3 # 远离零;floor(-2.5 + 0.5) 会得 -2
assert round_half_up(1.005, 2) == 1.0 # 1.005 在二进制里略小于 1.005,按存储值处理得 1.00(与题目示例核对)
assert fmt(-0.00004, 4) == "0.0000" # 不输出 -0.0000
assert fmt(0.6652, 4) == "0.6652" and fmt(3, 2) == "3.00"六条断言对应第 04、07 节的表;1.005 那条说明二进制表示的影响。
展开参考实现 2:stable_softmax 与 cross_entropy_from_logits(自带断言)
stable_softmax 与 cross_entropy_from_logits 的参考实现(自带断言)
Pythonimport math
def stable_softmax(scores):
m = max(scores) # 先减最大值:exp 的输入始终 ≤ 0,不会上溢
exps = [math.exp(s - m) for s in scores]
total = sum(exps)
return [e / total for e in exps]
def cross_entropy_from_logits(scores, label):
# -ln p[label],直接从原始分数算:ln Σexp(z - m) - (z[label] - m),不经过可能下溢成 0 的概率
m = max(scores)
lse = math.log(sum(math.exp(s - m) for s in scores))
return lse - (scores[label] - m)
p = stable_softmax([1000, 1001, 1002])
assert abs(sum(p) - 1.0) < 1e-12 # 未舍入的概率之和严格为 1
assert [round(x, 4) for x in p] == [0.0900, 0.2447, 0.6652] # 第 04 节三步表
assert all(abs(x - 1 / 3) < 1e-12 for x in stable_softmax([3, 3, 3])) # 全同分:均匀
assert stable_softmax([7]) == [1.0] # 单元素
assert abs(cross_entropy_from_logits([1000, 1001, 1002], 2) - 0.4076) < 1e-4 # -ln 0.6652
assert abs(cross_entropy_from_logits([1000, 1001, 1002], 0) - 2.4076) < 1e-4 # -ln 0.0900
assert abs(cross_entropy_from_logits([0, -2000], 1) - 2000.0) < 1e-6 # 概率下溢成 0 也能算:不能先算 p 再取 log七条断言:三步表、全同分、单元素、两个标签的交叉熵、下溢例。
09 / 边界、反例
错误做法在具体输入上各得到什么
下面每一行都可以自己复现:把参考实现改成对应写法就行。
| 错误做法 | 输入 | 错误结果 | 正确结果 | 判题结果 |
|---|---|---|---|---|
用默认 round / f-string 当「四舍五入」 | 0.125 保留两位;2.5 取整 | 0.12;2 | 0.13;3 | 答案错误(WA) |
floor(x + 0.5) 用在负数上(题目要求远离零) | −2.5 | −2 | −3 | 答案错误(WA) |
不减最大值直接 math.exp | [1000, 1001, 1002] | 抛出 OverflowError | [0.0900, 0.2447, 0.6652] | 运行错误(RE) |
| 先算概率再取对数 | [0, −2000],标签 1 | p = 0.0,math.log(0.0) 抛 ValueError | 2000.0 | 运行错误(RE) |
| 中间值提前舍入两位 | 0.125 + 0.125 | 0.26 或 0.24 | 0.25 | 答案错误(WA) |
| 直接格式化极小负数 | −0.00004 保留四位 | -0.0000 | 0.0000 | 答案错误(WA) |
| 把显示值凑成 1 | [0.0900, 0.2447, 0.6652] | 改动某一项 | 原样输出 | 答案错误(WA) |
10 / 渐进练习与参考答案
跟做 → 改一个条件 → 独立实现 → 迁移
每题先在纸上或文件里做完,再展开答案。
练习 1(跟做):按第 05 节表的格式,算出 [2, 1, 0] 的 softmax(保留三位)。
展开练习 1 答案
减最大值 2 → [0, −1, −2];指数 [1, 0.3679, 0.1353],和 1.5032;归一化 [0.665, 0.245, 0.090]。与补充学习「温度」表 T = 1 那行一致。
练习 2(改一个条件):把分数先除以温度 T = 0.5 再做 softmax,[2, 1, 0] 的结果变成什么?T = 2 呢?分布分别更集中还是更平缓?
展开练习 2 答案
T = 0.5:分数变 [4, 2, 0] → [0.867, 0.117, 0.016],更集中;T = 2:[1, 0.5, 0] → [0.506, 0.307, 0.186],更平缓。代码只多一步 s / T。
练习 3(改一个条件):第 06 节的 z = [1000, 1001, 1002],标签换成 1,交叉熵是多少?用两种算法各写一遍。
展开练习 3 答案
−ln 0.2447 = 1.4076;log-sum-exp:ln 1.5032 − (1001 − 1002) = 0.4076 + 1 = 1.4076。两种一致。
练习 4(独立实现):完成「代码自测」的 round_half_up 与 fmt,用 0.125、2.5、3.5、−2.5、−0.00004 各写一条断言。
展开练习 4 答案
round_half_up 与 fmt 的参考实现(自带断言)
Pythonfrom math import floor
def round_half_up(x, digits):
# 四舍五入、0.5 远离零:先取绝对值,加 0.5 向下取整,再还原符号
scale = 10 ** digits
v = floor(abs(x) * scale + 0.5) / scale
return -v if x < 0 else v
def fmt(x, digits):
# 绝对值小于精度一半的值按 0 输出,避免出现 -0.00…0
if abs(x) < 0.5 / 10 ** digits:
x = 0.0
return f"{round_half_up(x, digits):.{digits}f}"
assert round_half_up(0.125, 2) == 0.13 # Python 默认 f"{0.125:.2f}" 是 0.12
assert round_half_up(2.5, 0) == 3 and round_half_up(3.5, 0) == 4 # 默认 round(2.5) 是 2
assert round_half_up(-2.5, 0) == -3 # 远离零;floor(-2.5 + 0.5) 会得 -2
assert round_half_up(1.005, 2) == 1.0 # 1.005 在二进制里略小于 1.005,按存储值处理得 1.00(与题目示例核对)
assert fmt(-0.00004, 4) == "0.0000" # 不输出 -0.0000
assert fmt(0.6652, 4) == "0.6652" and fmt(3, 2) == "3.00"见第 08 节展开区(同一份代码)。
练习 5(迁移):完成 stable_softmax,再写 cross_entropy_from_logits,用第 06 节的两个标签和下溢例各写一条断言。
展开练习 5 答案
stable_softmax 与 cross_entropy_from_logits 的参考实现(自带断言)
Pythonimport math
def stable_softmax(scores):
m = max(scores) # 先减最大值:exp 的输入始终 ≤ 0,不会上溢
exps = [math.exp(s - m) for s in scores]
total = sum(exps)
return [e / total for e in exps]
def cross_entropy_from_logits(scores, label):
# -ln p[label],直接从原始分数算:ln Σexp(z - m) - (z[label] - m),不经过可能下溢成 0 的概率
m = max(scores)
lse = math.log(sum(math.exp(s - m) for s in scores))
return lse - (scores[label] - m)
p = stable_softmax([1000, 1001, 1002])
assert abs(sum(p) - 1.0) < 1e-12 # 未舍入的概率之和严格为 1
assert [round(x, 4) for x in p] == [0.0900, 0.2447, 0.6652] # 第 04 节三步表
assert all(abs(x - 1 / 3) < 1e-12 for x in stable_softmax([3, 3, 3])) # 全同分:均匀
assert stable_softmax([7]) == [1.0] # 单元素
assert abs(cross_entropy_from_logits([1000, 1001, 1002], 2) - 0.4076) < 1e-4 # -ln 0.6652
assert abs(cross_entropy_from_logits([1000, 1001, 1002], 0) - 2.4076) < 1e-4 # -ln 0.0900
assert abs(cross_entropy_from_logits([0, -2000], 1) - 2000.0) < 1e-6 # 概率下溢成 0 也能算:不能先算 p 再取 log见第 08 节展开区(同一份代码)。
11 / 复习 P2483 与输出要求清单
重做 P2483,说出它的两条输出要求;复习自评
P2483「单词重量」(模块 1 · 第 2 课 做过):一行空格分隔的单词,输出平均单词长度、保留两位小数。它考查的两条输出要求:保留几位(两位,由示例确定)、按什么规则取整(题目页参考题解直接用 .2f,与示例一致)。
| 项目 | 问自己 | 本课对应 |
|---|---|---|
| 位数 | 保留几位?由题面还是示例确定? | 第 04 节 |
| 取整规则 | 四舍五入、向偶数靠、向下取整?与本语言默认是否一致? | 第 04 节 |
| 容差 | 要求逐字节一致,还是误差范围内算对? | 补充学习「浮点比较」 |
| 特殊值 | −0.0000、NaN、inf 怎么处理? | 第 07 节、补充学习 |
| 中间值 | 是否全程双精度、只在最后格式化? | 第 07 节 |
复习与自评:本课的「学习完成检查」六条是自评,不改变题目的通过(AC)状态,本课算完成的条件以页面下方「学习完成检查」处的说明为准。复习时用三个问题自测:① 不看正文,说出 round(2.5) 与「四舍五入」的差别和处理写法;② 不看表格,重算 [1000, 1001, 1002] 的三步;③ 说出为什么交叉熵要从原始分数算。答不出哪一条,就回到对应的节重读,再做第 10 节对应的练习。
12 / 练习
按顺序完成本课的任务
编程任务已通过 0/1 道
实现四舍五入取整(round_half_up)与安全格式化(fmt)
代码自测自主练习练习重点:实现「四舍五入、.5 远离零」与防 -0.0000 的格式化;预计用时:20 分钟
完成标准:能说出你的语言默认 round 和题目「四舍五入」的差别
需要时查看提示
对负数,用向下取整函数(floor)写的 floor(x*100+0.5)/100 会把 −2.5 舍成 −2(向上),若题目要求远离零,先取绝对值再还原符号。测试就拿 0.125、2.5、3.5、−2.5 四个数(第 04 节表)。参考实现在第 08 节展开区。
实现稳定 softmax(stable_softmax)并测试边界输入
代码自测自主练习练习重点:先减最大值;覆盖大分数、全同分、单元素三种输入;预计用时:25 分钟
完成标准:能解释减最大值为什么不改变概率
需要时查看提示
减完最大值后最大项是 0,exp 的输入始终 ≤ 0。全同分 [3,3,3] 应给均匀分布——这也是检查归一化分母有没有写对的好用例。第 05 节有三步表。
自测代码(复制到你的代码文件中运行,检查输出是否一致)
import math
def stable_softmax(scores):
# 待完成:先减最大值,再取指数并归一化
...
# 大分数不上溢
probs = stable_softmax([1000, 1001, 1002])
assert abs(sum(probs) - 1.0) < 1e-9
assert abs(probs[2] - 0.6652) < 1e-4
# 全同分给均匀分布;单元素给 [1.0]
assert all(abs(p - 1 / 3) < 1e-12 for p in stable_softmax([3, 3, 3]))
assert stable_softmax([7])[0] == 1.0P2483 · 单词重量(复习)
重做任务 1练习重点:两位小数的输出格式要求;按题目要求正确处理位数和舍入规则;预计用时:25 分钟
完成标准:能指出这题的输出要求是哪两条(位数、取整规则)
需要时查看提示
本次先把输出位数和舍入规则记录在草稿上,再完成实现。全程双精度,只在输出时格式化。第 11 节有输出要求清单。
提交结果
提交结果说明与处理方法
- WA
答案错误
先查取整规则:你的语言默认 round 是不是题目要求的「四舍五入」;再查中间值有没有提前舍入。第 09 节的表给出了每种错误的具体结果
- PE
格式错误
位数、分隔符、行尾逐字符对样例;绝对值小于精度一半的值先归 0,避免输出 -0.0000
- RE
运行错误
exp 上溢是数值题运行错误的常见原因:softmax 先减最大值,指数输入始终 ≤ 0;
log(0)用 log-sum-exp 避开- TLE
超时
本课全是 O(n) 计算,超时先查是否在循环里做了格式化字符串拼接
- AC
通过
把「输出要求清单」记进错题本:位数、取整、容差、-0.0000——之后每道数值题动手前先过一遍
13 / 学习完成检查
本课学习完成检查
完成本课需要:必做题全部通过,并勾选本课的全部学习完成检查;进阶练习、基础加练与复习题单独统计,不影响完成状态。登录后,勾选记录会保存到账号,并更新课程总览的完成状态。