Hoje em dia, os robôs de voz estão ganhando imensa popularidade, desde pedir um táxi até a venda para clientes. A criação de um bot de voz se resume a três etapas básicas.
- ASR de reconhecimento de voz.
- Esclarecimento do significado do que foi dito e buscar as entidades necessárias no texto (por exemplo, endereço, valor, nome completo, etc.)
- Gerando uma resposta, convertendo texto em fala TTS. Iremos desde a criação de um bot de texto simples até a integração com o sistema de telefonia freeswitch com reconhecimento de voz e voz de respostas preparadas. Este artigo descreve as ferramentas usadas e a maneira de integrá-las para criar um robô de voz.
Na primeira parte, falaremos sobre a criação de um bot de texto simples que você pode incorporar em um chat.
Exemplo de conversa B-bot W-man
:
:
:
: ?
:
: ?
:?
:
:
Um pouco de teoria O
bot funciona com o princípio da intenção do usuário. Cada intenção tem uma lista de respostas preparadas. Para que o bot entenda a intenção do usuário, é necessário treinar o modelo no conjunto de dados com intenções e frases que possam ativar essa intenção.
Por exemplo
Intenção: Diga olá
Frases possíveis: olá, boa tarde, gratuti ...
Resposta: Olá
Intenção: Diga adeus
Frases possíveis: Tchau, tchau , Adeus ...
Resposta: Tchau
Etapa 1: pré-processamento do conjunto de dados
É baseado em um conjunto de dados do treinamento aberto da caixa de habilidades para escrever um bot de bate-papo em telegramas que podem falar com você sobre filmes. Não posso postar por motivos óbvios.
O pré-processamento é uma etapa muito importante.
Em primeiro lugar, removeremos todos os símbolos e números do texto e colocaremos tudo em minúsculas.
Em seguida, você precisa corrigir erros de digitação e de palavras.
-
Esta tarefa não é fácil, existe uma boa ferramenta do Yandex chamada Speller, mas é limitada no número de solicitações por dia, então vamos procurar alternativas gratuitas.Para
python existe uma biblioteca jamspell maravilhosa que corrige bem os erros de digitação. Há um bom modelo pré - treinado de língua russa para ela. Vamos rodar todos os dados de entrada por meio desta biblioteca. Para um robô de voz, esta etapa não é tão relevante, pois o sistema de reconhecimento de voz não deve emitir palavras com erros, ele pode emitir a palavra errada. Este processo é necessário para um bot de bate-papo. Além disso, para minimizar a influência de erros de digitação, você pode treinar a rede não em palavras, mas em n-gramas.
N-gramas são partes de palavras com n letras. por exemplo, os 3 gramas para a palavra olá serão
at, riv, salgueiro, veterinário. Isso o ajudará a ser menos dependente de erros de digitação e a aumentar a precisão do reconhecimento.
Em seguida, é necessário trazer as palavras à sua forma normal, o chamado processo de lematização de palavras.
-
A biblioteca rulemma é adequada para essa tarefa .
Você também pode remover palavras de parada de frases que têm pouca carga semântica, mas aumentar o tamanho da rede neural (eu tirei da biblioteca nltk stopwords.words ("russo")), mas no nosso caso é melhor não removê-las, já que o usuário pode responder um robô com apenas uma palavra, mas pode ser da lista de palavras de parada.
Etapa 2: converter o conjunto de dados em uma forma compreensível para NN
Primeiro, você precisa criar um dicionário de todas as palavras do conjunto de dados.
Para treinar o modelo, você precisa traduzir todas as palavras em oneHotVector.
Esta é uma matriz que é igual ao comprimento do dicionário de palavras, em que todos os valores são iguais a 0 e apenas um é igual a 1 na posição da palavra no dicionário.
Além disso, todas as frases de entrada são convertidas em uma matriz tridimensional que contém todas as frases, a frase contém uma lista de palavras no formato oneHotVector - este será nosso conjunto de dados de entrada X_train.
Cada frase de entrada precisa ser combinada com uma intenção apropriada no formato sameHotVector - esta é a nossa saída y_train.
Etapa 3: criar o modelo
Para um pequeno bot, um pequeno modelo com duas camadas lstm e duas camadas totalmente conectadas é o suficiente:
model = Sequential()
model.add(LSTM(64,return_sequences=True,input_shape=(description_length, num_encoder_tokens)))
model.add(LSTM(32))
model.add(Dropout(0.25))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(len(set(y)), activation='softmax'))
Compilamos o modelo e selecionamos um otimizador, escolhi adam porque deu o melhor resultado.
Etapa 4: treinar o modelo
Depois de preparar o conjunto de dados e compilar o modelo, você pode começar a treiná-lo. Como o conjunto de dados é pequeno, tivemos que treinar o modelo para 250-500 épocas, após as quais o retreinamento ocorreu.
Etapa 5: tentar falar com nosso bot
Para falar com nosso bot, você precisa enviar os dados corretamente preparados para a entrada do modelo treinado. A entrada do usuário precisa ser processada da mesma maneira que o conjunto de dados da primeira etapa. Em seguida, transforme-o em uma forma compreensível para o NN como na segunda etapa usando o mesmo dicionário de palavras e seus índices, de forma que as palavras de entrada correspondam às palavras com as quais o treinamento foi realizado.
A entrada processada é alimentada no modelo e obtemos uma matriz de valores em que as probabilidades de nossa frase atingir uma intenção específica estão presentes, mas precisamos selecionar a intenção com a maior probabilidade, isso pode ser feito por meio da biblioteca numpy
np.argmax(results)
É necessário avaliar a confiança da rede nesta resposta e selecionar o limite para emitir frases de falha para o usuário, como - eu não entendo você. Para meus propósitos, eu defino um limite de 50% de confiança, abaixo do qual o bot dirá que não entendeu você.
Em seguida, na lista de nossas intenções, selecionamos a resposta adequada e a fornecemos ao usuário.
PS: O modelo pode ser treinado não apenas com base em palavras, mas também dividindo as frases em letras ou n-gramas, caso em que será necessário um modelo mais sério.
model = Sequential()
model.add(LSTM(512,return_sequences=True,input_shape=(description_length, num_encoder_tokens)))
model.add(LSTM(256))
model.add(Dropout(0.25))
model.add(Dense(len(set(y)), activation='softmax'))