PyTorch torchaudio教程

2020-09-09 15:16 更新
標(biāo)題: https://pytorch.org/tutorials/beginner/audio_preprocessing_tutorial.html

PyTorch 是一個(gè)開源深度學(xué)習(xí)平臺(tái),提供了從研究原型到具有 GPU 支持的生產(chǎn)部署的無縫路徑。

解決機(jī)器學(xué)習(xí)問題的巨大努力在于數(shù)據(jù)準(zhǔn)備。 torchaudio充分利用了 PyTorch 的 GPU 支持,并提供了許多工具來簡化數(shù)據(jù)加載并使其更具可讀性。 在本教程中,我們將看到如何從簡單的數(shù)據(jù)集中加載和預(yù)處理數(shù)據(jù)。

對于本教程,請確保已安裝matplotlib軟件包,以便于查看。

  1. import torch
  2. import torchaudio
  3. import matplotlib.pyplot as plt

開啟檔案

torchaudio還支持以 wav 和 mp3 格式加載聲音文件。 我們將波形稱為原始音頻信號。

  1. filename = "../_static/img/steam-train-whistle-daniel_simon-converted-from-mp3.wav"
  2. waveform, sample_rate = torchaudio.load(filename)
  3. print("Shape of waveform: {}".format(waveform.size()))
  4. print("Sample rate of waveform: {}".format(sample_rate))
  5. plt.figure()
  6. plt.plot(waveform.t().numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_001.png

得出:

  1. Shape of waveform: torch.Size([2, 276858])
  2. Sample rate of waveform: 44100

torchaudio中加載文件時(shí),可以選擇指定后端以通過torchaudio.set_audio_backend使用 SoX 或 SoundFile 。 這些后端在需要時(shí)會(huì)延遲加載。

torchaudio還使 JIT 編譯對于功能是可選的,并在可能的情況下使用nn.Module。

轉(zhuǎn)變

torchaudio支持不斷增長的轉(zhuǎn)換列表。

  • 重采樣:將波形重采樣為其他采樣率。
  • 頻譜圖:從波形創(chuàng)建頻譜圖。
  • GriffinLim :使用 Griffin-Lim 轉(zhuǎn)換從線性比例幅度譜圖計(jì)算波形。
  • ComputeDeltas :計(jì)算張量(通常是聲譜圖)的增量系數(shù)。
  • ComplexNorm :計(jì)算復(fù)數(shù)張量的范數(shù)。
  • MelScale :使用轉(zhuǎn)換矩陣將正常 STFT 轉(zhuǎn)換為 Mel 頻率 STFT。
  • AmplitudeToDB :這將頻譜圖從功率/振幅標(biāo)度變?yōu)榉重悩?biāo)度。
  • MFCC :根據(jù)波形創(chuàng)建梅爾頻率倒譜系數(shù)。
  • MelSpectrogram :使用 PyTorch 中的 STFT 功能從波形創(chuàng)建 MEL 頻譜圖。
  • MuLawEncoding :基于 mu-law 壓擴(kuò)對波形進(jìn)行編碼。
  • MuLawDecoding :解碼 mu-law 編碼波形。
  • TimeStretch :在不更改給定速率的音高的情況下,及時(shí)拉伸頻譜圖。
  • FrequencyMasking :在頻域中對頻譜圖應(yīng)用屏蔽。
  • TimeMasking :在時(shí)域中對頻譜圖應(yīng)用屏蔽。

每個(gè)變換都支持批處理:您可以對單個(gè)原始音頻信號或頻譜圖或許多相同形狀的信號執(zhí)行變換。

由于所有變換都是nn.Modulesjit.ScriptModules,因此它們可以隨時(shí)用作神經(jīng)網(wǎng)絡(luò)的一部分。

首先,我們可以以對數(shù)刻度查看頻譜圖的對數(shù)。

  1. specgram = torchaudio.transforms.Spectrogram()(waveform)
  2. print("Shape of spectrogram: {}".format(specgram.size()))
  3. plt.figure()
  4. plt.imshow(specgram.log2()[0,:,:].numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_002.png

得出:

  1. Shape of spectrogram: torch.Size([2, 201, 1385])

或者我們可以以對數(shù)刻度查看梅爾光譜圖。

  1. specgram = torchaudio.transforms.MelSpectrogram()(waveform)
  2. print("Shape of spectrogram: {}".format(specgram.size()))
  3. plt.figure()
  4. p = plt.imshow(specgram.log2()[0,:,:].detach().numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_003.png

得出:

  1. Shape of spectrogram: torch.Size([2, 128, 1385])

我們可以一次對一個(gè)通道重新采樣波形。

  1. new_sample_rate = sample_rate/10
  2. ## Since Resample applies to a single channel, we resample first channel here
  3. channel = 0
  4. transformed = torchaudio.transforms.Resample(sample_rate, new_sample_rate)(waveform[channel,:].view(1,-1))
  5. print("Shape of transformed waveform: {}".format(transformed.size()))
  6. plt.figure()
  7. plt.plot(transformed[0,:].numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_004.png

得出:

  1. Shape of transformed waveform: torch.Size([1, 27686])

作為變換的另一個(gè)示例,我們可以基于 Mu-Law 編碼對信號進(jìn)行編碼。 但是要做到這一點(diǎn),我們需要信號在-1 和 1 之間。由于張量只是一個(gè)常規(guī)的 PyTorch 張量,因此我們可以在其上應(yīng)用標(biāo)準(zhǔn)運(yùn)算符。

  1. # Let's check if the tensor is in the interval [-1,1]
  2. print("Min of waveform: {}\nMax of waveform: {}\nMean of waveform: {}".format(waveform.min(), waveform.max(), waveform.mean()))

得出:

  1. Min of waveform: -0.572845458984375
  2. Max of waveform: 0.575958251953125
  3. Mean of waveform: 9.293758921558037e-05

由于波形已經(jīng)在 -1 和 1 之間,因此我們不需要對其進(jìn)行歸一化。

  1. def normalize(tensor):
  2. # Subtract the mean, and scale to the interval [-1,1]
  3. tensor_minusmean = tensor - tensor.mean()
  4. return tensor_minusmean/tensor_minusmean.abs().max()
  5. ## Let's normalize to the full interval [-1,1]
  6. ## waveform = normalize(waveform)

讓我們對波形進(jìn)行編碼。

  1. transformed = torchaudio.transforms.MuLawEncoding()(waveform)
  2. print("Shape of transformed waveform: {}".format(transformed.size()))
  3. plt.figure()
  4. plt.plot(transformed[0,:].numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_005.png

得出:

  1. Shape of transformed waveform: torch.Size([2, 276858])

現(xiàn)在解碼。

  1. reconstructed = torchaudio.transforms.MuLawDecoding()(transformed)
  2. print("Shape of recovered waveform: {}".format(reconstructed.size()))
  3. plt.figure()
  4. plt.plot(reconstructed[0,:].numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_006.png

得出:

  1. Shape of recovered waveform: torch.Size([2, 276858])

我們最終可以將原始波形與其重建版本進(jìn)行比較。

  1. # Compute median relative difference
  2. err = ((waveform-reconstructed).abs() / waveform.abs()).median()
  3. print("Median relative difference between original and MuLaw reconstucted signals: {:.2%}".format(err))

得出:

  1. Median relative difference between original and MuLaw reconstucted signals: 1.28%

功能性

上面看到的轉(zhuǎn)換依賴于較低級別的無狀態(tài)函數(shù)進(jìn)行計(jì)算。 這些功能在torchaudio.functional下可用。 完整列表位于,此處為包括

  • istft :短時(shí)傅立葉逆變換。
  • 增益:對整個(gè)波形進(jìn)行放大或衰減。
  • 抖動(dòng):增加以特定位深度存儲(chǔ)的音頻的動(dòng)態(tài)范圍。
  • compute_deltas :計(jì)算張量的增量系數(shù)。
  • equalizer_biquad :設(shè)計(jì)雙二階峰均化器濾波器并執(zhí)行濾波。
  • lowpass_biquad :設(shè)計(jì)雙二階低通濾波器并執(zhí)行濾波。
  • highpass_biquad :設(shè)計(jì)雙二階高通濾波器并執(zhí)行濾波。

例如,讓我們嘗試 <cite>mu_law_encoding</cite> 功能:

  1. mu_law_encoding_waveform = torchaudio.functional.mu_law_encoding(waveform, quantization_channels=256)
  2. print("Shape of transformed waveform: {}".format(mu_law_encoding_waveform.size()))
  3. plt.figure()
  4. plt.plot(mu_law_encoding_waveform[0,:].numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_007.png

得出:

  1. Shape of transformed waveform: torch.Size([2, 276858])

您可以看到從torchaudio.functional.mu_law_encoding的輸出與從torchaudio.transforms.MuLawEncoding的輸出相同。

現(xiàn)在,讓我們嘗試其他一些功能并將其輸出可視化。 通過我們的頻譜圖,我們可以計(jì)算出其增量:

  1. computed = torchaudio.functional.compute_deltas(specgram, win_length=3)
  2. print("Shape of computed deltas: {}".format(computed.shape))
  3. plt.figure()
  4. plt.imshow(computed.log2()[0,:,:].detach().numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_008.png

得出:

  1. Shape of computed deltas: torch.Size([2, 128, 1385])

我們可以獲取原始波形并對其應(yīng)用不同的效果。

  1. gain_waveform = torchaudio.functional.gain(waveform, gain_db=5.0)
  2. print("Min of gain_waveform: {}\nMax of gain_waveform: {}\nMean of gain_waveform: {}".format(gain_waveform.min(), gain_waveform.max(), gain_waveform.mean()))
  3. dither_waveform = torchaudio.functional.dither(waveform)
  4. print("Min of dither_waveform: {}\nMax of dither_waveform: {}\nMean of dither_waveform: {}".format(dither_waveform.min(), dither_waveform.max(), dither_waveform.mean()))

得出:

  1. Min of gain_waveform: -1.0186792612075806
  2. Max of gain_waveform: 1.024214744567871
  3. Mean of gain_waveform: 0.00016526904073543847
  4. Min of dither_waveform: -0.572784423828125
  5. Max of dither_waveform: 0.575927734375
  6. Mean of dither_waveform: 0.00010744280007202178

torchaudio.functional中功能的另一個(gè)示例是將濾波器應(yīng)用于我們的波形。 將低通雙二階濾波器應(yīng)用于我們的波形,將輸出修改了頻率信號的新波形。

  1. lowpass_waveform = torchaudio.functional.lowpass_biquad(waveform, sample_rate, cutoff_freq=3000)
  2. print("Min of lowpass_waveform: {}\nMax of lowpass_waveform: {}\nMean of lowpass_waveform: {}".format(lowpass_waveform.min(), lowpass_waveform.max(), lowpass_waveform.mean()))
  3. plt.figure()
  4. plt.plot(lowpass_waveform.t().numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_009.png

得出:

  1. Min of lowpass_waveform: -0.5595061182975769
  2. Max of lowpass_waveform: 0.5595013499259949
  3. Mean of lowpass_waveform: 9.293758921558037e-05

我們還可以使用高通雙二階濾波器可視化波形。

  1. highpass_waveform = torchaudio.functional.highpass_biquad(waveform, sample_rate, cutoff_freq=2000)
  2. print("Min of highpass_waveform: {}\nMax of highpass_waveform: {}\nMean of highpass_waveform: {}".format(highpass_waveform.min(), highpass_waveform.max(), highpass_waveform.mean()))
  3. plt.figure()
  4. plt.plot(highpass_waveform.t().numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_010.png

得出:

  1. Min of highpass_waveform: -0.11269105970859528
  2. Max of highpass_waveform: 0.10451901704072952
  3. Mean of highpass_waveform: -4.971002776077427e-12

從 Kaldi 遷移到 Torchaudio

用戶可能熟悉 Kaldi (一種用于語音識(shí)別的工具包)。 torchaudio提供與torchaudio.kaldi_io中的兼容性。 實(shí)際上,它可以通過以下方式從 kaldi scp 或 ark 文件或流中讀?。?/p>

  • read_vec_int_ark
  • read_vec_flt_scp
  • read_vec_flt_arkfile / stream
  • read_mat_scp
  • read_mat_ark

torchaudiospectrogram,fbank,mfcc和提供 Kaldi 兼容的轉(zhuǎn)換。 resample_waveform 受益于 GPU 支持。

  1. n_fft = 400.0
  2. frame_length = n_fft / sample_rate * 1000.0
  3. frame_shift = frame_length / 2.0
  4. params = {
  5. "channel": 0,
  6. "dither": 0.0,
  7. "window_type": "hanning",
  8. "frame_length": frame_length,
  9. "frame_shift": frame_shift,
  10. "remove_dc_offset": False,
  11. "round_to_power_of_two": False,
  12. "sample_frequency": sample_rate,
  13. }
  14. specgram = torchaudio.compliance.kaldi.spectrogram(waveform, **params)
  15. print("Shape of spectrogram: {}".format(specgram.size()))
  16. plt.figure()
  17. plt.imshow(specgram.t().numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_011.png

得出:

  1. Shape of spectrogram: torch.Size([1383, 201])

我們還支持根據(jù)波形計(jì)算濾波器組功能,以匹配 Kaldi 的實(shí)現(xiàn)。

  1. fbank = torchaudio.compliance.kaldi.fbank(waveform, **params)
  2. print("Shape of fbank: {}".format(fbank.size()))
  3. plt.figure()
  4. plt.imshow(fbank.t().numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_012.png

得出:

  1. Shape of fbank: torch.Size([1383, 23])

您可以從原始音頻信號創(chuàng)建梅爾頻率倒譜系數(shù),這與 Kaldi 的 compute-mfcc-feats 的輸入/輸出相匹配。

  1. mfcc = torchaudio.compliance.kaldi.mfcc(waveform, **params)
  2. print("Shape of mfcc: {}".format(mfcc.size()))
  3. plt.figure()
  4. plt.imshow(mfcc.t().numpy(), cmap='gray')

../_images/sphx_glr_audio_preprocessing_tutorial_013.png

得出:

  1. Shape of mfcc: torch.Size([1383, 13])

可用數(shù)據(jù)集

如果您不想創(chuàng)建自己的數(shù)據(jù)集來訓(xùn)練模型,則torchaudio提供了統(tǒng)一的數(shù)據(jù)集界面。 該接口支持將文件延遲加載到內(nèi)存,下載和提取函數(shù)以及數(shù)據(jù)集以構(gòu)建模型。

當(dāng)前支持的數(shù)據(jù)集torchaudio為:

  • VCTK :109 位以英語為母語的母語者發(fā)出的語音數(shù)據(jù),帶有各種重音(在此處詳細(xì)了解)。
  • 是或否:一個(gè)人在希伯來語中說是或否的 60 張錄音; 每個(gè)記錄長 8 個(gè)字(此處更多信息)。
  • 通用語音:開源的多語言語音數(shù)據(jù)集,任何人都可以用來訓(xùn)練啟用語音的應(yīng)用程序(在此處了解更多)。
  • LibriSpeech :閱讀英語語音的大型語料庫(1000 小時(shí))(在此處詳細(xì)了解)。
  1. yesno_data = torchaudio.datasets.YESNO('./', download=True)
  2. ## A data point in Yesno is a tuple (waveform, sample_rate, labels) where labels is a list of integers with 1 for yes and 0 for no.
  3. ## Pick data point number 3 to see an example of the the yesno_data:
  4. n = 3
  5. waveform, sample_rate, labels = yesno_data[n]
  6. print("Waveform: {}\nSample rate: {}\nLabels: {}".format(waveform, sample_rate, labels))
  7. plt.figure()
  8. plt.plot(waveform.t().numpy())

../_images/sphx_glr_audio_preprocessing_tutorial_014.png

得出:

  1. Waveform: tensor([[3.0518e-05, 6.1035e-05, 3.0518e-05, ..., 5.8594e-03, 3.5400e-03,
  2. 3.3569e-04]])
  3. Sample rate: 8000
  4. Labels: [0, 1, 0, 0, 1, 0, 1, 0]

現(xiàn)在,每當(dāng)您從數(shù)據(jù)集中請求聲音文件時(shí),僅當(dāng)您請求聲音文件時(shí),它才會(huì)加載到內(nèi)存中。 意思是,數(shù)據(jù)集僅加載您想要和使用的項(xiàng)目并將其保留在內(nèi)存中,并保存在內(nèi)存中。

結(jié)論

我們使用示例原始音頻信號或波形來說明如何使用torchaudio打開音頻文件,以及如何對該波形進(jìn)行預(yù)處理,轉(zhuǎn)換和應(yīng)用功能。 我們還演示了如何使用熟悉的 Kaldi 函數(shù)以及如何使用內(nèi)置數(shù)據(jù)集來構(gòu)建模型。 鑒于torchaudio是基于 PyTorch 構(gòu)建的,因此這些技術(shù)可在利用 GPU 的同時(shí),用作更高級音頻應(yīng)用(例如語音識(shí)別)的構(gòu)建塊。

腳本的總運(yùn)行時(shí)間:(0 分鐘 39.004 秒)

Download Python source code: audio_preprocessing_tutorial.py Download Jupyter notebook: audio_preprocessing_tutorial.ipynb

由獅身人面像畫廊生成的畫廊


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號