標(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
軟件包,以便于查看。
import torch
import torchaudio
import matplotlib.pyplot as plt
torchaudio
還支持以 wav 和 mp3 格式加載聲音文件。 我們將波形稱為原始音頻信號。
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
中加載文件時(shí),可以選擇指定后端以通過torchaudio.set_audio_backend
使用 SoX 或 SoundFile 。
這些后端在需要時(shí)會(huì)延遲加載。
torchaudio
還使 JIT 編譯對于功能是可選的,并在可能的情況下使用nn.Module
。
torchaudio
支持不斷增長的轉(zhuǎn)換列表。
每個(gè)變換都支持批處理:您可以對單個(gè)原始音頻信號或頻譜圖或許多相同形狀的信號執(zhí)行變換。
由于所有變換都是nn.Modules
或jit.ScriptModules
,因此它們可以隨時(shí)用作神經(jīng)網(wǎng)絡(luò)的一部分。
首先,我們可以以對數(shù)刻度查看頻譜圖的對數(shù)。
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])
或者我們可以以對數(shù)刻度查看梅爾光譜圖。
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])
我們可以一次對一個(gè)通道重新采樣波形。
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])
作為變換的另一個(gè)示例,我們可以基于 Mu-Law 編碼對信號進(jìn)行編碼。 但是要做到這一點(diǎn),我們需要信號在-1 和 1 之間。由于張量只是一個(gè)常規(guī)的 PyTorch 張量,因此我們可以在其上應(yīng)用標(biāo)準(zhǔn)運(yùn)算符。
# 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
由于波形已經(jīng)在 -1 和 1 之間,因此我們不需要對其進(jìn)行歸一化。
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)
讓我們對波形進(jìn)行編碼。
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])
現(xiàn)在解碼。
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])
我們最終可以將原始波形與其重建版本進(jìn)行比較。
# 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%
上面看到的轉(zhuǎn)換依賴于較低級別的無狀態(tài)函數(shù)進(jìn)行計(jì)算。 這些功能在torchaudio.functional
下可用。 完整列表位于,此處為包括
例如,讓我們嘗試 <cite>mu_law_encoding</cite> 功能:
mu_law_encoding_waveform = torchaudio.functional.mu_law_encoding(waveform, quantization_channels=256)
print("Shape of transformed waveform: {}".format(mu_law_encoding_waveform.size()))
plt.figure()
plt.plot(mu_law_encoding_waveform[0,:].numpy())
得出:
Shape of transformed waveform: torch.Size([2, 276858])
您可以看到從torchaudio.functional.mu_law_encoding
的輸出與從torchaudio.transforms.MuLawEncoding
的輸出相同。
現(xiàn)在,讓我們嘗試其他一些功能并將其輸出可視化。 通過我們的頻譜圖,我們可以計(jì)算出其增量:
computed = torchaudio.functional.compute_deltas(specgram, win_length=3)
print("Shape of computed deltas: {}".format(computed.shape))
plt.figure()
plt.imshow(computed.log2()[0,:,:].detach().numpy(), cmap='gray')
得出:
Shape of computed deltas: torch.Size([2, 128, 1385])
我們可以獲取原始波形并對其應(yīng)用不同的效果。
gain_waveform = torchaudio.functional.gain(waveform, gain_db=5.0)
print("Min of gain_waveform: {}\nMax of gain_waveform: {}\nMean of gain_waveform: {}".format(gain_waveform.min(), gain_waveform.max(), gain_waveform.mean()))
dither_waveform = torchaudio.functional.dither(waveform)
print("Min of dither_waveform: {}\nMax of dither_waveform: {}\nMean of dither_waveform: {}".format(dither_waveform.min(), dither_waveform.max(), dither_waveform.mean()))
得出:
Min of gain_waveform: -1.0186792612075806
Max of gain_waveform: 1.024214744567871
Mean of gain_waveform: 0.00016526904073543847
Min of dither_waveform: -0.572784423828125
Max of dither_waveform: 0.575927734375
Mean of dither_waveform: 0.00010744280007202178
torchaudio.functional
中功能的另一個(gè)示例是將濾波器應(yīng)用于我們的波形。 將低通雙二階濾波器應(yīng)用于我們的波形,將輸出修改了頻率信號的新波形。
lowpass_waveform = torchaudio.functional.lowpass_biquad(waveform, sample_rate, cutoff_freq=3000)
print("Min of lowpass_waveform: {}\nMax of lowpass_waveform: {}\nMean of lowpass_waveform: {}".format(lowpass_waveform.min(), lowpass_waveform.max(), lowpass_waveform.mean()))
plt.figure()
plt.plot(lowpass_waveform.t().numpy())
得出:
Min of lowpass_waveform: -0.5595061182975769
Max of lowpass_waveform: 0.5595013499259949
Mean of lowpass_waveform: 9.293758921558037e-05
我們還可以使用高通雙二階濾波器可視化波形。
highpass_waveform = torchaudio.functional.highpass_biquad(waveform, sample_rate, cutoff_freq=2000)
print("Min of highpass_waveform: {}\nMax of highpass_waveform: {}\nMean of highpass_waveform: {}".format(highpass_waveform.min(), highpass_waveform.max(), highpass_waveform.mean()))
plt.figure()
plt.plot(highpass_waveform.t().numpy())
得出:
Min of highpass_waveform: -0.11269105970859528
Max of highpass_waveform: 0.10451901704072952
Mean of highpass_waveform: -4.971002776077427e-12
用戶可能熟悉 Kaldi (一種用于語音識(shí)別的工具包)。 torchaudio
提供與torchaudio.kaldi_io
中的兼容性。 實(shí)際上,它可以通過以下方式從 kaldi scp 或 ark 文件或流中讀?。?/p>
torchaudio
為spectrogram
,fbank
,mfcc
和提供 Kaldi 兼容的轉(zhuǎn)換。 resample_waveform 受益于 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])
我們還支持根據(jù)波形計(jì)算濾波器組功能,以匹配 Kaldi 的實(shí)現(xiàn)。
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])
您可以從原始音頻信號創(chuàng)建梅爾頻率倒譜系數(shù),這與 Kaldi 的 compute-mfcc-feats 的輸入/輸出相匹配。
mfcc = torchaudio.compliance.kaldi.mfcc(waveform, **params)
print("Shape of mfcc: {}".format(mfcc.size()))
plt.figure()
plt.imshow(mfcc.t().numpy(), cmap='gray')
得出:
Shape of mfcc: torch.Size([1383, 13])
如果您不想創(chuàng)建自己的數(shù)據(jù)集來訓(xùn)練模型,則torchaudio
提供了統(tǒng)一的數(shù)據(jù)集界面。 該接口支持將文件延遲加載到內(nèi)存,下載和提取函數(shù)以及數(shù)據(jù)集以構(gòu)建模型。
當(dāng)前支持的數(shù)據(jù)集torchaudio
為:
yesno_data = torchaudio.datasets.YESNO('./', download=True)
## 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.
## Pick data point number 3 to see an example of the the yesno_data:
n = 3
waveform, sample_rate, labels = yesno_data[n]
print("Waveform: {}\nSample rate: {}\nLabels: {}".format(waveform, sample_rate, labels))
plt.figure()
plt.plot(waveform.t().numpy())
得出:
Waveform: tensor([[3.0518e-05, 6.1035e-05, 3.0518e-05, ..., 5.8594e-03, 3.5400e-03,
3.3569e-04]])
Sample rate: 8000
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)存中。
我們使用示例原始音頻信號或波形來說明如何使用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
由獅身人面像畫廊生成的畫廊
更多建議: