Aula 38 – TensorFlow – Keras – Redes Neurais – RNN Chatbot

Aula 38 – TensorFlow – Keras – Redes Neurais – RNN Chatbot

Voltar para página principal do blog

Todas as aulas desse curso

Aula 37                        Aula 39

TensorFlow - Keras - Redes Neurais

TensorFlow – Keras – Redes Neurais

Pacote Programador Fullstack

Pacote Programador Fullstack

Redes Sociais:

facebook              

 

Site das bibliotecas

Tensorflow

Keras

Cursos Gratuitos

Digital Innovation

Quer aprender python3 de graça e com certificado? Acesse então:

workover

Meus link de afiliados:

Hostinger

Digital Ocean

One.com

Canais do Youtube

Toti

Backing Track / Play-Along

Código Fluente

Putz!

Vocal Techniques and Exercises

Fiquem a vontade para me adicionar ao linkedin.

PIX para doações

PIX Nubank

PIX Nubank

Notebook da aula

Base de dados: human_text.txt e o robot_text.txt


Aula 38 – TensorFlow – Keras – Redes Neurais – RNN Chatbot

O artigo original seguido para essa aula é: Generative chatbots using the seq2seq model! de Dhruvil Shah.

Testando o modelo

Por fim, criaremos uma função que aceita nossas entradas de texto e gera uma resposta usando o codificador e o decodificador que criamos.

O codificador processa cada token na sequência de entrada.

Ele tenta agrupar todas as informações sobre a sequência de entrada em um vetor de comprimento fixo, ou seja, o ‘vetor de contexto’.

Depois de passar por todos os tokens, o codificador passa esse vetor para o decodificador.

Então, no exemplo, a função decode_response(), recebe uma matriz NumPy que representa a sentença de texto de entrada, o que o usuário digitou na caixa de diálogo, e obtém a resposta gerada.

O que acontece na função decode_response() é o seguinte:

1.) Recupera os estados de saída do codificador

2.) Passa os estados de saída para o decodificador que é o estado oculto inicial do decodificador para decodificar a frase palavra por palavra

3 .) Atualiza o estado oculto do decodificador após decodificar cada palavra para que possamos usar palavras previamente decodificadas para ajudar a decodificar novas

Para quando encontra o token ‘<END>‘ que foi adicionado às sequências de destino na tarefa de pré-processamento, ou quando atinge o comprimento máximo da sequência.

A gente pegou esse tamanho máximo com essas linhas de código na parte do Training setup:
max_encoder_seq_length = max([len(re.findall(r”[\w’]+|[^\s\w]”, input_doc)) for input_doc in input_docs])
max_decoder_seq_length = max([len(re.findall(r”[\w’]+|[^\s\w]”, target_doc)) for target_doc in target_docs])


def decode_response(test_input):
    #Getting the output states to pass into the decoder
    states_value = encoder_model.predict(test_input)
    #Generating empty target sequence of length 1
    target_seq = np.zeros((1, 1, num_decoder_tokens))
    #Setting the first token of target sequence with the start token
    target_seq[0, 0, target_features_dict['']] = 1.
    
    #A variable to store our response word by word
    decoded_sentence = ''
    
    stop_condition = False
    while not stop_condition:
      #Predicting output tokens with probabilities and states
      output_tokens, hidden_state, cell_state = decoder_model.predict([target_seq] + states_value)
      #Choosing the one with highest probability
      sampled_token_index = np.argmax(output_tokens[0, -1, :])
      sampled_token = reverse_target_features_dict[sampled_token_index]
      decoded_sentence += " " + sampled_token
      #Stop if hit max length or found the stop token
      if (sampled_token == '<END>' or len(decoded_sentence) > max_decoder_seq_length):
        stop_condition = True
      #Update the target sequence
      target_seq = np.zeros((1, 1, num_decoder_tokens))
      target_seq[0, 0, sampled_token_index] = 1.
      #Update states
      states_value = [hidden_state, cell_state]
    return decoded_sentence

Juntando tudo — Chatbot Generativo

Vamos criar uma classe que contém métodos necessários para executar um chatbot.


class ChatBot:
  negative_responses = ("no", "nope", "nah", "naw", "not a chance", "sorry")
  exit_commands = ("quit", "pause", "exit", "goodbye", "bye", "later", "stop")
  #Method to start the conversation
  def start_chat(self):
    user_response = input("Hi, I'm a chatbot trained on random dialogs. Would you like to chat with me?\n")
    
    if user_response in self.negative_responses:
      print("Ok, have a great day!")
      return
    self.chat(user_response)
  #Method to handle the conversation
  def chat(self, reply):
    while not self.make_exit(reply):
      reply = input(self.generate_response(reply)+"\n")
    
  #Method to convert user input into a matrix
  def string_to_matrix(self, user_input):
    tokens = re.findall(r"[\w']+|[^\s\w]", user_input)
    #max_encoder_seq_length is the number of matrix rows and num_encoder_tokens is the number of matrix cols
    user_input_matrix = np.zeros(
      (1, max_encoder_seq_length, num_encoder_tokens),
      dtype='float32')
    for timestep, token in enumerate(tokens):
      #input_features_dict[token] represent the col in array row of the matrix
      #in other words, the position in inner array.
      if token in input_features_dict:
        user_input_matrix[0, timestep, input_features_dict[token]] = 1.
    return user_input_matrix
  
  #Method that will create a response using seq2seq model we built
  def generate_response(self, user_input):
    input_matrix = self.string_to_matrix(user_input)
    chatbot_response = decode_response(input_matrix)
    #Remove and tokens from chatbot_response
    chatbot_response = chatbot_response.replace("",'')
    chatbot_response = chatbot_response.replace("",'')
    return chatbot_response
  #Method to check for exit commands
  def make_exit(self, reply):
    for exit_command in self.exit_commands:
      if exit_command in reply:
        print("Ok, have a great day!")
        return True
    return False

chatbot = ChatBot()

Todos os métodos são autoexplicativos no código acima.

Escopo futuro vs limitação

Aqui usamos um conjunto de dados muito pequeno e obtivemos uma precisão de cerca de 20%.

Testei localmente usando o dobro da amostragem, ao invés de 400 amostras, usei 800 amostras da base de dados.

Primeiro tentei usar 2000 amostras, mas, cada época demorava muito pra terminar, baixei para 800 amostras, só que o resultado da precisão não alterou, ficou em cerca de 20% mesmo.

A limitação de usar essa abordagem é que para criar chatbots generativos, precisamos de conjuntos de dados bem grandes e muito poder computacional para treinar a rede.

Para modelos como o do google translator, por exemplo, são investidos milhões de dólares em processamento computacional para o treinamento das redes.

Conclusão

A arquitetura de domínio fechado se concentra na seleção de respostas de um conjunto de respostas predefinidas, a arquitetura de domínio aberto, permite realizar geração de texto ilimitada.

Os sistemas de domínio fechado usam classificação de intenção, identificação de entidade e seleção de resposta.

Já um chatbot de domínio aberto, ou seja, um modelo generativo, em vez de selecionar respostas prontas,  ele gera a resposta palavra por palavra, permitindo novas combinações de linguagem.

Nas indústrias, algumas empresas utilizam os chatbots de domínio fechado para garantir que o usuário sempre receba a resposta predefinida certa.

O domínio Natural Language Processing-PNL está desenvolvendo e treinando redes neurais para aproximar a abordagem que o cérebro humano faz para o processamento de linguagem.

Essa estratégia de aprendizado profundo permite que os computadores manipulem a linguagem humana com muito mais eficiência.

Por essa aula é só, nos vemos na próxima, valeu \o/.


Voltar para página principal do blog

Todas as aulas desse curso

Aula 37                        Aula 39

Meu github:

https://github.com/toticavalcanti

Novamente deixo meus link de afiliados:

Hostinger

Digital Ocean

One.com

Obrigado, até a próxima e bons estudos. 😉

About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>