Аудиоклассификация с предварительно обученным VGG-19 (Keras)
В этом посте я остановлюсь на проблеме классификации аудио. Я обучу классификатор SVM на функциях, извлеченных предварительно обученным VGG-19 из сигналов аудио. Основная идея этого поста - показать мощь предварительно обученных моделей и простоту их применения.
Я хотел оценить этот подход на реальных данных. Так что я подумал о классификации аудио суперкаров и тяжелых мотоциклов. Ниже приведены шаги, которые я выполнил для создания этого классификатора:
Скачать аудиофайлы с Youtube
Сначала я выбрал видео на YouTube, для которых мне нужен звук, а затем использовал следующий фрагмент кода для загрузки аудиофайлов в формате .mp3.
from __future__ import unicode_literals import youtube_dl ydl_opts = { 'format': 'bestaudio/best', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], } with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([<youtube video link>]) # for bike sounds : https://www.youtube.com/watch?v=sRdRwHPjJPk # for car sounds : https://www.youtube.com/watch?v=PPdNb-XQXR8
Преобразование аудиофайлов из .mp3 в .wav
После загрузки файлов .mp3 я преобразовал их в файлы .wav, используя следующий фрагмент кода.
from pydub import AudioSegment sound = AudioSegment.from_mp3("car.mp3") sound.export("car.wav", format="wav")
Извлечение фрагментов аудио
На следующем этапе я извлек фрагменты 15-секундного аудио из файлов .wav.
from pydub import AudioSegment import os if not os.path.exists("bike"): os.makedirs("bike") count=1 for i in range(1,1000,15): t1 = i * 1000 #Works in milliseconds t2 = (i+15) * 1000 newAudio = AudioSegment.from_wav("bikes.wav") newAudio = newAudio[t1:t2] newAudio.export('bike/'+str(count)+'.wav', format="wav") #Exports to a wav file in the current path. print(count) count+=1
Построение кривых амплитуды
Следующим шагом было построение сигналов этих аудиофайлов. Это было сделано с помощью следующего кода.
from scipy.io.wavfile import read import matplotlib.pyplot as plt from os import walk import os if not os.path.exists("carPlots"): os.makedirs("carPlots") car_wavs = [] for (_,_,filenames) in walk('car'): car_wavs.extend(filenames) break for car_wav in car_wavs: # read audio samples input_data = read("car/" + car_wav) audio = input_data[1] # plot the first 1024 samples plt.plot(audio) # label the axes plt.ylabel("Amplitude") plt.xlabel("Time") # set the title # plt.title("Sample Wav") # display the plot plt.savefig("carPlots/" + car_wav.split('.')[0] + '.png') # plt.show() plt.close('all')
Извлечение функций и обучение LinearSVM
После того, как у меня были эти формы сигналов для автомобилей и мотоциклов, я извлек элементы из этих изображений, чтобы передать их в LinearSVM для классификации. Чтобы извлечь элементы, я использовал предварительно обученную модель VGG-19 и извлек абстрактные элементы изображения из плоского слоя. После извлечения этих функций я создал тестовую группу из 70–30 поездов и обучил LinearSVM. Ниже приведен код для этого.
import os from keras.applications.vgg19 import VGG19 from keras.preprocessing import image from keras.applications.vgg19 import preprocess_input from keras.models import Model import numpy as np base_model = VGG19(weights='imagenet') model = Model(inputs=base_model.input, outputs=base_model.get_layer('flatten').output) def get_features(img_path): img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) flatten = model.predict(x) return list(flatten[0]) X = [] y = [] car_plots = [] for (_,_,filenames) in os.walk('carPlots'): car_plots.extend(filenames) break for cplot in car_plots: X.append(get_features('carPlots/' + cplot)) y.append(0) bike_plots = [] for (_,_,filenames) in os.walk('bikePlots'): bike_plots.extend(filenames) break for cplot in bike_plots: X.append(get_features('bikePlots/' + cplot)) y.append(1) from sklearn.model_selection import train_test_split from sklearn.svm import LinearSVC from sklearn.metrics import accuracy_score X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42, stratify=y) clf = LinearSVC(random_state=0, tol=1e-5) clf.fit(X_train, y_train) predicted = clf.predict(X_test) # get the accuracy print (accuracy_score(y_test, predicted))
Эта простая модель показала точность 97% на тестовой выборке . Это показывает, насколько мощны эти предварительно обученные модели и как каждый может использовать их для создания инструмента.
Одно из применений этого, которое я могу придумать, - это создать расширение chrome, которое сообщает, содержит ли звук видео, присутствующего на веб-странице, явные шумы или нет. Я призываю новичков, читающих этот пост, подумать о новой проблеме и решить ее, используя метод, представленный здесь.