Извлечение признаков аудио с помощью Python

искусственный интеллект Python

написать впереди

Поскольку мне нравится играть в музыкальные игры, я планирую изучить, как использовать модель глубокого обучения для создания диаграммы музыкальных игр. Основная цель этой статьи — представить или обобщить некоторые сведения об аудио и коде.

доброта. Если вы еще не играли в нее раньше, музыкальная игра, вероятно, выглядит так.

Введите тему ниже.

Я погуглил и нашел эту статью:Music Feature Extraction in Python. Затем в этой статье представлена ​​еще одна практика классификации песен:Classification of Music into different Genres using Keras.

Следующее содержание будет в основном относиться к этим двум статьям и добавит часть моего понимания. Содержание следующее:

  • Введение в звуковые сигналы
  • Извлечение признаков аудио с помощью Python
  • Используйте Keras для категоризации темы песни

К основным базовым знаниям относятся:

  • преобразование Фурье
  • теорема выборки
  • Python
  • машинное обучение

Основы звука

звуковой сигнал

Во-первых, Baidu сначала смотрит на аудиосигнал,

Звуковой сигнал является носителем информации об изменении частоты и амплитуды регулярных звуковых волн с речью, музыкой и звуковыми эффектами. По характеристикам звуковых волн звуковую информацию можно разделить на обычный звук и неправильный звук. Обычное аудио можно разделить на речь, музыку и звуковые эффекты. Обычный звук — это постоянно изменяющийся аналоговый сигнал, который можно представить в виде непрерывной кривой, называемой звуковой волной. Три элемента звука — высота, интенсивность и тембр. Звуковая волна или синусоида имеет три важных параметра: Частотаω_0, амплитудаA_nи фазаψ_n, который также определяет характеристики звукового сигнала.

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

Общий звук, наверное, такой.

Горизонтальная ось — время, вертикальная ось — амплитуда звука. Поскольку это, по сути, суперпозиция синусоидальных волн, на самом деле она бывает положительной и отрицательной.

Диапазон частот человеческого слуха

В жизни существуют различные синусоиды, но не все они могут быть услышаны человеческим ухом. Например, сигнал нашей мобильной связи, сигнал Wi-Fi и солнечный свет — все это волны, но люди их не слышат.

Нормальное человеческое ухо слышит звук в диапазоне частот от 20 Гц до 20 000 Гц. Звуки с одинаковой интенсивностью, например разные частоты, будут звучать по-разному по громкости. Наиболее чувствительными частотами являются 3000 и 4000 Гц.

Поэтому на сигнал звуковой волны в основном нужно обращать внимание только в пределах 2 Вт Гц.

Теорема Найквиста о выборке

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

Теорема Найквиста о выборке выглядит следующим образом:

В процессе аналого-цифрового преобразования сигнала, когда частота дискретизации fs.max более чем в два раза превышает самую высокую частоту fmax в сигнале (fs.max>2fmax), цифровой сигнал после дискретизации полностью сохраняет информацию исходного сигнала.

Эту теорему очень просто описать, и ее нетрудно доказать.Для звуковых сигналов, пока частота дискретизации больше 2 * 2 Вт = 4 Вт, мы можем слышать качество звука без потерь.

Говорят, что диапазон чувствительности человеческого слуха в основном находится на частоте 4000 Гц, поэтому музыка, которую мы обычно слышим, на самом деле сэмплирована на частоте 8000 Гц. Здесь вы можете взглянуть на недавнюю популярную песню манго.

Продолжительность этой песни составляет 3 минуты 36 секунд, что составляет 216 секунд, а ее стандартный размер в качестве составляет 3,3М. Здесь вы можете рассчитать, используя частоту 8000 Гц и 16-битную выборку, тогда размер этого файла:

216*8000*16(bit) = 216*8000*16/8(字节) = 216*8000*2/1024/1024(M) = 3.296(M)

Это примерно 3,3 мегабайта.

Извлечение признаков аудио с помощью Python

Базовые знания, вероятно, указаны выше, а практическое занятие начинается ниже.

Готов к работе

используется здесьlibrosa, numpy, sklearn и keras. Конечно, для удобства разработки здесь я также использовал IPython NoteBook.

pip install librosa numpy sklearn tensorflow keras

загрузить музыку

Далее начинаю загружать музыку в питоне.Здесь я выбираю песню из музыкальной игры, которая мне очень нравится. Ссылка здесь:visions.mp3

import librosa

x , sr = librosa.load("visions.mp3", sr=8000)
print(x.shape, sr)

здесьxэто цифровая информация аудиосигнала, который можно рассматривать как одномерный,srЧастота дискретизации, просто используйте 8000.

Затем вы можете посмотреть на форму волны песни во временной области.

%matplotlib inline
import matplotlib.pyplot as plt
import librosa.display
plt.figure(figsize=(14, 5))
librosa.display.waveplot(x, sr=sr)

После запуска эффект следующий:

Горизонтальная ось — время, вертикальная ось — амплитуда.

Spectogram

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

Спектограмма не нашла здесь хорошего перевода, что, вероятно, означает: изменяющаяся во времени спектрограмма.

Кратковременное преобразование Фурье — STFT

Мы знаем, что для периодических сигналов преобразование Фурье можно использовать для преобразования информации во временной области в частотную область.

Например, глядя на приведенное выше изображение, волна на самом деле состоит из трехчастотных синусоидальных волн.Можно увидеть, что она простирается вверх от начала частотной области, и частота становится все выше и выше, а соответствующие формы волны становятся все плотнее и плотнее...

В статье упоминается понятие кратковременного преобразования Фурье.Я как студент бакалавриата по специальности "коммуникации" не помню, чтобы преподаватель говорил об этом преобразовании, только о дискретном преобразовании Фурье. Оригинальный автор дал видео:The Short Time Fourier Transform | Digital Signal Processing

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

Позже я нашел лучшее объяснение в Интернете:

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

Кроме того, есть еще одна вещь, которая может чувствовать STFT, здесь вы можете открыть NetEase Cloud Music, найти песню и открыть эффект движения.

Вы можете видеть постоянно меняющиеся формы волн, которые при отдельном просмотре фактически представляют информацию о частоте звука, содержащуюся в текущем коротком периоде времени. Приведенное выше изображение на самом деле получается путем выполнения DFT над аудиосигналом в текущий момент.

Постройте изменяющуюся во времени спектрограмму

Затем мы вызываем метод librosa stft, чтобы напрямую получить результат кратковременного преобразования Фурье.

X = librosa.stft(x)
Xdb = librosa.amplitude_to_db(abs(X))   # 把幅度转成分贝格式
plt.figure(figsize=(14, 5))
librosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='hz')
plt.colorbar()

Эффект следующий:

Здесь горизонтальная ось — время, вертикальная ось — частота, а цвет — децибел (громкость звука) Видно, что чем краснее место, тем больше громкость сигнала.

Извлечение признаков

Далее вводятся некоторые основные особенности музыки, и здесь в основном переводится содержание оригинального автора.

Скорость пересечения нуля

Скорость пересечения нуля (ZCR) относится к количеству раз, которое речевой сигнал проходит через нулевую точку (от положительного к отрицательному или от отрицательного к положительному) в каждом кадре. Эта функция широко используется в распознавании речи и поиске музыкальной информации и является ключевой особенностью металлического звука и рок-музыки.

Возвращаясь к картинке выше, мы увеличиваем время.

n0 = 9000
n1 = 9100
plt.figure(figsize=(14, 5))
plt.plot(x[n0:n1])
plt.grid()

Эффект следующий:

Здесь имеется 7 точек пересечения нуля, которые можно вычислить следующим методом.

zero_crossings = librosa.zero_crossings(x[n0:n1], pad=False)
print(sum(zero_crossings))

Спектральный центроид

Центр спектра представляет собой «центроид» звука, также известный как спектральное расстояние первого порядка. Меньшее значение в центре спектра указывает на то, что больше спектральной энергии сосредоточено в низкочастотном диапазоне.

#spectral centroid -- centre of mass -- weighted mean of the frequencies present in the sound
import sklearn
spectral_centroids = librosa.feature.spectral_centroid(x[:80000], sr=sr)[0]
# Computing the time variable for visualization
frames = range(len(spectral_centroids))
t = librosa.frames_to_time(frames, sr=8000)
# Normalising the spectral centroid for visualisation
def normalize(x, axis=0):
    return sklearn.preprocessing.minmax_scale(x, axis=axis)
#Plotting the Spectral Centroid along the waveform
librosa.display.waveplot(x[:80000], sr=sr, alpha=0.4)
plt.plot(t, normalize(spectral_centroids), color='r')

использовать здесьx[:80000]Обозначает первые 10 секунд музыки.

.spectral_centroidдля вычисления спектрального центра каждого кадра.

.frames_to_timeПреобразование кадра во время, time[i] == frame[i]. [Поскольку stft берется из окна (фрейма) и окна, то не соответствует частоте дискретизации, поэтому происходит преобразование]

Спектральные центры нормализованы для лучшей визуализации.

Спектральный спад

Смысл точки спада спектра, перевожу грубо: вся энергия частот ниже этой частоты больше определенной доли энергии всего спектра, обычно эта доля равна 0,85.

Это все еще кажется немного неудобным, и его легче понять с помощью формулы.

Давайте взглянем на приведенный ниже код, который похож на код в центре спектра выше, а также выполняет покадровое извлечение признаков.

spectral_rolloff = librosa.feature.spectral_rolloff(x, sr=sr)[0]
librosa.display.waveplot(x, sr=sr, alpha=0.4)
plt.plot(t, normalize(spectral_rolloff), color='r')

.spectral_rolloffдля вычисления точки спада спектра для каждого кадра.

MFCC (Кепстральный коэффициент частоты Mel)

MFCC является наиболее важной из функций аудиосигнала и в основном используется для обработки аудиосигналов. (Как бакалавр коммуникаций я тоже только об этом знал).

Параметры MFCC сигнала представляют собой небольшой набор признаков (обычно 10-20), которые могут лаконично представлять огибающую спектра.

mfccs = librosa.feature.mfcc(x, sr=sr)
print(mfccs.shape)
#Displaying  the MFCCs:
librosa.display.specshow(mfccs, sr=sr, x_axis='time')

.mfccПараметры MFCC, используемые для расчета сигнала.

путем печатиmfccs.shape, вы можете увидеть, сколько пространственных объектов MFCC имеется в каждом кадре. Первый параметр — размерность параметра mfcc, а второй параметр — количество кадров.

Всего имеется 3177 кадров, и каждый кадр имеет 20-мерные функции.

Используйте Keras для категоризации темы песни

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

подготовка данных

Загрузка набора данных

будет использоваться здесьGTZAN genre collection. Этот набор данных содержит 10 тем, и каждая тема содержит 100 музыкальных произведений продолжительностью 30 секунд.

Здесь мы будем использовать Keras с бэкендом Tensorflow для кодирования.

загрузить данные в память

Здесь данные загружаются первыми.

import librosa
import numpy as np
import os

genres = 'blues classical country disco hiphop jazz metal pop reggae rock'.split()

data_set = []
label_set = []

label2id = {genre:i for i,genre in enumerate(genres)}
id2label = {i:genre for i,genre in enumerate(genres)}

print(label2id)

for g in genres:
    print(g)
    for filename in os.listdir(f'./genres/{g}/'):
        songname = f'./genres/{g}/{filename}'
        y, sr = librosa.load(songname, mono=True, duration=30)
        chroma_stft = librosa.feature.chroma_stft(y=y, sr=sr)
        rmse = librosa.feature.rms(y=y)
        spec_cent = librosa.feature.spectral_centroid(y=y, sr=sr)
        spec_bw = librosa.feature.spectral_bandwidth(y=y, sr=sr)
        rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr)
        zcr = librosa.feature.zero_crossing_rate(y)
        mfcc = librosa.feature.mfcc(y=y, sr=sr)

        to_append = f'{np.mean(chroma_stft)} {np.mean(rmse)} {np.mean(spec_cent)} {np.mean(spec_bw)} {np.mean(rolloff)} {np.mean(zcr)}'    

        for e in mfcc:
            to_append += f' {np.mean(e)}'

        data_set.append([float(i) for i in to_append.split(" ")])
        label_set.append(label2id[g])

Видно, что в дополнение к некоторым функциям, упомянутым выше, первоначальный автор также упомянул здесь некоторые другие функции, такие как rmse и chroma_stft. Я не буду представлять их здесь по одному.

Как правило, здесь используется среднее значение шести характеристик chroma_stft, rmse, spec_cent, spec_bw, rolloff и zcr плюс среднее значение 20 характеристик mfcc, всего 26 характеристик для представления музыкального произведения.

Создать набор данных

Далее мы нормализуем данные и выполняем горячее кодирование меток.

from sklearn.preprocessing import StandardScaler
from keras.utils import np_utils

scaler = StandardScaler()
X = scaler.fit_transform(np.array(data_set, dtype = float))
y = np_utils.to_categorical(np.array(label_set))

Эффект следующий:

Затем разделите тестовый набор и обучающий набор.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

Создать модель

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

from keras import models
from keras.layers import Dense, Dropout

def create_model():
    model = models.Sequential()
    model.add(Dense(256, activation='relu', input_shape=(X_train.shape[1],)))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(64, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))

    return model

model = create_model()

Здесь создается нейронная сеть с тремя скрытыми слоями.Выводом последнего слоя является слой классификации.Поскольку это 10 классов, последний слой составляет 10 единиц. (По сравнению с исходным авторским кодом есть еще один слой Dropout для уменьшения переобучения данных)

Скомпилируйте модель

Затем нужно скомпилировать модель, у нас здесь проблема классификации, поэтому используйте функцию перекрестной энтропии категорий.categorical_crossentropy, затем оптимизатор выбирает Адама, а индекс оценки выбирает правильную ставку.

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

обучение и оценка

Следующее использованиеfitметод обучения, 50 раундов обучения.

model.fit(X_train, y_train, epochs=50, batch_size=128)

Обучение скоро закончится, тогда используйтеevaluateметод оценки.

test_loss, test_acc = model.evaluate(X_test,y_test)
print('test_acc: ',test_acc)

Уровень точности теста здесь составляет менее 70%.У исходного автора все еще есть код для использования предсказания модели, который кажется ненужным.

Суммировать

Этот блог в основном представляет знания и код извлечения некоторых звуковых функций, Просто посмотрите и поиграйте с последним случаем, который в основном непрактичен.