Pythonで長い会議を見える化〜話者ダイアリゼーションの動向〜

Pythonで長い会議を見える化シリーズ（[第1回](https://qiita.com/toast-uz/items/2f9fc5a436bd1d9e97a5)、[第2回](https://qiita.com/toast-uz/items/1f5a559ec67b443167c4)、[第3回](https://qiita.com/toast-uz/items/997ff7769235529d2acf)）は、むやみやたらにやっているように見えますが、・・・実際やっていましたが、だんだんと関連知識を仕入れて来ましたので、ここでまとめておきます。

#1. 君の名は「話者ダイアリゼーション」

まず、本領域は「**話者ダイアリゼーション**」と呼ぶ技術領域のようです。英語では"Speaker diarisation (or diarization)"です。diarisatinには残念ながら日本語訳は無く、ダイアリゼーションと、まんま読みします。英英辞典だと、"In voice recognition, the process of partitioning an input audio stream into homogeneous segments according to the speaker identity, so as to identify different speakers' turns in a conversation."という説明で、これもそのまんまですね。

#2. kmeansとspectral clusteringは基本

本領域の概況は、原文2018年末のこの記事「[Googleが精度92％の話者ダイアリゼーションAI技術をオープンソース化](https://www.infoq.com/jp/news/2019/01/Google-AI-Voice/)」が詳しいです。この表題の件は次の章で説明します。

記事中盤で「最近の話者ダイアリゼーションシステムは、通常、**k平均**または**スペクトルクラスタリング**のようなクラスタリングアルゴリズムを利用する」という記述があります。そうです。kmeansとspectral clusteringを使ってきた、Pythonで長い会議を見える化シリーズは、正しいアプローチだったのです。( *｀ω´) ﾄﾞﾔｧ

しかし、この記事で紹介するGoogleのUIS-RNNは、kmeansやspectral clusteringといった、教師なしクラスタリングの限界を指摘します。1つは教師データがうまく使えないこと、もう1つはリアルタイム化が難しいことです。後者は最近のスマートスピーカーに必要な技術ですので、今回の長い会議を見える化シリーズでは、不要です。しかし、前者は本質的です。事前に人間の声のパターンを多数学習しておくことで、精度を高めることが可能です。なお、会議の参加者そのものの音声を事前に録音しておくことは、必ずしも要らないようです。

#3. 話者ダイアリゼーション概観

GoogleのUIS-RNNは、2018年末に論文発表され、「話者ダイアリゼーション」の領域に大きな影響を与えました。オープンソースとしても提供されています。ただし、論文実証用のオープンソースの位置付けであるようで、あまりメンテはされておらず、これをソフトウェアとして広めていく意図はなさそうです。

+ [GitHubリポジトリ google/uis-rnn](https://github.com/google/uis-rnn)
+ [uis-rnnの日本語解説](https://salestech.plavox.info/2019/04/uis-rnn/)
+ [uis-rnnの説明動画: ICASSP 2019 Fully Supervised Speaker Diarization: Say Goodbye to clustering](https://www.youtube.com/watch?v=pGkqwRPzx9U)
+ [上記動画で事前視聴を強く推奨している動画: ICASSP 2018 Google's Diarization System: Speaker Diarization with LSTM](https://www.youtube.com/watch?v=pjxGPZQeeO4)

上記の最後のリンクの動画が、話者ダイアリゼーション分野を概観するためのバイブルになっています。一連の動画を投稿しているGoogleのQuanさんは、本領域の教祖ですね。動画によると、話者ダイヤリゼーションの流れは以下のようになっています。

1. Speech Detection: Voice Activity Detector (**VAD**)により発言部分のみを抽出する
2. Speech Segmentation: 短時間に区切る
3. Embedding Extraction: **i-vector**、**d-vector**などの特徴量に変換する
4. Clustering: 話者数を決定して、個々の話者を個々のクラスタに分類する
5. Resegmentation (Optional): 結果を調整する

この中で、重要なキーワードはi-vector、d-vectorです。

現在の「Pythonで長い会議を見える化シリーズ」では、特徴量として短時間フーリエ変換した周波数成分を高周波部分をカットしたものを採用しており、発言抽出であるVADにはそれなりに使えることがわかりました。ちなみに、VADの特徴量には「**MFCC**（メル周波数ケプストラム係数）」が良いとされていますが、本質的には同等の方式です。

しかし、話者ダイアリゼーションを行うには力不足で、i-vector、できればd-vectorの採用が必要なようです。なお、i-vectorやd-vectorの比較には、通常のユークリッド距離ではなく、**コサイン類似度**を使うとよいそうです。

後半のクラスタリングの部分では、話者ダイアリゼーションに対して、kmeansよりもspectral clusteringが優れていることを丁寧に説明しています。また、結果を評価するメトリックについても説明しています。

i-vectorを使ったクラスタリングについては、日本語の文献もいくつか見られるようです。i-vectorはMFCCをもとに、事前に教師あり学習を行ったモデルを使って、識別精度を向上させています。

参考:

+ [様々な音響特徴量 それぞれの使い方や意味を教えて下さい](http://abcpedia.acoustics.jp/acoustic_feature_2.pdf) (MFCCの詳細解説)
+ i-vector論文「[Front-End Factor Analysis For Speaker Verification, 2010](http://groups.csail.mit.edu/sls/archives/root/publications/2010/Dehak_IEEE_Transactions.pdf)」
+ [i−vectorを用いた誥者認識, 2014](https://www.jstage.jst.go.jp/article/jasj/70/6/70_KJ00009379103/_pdf)
+ [i-vectorを用いたスペクトラルクラスタリングによる雑音環境下話者クラスタリング, 2015](https://ipsj.ixsq.nii.ac.jp/ej/?action=repository_action_common_download&item_id=113134&item_no=1&attribute_id=1&file_no=1) (pdfがダウンロードされます)
+ [音声を用いた生体認証技術，話者照合ソフトウェア入門, 2018](https://www.jstage.jst.go.jp/article/isciesci/62/2/62_63/_pdf/-char/ja)

#4. デジタル声紋となる特徴量d-vector

さて、GoogleがUIS-RNNで、i-vectorよりも精度が高いとして採用したd-vectorについて解説します。
しかし残念ながら、UIS-RNNのサンプルソースにはd-vectorの計算部分は実装されていません。UIS-RNNそのものは、d-vectorライクなものは何でも使える設計であり、d-vectorそのものは既に求められている前提になっているようです。またGoogleの動画にもd-vectorの詳細説明の回はあるものの、実装については不明確です。いろいろ探して以下の記事に行き当たりました。

+ [Building Speaker Recognition Systems and Diarization Using d-vectors](https://medium.com/saarthi-ai/using-d-vector-for-speaker-recognition-and-diarization-4a3450dd8a01)

この記事の前半は、話者識別のための教師データ音声を水増しするために、**librosa**と**nlpaug**を使って、ホワイトノイズの追加・ピッチの変更・背景雑音の追加をする手法を紹介しています。

記事の後半が教師あり話者識別モデルである**SincNet**の紹介です。SincNetは畳み込みニューラルネットワーク(**CNN**: Convolutional Neural Network)を拡張したディープラーニングモデルです。SincNetの最後の隠れ層の出力がd-vectorになるそうです。教師あり話者識別モデルでは、このd-vectorをもとに、softmax層で分類結果である話者特定情報を得ます。

ざっくり言うと、i-vectorは従来型の数値処理で求められた特徴量であるのに対して、d-vectorはディープラーニングを活用した特徴量である、ということです。

ここで、「**話者識別**」とは、Aさんを含む複数の音声を予め学習した状態で、未知の音声をAさんのものと推定するモデルです。話者ダイアリゼーションとは似ていますが微妙に異なります。なお、librosaではMFCCを簡単に求められるため、VADにも使えそうです。

参考

+ d-vector論文「[Deep Neural Networks for Small Footprint Text-Dependent Speaker Verification, 2014](https://static.googleusercontent.com/media/research.google.com/ja//pubs/archive/41939.pdf)」
+ [Google版のd-vector実装 HarryVolek
/
PyTorch_Speaker_Verification](https://github.com/HarryVolek/PyTorch_Speaker_Verification)

#5. d-vectorからx-vector、さらにその先へ

ディープラーニングによる教師ありの話者識別モデルを使ったデジタル声紋は、d-vectorからさらに進化しています。

まずは、以下の論文とYoutubeで**x-vector**という名称が出ています。最近の「ディープラーニングを使ったデジタル声紋」の名称としては、d-vectorよりもこのx-vectorが使われることが多いようです。残念Google Quanさん、おめでとうKrishnaさん。教祖交代です。

+ x-vector論文「[Deep Neural Network Embeddings for Text-Independent Speaker Verification, 2017](https://danielpovey.com/files/2017_interspeech_embeddings.pdf)」
+ Youtube [Deep Neural Network Embeddings for Text-Independent Speaker Verification](https://www.youtube.com/watch?v=hwSVs7muapQ)

これによると、x-vectorは、25ms単位の20次元MFCCの最大3秒間のデータをもとに、**TDNN** (Time Delay deep Neural Network)を適用する教師ありの話者識別モデルのようです。MFCC復権かつCNN層が無いため、d-vectorと別の名前がつけられたのですね。

さらに本領域はどんどん進化しています。以下のリンクにあるように、最近では**ResNet**をベースにファインチューニングしたモデルが強いようです。d-vectorもx-vectorもワンノブゼムです。新たな話者識別モデルが生み出されると、その最後の隠れ層出力が、新たな高精度の「デジタル声紋」になるわけです。

+ [Biometric Recognition Using Deep Learning: A Survey](https://paperswithcode.com/paper/biometric-recognition-using-deep-learning-a/review/)

参考:

+ NEC技報 2018年3月 「[声認証技術がもたらす安全・安心で便利な社会](https://jpn.nec.com/techrep/journal/g18/n02/180218.html)」