PyTorch 1.3 Tutorials : 音声 : torchaudio チュートリアル

PyTorch 1.3 Tutorials : 音声 : torchaudio チュートリアル (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/22/2019 (1.3.1)

* 本ページは、PyTorch 1.3 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、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 を活用しながら、発話認識のようなより進んだ音声アプリケーションのためのビルディングブロックとして使用できます。

 
以上