Автоматическое определение эмоций в текстовых беседах с использованием нейронных сетей |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-08-26 11:20 Одна из основных задач диалоговых систем состоит не только в предоставлении нужной пользователю информации, но и в генерации как можно более человеческих ответов. А распознание эмоций собеседника — уже не просто крутая фича, это жизненная необходимость. В этой статье мы рассмотрим архитектуру рекуррентной нейросети для определения эмоций в текстовых беседах, которая принимала участие в SemEval-2019 Task 3 “EmoContext”, ежегодном соревновании по компьютерной лингвистике. Задача состояла в классификации эмоций (“happy”, “sad”, “angry” и “others”) в беседе из трех реплик, в которой участвовали чат-бот и человек, пишет m.habr.com 1. Обучающие данные Трек “EmoContext” на SemEval-2019 был посвящен определению эмоций в текстовых беседах с учетом контекста переписки. Контекст в данном случае — это несколько последовательных реплик участников диалога. В беседе два участника: анонимный пользователь (ему принадлежит первая и третья реплика) и чат-бот Ruuh (ему принадлежит вторая реплика). На основе трех реплик необходимо определить, какую эмоцию испытывал пользователь при написании ответа чат-боту (Таблица 1). Всего разметка датасета содержала четыре эмоции: «happy», «sad», «angry» или «others» (Таблица 1). Подробное описание представлено здесь: (Chatterjee et al., 2019). Таблица 1. Примеры из датасета EmoContext (Chatterjee et al., 2019) В ходе состязания организаторы предоставили несколько наборов данных. Обучающий датасет (Train) состоял из 30 160 размеченных вручную текстов. В этих текстах было примерно по 5000 объектов, относящихся к классам «happy», «sad» и «angry», а также 15000 текстов из класса «others» (Таблица 2). Также организаторы предоставили наборы данных для разработки (Dev) и тестирования (Test), в которых, в отличие от обучающего датасета, распределение по классам эмоций соответствовало реальной жизни: примерно по 4 % для каждого из классов «happy», «sad» и «angry», а остальное — класс «others». Данные предоставлены Microsoft, скачать их можно в официальной группе в LinkedIn. Таблица 2. Распределение меток классов эмоций в датасете (Chatterjee et al., 2019). В дополнение к этим данным мы собрали 900 тыс. англоязычных сообщений из Twitter, чтобы создать Distant-датасет (300 тыс. твитов на каждую эмоцию). При его создании мы придерживались стратегии Go et al. (2009), в рамках которой просто ассоциировали сообщения с наличием относящихся к эмоциям слов, таких как #angry, #annoyed, #happy, #sad, #surprised и так далее. Список терминов основан на терминах из SemEval-2018 AIT DISC (Duppada et al., 2018). Главной метрикой качества в соревновании EmoContext является усредненная F1-мера для трёх классов эмоций, то есть для классов «happy», «sad» и «angry». def preprocessData(dataFilePath, mode): texts_train, labels_train = preprocessData(‘./starterkitdata/train.txt’, mode=»train») 2. Предварительная обработка текста Перед обучением мы предварительно обработали тексты с помощью инструмента Ekphrasis (Baziotis et al., 2017). Он помогает исправить орфографию, нормализовать слова, сегментировать, а также определить, какие токены следует отбросить, нормализовать или аннотировать с помощью специальных тегов. На этапе предварительной обработки мы сделали следующее: Адреса URL и почту, дату и время, ники, проценты, валюты и числа заменили соответствующими тегами. Кроме того, Emphasis содержит токенизатор, который может идентифицировать большинство эмодзи, эмотиконов и сложных выражений, а также даты, время, валюты и акронимы. Таблица 3. Примеры предварительной обработки текста. from ekphrasis.classes.preprocessor import TextPreProcessor import re label2emotion = {0: «others», 1: «happy», 2: «sad», 3: «angry»} emoticons_additional = { text_processor = TextPreProcessor( def tokenize(text): 3. Векторное представление слов Векторное представление стало неотъемлемой частью большинства подходов к созданию NLP-систем с применением глубокого обучения. Чтобы определить наиболее подходящие модели векторного отображения, мы попробовали Word2Vec (Mikolov et al., 2013), GloVe (Pennington et al., 2014) и FastText (Joulin et al., 2017), а также предварительно обученные векторы DataStories (Baziotis et al., 2017). Word2Vec находит взаимосвязи между словами согласно предположению, что в похожих контекстах встречаются семантически близкие слова. Word2Vec пытается прогнозировать целевое слово (архитектура CBOW) или контекст (архитектура Skip-Gram), то есть минимизировать функцию потерь, а GloVe рассчитывает вектора слов, уменьшая размерность матрицы смежности. Логика работы FastText похожа на логику Word2Vec, за исключением того, что для построения векторов слов она использует символьные n-граммы, и как следствие, может решать проблему неизвестных слов. Для всех упомянутых моделей мы используем параметры обучения по умолчанию, предоставленные авторами. Мы обучили простую LSTM-модель (dim=64) на основе каждого из этих векторных представлений и сравнили эффективность классификации с помощью кросс-валидации. Наилучший результат в F1-меры показали предварительно обученные вектора DataStories. Для обогащения выбранного векторного отображения эмоциональной окраской слов мы решили произвести тонкую настройку векторов с помощью автоматически размеченного Distant-датасета (Deriu et al., 2017). Мы использовали Distant-датасет для обучения простой LSTM-сети, чтобы классифицировать «злые», «грустные» и «счастливые» сообщения. Эмбеддинг слой был заморожен в течение первой итерации обучения, чтобы избежать сильных изменений у весов векторов, а для последующих пяти итераций слой был разморожен. После обучения «оттюненные» векторы были сохранены для последующего использования в нейронной сети, а также выложены в общий доступ. def getEmbeddings(file): def getEmbeddingMatrix(wordIndex, embeddings, dim): from keras.preprocessing.text import Tokenizer embeddings, dim = getEmbeddings(’emosense.300d.txt’) wordIndex = tokenizer.word_index embeddings_matrix = getEmbeddingMatrix(wordIndex, embeddings, dim) 4. Архитектура нейросети Рекуррентные нейросети (RNN) — это семейство нейросетей, специализирующихся на обработке серии событий. В отличие от традиционных нейросетей, RNN предназначены для работы с последовательностями путем использования внутренних весов. Для этого вычислительный граф RNN содержит циклы, отражающие влияние предыдущей информации из последовательности событий на текущую. LSTM-нейросети (Long Short-Term Memory) были представлены в качестве расширения RNN в 1997-м (Hochreiter and Schmidhuber, 1997). Рекуррентные ячейки LSTM соединены так, чтобы избегать проблем с взрывом и затуханием градиентов. Традиционные LSTM лишь сохраняют прошлую информацию, поскольку обрабатывают последовательность в одном направлении. Двунаправленные LSTM, работающие в обоих направлениях, комбинируют выходные данные двух скрытых LSTM-слоёв, передающих информацию в противоположных направлениях — один по ходу времени, другой против, — тем самым одновременно получая данные из прошлого и будущего состояний (Schuster and Paliwal, 1997). Рисунок 1: Уменьшенная версия архитектуры. LSTM-модуль использует одни и те же веса для первого и третьего этапов. Упрощённое представление описанного подхода представлено на рисунке 1. Архитектура нейросети состоит из эмбеддинг-слоя и двух двунаправленных LTSM-модулей (dim = 64). Первый LTSM-модуль анализирует слова первого пользователя (то есть первую и третью реплику беседы), а второй модуль анализирует слова второго пользователя (вторую реплику). На первом этапе слова каждого пользователя с помощью заранее обученных векторных представлений подаются в соответствующий двунаправленный LTSM-модуль. Затем получившиеся три карты признаков объединяются в плоский вектор признаков, а затем передаются в полносвязный скрытый слой (dim=30), который анализирует взаимодействия между извлечёнными признаками. Наконец, эти признаки обрабатываются в выходном слое с помощью функции softmax-активации, чтобы определить финальную метку класса. Для уменьшения переобучения после слоёв векторного представления были добавлены слои регуляризации с гауссовским шумом, а также в каждый LTSM-модуль (p = 0.2) и перед скрытым полностью связным слоем (p = 0.1) были добавлены dropout-слои (Srivastava et al., 2014). from keras.layers import Input, Dense, Embedding, Concatenate, Activation, def buildModel(embeddings_matrix, sequence_length, lstm_dim, hidden_layer_dim, num_classes, turn1_branch = embeddingLayer(turn1_input) turn1_branch = GaussianNoise(noise, input_shape=(None, sequence_length, embedding_dim))(turn1_branch) lstm1 = Bidirectional(LSTM(lstm_dim, dropout=dropout_lstm)) turn1_branch = lstm1(turn1_branch) x = Concatenate(axis=-1)([turn1_branch, turn2_branch, turn3_branch]) x = Dropout(dropout)(x) x = Dense(hidden_layer_dim, activation=’relu’)(x) output = Dense(num_classes, activation=’softmax’)(x) model = Model(inputs=[turn1_input, turn2_input, turn3_input], outputs=output) model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘acc’]) return model model = buildModel(embeddings_matrix, MAX_SEQUENCE_LENGTH, lstm_dim=64, hidden_layer_dim=30, num_classes=4) 5. Результаты В ходе поиска оптимальной архитектуры мы экспериментировали не только с количеством нейронов в слоях, функциями активации и параметрами регуляризации, но и с самой архитектурой нейросети. Подробнее об этом говорится в исходной работе. Описанная в предыдущем разделе архитектура продемонстрировала наилучшие результаты при обучении на датасете Train и валидации на датасете Dev, поэтому она использовалась на финальной стадии состязания. На последнем тестовом датасете модель показала микро-усредненную F1-меру 72,59 %, а максимально достигнутый результат среди всех участников составил 79,59 %. Тем не менее, наш результат оказался гораздо выше базового значения в 58,68 %, заданного организаторами. Исходный код модели и векторного представления слов доступен на GitHub. Цитирование: Источник: podii.net Комментарии: |
|