Как применить CNN к Кратковременному преобразованию Фурье? - PullRequest
1 голос
/ 24 мая 2019

Итак, у меня есть код, который возвращает кратковременный спектр Фурье-преобразования файла .wav. Я хочу быть в состоянии взять, скажем, миллисекунду спектра, и обучить его CNN.

Я не совсем уверен, как бы это реализовать. Я знаю, как форматировать данные изображения для подачи в CNN и как обучать сеть, но я заблудился о том, как взять FFT-данные и разделить их на небольшие временные рамки.

Код FFT (простите за сверхдлинный код):

rate, audio = wavfile.read('scale_a_lydian.wav')

audio = np.mean(audio, axis=1)

N = audio.shape[0]
L = N / rate

M = 1024

# Audio is 44.1 Khz, or ~44100 samples / second
# window function takes 1024 samples or 0.02 seconds of audio (1024 / 44100 = ~0.02 seconds)
# and shifts the window 100 over each time
# so there would end up being (total_samplesize - 1024)/(100) total steps done (or slices)

slices = util.view_as_windows(audio, window_shape=(M,), step=100) #slices overlap

win = np.hanning(M + 1)[:-1]
slices = slices * win #each slice is 1024 samples (0.02 seconds of audio)

slices = slices.T #transpose matrix -> make each column 1024 samples (ie. make each column one slice)


spectrum = np.fft.fft(slices, axis=0)[:M // 2 + 1:-1] #perform fft on each slice and then take the first half of each slice, and reverse

spectrum = np.abs(spectrum) #take absolute value of slices

# take SampleSize * Slices
# transpose into slices * samplesize
# Take the first row -> slice * samplesize
# transpose back to samplesize * slice (essentially get 0.01s of spectrum)

spectrum2 = spectrum.T
spectrum2 = spectrum2[:1]
spectrum2 = spectrum2.T

Следующие данные выводят спектр БПФ:

N = spectrum2.shape[0]
L = N / rate

f, ax = plt.subplots(figsize=(4.8, 2.4))

S = np.abs(spectrum2)
S = 20 * np.log10(S / np.max(S))

ax.imshow(S, origin='lower', cmap='viridis',
          extent=(0, L, 0, rate / 2 / 1000))
ax.axis('tight')
ax.set_ylabel('Frequency [kHz]')
ax.set_xlabel('Time [s]');
plt.show()

(Не стесняйтесь исправлять любые теоретические ошибки, которые я помещаю в комментарии)

Итак, насколько я понимаю, у меня есть массив массивов (спектр), где каждый столбец представляет собой срез с 510 выборками (разрезанный пополам, потому что половина каждого среза БПФ избыточна (бесполезна?)), Причем каждый образец имеет список частот?

Приведенный выше код теоретически выводит 0,01 с аудио в виде спектра, и это именно то, что мне нужно. Это правда или я не так думаю?

1 Ответ

0 голосов
/ 24 мая 2019

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

import librosa

y, sr = librosa.load(audiofile, offset=10.0, duration=30.0, sr=16000)

Таким образом, вы будете иметь свой временной ряд как y.Отсюда я бы использовал эту красивую реализацию CNN для аудио.Здесь парень использует свою собственную библиотеку, которая выполняет вычисление mel-спектрограммы на GPU.Вам просто нужно передать свой параметр y в сеть.Смотрите здесь как это делается.Кроме того, вы можете удалить первый слой этой сети, предварительно рассчитать свои mel-спектрограммы и сохранить их где-нибудь.Это будут ваши входы в сеть.См. здесь

Другие ресурсы: Классификация аудио: подход сверточной нейронной сети

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...