はじめに
音声の位相復元という研究トピックが存在している.分野に不慣れな人はまず,矢田部先生の解説記事を読むことをおすすめする.
音声の位相復元をDNNで行う流れがあり,日本の研究者も大いに貢献している.
表題のvon Mises 分布DNNに基づく位相復元手法は,慶應義塾大学の高道先生が東京大学に在籍していたころの仕事である.
今回はこの手法をPyTorchで実装し,位相復元の実験をしてみたということである.
実装
以下のリポジトリに置いた.Enjoy!
基本的な構造は全結合層からなるDNNであり,活性化関数はGLUである.オリジナルのGLUは線形変換に対してgateの役割を果たすシグモイド関数を乗じているが,今回はシグモイド関数の代わりにGELU (Gaussian Error Linear Units) を用いることにした.手元の実験では収束がシグモイド関数よりも早くなる(=損失が早く減少する)ことを確認している.なおオリジナルの論文では言及されていなかったLayerNormも導入している.
ファイル名 | 機能 |
---|---|
preprocess.py | 各種の前処理を実施するスクリプト |
dataset.py | データローダの構築を実施するスクリプト |
model.py | ネットワークを定義 |
factory.py | オプティマイザ,スケジューラ,loss関数を定義 |
training.py | モデルの訓練を実施するスクリプト |
evaluate_scores.py | 音質の客観評価指標を計算するスクリプト |
実験
JSUTコーパスのBASIC5000を訓練データに,ONOMATOPE300をテストデータに用いた.客観評価指標にSTOI, (wideband) PESQ,LSC (log-spectral convergence)を採用した.
特徴抽出およびミニバッチ構築について
少々込み入っているので説明しておく.
BASIC5000について,東京大学猿渡研究室の公式リポジトリにおいてフルコンテキストラベルが公開されている.
まず上記フルコンテキストラベルに基づいて,BASIC5000に含まれている各音声ファイルの無音区間(発話冒頭および発話末尾)を削除する. 得られた音声ファイルをサンプリング周波数16kHzにリサンプリングしたうえで,音響特徴量を抽出する.音声の分析条件は後述する. 今回は位相復元ということで,DNNの入力は対数振幅スペクトル,出力は位相スペクトルであり,これらが抽出対象である. 抽出済の特徴量は一旦ファイルに保存しておく(ファイルは発話単位).
無音区間除去後のBASIC5000の音声データは,最小時間(duration)が約0.9秒である.その特徴量のフレーム数(約110フレーム)をもって時間軸方向に固定長のミニバッチを構築する. 一方で0.9秒を超えて3秒や4秒近くになる音声(発話)データも数多く存在する.したがってそのような音声データについて,特徴量抽出前に一様に約0.9秒単位で分割してしまうのは一つの手なのだが,今回は事前の分割はしなかった.その代わり,ミニバッチ構築時には発話単位の特徴量をロードし,その開始フレーム位置をランダムに決定する.フレーム終端はそこから定数フレーム(約110フレーム)だけ後ろの位置で決まる.フレーム数が固定長となるため,lossを取る際にマスクが不要になりモデル訓練のコードが幾分すっきりする.ミニバッチ構築時にサンプル単位でランダムに音声の小区間を決定したのちに特徴抽出を行う方法も考えられたが,ミニバッチ構築の度に特徴量を抽出するのは訓練時間を多く消費するため,採用を見送った.そのほか,ミニバッチサイズを可変にすることも不可能ではないが,実装をシンプルにすることを優先した.
上記,preprocess.pyが特徴量抽出であり,dataset.pyがミニバッチ構築の処理をしているので参考にしてほしい.
ちなみに当該フレームに前後2フレームを加えた5フレーム分をまとめて入力特徴量を構築する.その特徴量構築にはPyTorchのunfold関数が便利に使える.
音声の分析条件
計算機環境を示す。
計算機環境 | バージョンなど |
---|---|
OS | Ubuntu 22.04 |
CPU | Intel i9-9900K |
GPU | RTX2070 |
Python | 3.10.12 |
PyTorch | 2.2 |
訓練の基本的な設定は以下の通りである。
項目 | 設定 |
---|---|
ミニバッチサイズ | 256 |
エポック数 | 500 |
オプティマイザ | RAdam |
学習率 | 0.001から開始し,100エポックごとに0.8倍する |
勾配クリッピングのしきい値 | 10.0 |
群遅延ロスの重み | 0.1 |
音響特徴量の設定は以下の通りである。
項目 | 設定 |
---|---|
標本化周波数 | 16000Hz |
音響特徴量 | 対数振幅スペクトルおよび位相スペクトル |
分析窓 | ハン窓 |
FFTの窓長 | 512 |
フレーム長 | 512 |
フレームシフト | 128 |
なお特徴抽出に用いたライブラリはscipyのShortTimeFFTである.以前書いた記事は本記事の布石であった.
実験結果
図1,図2,図3に各評価指標の箱ひげ図を示す.図中,"Amp"は位相スペクトルを定数値0と置いたもの,"Rnd"は位相スペクトルを$-\pi$から$\pi$の乱数としたもの,"vM"はvon Mises分布による位相復元手法を示す.また図1はDNNの出力直後の位相スペクトルを復元に利用し,図2および図3はGriffin-Limアルゴリズム(GLA)による事後処理的な位相補正を行ったときの結果である.それぞれGLAの繰り返し回数は10および100である.
図1より,von Mises分布DNNによる位相復元のスコアはいずれも優れたものになっており,先行研究で示された有効性がここでも確認できた.GLAによる位相復元を重ねると,客観評価指標のうえでは位相の初期化手法の違いが少なくなっているようである.GLA 100回後の"Amp"(zero-phase)のLSCが一番良い値になっているのは興味深い.
以下,それぞれの復元音声サンプルを載せておく."vM"の生成音声(GLAなし)に”ビリビリ”としたノイズがかすかに乗っているが,これはShortTimeFFTのistftによる影響もあるだろうか.
- サンプル1
オリジナルの音声:
復元音声:
GLA | Amp | Rnd | vM |
---|---|---|---|
0 | |||
10 | |||
100 |
- サンプル2
オリジナルの音声:
復元音声:
GLA | Amp | Rnd | vM |
---|---|---|---|
0 | |||
10 | |||
100 |
おわりに
本記事ではvon Mises分布DNNに基づく位相復元技術を実装した.簡単な評価実験により,件の手法は客観評価指標を改善できることが確かめられた(少なくともGLAなしのとき).位相復元手法は他にも多くあるので,色々と実装してみたい.
追記
Recurrent phase unwrapping (RPU) に基づく位相復元手法を実装したのは以下の記事にて.
以下はRPUをさらに改善した「重みつきRPU」の記事.