作者|Ayisha D
編譯|VK
來源|Towards Data Science
這篇文章中,我們探討從語音數據中提取的特征,以及基於這些特征構建模型的不同方法。
語音數字(Spoken digits)數據集是Tensorflow語音數據集的一個子集,它包括數字0-9之外的其他錄音。在這里,我們只關注識別口語數字。
數據集可以按如下方式下載。
data = download_url("http://download.tensorflow.org/data/speech_commands_v0.01.tar.gz", "/content/")
with tarfile.open('/content/speech_commands_v0.01.tar.gz', 'r:gz') as tar:
tar.extractall(path='./data')
Downloading http://download.tensorflow.org/data/speech_commands_v0.01.tar.gz to /content/speech_commands_v0.01.tar.gz
HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))
digit = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
for x in digit:
print(x, ": ", len(os.listdir('/content/data/'+x)))
#平衡
zero : 2376
one : 2370
two : 2373
three : 2356
four : 2372
five : 2357
six : 2369
seven : 2377
eight : 2352
nine : 2364
評估指標
數字相當平衡,每個類有大約2300個樣本。因此,准確度是評估模型性能的一個很好的指標。准確度是正確預測數與總預測數的比較。
對於不平衡的數據集,這不是一個很好的性能度量,因為少數類可能會黯然失色。
循環學習率
在訓練一個模型時,學習率逐漸降低,以對訓練進行微調。為了提高學習效率,可以采用循環學習率。在這里,學習率在不同時期的最小值和最大值之間波動,而不是單調下降。
初始訓練率對模型的性能至關重要,低訓練率可防止在訓練開始時被卡住,隨后的波動抑制了局部極小值的情況。
該項目有三種分類方法:
-
使用五個提取的特征進行Logistic回歸分析,准確率為76.19%。
-
僅使用MFCCs的Logistic回歸-准確率為95.56%。
-
CNN使用Mel譜圖-准確率為95.81%。
通過改變epoch和訓練率對模型進行反復訓練。隱藏層的數量和每個層中的節點也各不相同。這里描述了每種方法的最佳架構和超參數。由於訓練和驗證集划分的隨機性,再訓練的精確度可能略有不同。
項目的源代碼在這里:https://github.com/AyishaR/Spokendigit
有五個.ipynb文件:
-
特征提取-提取三種方法所需的CSV文件和特征。
-
特征可視化-在每個類中繪制特征圖。
-
Spokendigit五個特征-使用五個提取的特征實現邏輯回歸。
-
Spokendigit MFFC-使用MFCC實現邏輯回歸。
-
Spokendigit CNN-使用Mel譜圖實現CNN。
1.使用五個提取特征的Logistic回歸
特征
提取的特征包括:
- Mel Frequency Cepstral Coefficients (MFCCs)-根據人類聽覺系統的響應(Mel尺度)間隔的頻帶組成聲音的頻譜表示的系數。
- Chroma -與12個不同的音高等級有關。
- Mel spectrogram的平均值-基於Mel標度的Mel譜圖。
- Spectral Contrast-表示譜的質心。
- Tonnetz -代表音調空間。
這些特征是大小為(20,)(12,)(128,)(7,)和(6,)的NumPy數組。這些連接起來形成一個大小為(173,)的特征數組。標簽被附加到數組的頭部,並寫入每個記錄的CSV文件中。
def extract_features(files):
data, sr = librosa.load('/content/data/'+files.File)
mfccs = np.mean(librosa.feature.mfcc(y = data, sr=sr).T, axis = 0)
stft = np.abs(librosa.stft(data))
chroma = np.mean(librosa.feature.chroma_stft(S = stft, sr = sr).T, axis = 0)
mel = np.mean(librosa.feature.melspectrogram(data, sr).T, axis = 0)
contrast = np.mean(librosa.feature.spectral_contrast(S = stft, sr = sr).T, axis = 0)
tonnetz = np.mean(librosa.feature.tonnetz(y = librosa.effects.harmonic(data), sr = sr).T, axis = 0)
#print(mfccs.shape, stft.shape, chroma.shape, mel.shape, contrast.shape, tonnetz.shape)
row = np.concatenate((mfccs, chroma, mel, contrast, tonnetz), axis = 0).astype('float32')
csvwriter.writerow(np.concatenate(([digit.index(files.Label)], row)))
模型
線性回歸模型共有1個輸入層、2個隱藏層和1個帶ReLu激活的輸出層。
class SpokenDigitModel(nn.Module):
def __init__(self):
super().__init__()
self.l1 = nn.Linear(173, 1024)
self.l2 = nn.Linear(1024, 512)
self.l3 = nn.Linear(512, 64)
self.l4 = nn.Linear(64, 10)
def forward(self, x):
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = self.l4(x)
return x
def training_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
return loss
def validation_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
_, pred = torch.max(outputs, 1)
accuracy = torch.tensor(torch.sum(pred==labels).item()/len(pred))
return [loss.detach(), accuracy.detach()]
訓練
model = to_device(SpokenDigitModel(), device)
history = []
evaluate(model, val_dl)
{'accuracy': 0.10285229980945587, 'loss': 3.1926627159118652}
history.append(fit(model, train_dl, val_dl, 64, 0.01))
r = evaluate(model, val_dl)
yp, yt = predict_dl(model, val_dl)
print("Loss: ", r['loss'], "\nAccuracy: ", r['accuracy'], "\nF-score: ", f1_score(yt, yp, average='micro'))
Loss: 2.0203850269317627
Accuracy: 0.7619398832321167
F-score: 0.7586644125105664
該模型在CPU上訓練約3分鍾,准確率為76.19%。
plot(losses, 'Losses')
從最小值開始,最終驗證損失慢慢變大。
plot(accuracies, 'Accuracy')
以上為准確率曲線
plot(last_lr, 'Last Learning Rate')
以上為每一epoch的學習率曲線
2.僅使用MFCCs的Logistic回歸
特征
該模型僅使用Mel頻率倒譜系數(MFCCs)。這個特征是一個大小為(20,)的NumPy數組。它從包含上述所有特征的CSV文件中檢索。
模型
線性回歸模型共有1個輸入層、2個隱藏層和1個帶ReLu激活的輸出層。
class SpokenDigitModel(nn.Module):
def __init__(self):
super().__init__()
self.l1 = nn.Linear(20, 1024)
self.l2 = nn.Linear(1024, 512)
self.l3 = nn.Linear(512, 64)
self.l4 = nn.Linear(64, 10)
def forward(self, x):
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = self.l4(x)
return x
def training_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
return loss
def validation_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
_, pred = torch.max(outputs, 1)
accuracy = torch.tensor(torch.sum(pred==labels).item()/len(pred))
return [loss.detach(), accuracy.detach()]
訓練
model = to_device(SpokenDigitModel(), device)
history = []
evaluate(model, val_dl)
{'accuracy': 0.08834186941385269, 'loss': 8.290132522583008}
history.append(fit(model, train_dl, val_dl, 128, 0.001))
r = evaluate(model, val_dl)
yp, yt = predict_dl(model, val_dl)
print("Loss: ", r['loss'], "\nAccuracy: ", r['accuracy'], "\nF-score: ", f1_score(yt, yp, average='micro'))
Loss: 0.29120033979415894
Accuracy: 0.9556179642677307
F-score: 0.9556213017751479
該模型在CPU上訓練約10分鍾,准確率為95.56%。
mfcc是基於Mel尺度的,在Mel尺度中,頻率是根據人的聽覺反應而不是線性尺度來分組的。人耳是一個經過考驗的語音識別系統,因此Mel尺度給出了很好的結果。
另一方面,mfcc容易受到背景噪聲的影響,因此在處理干凈的語音數據(無噪聲或最小噪聲)時效果最好。
plot(losses, 'Losses')
以上是驗證集損失曲線
plot(accuracies, 'Accuracy')
以上是驗證集准確率曲線
plot(last_lr, 'Last Learning Rate')
以上是每個epoch最后學習率的曲線
3.使用Mel譜圖圖像的CNN。
特征
該模型使用了Mel譜圖。Mel譜圖是將頻率轉換為Mel標度的譜圖。這些特征從錄音中提取並存儲在驅動器中。這花了4.5個多小時。
def extract_mel(f, label):
data, sr = librosa.load('/content/data/'+label+'/'+f)
fig = plt.figure(figsize=[1,1])
ax = fig.add_subplot(111)
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.set_frame_on(False)
S = librosa.feature.melspectrogram(y=data, sr=sr)
librosa.display.specshow(librosa.power_to_db(S, ref=np.max), x_axis='time', y_axis='mel', fmin=50, fmax=280)
file = '/content/drive/My Drive/Dataset/spokendigit/'+label+'/' + str(f[:-4]) + '.jpg'
plt.savefig(file, dpi=500, bbox_inches='tight',pad_inches=0)
plt.close()
模型
class SpokenDigitModel(nn.Module):
def __init__(self):
super().__init__()
self.network = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, 10),
nn.Sigmoid()
)
def forward(self, x):
return self.network(x)
def training_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
return loss
def validation_step(self, batch):
inputs, labels = batch
outputs = self(inputs)
loss = F.cross_entropy(outputs, labels)
_, pred = torch.max(outputs, 1)
accuracy = torch.tensor(torch.sum(pred==labels).item()/len(pred))
return [loss.detach(), accuracy.detach()]
訓練
model = to_device(SpokenDigitModel(), device)
history = []
evaluate(model, val_dl)
{'accuracy': 0.09851787239313126, 'loss': 2.3029427528381348}
history.append(fit(model, train_dl, val_dl, 128, 0.001))
r = evaluate(model, val_dl)
yp, yt = predict_dl(model, val_dl)
print("Loss: ", r['loss'], "\nAccuracy: ", r['accuracy'], "\nF-score: ", f1_score(yt, yp, average='micro'))
Loss: 1.492598056793213
Accuracy: 0.9581243991851807
F-score: 0.9573119188503804
該模型在Colab GPU上訓練約5小時,准確率為95.81%。
高准確率可以再次歸因於Mel標度。
plot(losses, 'Losses')
以上是驗證集損失曲線
plot(accuracies, 'Accuracy')
以上是驗證集准確度曲線
plot(last_lr, 'Last Learning Rate')
以上是每個epoch最后學習率的曲線
參考
- https://musicinformationretrieval.com/
- [https://github.com/jurgenarias/Portfolio/tree/master/Voice Classification/Code](https://github.com/jurgenarias/Portfolio/tree/master/Voice Classification/Code)
- https://arxiv.org/abs/1506.01186
- https://en.wikipedia.org/wiki/Mel-frequency_cepstrum
原文鏈接:https://towardsdatascience.com/torch-spoken-digits-recognition-from-features-to-model-357209cd49d1
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方文檔:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/