音声認識の雰囲気を掴もう

こんにちは。リサーチャーの古谷です。

私は普段、音声認識の研究開発をしています。

今回の記事では、音声認識がどのように実現されているのかを、非技術者の方にも伝わるように紹介してみたいと思います。

あまり込み入った話はできないので、スタンダードな教師あり学習に限定して、音声認識の概要を解説してみます。

非技術者の方に伝えることを目指す都合で、かなり説明を端折っている部分があります。この記事を読んだだけでは絶対に実装できるようにならないので、実装レベルの情報が欲しい方はごめんなさい。あくまで「なんとなく音声認識の雰囲気が分かる」というぐらいの読み物としてご覧ください。

また、音声認識の歴史の話はせずに、現在主流の深層学習に限ったお話をします。

音声認識の概要

音声認識とは、「発話音声を入力すると、その発話内容(に近い)テキストを出力してくれる技術」です。

したがって、数学っぽい言い方をすると、「音声認識システム」とは「音声をテキストに変換する関数」と表現できます。

音声認識システムは音声を入力するとテキストが出力される関数

そんなすごい関数を作るための手法として、現在は深層学習(ディープラーニング)と呼ばれる手法を使うのが主流になっています。

深層学習とは、ざっくり言うと「基本となる関数をたくさん繋げて合成関数を作り、意図した挙動をする関数になるよう調整する技術」です。深層学習において、基本となる関数は「層」と呼ばれ、「全結合層」や「畳み込み層」などさまざまなものがあります。

つまり、深層学習で音声認識を実現するには、

  1. 基本となる関数に何をいくつ使うかを決めて、それらを繋げた大きな合成関数を作る(音を扱うので、この合成関数を音響モデルと呼ぶ)
  2. 音響モデルが正しく発話内容のテキストを返してくれるように調整する

という手順が必要になります。

a. については『音響モデルの構造の決定』の章で、b. については『音響モデルの調整(訓練)』の章でそれぞれ説明します。

b. で、音響モデルの調整をするために「発話音声とその発話内容テキストのペア」がたくさん必要になります。たくさんの発話音声の内容を人手で書き起こす必要があるので大変ですが、テレビの字幕やオーディオブックのデータを活用する研究もあります。

それでは、各手順について解説していきましょう。

音響モデルの構造の決定

まず、音声認識に使う深層学習モデルの構造を決定します。

簡単に言うと、どんな関数を繋げた合成関数を作るかということを考えます。

音声データには「長さが毎回同じとは限らない」「順番に意味がある」という特徴があります。このようなデータを「時系列データ」と呼んだりします。

深層学習で使える、基本となる関数には「全結合層」や「畳み込み層」など様々なものがありますが、時系列データに対しては「RNN(リカレントニューラルネットワーク)」と呼ばれるものがよく使われます。RNN は、長さが異なる入力を扱ったり、順番の依存を扱えたりする性質があります。

RNN の中でも特に LSTM (Long short-term memory)1 と呼ばれる関数は、時系列データにおいて離れた位置にある値の依存関係を扱うことができる関数です。これが音声認識ではよく利用されています。

しかし、LSTM でも扱える依存の距離(時間間隔)に限りはあるので、より離れた位置の依存関係を扱える関数がよく使われるようになってきました。それが Attention 機構と呼ばれる構造を持つものです。

Transformer2 と呼ばれる深層学習モデルが、この Attention 機構を活用したものです。

Transformer に、畳み込み層と呼ばれる関数も取り入れた Conformer3 と呼ばれる深層学習モデルは、精度が高いため音声認識におけるデファクトスタンダード的な立ち位置になっています。

Conformer の構造をシンプルにして高速化を目指した Squeezformer4 というモデルが研究されているなど、音響モデル構造は現在も熱心に研究されています。

音響モデルのイメージ。畳み込み層・LSTM・全結合層は深層学習で基本となる関数の例

また、実際に音響モデルを作る際は、精度に加えてマシンスペックとの兼ね合いも考える必要があります。

メモリや計算量が大きいが精度が良いモデルを使うのか、あまり強くないマシンでも動くような軽量なモデルを使うのか、音声認識を活用する場面に応じて判断します。

音響モデルの調整(訓練)

この章では、前述の手順 b.「音響モデルが正しく発話内容のテキストを返してくれるように調整する」について解説します。

音響モデルの構造を決めたら、たくさんのデータを使って調整をします。この調整を「訓練」あるいは「学習」と言います。

また、訓練に使用するデータを「教師データ」と呼びます。音声認識における教師データは、発話音声と発話内容テキストのペアです。

具体的な音響モデルの訓練方法に入る前に、「教師データを使ってモデル(関数)を調整する」というのがどういうことかを簡単に解説します。


例えば、一次関数 f(x)=ax+b というモデルを使って、気温(℃)から積雪量(cm)を推定したいとしましょう。これは、定数 a,b を持つ関数で、入力された値を a 倍して b を足すという変換を行うものです。雑に設定している問題なので、値は適当です。あくまでイメージということでご理解ください。

とりあえず、気温が低いほど積雪量が多そうなので係数は負として、 f(x)=-10x+50\ (a=-10, b=50) としましょう。1 ℃下がると 10 cm 高く積もるということです。

このモデルに対して、教師データとして「2 ℃のときに 20 cm 積もった」を与えたとします。このとき、モデルの出力は f(2)=30 なので、モデルは 30 cm 積もると推定しています。つまり、誤差は 10 となります。真の値よりも大きい値を出力しているので、誤差を小さくするためには、出力する値をもっと小さくするべきです。

x=2 での出力を小さくするためには、係数 a と定数項 b をともに小さくすればよいです。なので、とりあえず f(x)=-11x+49 と微調整したとします。

教師データ (2, 20) に基づいて関数を調整する例

続いて、別の教師データとして「-10 ℃のときに 150 cm 積もった」を与えたとします。このとき、モデルの出力は f(-10)=159 です。したがって、誤差は 9 となります。またしても真の値よりも大きい値を出力しているので、誤差を小さくするためには、出力する値をもっと小さくするべきです。

x=-10 での出力を小さくするためには、係数 a を大きくし、定数項 b を小さくすればよいです。入力となる x の値が負なので、ax を小さくするためには a を大きくする必要があります。

また、x=-10 の場合は、x=2 の場合と比べて、a を値を変化させたときの出力の変化量が大きいので、a の調整は細かくても良いでしょう。

ということで、f(x)=-10.8x+48 ぐらいに調整しましょう。

教師データ (-5, 150) に基づいて関数を調整する例

このようなイメージで、関数の出力が教師データに近づくように関数のパラメータ(ここでは係数 a と定数項 b)を調整していくのが教師あり学習と呼ばれるモデルの訓練方法です。

モデルの訓練の手順をまとめると、以下のようになります。

  1. 教師データの入力値(ここでは気温)をモデルに入力し、モデル出力を得る
  2. 教師データの真の出力値(ここでは積雪量)とモデル出力の誤差を計算する
  3. 誤差が小さくなるように、モデルの中の「調整可能なパラメータ」を微調整する(今回の例では、調整可能なパラメータは係数 a と定数項 b

つまり、モデルの訓練のためには教師データの他に「誤差を計算する方法」を用意する必要があります。

3. での調整は、実際には微分を使って実行します。微分を使うと、誤差を小さくするために各パラメータを大きくすれば良いのか小さくすれば良いのかが分かるのです。


以上が、モデル訓練の簡単な解説です。

では、音声認識の話に戻りましょう。

音響モデルは、音声を入力するとテキストを出力するような関数になっているはずですが、実はそうではなく、出力は「簡単にテキストに変換できる値」になっています。具体的には「ある時間にある単語を発話している確率」のようなデータになっています。このデータから、最も確率が高い単語を選択していくとテキストを作れます。

なぜそうなっているかと言うと、数値の方が深層学習モデルが出力しやすいという理由と、数値の方が誤差を計算しやすいという理由があります。

音響モデルを訓練するためには、「正解の発話内容テキスト」と「音響モデルの出力」の誤差を計算する必要があります。この誤差には CTC 誤差関数と呼ばれるものがよく使われます。CTC 誤差関数については過去に詳細な解説記事を書いているので、数式を追いたい方はぜひご覧ください。

CTC 誤差関数を完全に理解したい(前編)

CTC 誤差関数を完全に理解したい(後編)

CTC 誤差関数を使うと、音響モデルの出力と正解テキストがどれだけ離れているかが分かります。さらに、微分を使うことで音響モデルに含まれるパラメータをどう調整すれば音響モデルの出力が正解テキストに近づくかも分かります。

つまり、音響モデルの場合、モデルの訓練の手順は以下のようになります。

  1. 教師データの音声を音響モデルに入力し、モデル出力(確率データ)を得る
  2. 教師データのテキストとモデル出力の誤差を、CTC 誤差関数などで計算する
  3. 誤差が小さくなるように、音響モデルの中の「調整可能なパラメータ」を調整する(LSTM や Attention などのパラメータを調整)

この手順を繰り返して、教師データとは別で用意する評価用のデータでの認識精度が十分高くなったら、音響モデルの完成です。

以上で、音声認識の仕組みをざっくりと解説しました。

最後に、精度を上げるための工夫について紹介します。

音声認識の精度を上げるための工夫

音声認識に限らず、深層学習においては教師データの量と質がとても大事です。

データが少ないとまともに訓練できませんし、データが実際に適用したい音声とかけ離れていると意味がありません。また、似たようなデータがたくさんあっても意味がありません。データの多様性も大事です。

教師データを改変してデータの水増しをする「データ拡張」と呼ばれる工夫もよく行われます。雑音を重ねたり再生速度を変えたりすることで、データの多様性を確保しつつ量を増やします。データ拡張にも色々な手法があり、日々研究されています。

音響モデルの出力をそのままテキストに変換するのではなく、言語モデルという別のモデルを使って音響モデルの誤りを訂正するという手法もあります。言語モデルはテキストデータだけで訓練できるので、大量のテキスト(Wikipedia の記事全部など)を用いて強いモデルを作ることができます。

もちろん、モデル構造を工夫したり、モデルをできる限り大きくすることでも精度改善は見込めます。

訓練のしかたを工夫するという方法もあります。例えば、パラメータを微調整する際に、最初はあまり大きく調整せず、徐々に調整幅を大きくし、途中からまた調整幅を小さくしていく方法(学習率スケジューリング)などがあります。

以上をまとめると、音声認識の精度を上げるための工夫には、以下のようなものがあります。

  • 教師データをたくさん集める・質の良い教師データを集める
  • データ拡張で教師データを水増しする
  • 言語モデルを用意して組み合わせる
  • 音響モデルの構造を工夫する
  • 音響モデルのサイズを大きくする
  • 学習率スケジューリングなどで、訓練のしかたを工夫する

音声認識の研究開発では、上記のようなことやここでは書ききれなかったことなどを考えながら精度向上を目指しています。

おわりに

今回の記事では、非技術者の方にも伝わることを目指して、音声認識を実現する仕組みについて解説してみました。

細かい部分の説明をかなり端折ったので、この記事だけで音声認識を完全に理解することはできませんが、音声認識の雰囲気がなんとなく分かっていただければ嬉しいです。