PyTorch 1.3 Tutorials : 音声 : torchaudio チュートリアル (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/22/2019 (1.3.1)
* 本ページは、PyTorch 1.3 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:
- Audio : torchaudio Tutorial
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
音声 : torchaudio チュートリアル
PyTorch はオープンソースの深層学習プラットフォームで、GPU サポートとともに研究プロトタイピングからプロダクション配備までシームレスなパスを提供します。
機械学習問題を解く重要な努力はデータ準備に進んでいます。torchaudio は PyTorch の GPU サポートを活用し、そしてデータロードを容易にしてより可読にするために多くのツールを提供します。このチュートリアルでは、単純なデータセットからデータをどのようにロードして前処理するかを見ます。
このチュートリアルのために、容易な可視化のために matplotlib パッケージがインストールされていることを確実にしてください。
import torch import torchaudio import matplotlib.pyplot as plt
データセットをオープンする
torchaudio は wav と mp3 形式の音声ファイルのロードをサポートします。結果としての生音声信号を waveform 呼び出しをします。
filename = "../_static/img/steam-train-whistle-daniel_simon-converted-from-mp3.wav" waveform, sample_rate = torchaudio.load(filename) print("Shape of waveform: {}".format(waveform.size())) print("Sample rate of waveform: {}".format(sample_rate)) plt.figure() plt.plot(waveform.t().numpy())
Shape of waveform: torch.Size([2, 276858]) Sample rate of waveform: 44100
変換
torchaudio は次の変換の増大するリストをサポートします。
- Resample: 異なるサンプルレートで waveform を再サンプリングする。
- Spectrogram: waveform からスペクトログラムを作成する。
- MelScale: これは変換行列を使用して、normal STFT をメル周波数 STFT に変える。
- AmplitudeToDB: これはパワー/振幅スケールからのスペクトログラムをデシベル・スケールに変える。
- MFCC: waveform からメル周波数ケプストラム係数を作成する。
- MelSpectrogram: PyTorch の STFT 関数を使用して waveform からメル・スペクトログラムを作成する。
- MuLawEncoding: μ-law 圧伸に基づいて waveform をエンコードする。
- MuLawDecoding: μ-lay エンコードされた waveform をデコードする。
総ての変換は nn.Modules か jit.ScriptModules ですので、それらは任意のポイントでニューラルネットワークの一部として使用できます。
始めるために、log スケールでスペクトログラムの log を見ることができます。
specgram = torchaudio.transforms.Spectrogram()(waveform) print("Shape of spectrogram: {}".format(specgram.size())) plt.figure() plt.imshow(specgram.log2()[0,:,:].numpy(), cmap='gray')
Shape of spectrogram: torch.Size([2, 201, 1385])
あるいは log スケールでメル・スペクトログラムを見ることができます。
specgram = torchaudio.transforms.MelSpectrogram()(waveform) print("Shape of spectrogram: {}".format(specgram.size())) plt.figure() p = plt.imshow(specgram.log2()[0,:,:].detach().numpy(), cmap='gray')
Shape of spectrogram: torch.Size([2, 128, 1385])
一度に 1 チャネルで、waveform を再サンプリングすることができます。
new_sample_rate = sample_rate/10 # Since Resample applies to a single channel, we resample first channel here channel = 0 transformed = torchaudio.transforms.Resample(sample_rate, new_sample_rate)(waveform[channel,:].view(1,-1)) print("Shape of transformed waveform: {}".format(transformed.size())) plt.figure() plt.plot(transformed[0,:].numpy())
Shape of transformed waveform: torch.Size([1, 27686])
変換のもう一つの例として、μ-Law エンコーディングに基して信号をエンコードできます。しかしそのためには、信号が -1 と 1 の間にあることを必要とします。tensor は単なる通常の PyTorch tensor ですので、その上で標準的な演算を適用できます。
# Let's check if the tensor is in the interval [-1,1] print("Min of waveform: {}\nMax of waveform: {}\nMean of waveform: {}".format(waveform.min(), waveform.max(), waveform.mean()))
Min of waveform: -0.572845458984375 Max of waveform: 0.575958251953125 Mean of waveform: 9.293758921558037e-05
waveform は既に -1 と 1 の間ですので、それを正規化する必要はありません。
def normalize(tensor): # Subtract the mean, and scale to the interval [-1,1] tensor_minusmean = tensor - tensor.mean() return tensor_minusmean/tensor_minusmean.abs().max() # Let's normalize to the full interval [-1,1] # waveform = normalize(waveform)
waveform のエンコードを適用しましょう。
transformed = torchaudio.transforms.MuLawEncoding()(waveform) print("Shape of transformed waveform: {}".format(transformed.size())) plt.figure() plt.plot(transformed[0,:].numpy())
Shape of transformed waveform: torch.Size([2, 276858])
そして今はデコードします。
reconstructed = torchaudio.transforms.MuLawDecoding()(transformed) print("Shape of recovered waveform: {}".format(reconstructed.size())) plt.figure() plt.plot(reconstructed[0,:].numpy())
Shape of recovered waveform: torch.Size([2, 276858])
最後に元の waveform を再構築されたバージョンと比較できます。
# Compute median relative difference err = ((waveform-reconstructed).abs() / waveform.abs()).median() print("Median relative difference between original and MuLaw reconstucted signals: {:.2%}".format(err))
Median relative difference between original and MuLaw reconstucted signals: 1.28%
Kaldi から torchaudio にマイグレートする
ユーザは Kaldi、発話認識のためのツールキットに馴染みがあるかもしれません。torchaudio は torchaudio.kaldi_io でそれとの互換性を提供します。それは実際には kaldi scp、または ark ファイルあるいは次によるストリームから読むことができます :
- read_vec_int_ark
- read_vec_flt_scp
- read_vec_flt_arkfile/stream
- read_mat_scp
- read_mat_ark
torhaudio はスペクトログラムと fbank のための Kaldi-互換な変換を GPU サポートの利点とともに提供します、より多くの情報については こちら を見てください。
n_fft = 400.0 frame_length = n_fft / sample_rate * 1000.0 frame_shift = frame_length / 2.0 params = { "channel": 0, "dither": 0.0, "window_type": "hanning", "frame_length": frame_length, "frame_shift": frame_shift, "remove_dc_offset": False, "round_to_power_of_two": False, "sample_frequency": sample_rate, } specgram = torchaudio.compliance.kaldi.spectrogram(waveform, **params) print("Shape of spectrogram: {}".format(specgram.size())) plt.figure() plt.imshow(specgram.t().numpy(), cmap='gray')
Shape of spectrogram: torch.Size([1383, 201])
Kaldi の実装に適合させて、waveform からの filterbank 特徴の計算もまたサポートしています。
fbank = torchaudio.compliance.kaldi.fbank(waveform, **params) print("Shape of fbank: {}".format(fbank.size())) plt.figure() plt.imshow(fbank.t().numpy(), cmap='gray')
Shape of fbank: torch.Size([1383, 23])
終わりに
サンプル生音声信号、あるいは waveform を使用して、torchaudio を使用してどのように音声ファイルをオープンするか、そしてそのような waveform をどのように前処理して変換するかを示しました。torchaudio が PyTorch 上で構築されたとすると、これらのテクニックは、GPU を活用しながら、発話認識のようなより進んだ音声アプリケーションのためのビルディングブロックとして使用できます。
以上