Torch: распознавание речи от извлечения признаков до модели

машинное обучение глубокое обучение компьютерное зрение NLP

Автор|Аиша Д Компилировать|ВКонтакте Источник | К науке о данных

В этом посте мы исследуем функции, извлеченные из речевых данных, и различные подходы к построению моделей на основе этих функций.

Набор данных Speech Digits (Spoken digits) — это подмножество набора данных Tensorflow Speech, которое включает в себя другие записи цифр 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 образцов на класс. Таким образом, точность является хорошим показателем для оценки производительности модели. Точность — это количество правильных прогнозов по сравнению с общим количеством прогнозов.

Это не лучший показатель производительности для несбалансированных наборов данных, так как класс меньшинства может оказаться в тени.

Циклическая скорость обучения

При обучении модели скорость обучения постепенно снижается для точной настройки обучения. Для повышения эффективности обучения можно использовать циклическую скорость обучения. Здесь вместо монотонного уменьшения скорость обучения колеблется между минимальным и максимальным значениями в разные эпохи.

Начальная скорость обучения имеет решающее значение для производительности модели, низкая скорость обучения предотвращает застревание в начале обучения, а последующие колебания подавляют локальные минимумы.

Для этого проекта существует три метода классификации:

  1. Логистический регрессионный анализ был выполнен с использованием пяти извлеченных признаков с точностью 76,19%.

  2. Логистическая регрессия с использованием только MFCC — точность 95,56%.

  3. CNN использует спектрограмму Мела с точностью 95,81%.

Модель итеративно обучается путем изменения эпохи и скорости обучения. Количество скрытых слоев и узлов в каждом слое также различается. Здесь описаны оптимальная архитектура и гиперпараметры для каждого метода. Точность переобучения может незначительно отличаться из-за случайности разделения набора для обучения и проверки.

Исходный код проекта находится здесь:GitHub.com/A Doctor AR/S Po…

Имеется пять файлов .ipynb:

  1. Извлечение функций. Извлеките файлы CSV и функции, необходимые для трех методов.

  2. Визуализация функций. Нарисуйте карты функций в каждом классе.

  3. Spokendigit Five Features — реализует логистическую регрессию с использованием пяти извлеченных признаков.

  4. Spokendigit MFFC — реализация логистической регрессии с использованием MFCC.

  5. Spokendigit CNN — реализация CNN с использованием Mel Spectrogram.


1. Логистическая регрессия с использованием пяти извлеченных признаков.

особенность

Извлеченные функции включают в себя:

  • Mel Frequency Cepstral Coefficients (MFCCs)- Коэффициенты спектрального представления звука, составленного из полос частот, разнесенных в соответствии с реакцией слуховой системы человека (шкала Мел).
  • Chroma- Относится к 12 различным уровням высоты тона.
  • Mel spectrogramСреднее значение спектра -Mel на основе шкалы Mel.
  • Spectral Contrast- Указывает центр тяжести спектра.
  • Tonnetz- Представляет тональное пространство.

Функции представляют собой массивы NumPy размером (20,) (12,) (128,) (7,) и (6,). Они объединяются для формирования массива признаков размером (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

Модель обучалась на ЦП около 3 минут с точностью 76,19%.

plot(losses, 'Losses')

Начиная с минимального значения, окончательные потери при проверке медленно увеличиваются.

plot(accuracies, 'Accuracy')

Выше приведена кривая точности

plot(last_lr, 'Last Learning Rate')

Выше приведена кривая скорости обучения для каждой эпохи.

2. Логистическая регрессия с использованием только MFCC

особенность

В модели используются только частотные кепстральные коэффициенты Mel (MFCC). Эта функция представляет собой массив NumPy размером (20). Он извлекается из файла 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

Модель обучалась на ЦП около 10 минут с точностью 95,56%.

mfcc основан на шкале Мела, где частоты сгруппированы в соответствии со слуховыми реакциями человека, а не по линейной шкале. Человеческое ухо — проверенная система распознавания речи, поэтому шкала Мела дает хорошие результаты.

С другой стороны, mfcc чувствителен к фоновому шуму и поэтому лучше всего работает при работе с чистыми речевыми данными (шум отсутствует или минимален).

plot(losses, 'Losses')

Выше приведена кривая потерь набора проверки.

plot(accuracies, 'Accuracy')

Выше приведена кривая точности набора проверки.

plot(last_lr, 'Last Learning Rate')

Выше приведена кривая конечной скорости обучения для каждой эпохи.

3. CNN с использованием изображений спектрограммы Мела.

особенность

В модели используются спектрограммы Мела. Спектрограммы Мела — это спектрограммы, преобразующие частоты в шкалу Мел. Эти функции извлекаются из записи и сохраняются на диске. Это заняло более 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 около 5 часов с точностью 95,81%.

Высокая точность снова может быть связана со шкалой Мела.

plot(losses, 'Losses')

Выше приведена кривая потерь набора проверки.

plot(accuracies, 'Accuracy')

Выше приведена кривая точности набора проверки.

plot(last_lr, 'Last Learning Rate')

Выше приведена кривая конечной скорости обучения для каждой эпохи.

Ссылаться на

Оригинальная ссылка:к data science.com/torch-spoke…

Добро пожаловать на сайт блога Panchuang AI:panchuang.net/

sklearn машинное обучение китайские официальные документы:sklearn123.com/

Добро пожаловать на станцию ​​сводки ресурсов блога Panchuang:docs.panchuang.net/