Win+H で声がそのまま質問になる。ゲームの側には一行も足していない
Win+H turns your voice into a question, without a single line added to the game
D13-4-T26-play-by-voice-typing・技術・日本語入力でプレイする仕組み
入力欄をクリックして Win キー+H を押し、「昨日の夜はどこにいた」と話す。それだけで、佐伯への質問になります。
声のために足したコードはありません。入力欄が、OS から見てふつうの文字入力だからです。
前の回(T25)で、入力欄は IME を自前で受けず、UE とブラウザの本物の入力欄を借りている、と書きました。
その作りの、思わぬ副産物がこれです。
Windows の音声入力は、IME と同じく、焦点のある文字欄へ文字を届ける仕組みです。
届いた文字は、キーボードで入力した日本語と区別なく照合に回ります。
ゲーム実況で、刑事として声で問い詰めながら遊べる。作者が 10 月 27 日に、UE 版とブラウザ版の両方で確かめました。
今日は、なぜそのまま動くのかと、声の文字が照合にどう効くかを書きます。
この回の位置と、前後の回#
区切り: T25〜T29 画面と入力(5 回のうち 2 回目)
先に読むとよい回: T25(入力欄の中の IME)・T12(複文を節に割る)・T10(固有名詞の辞書)
次に読む回: T27(C++ の核を三つの外側で共有する)
名前 — Windows voice typing#
- 正式名
- Windows voice typing(Windows 11 での呼び名。Windows 10 では dictation と呼ばれていた)。技術の一般名は automatic speech recognition(ASR)
- 略称
- ASR
- 日本語
- 音声入力、音声認識
- 出所
- Microsoft サポートの記事 "Use voice typing to talk instead of type on your PC"。Win+H が何年のどの版から使えるかは、今日は Microsoft の文書で確かめられませんでした
Windows の音声入力とは#
Microsoft の記事によると、こういうものです。
- ハードウェアのキーボードでは Windows キー+H、タッチキーボードではマイクのボタンで始まる
- 使うには、インターネットへの接続と、使えるマイクと、カーソルがテキストボックスにあることが要る
- オンラインの音声認識(Azure Speech services)で文字にする
- 「Stop listening」のような声の命令で止められる
- エコーキャンセルが、スピーカーから出ている音(ナレーターやアプリの再生)を抑える
- Windows の表示言語と違う言語でも、その言語を入れれば使える
仕組みの側から見ると、TSF のテキストサービスの一つです。
TSF のテキストサービスには、キーボードの IME のほかに手書きと音声認識が入る、と Microsoft の TSF の文書は書いています。
アプリから見ると、IME で確定した文字列が入るのと同じ道を通って、文字が入ってきます。
音声認識の一般的な弱点#
音声認識の誤りは、ふつう単語誤り率(WER)で測ります。
WER = (S + D + I) / N
S は置き換え、D は落ち、I は余計に入った語の数、N は正解の語の数です。
日本語は語の境目が文字に出ないので、文字の単位で数える文字誤り率(CER)がよく使われます。
数字に出にくい弱点もあります。
- 同音の別の字。人の名前・地名のような固有名詞で起きやすい
- 句読点。話し言葉には句読点が無いので、付けるかどうかは認識の側の推定になる
- 言いよどみ(「えーと」「あのー」)がそのまま文字になる
- 数の書き方(「十時」か「10時」か)
- オンラインの認識なら、通信の遅れと、ネットにつながらないときに使えないこと
ゲームの入力として効いてくるのは、上の三つです。
なぜゲームの側に何も足さずに動くのか#
UE 版の入力欄は、編集している間だけ、枠の位置に Slate の SEditableText を置いています(T25)。
SEditableText は、キーボードの焦点を得たときに UE の ITextInputMethodSystem へ自分を登録して有効にし、Windows の実装はその先で TSF とつながっています。
音声入力の文字は、その口から入ってきます。
ブラウザ版は、キャンバスの上に重ねた本物の <input> です。
音声入力から見れば、ブラウザのふつうのテキストボックスです。
どちらも、入った文字列は Enter で送るまで欄の中にあり、送ると核(core)へそのまま渡ります。
核は、その文字列がキーボードから来たか声から来たかを知りません。
知る必要もありません。照合が見るのは文字列だけだからです。
逆に言うと、声のための特別な口を作っていたら、こうはいきませんでした。
音声認識のライブラリを組み込み、UE とブラウザで別々に動かし、結果を照合へつなぐ。
それより、OS の入力の口を一つも塞がない方が、ずっと安上がりでした。
声の文字は、照合でどうなるか#
作者が確かめたとき、音声入力の文には句読点が付きませんでした(それでも返事は返った)。
今日は声そのものは入れず、音声入力が出しそうな文を文字で入れて、照合の中で何が変わるかを測りました。
場所は港、相手は佐伯です。
- 句読点が無いと、点が下がる
「ゆうべ、何時までどこにいたんですか?」は 0.647。
句読点を除いた「ゆうべ何時までどこにいたんですか」は 0.489。
正規化(norm/1)のあとの文字列は同じなのに、点が違います。
どちらも採用の線(0.33)を越え、同じ証言が返りました。
理由は、文の埋め込みの引き方です。AdvMatcher.hpp の注記です。
// 入力全体に加えて、句読点で割った各節のベクトルも引く。
// 「佐伯が古い話を認めました。当時の記録を出してください」のような前置き付きの入力で、
// 文全体だと前置きに引っ張られて話題を取り違えるため(凍結ゴールデンで実測)。
埋め込みは、正規化する前の原文と、句読点で割った節ごとに引いて、意図ごとに最大を採ります(T05・T12)。
句読点があれば「ゆうべ」と「何時までどこにいたんですか」が別の節になり、後ろの節が言い換えの辞書の文に近く出ます。
句読点が無いと、全体の 1 本だけです。
逆の例もありました。
「事件が起きた夜、あなたは何時までどこにいましたか。」は 0.662、句読点なしは 0.685。
句読点が無い方が高い。2 位との差も、句読点なしの方が開きました(0.463 → 0.368)。
句読点は効くことも効かないこともあり、どちらに出るかは文しだいです。
- 二つの問いが一つにつながる
いちばん大きな違いはこれでした。
「昨日の夜はどこにいた。それと、組合長とは会いましたか。」
→ 佐伯「どちらの話を先に確かめますか。一つずつ挙げてください」
「昨日の夜はどこにいたそれと組合長とは会いましたか」
→ アリバイの証言が返る(0.737。2 位は組合長との関係の意図で 0.564)
句読点があれば、進む問いが二つ並んだ複文として節に割れ、どちらから確かめるかを尋ねます(T12)。
句読点が無いと一つの文として照合され、点の高い方の問いにだけ答えて、もう一つは黙って消えます。
声で二つまとめて聞くと、後ろの問いが聞こえなかったことになる。
-
言いよどみは、ほぼ効かない
「えーと昨日の夜はどこにいたんですか」は、正規化で長音が落ちて「えと昨日の夜は…」になり、0.917 で着地しました。
「えーっと組合長とはどういう関係なんですか」も、組合長との関係の意図に着地(0.581)。
文字の 1〜3-gram の照合では、頭の数文字が増えても、残りの n-gram の重なりは大きく変わりません。 -
名前の漢字違いは効く
佐伯に、組合長との関係を聞きます。
「戸倉さんとはどういう関係ですか」→ 1.057。佐伯「組合長とは、特に付き合いはねえ」
「とくらさんとはどういう関係ですか」→ 0.733。同じ返事
「徳良さんとはどういう関係ですか」→ 0.600。佐伯「誰のことを言っとるんだ。名前を出せ」
固有名詞の辞書(entities.json)は、組合長に「戸倉」「組合長」「とくら」「戸倉誠一」「被害者」の 5 つの別名を持っています(T10)。
ひらがなの「とくら」は別名にあるので、固有名詞の加点(+0.15)が付き、材料を挙げた問いとして通ります。
「徳良」は別名に無いので、意図には着地しても「誰のことか」を挙げていない問いとして扱われ、名前を出せ、と返されます。
音声認識が名前を別の字にしたとき、プレイヤーには「ちゃんと名前を言ったのに」と見えるはずです。
名前どおりでない所 — Windows voice typing#
名前どおりです。
Windows の音声入力をそのまま使っていて、ゲームの側に音声認識はありません。
ゲームの照合は声を知らず、文字列だけを見ています。
弱点と、採らなかった案 — Windows voice typing#
弱点です。
- Windows だけです。macOS やスマートフォンの音声入力でもブラウザ版の <input> に文字は入るはずですが、確かめていません。
- オンラインが要ります。ゲーム自体はネットにつながずに動きますが、声で遊ぶときだけはつながっている必要があります。
- 句読点が無いと、上に書いたとおり、二つの問いが一つになります。声で遊ぶ人には「一つずつ聞く」と伝える方がよさそうです。
- 名前の漢字違いは、別名を足せば通ります。ただ、音声認識がどの字を出すかは、こちらでは決められません。別名を足すほど、ほかの名前と取り違える余地も増えます。
- 全画面のときに音声入力の小窓が出るかは、記録が無く、確かめていません。
採らなかった案です。
- ゲームに音声認識を組み込む。オフラインで動くモデルを積めば、ネットは要らなくなります。ただ UE とブラウザで別々に積むことになり、核の決定性(同じ入力に同じ返事・T23)の外側に、もう一つ揺れる部品が増えます。
- 声のときだけ、句読点を推定して足す。照合の前に文を割る規則がもう一つ増え、キーボードの入力と声の入力で判定が変わります。今は入れていません。
- 音声入力の文に専用の言い換えを足す。T50 で書く予定の失敗(落ちた入力を辞書に写して率を上げる)と同じ道です。
声で聞き込めるのは、入力欄をふつうの入力欄にしておいた結果でした。
作ったのではなく、塞がなかっただけです。
検索語#
Windows voice typing Win+H
Use voice typing to talk instead of type on your PC
automatic speech recognition word error rate
Text Services Framework speech
マイクがあれば、Win キー+H で佐伯に声で聞いてみてください。『霧走町 流氷に眠る』の第一章はブラウザで、プロフィールのリンクから遊べます。