В первой части анализа аудиоданных мы рассмотрели характеристики, которые есть у каждого аудиосигнала.
Характеристики аудиофайлов для разных аудио записей.
В наборе аудиоданных есть Human files - 10322 файла ( записи “живого” голоса (класс 1)) и Spoof files - 39678 файлов ( записи синтетического/конвертированного/перезаписанного голоса (класс 2)) . В одном аудиофайле (3 - 6 сек) голос мужской или женский что-то говорит на каком-то языке (английском, русском, немецком, китайском)
Вот так выглядят характеристики аудиофайлов для разных аудио записей:
Выбор характеристик для извлечения из аудиофайла.
Каждый исследователь выбирает свои характеристики для извлечения из аудиофайла.
Мы разберем относительно простой и более быстрый способ классификации аудиофайлов - алгоритм машинного обучения - SVM (Support Vector Machines) / машины опорных векторов. ( Подробно разберем в третьей части анализа аудиоданных).
А для этого нам нужно извлечь значимые характеристики и преобразовать их в структурированные данные - в двухмерную таблицу, состоящую из столбцов и строк с помощью библиотеки Pandas. Эта таблица называется фреймом данных - Dataframes.
Из значимых характеристик я выбрала:
Средние значения и стандартные отклонения Мел-кепстральных коэффициентов ( по 20 значений);
Среднее значение, стандартное отклонение и skew (наклон) Спектрального центроида
Среднее значение и стандартное отклонение Спектрального спада;
Мел-кепстральные коэффициенты (MFCC).
Мел-кепстральные коэффициенты — один из важнейших признаков в обработке аудио. MFCC — это матрица значений, которая захватывает тембральные аспекты. Мел - это единица высоты звука, это та же частотная ось, только выражается в Мелах, вместо Герц. Кепстр - это акустическая волна (параметры голосового тракта, тоновые сигналы, шумы и фильтры).
MFCC - Представляют собой набор признаков , которые описывают общую форму спектральной огибающей. Они моделируют характеристики человеческого голоса - общие (отношение к языковой группе) и индивидуальные (уникальные особенности в речи, произношения, тембра голоса ). MFCC - коэффициенты частотной капсулы, суммируют частотное распределение по размеру окна (окно - это сегмент сигнала). Поэтому можно анализировать как частотные, так и временные характеристики звука. Перед построением графика коэффициенты нормализуются.
Частотные характеристики речи:
частота основного тона;
период основного тона (мс);
количество побочных гармоник (формантных областей);
нижняя частота спектра;
верхняя частота спектра;
частотный диапазон;
частота максимального уровня спектральной плотности
Временные характеристики речи:
длительность звука речи (мс);
длительность пауз речи между словами (мс);
длительность пауз речи между фразами (мс);
скорость звуков речи (звуков/с);
темп речи (слов/мин);
плотность речи (%) – отношение времени наличия звука к полному времени речевого сигнала;
скорость изменения уровня громкости основного тона (дБ/с);
скорость изменения частоты основного тона (Гц/с).
Вот так выглядят Мел-кепстральные коэффициенты:
Мел-кепстральные коэффициенты (MFCC) в виде массива numpy:
Для каждого аудиофайла свои Мел-кепстральные коэффициенты. Это хорошо видно, если рассмотреть Мел-кепстральные коэффициенты в виде массива numpy. Все коэффициенты разные.
Средние значения и стандартные отклонения Мел-кепстральных коэффициентов
Давайте посмотрим, как выглядят Средние значения и стандартные отклонения Мел-кепстральных коэффициентов в виде двухмерной таблицы (Dataframes), состоящей из столбцов и строки и в виде графика.
# Feature Generation
# MFCCs
mfccs_mean=np.mean(mfccs,axis=1)
mfccs_std=np.std(mfccs,axis=1)
coeffs=np.arange(0,20)
plt.figure(figsize=(15,5))
plt.title('Mean MFCCs')
sns.barplot(x=coeffs,y=mfccs_mean)
plt.figure(figsize=(15,5))
plt.title('SD MFCCs')
sns.barplot(x=coeffs,y=mfccs_std)
# Generate the chroma Dataframe
mfccs_df=pd.DataFrame()
for i in range(0,20):
mfccs_df['mfccs_mean_'+str(i)]=mfccs_mean[i]
for i in range(0,20):
mfccs_df['mfccs_std_'+str(i)]=mfccs_mean[i]
mfccs_df.loc[0]=np.concatenate((mfccs_mean,mfccs_std),axis=0)
mfccs_df
Спектральный центроид - Spectral Centroid
Спектральный центроид относится к спектральным (частотным) признакам. Спектральные характеристики всех звуковых сигналов определяются с помощью двух зависимостей:
зависимость амплитуды от времени
зависимость амплитуды от частоты Спектральный центроид указывает, на какой частоте сосредоточена энергия спектра ( энергия напряжения) или, другими словами, указывает, где расположен “центр масс” для звука.
Вот так выглядит Спектральный центроид:
Среднее значение, стандартное отклонение и skew (наклон) Спектрального центроида;
# Spectral Features
# Spectral Centroid
cent_mean=np.mean(cent)
cent_std=np.std(cent)
cent_skew=scipy.stats.skew(cent,axis=1)[0]
print('Mean: '+str(cent_mean))
print('SD: '+str(cent_std))
print('Skewness: '+str(cent_skew))
Спектральный спад - Spectral Rolloff
Спектральный спад относится к спектральным (частотным) признакам. Это мера формы сигнала, представляющая собой частоту, в которой высокие частоты снижаются до 0. Чтобы получить ее, нужно рассчитать долю элементов в спектре мощности, где 85% ее мощности находится на более низких частотах.
Вот так выглядит Спектральный спад:
Среднее значение и стандартное отклонение Спектрального спада;
# Spectral Rolloff
rolloff_mean=np.mean(rolloff)
rolloff_std=np.std(rolloff)
rolloff_skew=scipy.stats.skew(rolloff,axis=1)[0]
print('Mean: '+str(rolloff_mean))
print('SD: '+str(rolloff_std))
print('Skewness: '+str(rolloff_skew))
Извлечение значимых характеристик
Для извлечения необходимо импортировать библиотеки Python:
import librosa
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import os
import pathlib
import csv
import warnings
warnings.filterwarnings('ignore')
Из всех аудиофайлов в наборе данных с помощью библиотеки librosa - librosa.feature, метода append( ) и метода extend( ) проводим:
Извлечение из Мел-кепстральных коэффициентов - средние значения и стандартные отклонения (по 20 значений);
Извлечение из Спектрального центроида - среднее значение, стандартное отклонение и skew (наклон);
Извлечение из Спектрального спада - среднее значение и стандартное отклонение;
Извлечение значимых характеристик:
def extract_features(directory, file):
name = f'{directory}/{file}'
y, sr = librosa.load(name, mono=True, duration=5)
features = []
features.append(file) # filename
features.extend([np.mean(e) for e in librosa.feature.mfcc(y=y, sr=sr,
n_mfcc=20)]) # mfcc_mean<0..20>
features.extend([np.std(e) for e in librosa.feature.mfcc(y=y, sr=sr,
n_mfcc=20)]) # mfcc_std
features.append(np.mean(librosa.feature.spectral_centroid(y=y, sr=sr).T,
axis = 0)[0]) # cent_mean
features.append(np.std(librosa.feature.spectral_centroid(y=y,sr=sr).T,
axis = 0)[0]) # cent_std
features.append(scipy.stats.skew(librosa.feature.spectral_centroid(y=y,sr=sr).T,
axis = 0)[0]) # cent_skew
features.append(np.mean(librosa.feature.spectral_rolloff(y=y, sr=sr).T,
axis = 0)[0]) # rolloff_mean
features.append(np.std(librosa.feature.spectral_rolloff(y=y, sr=sr).T,
axis = 0)[0]) # rolloff_std
features.append(directory.split('/')[-1])
return features
Давайте посмотрим на аудио файлы в наборе данных:
#Cписки файлов
human_dir, _, human_files = next(os.walk('../input/audioset/Training_Data/human'))
spoof_dir, _, spoof_files = next(os.walk('../input/audioset/Training_Data/spoof'))
print(f"Human files: {len(human_files)}\nSpoof files: {len(spoof_files)}")
Human files: 10322 Spoof files: 39678
Извлечение и сохранение значений в формате CSV файла
buffer = []
buffer_size = 5000
buffer_counter = 0
# Создание заголовка для файла CSV.
header = ['filename']
header.extend([f'mfcc_mean{i}' for i in range(1, 21)])
header.extend([f'mfcc_std{i}' for i in range(1, 21)])
header.extend(['cent_mean', 'cent_std', 'cent_skew', 'rolloff_mean', 'rolloff_std',
'label'])
with open('dataset.csv', 'w', newline='') as file:
writer = csv.writer(file, delimiter=',')
writer.writerow(header)
for directory, files in [(human_dir, human_files), (spoof_dir, spoof_files)]:
for file in files:
features = extract_features(directory, file)
if buffer_counter + 1 == buffer_size:
buffer.append(features)
writer.writerows(buffer)
print(f"- [{directory.split('/')[-1]}] Write {len(buffer)} rows")
buffer = []
buffer_counter = 0
else:
buffer.append(features)
buffer_counter += 1
if buffer:
writer.writerows(buffer)
print(f"- [{directory.split('/')[-1]}] Write {len(buffer)} rows")
print(f"- [{directory.split('/')[-1]}] Writing complete")
buffer = []
buffer_counter = 0
Загрузка формата CSV файла
Для загрузки формата CSV файла используется метод Pandas read.csv(). В скобках указывается путь к файлу в кавычках, чтобы Pandas считывал файл во фрейм данных (Dataframes - df) с этого адреса.
data = pd.read_csv('../input/datatrain/dataset.csv')
data
В таблице data мы видим:
столбец ‘filename’, где указан номер и название файла (Аудиофайлы перемешаны);
столбцы ‘mfcc_mean{i}’ и ‘mfcc_std{i}’ - средние значения и стандартные отклонения (по 20 значений) из Мел-кепстральных коэффициентов;
столбцы 'cent_mean', 'cent_std', 'cent_skew' - среднее значение, стандартное отклонение и skew (наклон) из Спектрального центроида;
столбцы 'rolloff_mean', 'rolloff_std' - среднее значение и стандартное отклонение из Спектрального спада ;
столбец ‘label’ метка.
В следующей (третьей части анализа аудиоданных) разберем алгоритм машинного обучения - SVM (Support Vector Machines) / Машины опорных векторов.
Gorodach
Очень интересные статьи, жду продолжения, сам занимался распознаванием эмоций по голосу.
Но мне кажется не хватает более человеческого прикладного объяснения некоторых вещей/фичей/характеристик звука.
AigizK
Согласен. Тех часть очень подробно описана, но не хватает описания, что в каких случаях можно применять. Выглядит как шпаргалка, которая понятна только автору.
tatvch Автор
Спасибо!
Звук и анализ аудиоданных - тема сложная, но и интересная.
При прохождении воздуха через голосовые связки возникают вибрации, которые в виде упругих волн распространяются в среде. Каждый звук представляет собой набор волн. Это основной тон - волны гендерной идентификации ( у каждого говорящего базовая частота основного тона индивидуальна и обусловлена особенностями строения гортани, в среднем для мужского голоса она составляет от 80 до 210 Гц, для женского — от 150 до 320 Гц. ). Это волны - обертоны ( призвуки, которые выше основного тона) и волны форманты (распознавание речи) связанные с уровнем частоты голосового тона, которые образуют тембр звука.
Аудиосигнал, как амплитуда ко времени и частоте. Преобразование Фурье разлагает функцию времени (сигнал) на составляющие частоты, которые отображают амплитуду каждой частоты в сигнале. В каждой частоте с помощью признаков (характеристик) анализируем плотность, мощность сигнала, высоту (зависит от частоты (число звуковых колебаний за 1 сек) низкочастотные, среднечастотные, высокочастотные) , длительность, громкость (сила звука, которая определяется амплитудой колебаний: чем она больше, тем звук получается громче), тембр (окраска звука), интенсивность , спектральный состав ( волны основного тона, обертоны, форманты) и другие физические свойства звука в определенный промежуток времени.
Все фичи (характеристики) важны при анализе аудиоданных, так как описывают физические свойства звука: высоту, громкость, тембр и т. д. И все характеристика есть у каждого аудиосигнала. Выбор значимых характеристик зависит от исследователя и той задачи, которую он решает и способа решения.
Для решения своей задачи я использую алгоритм Машинного обучения. У меня в наборе данных - 50000 тысяч аудио записей. И в ручную прослушать записи и найти закономерности просто нереально!
Знание и понимание как выглядит звук и какие признаки (фичи) можно извлечь очень важно для построения модели машинного обучения, чтобы компьютер сам просмотрел 50000 строк и 45 значений в каждой строке (фичи), изучил их, сравнил все фичи и нашел закономерности и далее смог использовать этот опыт для решения той же проблемы в новых ситуациях и на новых данных. Это и есть машинное обучение, которое охватывает статистическую часть искусственного интеллекта.
Gorodach
Спасибо большое! Тут реально ещё на 4ую часть потянет)
Я просто этим занимался и продолжаю в свободное время, так что чуть чуть понимаю, хотя тоже некоторые вещи подчеркнул.
Но думаю хабрчанам будет очень интересно)
tatvch Автор
Спасибо большое!
AigizK
Иногда кажется, что изучая голос человека и пытаясь найти какие то фичи в них, мы подходим не с того конца, а точнее не с того места. Мы берем звук, который образуется после наших губ, причем многие, когда говорят звуковая волна, даже не понимают, что это за волна. А на самом деле это перепад давления или по другому можно сказать количество точек в единичном кубе. Там где в данный момент максимум точек, мы берем как максимум волны, там где их меньше всего - за минимум. И что молекулы воздуха с одной стороны стоят почти на месте, просто качаясь(так же как и волна на воде), но с другой они двигаются, так как человек выдыхает воздух(как будто волна на воде, которая еще и течет).
И как мне кажется, если бы мы попробовали проанализировать как образуется звук с момента, когда воздух начинает выходить из легких и до момента когда покинул губы, нам было проще отличить мужской от женского, смеется или плачет, создавать разные синтезаторы голоса, меняя только основной тон или размеры голосовых связок.