5D Library › 学习的85%最优错误率定律、髓鞘化动力学与刻意练习 · English

第四章 遗忘曲线、间隔效应与提取练习

艾宾浩斯的无意义音节

1885 年,艾宾浩斯出版了《论记忆》。他以自己为唯一的被试,背诵由辅音—元音—辅音组成的无意义音节表,过一段时间再重新背到能无误背诵,用「重学比初学节省了多少时间」(节省法)来衡量还记得多少 (Ebbinghaus 1885)。他发现遗忘起初很快,随后越来越慢。一百多年后,默雷与德罗斯用同样的方法让一位被试花了约 70 小时重复这项实验,得到了与艾宾浩斯形状相似的遗忘曲线 (Murre and Dros 2015)。

遗忘曲线的具体形状有过长期讨论。指数函数意味着每单位时间失去「剩余记忆」的固定比例;幂函数则意味着记忆越老、衰退得越慢。维克斯特德与埃布森比较了多组数据,认为幂函数等形式比指数函数更好地描述了遗忘 (Wixted and Ebbesen 1991)。这一点对后面的模型和调度器都有影响。

间隔效应

证据

间隔效应的元分析与「最优间隔」。 塞佩达等人 2006 年汇总了 317 项实验中的 839 个评估,确认在言语回忆任务中,把同样次数的学习分散到不同时间(间隔学习)比集中在一起(集中学习)带来更好的长期保持 (Cepeda et al. 2006)。2008 年,同一团队让 1,354 名参与者学习一组冷知识,第一次学习与复习之间的间隔最长 3.5 个月,复习后最长一年再测验 (Cepeda et al. 2008)。最优间隔随测验延迟增加而变长,但占测验延迟的比例下降:测验在一周后时,最优间隔约为延迟的 20%–40%;测验在一年后时,约为 5%–10%。

所以,「隔多久复习最好」没有唯一的答案,取决于你需要记住多久。

提取练习:为什么重读的熟悉感靠不住

证据

罗迪格与卡尔匹克 2006。 大学生阅读科普短文。实验一比较「读两遍」与「读一遍、做一次回忆测验」,在 5 分钟、2 天与 1 周后测验:5 分钟后重读组更好,2 天与 1 周后测验组更好 (Roediger and Karpicke 2006)。实验二比较三种安排:读四遍(SSSS)、读三遍加一次回忆(SSST)、读一遍加三次回忆(STTT)。5 分钟后的回忆比例依次为 83%、78%、71%;1 周后依次为 40%、56%、61%。读得最多的组在学习结束时对自己将来的记忆最有信心,一周后却记得最少。

证据

提取练习与概念图。 卡尔匹克与布朗特 2011 年让 80 名大学生阅读一段科学文章后,分别只读一遍、反复阅读、绘制概念图,或做两轮自由回忆(每轮后可再读)。一周后,提取练习组在事实题与推理题上的平均正确率约 67%,反复阅读组约 49%,概念图组约 45%,只读一遍组约 27% (Karpicke and Blunt 2011)。一个需要注意的限制是:各组的学习时间并不完全相等。罗兰 2014 年对测验效应的元分析给出总体效应量约 g = 0.50 (Rowland 2014)。邓洛斯基等人 2013 年的综述把练习测验与间隔练习评为「高效用」的学习方法,把重读与划线评为「低效用」 (Dunlosky et al. 2013)。

为什么会这样?一个常见的解释是:重读带来的是流畅感,文字一看就懂,于是人们误以为自己记住了;而提取是一个费力的重建过程,它本身就是一次强化记忆、并暴露「其实没记住」之处的练习。主动提取在当下的成绩更低,正是第五章要讨论的「必要难度」的一个例子。

只用罗迪格与卡尔匹克实验二公布的三组平均数,让每种条件的曲线恰好通过它的两个点,分别假设遗忘服从幂函数或指数函数,再求「读四遍」与「读一遍测三遍」两条曲线在何时相交。两个点无法区分曲线形状,这只是对公布均值的算术,不是对个体数据的拟合。

推导

# Roediger & Karpicke (2006, Exp. 2) means at 5 min and 1 week, passed exactly through a power
# law p0 (1 + t)^-d or an exponential p0 exp(-t / tau): when do SSSS and STTT cross?
import math

T1, T2 = 5.0, 7 * 24 * 60.0
data = {"SSSS": (0.83, 0.40), "SSST": (0.78, 0.56), "STTT": (0.71, 0.61)}

def power(p1, p2):
    d = math.log(p1 / p2) / math.log((1 + T2) / (1 + T1))
    return p1 * (1 + T1) ** d, d

def expo(p1, p2):
    tau = (T2 - T1) / math.log(p1 / p2)
    return p1 * math.exp(T1 / tau), tau

def fmt(m):
    if m < 120:
        return f"{m:.0f} min"
    return f"{m / 60:.1f} h" if m < 2880 else f"{m / 1440:.1f} days"

for name, (p1, p2) in data.items():
    p0, d = power(p1, p2)
    q0, tau = expo(p1, p2)
    print(f"{name}: power p0 = {p0:.3f}, d = {d:.3f};  exponential p0 = {q0:.3f},"
          f" tau = {tau / 1440:.1f} days")

(a0, ad), (b0, bd) = power(*data["SSSS"]), power(*data["STTT"])
tx = math.exp(math.log(a0 / b0) / (ad - bd)) - 1
print(f"power law: SSSS and STTT curves cross at about {fmt(tx)}")
(a0, at), (b0, bt) = expo(*data["SSSS"]), expo(*data["STTT"])
tx = math.log(a0 / b0) / (1 / at - 1 / bt)
print(f"exponential: they cross at about {fmt(tx)}")

print("power law (SSSS): share of what is still remembered that is lost over the next hour")
a0, ad = power(*data["SSSS"])
for t in (10, 60, 24 * 60, 7 * 24 * 60):
    loss = 1 - ((1 + t + 60) / (1 + t)) ** (-ad)
    print(f"   memory {fmt(t)} old: {loss:6.2%} lost in the next hour")
# SSSS: power p0 = 0.990, d = 0.098;  exponential p0 = 0.830, tau = 9.6 days
# SSST: power p0 = 0.845, d = 0.045;  exponential p0 = 0.780, tau = 21.1 days
# STTT: power p0 = 0.736, d = 0.020;  exponential p0 = 0.710, tau = 46.1 days
# power law: SSSS and STTT curves cross at about 44 min
# exponential: they cross at about 45.4 h
# power law (SSSS): share of what is still remembered that is lost over the next hour
#    memory 10 min old: 16.75% lost in the next hour
#    memory 60 min old:  6.51% lost in the next hour
#    memory 24.0 h old:  0.40% lost in the next hour
#    memory 7.0 days old:  0.06% lost in the next hour

两种形状给出的交点相差很大:幂函数假设下,两条曲线约在学习后 44 分钟相交;指数函数假设下约在 45 小时后。实验一已经显示 2 天时测验组更好,与两种假设都相容。所以,「提取练习什么时候开始占优」不能只靠两个时间点回答,需要多个延迟的数据。程序的最后几行说明了幂函数的一个性质:记忆越老,接下来一小时内失去的比例越小(10 分钟的记忆在下一小时失去约 16.8%,一天的记忆约 0.4%),这与艾宾浩斯「起初快、后来慢」的观察一致。

ACT-R 激活模型:为什么集中学习忘得快

帕夫利克与安德森在 ACT-R 认知架构中提出了一个解释间隔效应的模型 (Pavlik and Anderson 2005)。每一次学习留下一条痕迹,痕迹的强度随时间按幂函数衰减;关键在于,衰减速度取决于这次学习发生时该项目的激活水平:

m(t)=ln⁡∑j(t−tj)−dj,dj=cem(tj)+a.m(t) = \ln \sum_j (t – t_j)^{-d_j}, \qquad d_j = c\, e^{m(t_j)} + a.

如果在项目还很「新鲜」时又学一遍(集中学习),这次学习留下的痕迹衰减得更快;隔一段时间、项目已经有些淡忘时再学(间隔学习),痕迹衰减得更慢。回忆概率由激活与阈值之差决定。

四次学习,间隔从 10 秒到 10 天不等,在最后一次学习后 10 分钟到一年测验。参数是示意值:aa 与 cc 与该模型文献中报告的量级相近,但原模型对学习单元之间的时间做了重新标定,这里省略了,因此把阈值设得较低。

推导

# ACT-R spacing model (Pavlik & Anderson 2005): m(t) = ln sum (t - t_j)^-d_j,
# d_j = c exp(m(t_j)) + a; P = 1 / (1 + exp((tau - m) / s)). Illustrative parameters
# (no between-session time rescaling, so tau is set lower). Time in seconds.
import math

A, C, TAU, S = 0.18, 0.22, -1.60, 0.30

def activation(times, t, decays):
    return math.log(sum((t - tj) ** (-dj) for tj, dj in zip(times, decays) if t > tj))

def study(gap, n=4):
    times, decays = [], []
    for k in range(n):
        t = k * gap
        m = activation(times, t, decays) if times else -math.inf
        decays.append(C * math.exp(m) + A)
        times.append(t)
    return times, decays

def p_recall(gap, ri, n=4):
    times, decays = study(gap, n)
    m = activation(times, times[-1] + ri, decays)
    return 1 / (1 + math.exp((TAU - m) / S))

MIN, HOUR, DAY = 60, 3600, 86400
gaps = (("10 s", 10), ("1 min", MIN), ("10 min", 10 * MIN), ("1 h", HOUR),
        ("1 day", DAY), ("3 days", 3 * DAY), ("10 days", 10 * DAY))
ris = (("10 min", 10 * MIN), ("1 day", DAY), ("7 days", 7 * DAY), ("30 days", 30 * DAY),
       ("1 year", 365 * DAY))
print("P(recall) after 4 presentations; rows: gap between presentations, columns: test delay")
print("   gap     | " + " | ".join(f"{r:>7s}" for r, _ in ris))
for g, gs in gaps:
    print(f"   {g:7s} | " + " | ".join(f"{p_recall(gs, rs):7.1%}" for _, rs in ris))
print("best gap for each test delay (search over 1 s to about 300 days):")
cands = [round(10 ** (i / 20)) for i in range(0, 150)]
for r, rs in ris:
    best = max(cands, key=lambda g: p_recall(g, rs))
    b = f"{best / HOUR:.2f} h" if best < DAY else f"{best / DAY:.1f} days"
    print(f"   delay {r:7s}: best gap {b:>9s} = {best / rs:5.1%} of the delay")
print("decay rates of the four traces, massed (10 s) vs spaced (1 day):")
for g in (10, DAY):
    print(f"   gap {g:6d} s: " + ", ".join(f"{d:.3f}" for d in study(g)[1]))
# P(recall) after 4 presentations; rows: gap between presentations, columns: test delay
#    gap     |  10 min |   1 day |  7 days | 30 days |  1 year
#    10 s    |   96.7% |   35.2% |   11.8% |    4.6% |    0.9%
#    1 min   |   98.0% |   50.3% |   19.0% |    7.5% |    1.4%
#    10 min  |   98.2% |   68.6% |   34.0% |   15.0% |    2.9%
#    1 h     |   97.4% |   77.8% |   47.0% |   23.8% |    5.0%
#    1 day   |   94.8% |   80.3% |   62.3% |   40.3% |   11.2%
#    3 days  |   93.7% |   76.6% |   62.6% |   44.0% |   13.8%
#    10 days |   92.4% |   70.7% |   58.9% |   45.0% |   16.5%
# best gap for each test delay (search over 1 s to about 300 days):
#    delay 10 min : best gap    0.07 h = 41.8% of the delay
#    delay 1 day  : best gap    7.83 h = 32.6% of the delay
#    delay 7 days : best gap  1.8 days = 26.2% of the delay
#    delay 30 days: best gap  7.3 days = 24.3% of the delay
#    delay 1 year : best gap 73.0 days = 20.0% of the delay
# decay rates of the four traces, massed (10 s) vs spaced (1 day):
#    gap     10 s: 0.180, 0.325, 0.412, 0.467
#    gap  86400 s: 0.180, 0.208, 0.226, 0.238
ACT-R 激活模型(示意参数)中,四次学习的间隔为 10 秒、10 分钟与 1 天时,回忆概率随测验延迟的变化(横轴为对数刻度)。短延迟时集中学习略好,长延迟时间隔学习好得多,曲线交叉。

模型重现了间隔效应的几个特征。10 分钟后测验时,间隔 10 秒的集中学习(96.7%)与间隔一天的学习(94.8%)差不多,甚至略好;但一天后,前者只剩 35.2%,后者为 80.3%;一个月后分别为 4.6% 与 40.3%。原因写在最后两行:集中学习时,后三次学习的衰减率从 0.18 升到约 0.47;间隔一天时只升到约 0.24。模型给出的最优间隔占测验延迟的比例,从 10 分钟测验的约 42% 降到一年测验的约 20%,方向与塞佩达等人的数据一致,但下降的幅度比数据(一年时 5%–10%)温和得多。这提醒我们:这个简化版本抓住了机制的方向,没有抓住数量。

间隔重复调度器:SM-2

把这些原理变成工具,最早且最广为人知的是沃兹尼亚克在 1990 年描述的 SM-2 算法 (Woźniak 1990)。每复习一次,学习者给自己的回忆打 0–5 分;算法据此调整这个项目的「难易系数」,并决定下一次复习在几天后:第一次 1 天,第二次 6 天,此后每次乘以难易系数;如果回忆失败(低于 3 分),就从头开始。

用一个模拟的学习者驱动 SM-2。学习者的假设:每个项目有一个「记忆稳定性」,回忆成功的概率按指数随时间下降;成功回忆会提高稳定性(越难的成功提高越多),失败后看到答案会部分重建。比较 SM-2、每三天复习一次与考前两天突击复习八次,60 天学习期后的第二天与第 90 天测量平均回忆概率。

推导

# SM-2 (Wozniak 1990): EF <- max(1.3, EF + 0.1 - (5-q)(0.08 + 0.02(5-q))); intervals 1, 6,
# then previous * EF; q < 3 restarts. SIMULATED learner (illustrative): R = exp(-t / S);
# success: S *= 1.5 + 4(1 - R); failure then answer: S = 1.3 max(1, S/2).
import math, random

def learner_review(item, t_now, rng):
    R = math.exp(-(t_now - item["last"]) / item["S"])
    ok = rng.random() < R
    item["S"] = item["S"] * (1.5 + 4 * (1 - R)) if ok else 1.3 * max(1.0, item["S"] / 2)
    item["last"] = t_now
    return (5 if R > 0.9 else 4 if R > 0.75 else 3) if ok else 1

def sm2(n, interval, ef, q):
    ef = max(1.3, ef + 0.1 - (5 - q) * (0.08 + 0.02 * (5 - q)))
    if q < 3:
        return 0, 1, ef
    interval = 1 if n == 0 else 6 if n == 1 else round(interval * ef)
    return n + 1, interval, ef

def make_items(rng, k=40):
    return [{"S": rng.uniform(0.5, 2.0), "last": 0.0} for _ in range(k)]

def retention(items, t):
    return sum(math.exp(-(t - it["last"]) / it["S"]) for it in items) / len(items)

def run(policy, seed=11, days=60):
    rng = random.Random(seed)
    items, reviews, trace = make_items(rng), 0, []
    state = [(0, 0, 2.5, 0) for _ in items]                 # n, interval, EF, next due day
    for day in range(1, days + 1):
        for i, it in enumerate(items):
            n, iv, ef, due = state[i]
            if policy == "SM-2" and day >= due:
                q = learner_review(it, day, rng); reviews += 1
                n, iv, ef = sm2(n, iv, ef, q)
                state[i] = (n, iv, ef, day + iv)
                if i == 0:
                    trace.append(f"d{day}:q{q}")
            elif policy == "every 3 days" and day % 3 == 0:
                learner_review(it, day, rng); reviews += 1
            elif policy == "cram: 8 times in last 2 days" and day >= days - 1:
                for _ in range(4):
                    learner_review(it, day, rng); reviews += 1
    return reviews, retention(items, days + 1), retention(items, days + 30), trace

print("40 simulated items, 60 days of study; retention = mean recall probability")
print("policy                       | reviews | at day 61 | at day 90")
for pol in ("SM-2", "every 3 days", "cram: 8 times in last 2 days"):
    rev, r60, r90, tr = run(pol)
    print(f"{pol:28s} | {rev:7d} | {r60:9.1%} | {r90:9.1%}")
tr = run("SM-2")[3]
print("SM-2 review days and grades, item 1:", " ".join(tr[:8]))
print("   ...", " ".join(tr[8:]))
# 40 simulated items, 60 days of study; retention = mean recall probability
# policy                       | reviews | at day 61 | at day 90
# SM-2                         |     418 |     96.5% |     87.9%
# every 3 days                 |     800 |     91.7% |     77.0%
# cram: 8 times in last 2 days |     320 |     95.7% |     34.2%
# SM-2 review days and grades, item 1: d1:q3 d2:q1 d3:q3 d4:q4 d10:q3 d19:q4 d33:q1 d34:q5
#    ... d35:q5 d41:q5 d51:q5

在这个模拟中,SM-2 用 418 次复习,学习期结束后第二天的平均回忆概率为 96.5%,一个月后为 87.9%;每三天复习一次用了将近两倍的复习次数(800 次),两个数字反而都更低(91.7% 与 77.0%);考前突击只用 320 次,第二天的成绩(95.7%)几乎与 SM-2 一样好,但一个月后只剩 34.2%。第一个项目的复习记录显示了调度器的逻辑:一次失败后间隔重置为 1 天,随后又迅速拉长。

注

模拟不是证据。 结果完全取决于对模拟学习者的假设,说明的是调度器的逻辑,而不是它在真实学习者身上的效果;SM-2 是 1990 年代的启发式算法,此后有许多改进。突击复习第二天的好成绩也提醒我们,只看考试当天的表现很容易得出错误结论。

本章小结

遗忘起初快、后来慢,幂函数常比指数函数描述得更好。间隔学习优于集中学习,最优间隔随需要保持的时间变长,但占它的比例变小。检索练习在当下不如重读,一周后却明显更好(罗迪格与卡尔匹克实验二:61% 对 40%);重读的流畅感会让人高估自己的记忆。ACT-R 激活模型用「新鲜时再学,衰减更快」解释间隔效应;SM-2 等调度器把这些原理变成每天的复习清单。下一章讨论另一种「当下更难、长期更好」的做法:交错练习。

参考文献

Cepeda, Nicholas J., Harold Pashler, Edward Vul, John T. Wixted, and Doug Rohrer. 2006. “Distributed Practice in Verbal Recall Tasks: A Review and Quantitative Synthesis.” Psychological Bulletin 132 (3): 354–80. https://doi.org/10.1037/0033-2909.132.3.354.
Cepeda, Nicholas J., Edward Vul, Doug Rohrer, John T. Wixted, and Harold Pashler. 2008. “Spacing Effects in Learning: A Temporal Ridgeline of Optimal Retention.” Psychological Science 19 (11): 1095–102. https://doi.org/10.1111/j.1467-9280.2008.02209.x.
Dunlosky, John, Katherine A. Rawson, Elizabeth J. Marsh, Mitchell J. Nathan, and Daniel T. Willingham. 2013. “Improving Students’ Learning with Effective Learning Techniques: Promising Directions from Cognitive and Educational Psychology.” Psychological Science in the Public Interest 14 (1): 4–58. https://doi.org/10.1177/1529100612453266.
Ebbinghaus, Hermann. 1885. Über Das Gedächtnis: Untersuchungen Zur Experimentellen Psychologie. Duncker & Humblot.
Karpicke, Jeffrey D., and Janell R. Blunt. 2011. “Retrieval Practice Produces More Learning Than Elaborative Studying with Concept Mapping.” Science 331 (6018): 772–75. https://doi.org/10.1126/science.1199327.
Murre, Jaap M. J., and Joeri Dros. 2015. “Replication and Analysis of Ebbinghaus’ Forgetting Curve.” PLoS ONE 10 (7): e0120644. https://doi.org/10.1371/journal.pone.0120644.
Pavlik, Jr., Philip I., and John R. Anderson. 2005. “Practice and Forgetting Effects on Vocabulary Memory: An Activation-Based Model of the Spacing Effect.” Cognitive Science 29 (4): 559–86. https://doi.org/10.1207/s15516709cog0000_14.
Roediger, III, Henry L., and Jeffrey D. Karpicke. 2006. “Test-Enhanced Learning: Taking Memory Tests Improves Long-Term Retention.” Psychological Science 17 (3): 249–55. https://doi.org/10.1111/j.1467-9280.2006.01693.x.
Rowland, Christopher A. 2014. “The Effect of Testing Versus Restudy on Retention: A Meta-Analytic Review of the Testing Effect.” Psychological Bulletin 140 (6): 1432–63. https://doi.org/10.1037/a0037559.
Wixted, John T., and Ebbe B. Ebbesen. 1991. “On the Form of Forgetting.” Psychological Science 2 (6): 409–15. https://doi.org/10.1111/j.1467-9280.1991.tb00175.x.
Woźniak, Piotr A. 1990. “Optimization of Learning.” Master’s thesis, University of Technology in Poznań.

Fan, Y. (2026). The 85% Rule for Optimal Learning, Myelination Kinetics and Deliberate Practice: From Stochastic Gradient Descent and the Zone of Proximal Development to Spaced Repetition, Read Beside Classical Chinese Learning Theory [学习的85%最优错误率定律、髓鞘化动力学与刻意练习] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23761339 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).