20 句天气语料建的二元模型:真句每字平均对数概率 -3.581,打乱字序的假句 -4.270, 按中点阈值判真假 60 / 60 全对。生成侧随机续写的困惑度 65.9,真句只有 35.9。
上一节比了两条技术路线,这一节比两类任务。理解和生成看着是一体两面,其实难点完全不同。
一、理解是收,生成是放
理解类任务:给一段文本,输出一个判断。情感分类、意图识别、真假判别、信息抽取,都属于这一类。 输出空间小,好评估。 生成类任务:给一段上下文,输出下一段文本。翻译、摘要、对话、续写,都属于这一类。 输出空间是整个词表的所有组合。 难度差别在这里:理解只要「判对」,生成要「每一步都判对」,而且一步错,后面全按错的前提往下走。 Demo 用同一个二元模型同时干这两件事,正好能看出差别。
二、判别这一半:真句和乱码分得开吗
做法很朴素:用 20 句真语料统计相邻两字的概率,然后给每句话算一个「每字平均对数概率」。 真句平均 -3.581,把字打乱重排得到的假句平均 -4.270。差 0.689。 取两者中点 -3.926 当阈值,60 条(20 真 + 40 假)全判对。 注意这个 100% 有多容易:假句是把字完全打乱的,相邻关系全毁。 真实的语病句、机器翻译腔,字序大体正常,这个模型就分不出来了。
三、生成这一半:往外续会续出什么
从「今」「明」「下」三个字起步,每次按概率抽下一个字,续 10 个,不许原地打转。 抽出来的三条是:今末天到近风多外温晚晴、明弱厚夜空零三白很午明、下小最量下周零傍今面级。 读一眼就知道:开头两个字像话,往后就散了。因为模型只看前一个字,它不知道整句要说什么。 困惑度也说明了这一点:生成句 65.9,真句 35.9。困惑度越低越像人话,生成的高了近一倍。
四、两类任务的评估方式也不一样
理解类用准确率、精确率、召回率、F1。标准答案唯一,对错清楚。 生成类没法这么算。同一个意思有十种说法,逐字比对会把对的判成错的。 所以用 BLEU、ROUGE 这类「重叠度」,或者干脆用人评。 BLEU 的问题是只数重叠,不看意思。人评的问题是贵、慢、不一致。这是生成任务至今没解决好的评估难题。 现在常见做法是「自动指标筛一遍,人评定稿」。自动指标负责把明显差的挑出去,人负责在剩下的里面排序。
五、动手 Demo:一个二元模型,干判别也干生成
用 20 句天气短句建字符二元模型(加一平滑); 给每句算每字平均对数概率,再拿 40 条打乱字序的假句作对照,取中点当阈值算判别准确率; 然后从三个字起步各续写 10 个字,最后比较真句和生成句的困惑度。
def lp(a, b): # log P(b|a)
return math.log((bi.get(a + b, 0) + 1.0) / (ctx.get(a, 0) + V))
score = sum(lp(t[i], t[i + 1]) for i in range(len(t) - 1)) / (len(t) - 1)
w = np.array([math.exp(lp(cur, c)) for c in cands])
nxt = rr.choice(cands, p=w / w.sum()) # 按概率抽,不取最大
实跑输出:
--------------------------------------------------------------------
理解与生成:判别式判真假,生成式往后续
--------------------------------------------------------------------
真句平均对数概率 -3.581(每字)
打乱句平均 -4.270(每字)
阈值 -3.926
判别准确率 60 / 60 = 1.000
生成侧:从「今」开始,按概率抽下一个字(不许原地打转),续 10 个字。
生成 1 今末天到近风多外温晚晴
生成 2 明弱厚夜空零三白很午明
生成 3 下小最量下周零傍今面级
生成句平均对数概率 -4.188
真句对应困惑度 35.9
生成句对应困惑度 65.9
困惑度越低越像人话。生成句比真句高一截,因为每续一个字都可能走岔,一旦走岔,后面的条件概率全按错的上文算。
读一眼生成结果:开头两个字像词,往后就散了。这就是二元模型的上限——它只看前一个字,攒不出整句的意思。
判别那一栏 60 / 60 看着漂亮,但要打个折扣:假句是彻底打乱的,相邻关系全毁,分它们太容易。 三个生成结果里,第一个「今末天到近风多外温晚晴」还算能看出是天气词堆的,后两个就完全散了。 困惑度 35.9 对 65.9,差得不算悬殊,但方向对:生成句确实更不像话。 生成用「按概率抽」而不是「取最大」,是因为取最大会陷入循环——第一版就是这样, 续出来一串「今今今今」。这件事值得单独记一笔。
30 秒实验
- 把语料从 20 句扩到 40 句,看判别准确率和生成困惑度各怎么变。
- 把生成改成「取概率最大的字」,看会不会原地打转。
- 想一想:为什么生成任务的评估比理解任务难?
常见误区
- 「判别 100% 说明模型好」——假句太假,任务太容易。
- 「生成就是判别反过来」——生成要保证每一步都对,误差会累积。
- 「困惑度低就一定通顺」——它只衡量「像不像语料」,不衡量「对不对」。
自测三问(点开对答案)
1. 理解和生成两类任务的核心差别是什么? —— 理解输出一个小判断,生成输出一整个序列,前一步错会带错后面所有步。 2. 为什么生成时不能每次取概率最大的字? —— 会陷入循环,反复吐同一个字。 3. 为什么生成任务不好用准确率评估? —— 同一意思有十种说法,逐字比对会把对的判成错的。两大类任务认清了。下一节回到最脏最累的一步:语料怎么洗。
- ☐ (本节完,下一节 6.1.5 语料预处理的6个关键步骤)