Распознавание эмоций с использованием нейронной сети

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

Данная технология используется в колл-центрах для классификации звонков (в соответствии с эмоциями можно различить недовольство, удовлетворенность или гнев клиента), что помогает эффективно построить дальнейший диалог.

Распознавание эмоций с использованием нейронной сети

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

Исходный набор данных:

Распознавание эмоций с использованием нейронной сети

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

Распознавание эмоций с использованием нейронной сети

Всего в наборе представлено 6 различных эмоций, при этом данные сбалансированы.

Распознавание эмоций с использованием нейронной сети

Для анализа и извлечения данных из аудиофайлов будем использовать библиотеку librosa. Для примера посмотрим на волны «счастья» и «злости».

def wave(data, sr, e): plt.figure(figsize=(10, 3)) plt.title('Waveplot for {}'.format(e), size=15) librosa.display.waveplot(data, sr=sr) plt.show()
Распознавание эмоций с использованием нейронной сети
Распознавание эмоций с использованием нейронной сети

При гневе вся фраза как будто бы произносится на одном дыхании, с большим напором в начале, это отчетливо видно на графике. Если посмотреть на график «счастья», то можно заметить, что фраза произносится протяжнее, равномернее. Видно, что на записях присутствуют небольшие шумы. Именно изменение интонации и тембра голоса поможет нам классифицировать эмоции, представленные на аудиозаписях.

Данные, полученные из аудио, не могут быть использованы для обучения модели напрямую, поэтому преобразуем их в подходящий формат. Одними из лучших инструментов для извлечения информации из звуковых сигналов являются MFCC (Мел-кепстральные коэффициенты). Коэффициенты описывают форму спектральной огибающей сигнала. Пройдемся по записям. Считаем их, отбросив 0,15 секунды в начале, а длину записей ограничим 3 секундами. В качестве признаков будем использовать средние значения mfcc.

df_1 = pd.DataFrame(columns=['feature']) i=0 for index,path in enumerate(df.path): X, sample_rate = librosa.load(path, duration=3, offset=0.15) sample_rate = np.array(sample_rate) mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=20), axis=0) df_1.loc[i] = [mfccs] i=i+1

Результаты извлечения признаков:

Распознавание эмоций с использованием нейронной сети

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

y= pd.get_dummies(df_1.path) tr_x, test_x, tr_y, test_y= train_test_split( df_1.drop([‘emotions’,’path’], axis=1), y, test_size=0.3, random_state=42)

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

in_node = Input( shape = (130,1)) out_node = Conv1D (128,4, padding = ‘same’, activation = ‘relu’)(in_node) out_node=Dropout(0.15)(out_node) out_node = MaxPooling1D(pool_size=(4))(out_node) out_node=Conv1D(64,4, padding=’same’, activation = ‘relu’)(out_node) out_node=Dropout(0.15)(out_node) out_node = MaxPooling1D(pool_size=(4))(out_node) out_node=Conv1D(32,4, padding=’same’, activation = ‘relu’)(out_node) out_node=Flatten()(out_node) out_node=Dense(6, activation=’sigmoid’)(out_node) mod=Model(inputs = in_node, outputs = out_node) mod.compile(loss = ‘categorical_crossentropy’, optimizer = ‘adam’, metrics=[‘accuracy’]) mod.fit(tr_x,tr_y, epochs=70)

Построим график изменения точность в процессе обучения.

Распознавание эмоций с использованием нейронной сети

Результаты на тестовой выборке:

Распознавание эмоций с использованием нейронной сети

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

77
4 комментария

О, ещё одна интересная библиотека, спасибо за обзор.
Надо будет протестировать, может чего интересного получится сделать, например в связке с open cv...

Ответить
Автор

Вот еще один кейс мы рассматривали с применением библиотеки librosa https://vc.ru/ml/136589-vyyavlyaem-priznaki-audiomontazha-metodami-ai (про выявление признаков аудиомонтажа)

Ответить

А как у вас так работает нейрона с таким размером входных данных ? может где можно посмотреть весь код ?

Ответить
Автор

Добрый день! В тексте публикации продемонстрированы просто сэмплы, а не весь набор входных данных (он составляет 7 442 аудиофайла). Код, к сожалению, не сохранился...

Ответить