blond-businesswoman-talking-into-phone-6

23 июня 2020 Python

В этом руководстве разберем создание голосового бота использующего технологии нейронных сетей на языке Python. Бот может распознавать человеческий голос в реальном времени с вашего устройства, например с микрофона ноутбука, и произносить осознанные ответы, которые обрабатывает нейронная сеть.

Бот состоит из двух основных частей: это часть обрабатывающая словарь и часть с голосовым ассистентом.

Всю разработку по написанию бота вы можете вести в IDE PyCharm, скачать можно с официального сайта JetBrains.

Все необходимые библиотеки можно установить с помощью PyPI прямо в консоле PyCharm. Команды для установки вы можете найти на официальном сайте в разделе нужной библиотеки.

voice-bot2-1024x454-8049003 Официальный сайт PyPI

Проблема возникла только с библиотекой PyAudio в Windows. Помогло следующее решение:

pip install pipwin
pipwin install pyaudio

Содержание

  • 1 Дата-сет
  • 2 Голосовой ассистент
  • 3 Текст дата-сета
  • 4 Код Python

Дата-сет

Дата-сет — это набор данных для анализа. В нашем случае это будет некий текстовый файл содержащий строки в виде вопросответ.

Все строки текста перебираются с помощью функции for, при этом из текста удаляются все ненужные символы по маске, находящейся в переменной alphabet. Каждое значение строки раздельно заносится в массив dataset.

После обработки текста все его значения преобразуются в вектора с помощью библиотеки для машинного обучения Scikit-learn. В этом примере используется функция CountVectorizer(). Далее всем векторам присваивается класс с помощью классификатора LogisticRegression().

Когда приходит сообщение от пользователя оно так же преобразуется в вектор, и далее нейросеть пытается найти похожий вектор в датасете соответствующий какому-то вопросу, когда вектор найден, мы получим ответ.

Голосовой ассистент

Для распознавания голоса и озвучивания ответов бота, используется библиотека SpeechRecognition. Система ждет в бесконечном цикле, когда придет вопрос, в нашем случае голос с микрофона, после чего преобразует его в текст и отправляет на обработку в нейросеть. После получения текстового ответа он преобразуется в речь, запись сохраняется в папке с проектом и удаляется после воспроизведения. Вот так все просто! Для удобства все сообщения дублируются текстом в консоль.

При дефолтных настройках время ответа было достаточно долгим, иногда нужно было ждать по 15-30 сек. К тому же вопрос принимался от малейшего шума. Помогли следующие настройки:

voice_recognizer.dynamic_energy_threshold = False
voice_recognizer.energy_threshold = 1000
voice_recognizer.pause_threshold = 0.5

И timeout = None, phrase_time_limit = 2 в функции listen()

После чего бот стал отвечать с минимальной задержкой.

Возможно вам подойдут другие значения. Описание этих и других настроек вы можете посмотреть все на том же сайте PyPI в разделе библиотеки SpeechRecognition. Но настройку phrase_time_limit я там почему-то не нашел, наткнулся на нее случайно в Stack Overflow.

Текст дата-сета

Это небольшой пример текста. Конечно же вопросов и ответов должно быть гораздо больше.

приветпривет
как делавсё прекрасно
как деласпасибо отлично
кто тыя бот
что делаешьс тобой разговариваю

Код Python

import speech_recognition as sr
from gtts import gTTS
import playsound
import os
import random
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression

# Словарь
def clean_str(r):
r = r.lower()
r = [c for c in r if c in alphabet]
return ''.join(r)

alphabet = ' 1234567890-йцукенгшщзхъфывапролджэячсмитьбюёqwertyuiopasdfghjklzxcvbnm'

with open('dialogues.txt', encoding='utf-8') as f:
content = f.read()

blocks = content.split('n')

dataset = []

for block in blocks:
replicas = block.split('\')[:2]
if len(replicas) == 2:
pair = [clean_str(replicas[0]), clean_str(replicas[1])]
if pair[0] and pair[1]:
dataset.append(pair)

X_text = []
y = []
for question, answer in dataset[:10000]:
X_text.append(question)
y += [answer]

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(X_text)

clf = LogisticRegression()
clf.fit(X, y)

def get_generative_replica(text):
text_vector = vectorizer.transform([text]).toarray()[0]
question = clf.predict([text_vector])[0]

return question

# Голосовой ассистент
def listen():
voice_recognizer = sr.Recognizer()
voice_recognizer.dynamic_energy_threshold = False
voice_recognizer.energy_threshold = 1000
voice_recognizer.pause_threshold = 0.5

with sr.Microphone() as source:
print("Говорите