[Python] 転職のための音声認識入門 ①

# はじめに
### わたしとこの記事シリーズ
現在 測定器メーカーでアプリケーション開発して3年が経ちました。
もう少し信号処理にかかわりたくて、生体認証の仕事に興味を持ち、勉強を始めました。
この記事シリーズはその勉強の跡筋です。同じようなレベルの人の参考になれば幸いです。
ちなみに、学生・院生時代に C/C++ Python Matlab と基礎的な音響の知識は学習済みです。

課題図書として以下を選びました。

https://book.impress.co.jp/books/1120101083

2週間を目安にがっつり勉強します。Pytorch DNN-HMM による音声認識モデル構築を目標にします。
このシリーズには、この書籍の詳細な内容ではなく（もちろん）、**学習の流れや追加で必要だったこと**について書き残します。

このパートは音声認識の概要に焦点を当てています。
まだ Python に関する記述はありません。次のパートから含む予定です。

限られた時間の中での勉強なので、粗削りのノートになりそうです。
時間を見つけてちょくちょく更新してきれいにしていきます。


### このパートの参考文献

https://www.youtube.com/watch?v=mMeAwAsnpqc

https://www.headboost.jp/bayes-theorem/


# 音声データ処理
### 種類
- **音声認識** (音声信号を文章に直す)
- 話者認識 (音声から誰が話しているかを識別)
- 声紋認証 (声でパソコンやスマホにログイン)
- 音声合成 (PCなどに自然に話させる)
- 騒音調査 (飛行場や工場の騒音を調べる)
- 探知・測距 (魚群探知機・車載コーナーセンサー)
- 音楽情報処理 (自動採譜・楽器ごとの音に分離)

### 音声データの特徴
- マイクや耳に到達する圧力の時間的変動 → データの意味を見るには処理が必要
- ばらつきが大きい → 雑音・伝達ひずみ・人による話し方
- 時間方向に伸縮する (「おはよう」を.5秒でいう人もいれば1s以上かける人もいるかもしれない)
- 対象により、扱う周波数範囲が変わる (人？動物？無機物？)

### 人の声紋にみられる特徴
- 声の高さ＝母音部分の基本周波数
- スペクトログラムの縞の間隔が広い＝高い声
- 縞などの微細構造を無視した概形を**スペクトル包絡**という。
- フォルマント: スペクトル包絡のピーク。周波数の低い順に第１フォルマント、第２フォルマントと呼ぶ。

# 音声認識の概要
### 音声認識とは
- 音声信号から発話した内容を認識すること
  - 音声: 人が出す声
  - 音源分離（雑音除去など）→ 音声認識（発話の認識）→ 自然言語処理（発話内容の解析）
- ヒトの音声認識は 知覚（耳） → 認識（脳）
- 知覚 ＝ 特徴量抽出、認識にとって都合をよくする前処理
- 認識 ＝ 妥当性評価、音声認識モデルを基にした判定など、事前学習が必要

### 音声認識モデル
- 入力特徴量 から 認識結果の確率 を返す計算規則のこと
- 以下の３つのモジュールで順序的に構成・実装される
1.  音響モデル: 音声特徴量 から 音素（a/na/ro/gu など） の確率を計算するモデル
1.  発音辞書: 音素 と 単語 の対応リスト
1.  言語モデル: 文脈を考慮し 単語が現れる確率を計算するモデル
- デコーダはこれらの出力を統合する
- 歴史
    - 1980-2010: 隠れマルコフモデル ＋ 混合正規分布
    - 2010-現在: 隠れマルコフモデル ＋ ディープニューラルネットワーク
    - 2015-現在: End-to-end モデル
      （音響モデル・発音辞書・言語モデルを一つのニューラルネットワークで表現する）

# 音声認識と確率
- モデル: 学習データ（過去の試行）から事象が発生する確率を求める
- 音声認識は 事後確率 を考える問題といえる

### 確率の基礎
- 事前確率: 純粋に過去の結果のみを考慮した確率
    - ○○●● から ○ を選ぶ確率
```math
P(x=\text{white})
```

- 事後確率・条件付確率: ある事象が観測された後を考える確率
    - ○○●● から ○ を取った後に ● を選ぶ確率
```math
P(y=\text{black}|x=\text{white})
```

- 同時確率: 
    - ○○●● から ○ と ○ を選ぶ確率
    - Chain rule: 同時確率 = 一方の事前確率 × その後のもう一方の事後確率
```math
P(x,y) = P(x)P(y|x) = P(y)P(x|y)
```

- 確率の周辺化
    - ○○●● から ○○ を選ぶ確率 と ○● を選ぶ確率の和をとること。これは ○ を選ぶ確率に等しい。
```math
\sum_{y} P(x, y) = P(x)\\
```
```math
\sum_{x} P(x, y) = P(y) 
```

- 条件付き確率と同時確率
    - 同時確率の式を変形。
```math
P(y|x)=\frac{P(y)P(x|y)}{P(x)}
```

### ベイズの定理
- 事前確率（もともと持っている考え、仮説 Hypothesis）が尤度（新しいデータや経験 Data）を受けて、どう変化するのかを示す事後確率を求めるための方法。事後確率と条件付き確率との関係式を、事前確率（仮説）・データ（尤度）・事後確率の関係性に持ち込んだもの。
```math
P(H|D)=\frac{P(H)P(D|H)}{P(D)}
```
- 詳細の説明は 参考文献 に委ねます。痒い所に手が届く説明で、練習問題もあり、私のような初学者にとってとても分かりやすいです。

https://www.headboost.jp/bayes-theorem/



# 音声認識命題の数式化
- 入力音声データ $x$ に対して最も確率が高いテキスト列 $\hat{w}$ を返す命題と解釈できる。
```math
\newcommand{\argmax}{\mathop{\rm arg~max}\limits}
\newcommand{\argmin}{\mathop{\rm arg~min}\limits}

\hat{w} = \argmax P(w|x)
```

- $w$ は認識仮説と呼ばれる認識結果テキスト列の候補となるテキスト列。$\hat{w}$ が最終的に出力する認識結果のテキスト列。

- ベイズの定理を用いて、変形。
```math
\hat{w} = \argmax \frac{P(x|w)P(w)}{P(x)}
```
- $P(x)$ は $w$ を含まないため、以下の式を得る。
```math
\hat{w} = \argmax P(x|w)P(w)
```

- $P(x|w)$ はテキスト $w$ を発話したときに収録される音声 $x$である確率。この確率を計算するモジュールを **音響モデル** と呼ぶ。テキストと音声が対になったデータを用いて学習させる。

- $P(w)$ は純粋に $w$ という発話内容が話される確率を示す事前確率。この確率を計算するモジュールを **言語モデル** 呼ぶ。テキストデータを用いて学習される。

- 基本的な音響認識モデルは音響モデルと言語モデルのセットによって構成される。

# 発音辞書
- 音響モデル $P(x|w)$ を学習するためにすべての単語の音声データを集めることは無謀。→ **音素モデル** と **発音辞書** に分解する。

- 音素列を $p$ とすると、上式は確率の周辺化を用いて以下のように変形できる。
```math
\begin{align}
\hat{w} &= \argmax P(x|w)P(w) \\
& = \argmax \sum_{p} P(x,p|w)P(w)
\end{align}
```

- この式を Chain rule を用いて以下のように展開できる。
```math
\begin{align}
\hat{w} &= \argmax P(x|w)P(w) \\
& = \argmax \sum_{p} P(x,p|w)P(w) \\
&= \argmax \sum_{p} P(x|w)P(p|w)P(w)
\end{align}
```

- $P(p|w)$ を発音辞書と呼び、単語列が与えられた時に、音素列である確率を示す。一致なら１，不一致なら０のように返す。

- この変形によってすべての音素が学習データに含まれていれば、学習が可能となる。すなわち、学習データに存在しない単語であっても、その単語の音素列が発音辞書に定義されて入れば、音素レベルでの音響モデル出力を発音辞書に繋げることで認識できるようになる。

# 音声認識タスク
- 孤立単語認識
    - 発話された一単語の音声を認識し、単語を推測するタスク。
    - 「照明オン」のようなフレーズも可。
    - 登録する語彙を絞れば、用途が限定的になるが、相対的に認識制度を上げることができる。
    - 文脈を考慮しないため、言語モデルの定義をシンプルにできるため、以下のように命題を簡単化できる。
    ```math
    \begin{align}
    \hat{w} &= \argmax P(x|w)P(w) \\
    & = \argmax \{\max P(x|p)P(w)\} 
    \end{align}
    ```
    - 隠れマルコフモデルでの実験は後述される。
- 連続音声認識
    - 文章を認識するタスク。
    - End-to-end による実験は後述される。

# 音声認識実験の流れ
- 音声とテキストが対になったデータセットを用意する。
- このデータセットを３つのサブセットに分ける。
    - 学習データ: モデル内のパラメータを求めるため（過去問）
    - 開発データ: 学習させたモデルを実際に運用した場合の精度確認のため
    - 評価データ: ハイパーパラメータを決定するため（本試験）
- これらを混ぜて使用してはいけない。
- 評価項目例
    - 音声認識誤り率
    - 音声認識の処理速度
    - CPU や メモリの使用率

# 次回
Python で特徴量抽出