用浏览器语音识别低成本检测发音
作者利用浏览器语音识别结果判断易混淆音,并按学习者母语分配测试词对。实现重点是通过 maxAlternatives 保留多个识别候选,而非只读取首个结果。
AI 深度解读
浏览器的语音识别,能不能临时充当英语发音考官?作者给印度英语学习者做了一个免费测试:让用户读出容易混淆的单词,再看识别器到底听成了哪个词。它检查的是特定听者能否分辨你的发音,并不提供完整的发音评分。
这个方案值得程序员读几分钟,因为它把现成 API 拼成了一个边界清楚的小工具。不过,识别结果能否代表真人听感、不同语言设置到底有多严格,原文还缺少系统验证。
把发音问题缩小到一个音
作者选择了最小对立词(minimal pairs):两个词只差一个音,比如 vest/west、thin/tin、ship/sheep。学习者读 vest,识别器却写出 west,就被视为可能混淆了 V/W。
这样做的好处是定位具体。比起给整段朗读打分,单词对更容易回答「哪个音需要继续练」。
题目还按母语分配。原文共覆盖 14 种语言,其中 Hindi 对应 vw、zj、tht、thd、ii,检查 V/W、Z/J、TH/T、TH/D,以及短 I 和长 EE;Tamil 对应 pb、kg、fp、zj、thd;Bengali 对应 bv、ssh、zj、fp、tht。作者认为,Tamil 使用者更需要检查 P/B、K/G,而 Hindi 使用者通常较少需要。
这是一种按预期难点筛题的办法。原文没有交代这些母语映射的研究来源,也没有给出每组题目的验证数据。
别只读第一条转写,候选结果也有信息
实现里的关键是 maxAlternatives。多数演示只取 results[0][0],作者则请求最多 6 个候选,保留识别器的其他猜测。
下面这段代码负责完成一次识别,并收集候选文本:
function hearOnce(lang, cb) {
var rec = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
rec.lang = lang || "en-IN";
rec.continuous = false;
rec.interimResults = false;
rec.maxAlternatives = 6;
rec.onresult = function (e) {
var alts = [];
for (var i = 0; i < e.results[0].length; i++)
alts.push(e.results[0][i].transcript.toLowerCase().trim());
cb(alts);
};
rec.start();
}
要看的是 rec.maxAlternatives = 6,以及按实际结果长度遍历的循环:请求 6 个,不等于每次一定返回 6 个。
随后,程序根据目标词和混淆词出现的位置分类:
function judge(s, alts) { // s.w = 目标词,s.o = 词对中的另一个词
if (!alts.length) return "unclear";
var top = words(alts[0]);
if (top.indexOf(s.w) > -1) return "ok";
if (top.indexOf(s.o) > -1) return "merged";
if (has(alts, s.w)) return "close";
if (has(alts, s.o)) return "merged";
return "unclear";
}
这里要留意判断顺序:第一候选包含目标词,返回 ok;包含混淆词,直接返回 merged。只有第一候选两者都不包含,才继续查其他候选。
原文还有一处没讲清:文字说目标词排到第四候选时标为 Unclear,代码却返回 close。它可能在界面上被合并为 Unclear,也可能是描述与实现不一致,文中没有展示对应逻辑。words()、has() 的实现同样没有给出。
不明确的结果允许重试一次,并显示实际听到的内容。这个反馈比单独给出「失败」更方便排查。
切换语言设置,也是在切换评判条件
作者把 rec.lang 理解为选择听者。按他们的描述,en-IN 更适应印度英语,对某些混淆更宽容;en-US 更严格。如果学习者准备和美国客户通话,这种设置就有具体用途。
但这是作者的解释,原文没有给出两种设置的对照数据。语言设置也不能直接等同于某一类真人听者。
运行条件同样会影响结果。作者提醒,笔记本风扇噪声和廉价麦克风可能造成误判,标为 Merging 的词对应先复测。作者演示中,多数 Hindi 使用者首先在 V/W 上失败,vest 几乎总被识别为 west;这仍是演示观察,没有样本量和错误率统计。
音频也没有完全留在本机。原文明确说,Chrome 会把音频发送给 Google 处理,页面承诺的只是音频不会到达 WizMantra。
按原文描述,Firefox 没有 SpeechRecognition,工具便改用 speechSynthesis 播放词对中的一个词,让用户选择听到了哪个。此时测的是听辨能力,无法直接判断用户自己的发音。
我的判断
这个方案适合筛查值得复测的发音问题。
最有价值的做法,是利用多个候选保留不确定性,再把结果限定在具体词对上。相比只有一个转写结果,它给产品留下了更多反馈空间。
但「机器听成 west,真人大概也会听成 west」仍是需要验证的假设。识别器会受到语言模型、口音适配和录音条件影响,候选排序也不是经过校准的发音分数。
原文没有拿它与教师判断或专门的发音评分 API 做对照,因此还不能证明准确率相当。免费、无需注册、作者无需自建音频处理服务,是它的实际优势;作者最后强调仍需教师听辨,这个边界很合理。
能拿来做什么
- 做浏览器口语练习时,可以先限定少量词对,用候选转写生成反馈,并提供重试入口。
- 实现分类逻辑时,要核对
close、unclear和界面文案的对应关系,避免代码判断与用户看到的结论脱节。 - 面向不同交流对象时,可以开放
en-IN、en-US切换,同时说明它改变的是识别设置,不能保证模拟真人听感。 - 上线前应说明音频处理去向;缺少识别能力时,可以提供听辨练习,并清楚标明测试内容发生了变化。