[PYTHON] J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow

J'étudiais TensorFlow et je voulais créer quelque chose Modèles de séquence à séquence Discuter à la fin Il a été écrit que vous pouvez créer des bots, j'ai donc essayé de le faire en me référant au code du tutoriel. En particulier, j'ai fait référence à j'ai fait une conversation AI avec TensorFlow. Cliquez ici pour github (https://github.com/sanshirookazaki/chat)

Environnement d'exécution

-OS X -TensorFlow r0.9

Fichier

Le fichier est le suivant

nom de fichier Contenu
seq2seq_model.py modèle seq2seq
data_utils.py Préparez les données
translate.py Formation et exécution
datas Dossier de données

Préparation des données

Le contenu du dossier de données est le suivant. L'envoi d'un chat est IN et la réponse est OUT. Mettez les données nécessaires dans les quatre fichiers ci-dessus et préparez le reste vide.

nom de fichier Contenu
train_data_in.txt Formation IN
train_data_out.txt Formation OUT
test_data_in.txt Test IN
test_data_out.txt Tester
vocab_in.txt Dans le vocabulaire
vocab_out.txt Vocabulaire OUT
train_data_ids_in.txt Conversion d'identité de la formation IN
train_data_ids_out.txt Conversion d'identifiant de la formation OUT
test_data_ids_in.txt Conversion d'identifiant du test IN
test_data_ids_out.txt Conversion d'ID du test OUT

Contenu des données

Je n'ai pas trouvé beaucoup de données de conversation, alors j'ai utilisé Mecab pour analyser morphologiquement la traduction de la conversation dans un manuel d'anglais du collège et la mettre dans un saut de ligne.

Sortant

train_data_in.txt


Êtes-vous de New York? ..
・
・
・

réponse

train_data_out.txt


Non ce n'est pas. Je viens de Boston.
・
・
・

C'est comme ressentir. Préparez test_data_in.txt et test_data_out.txt de la même manière. Il y a 306 phrases pour la formation et 306 phrases pour le test (153 chacune pour IN et OUT), pour un total de 712 phrases, et le nombre de vocabulaire est d'environ 500 chacun pour la formation et le test. Très peu de données (pleurs)

Code d'apprentissage

C'est le code pour apprendre. Par défaut dans le didacticiel, le lot (batch_size) était de 64, le nombre de couches (num_layers) était de 3, l'unité de couches (taille) était de 1024 et le nombre de vocabulaire (vocab_size) était de 40000.

translate.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import math
import os
import random
import sys
import time

import tensorflow.python.platform

import numpy as np
from six.moves import xrange  
import tensorflow as tf

import data_utils
from tensorflow.models.rnn.translate import seq2seq_model
from tensorflow.python.platform import gfile


tf.app.flags.DEFINE_float("learning_rate", 0.5, "Learning rate.")
tf.app.flags.DEFINE_float("learning_rate_decay_factor", 0.99,
                          "Learning rate decays by this much.")
tf.app.flags.DEFINE_float("max_gradient_norm", 5.0,
                          "Clip gradients to this norm.")
tf.app.flags.DEFINE_integer("batch_size", 4,
                            "Batch size to use during training.")
tf.app.flags.DEFINE_integer("size", 256, "Size of each model layer.")
tf.app.flags.DEFINE_integer("num_layers", 2, "Number of layers in the model.")
tf.app.flags.DEFINE_integer("in_vocab_size", 500, "input vocabulary size.")
tf.app.flags.DEFINE_integer("out_vocab_size", 500, "output vocabulary size.")
tf.app.flags.DEFINE_string("data_dir", "datas", "Data directory")       
tf.app.flags.DEFINE_string("train_dir", "datas", "Training directory.")
tf.app.flags.DEFINE_integer("max_train_data_size", 0,
                            "Limit on the size of training data (0: no limit).")
tf.app.flags.DEFINE_integer("steps_per_checkpoint", 100,
                            "How many training steps to do per checkpoint.")
tf.app.flags.DEFINE_boolean("decode", False,
                            "Set to True for interactive decoding.")
tf.app.flags.DEFINE_boolean("self_test", False,
                            "Run a self-test if this is set to True.")

FLAGS = tf.app.flags.FLAGS

_buckets = [(5, 10), (10, 15), (20, 25), (40, 50)]


def read_data(source_path, target_path, max_size=None):
  data_set = [[] for _ in _buckets]
  source_file = open(source_path,"r")
  target_file = open(target_path,"r")

  source, target = source_file.readline(), target_file.readline()     
  counter = 0
  while source and target and (not max_size or counter < max_size):
    counter += 1
    if counter % 50 == 0:                         
      print("  reading data line %d" % counter)
      sys.stdout.flush()

    source_ids = [int(x) for x in source.split()]   
    target_ids = [int(x) for x in target.split()]    
    target_ids.append(data_utils.EOS_ID)             
    for bucket_id, (source_size, target_size) in enumerate(_buckets):        
      if len(source_ids) < source_size and len(target_ids) < target_size:    
        data_set[bucket_id].append([source_ids, target_ids])                 
        break
    source, target = source_file.readline(), target_file.readline()
  return data_set

def create_model(session, forward_only):
  model = seq2seq_model.Seq2SeqModel(
      FLAGS.in_vocab_size, FLAGS.out_vocab_size, _buckets,                           
      FLAGS.size, FLAGS.num_layers, FLAGS.max_gradient_norm, FLAGS.batch_size,      
      FLAGS.learning_rate, FLAGS.learning_rate_decay_factor,                       
      forward_only=forward_only)                                                    
  
  ckpt = tf.train.get_checkpoint_state(FLAGS.train_dir)                             
  if ckpt and gfile.Exists(ckpt.model_checkpoint_path):                              
    print("Reading model parameters from %s" % ckpt.model_checkpoint_path)          
    model.saver.restore(session, ckpt.model_checkpoint_path)                        
  else:
    print("Created model with fresh parameters.")
    session.run(tf.initialize_all_variables())                                      
  return model                                                                      


def train():
                                                                                    
  print("Preparing data in %s" % FLAGS.data_dir)                                
  in_train, out_train, in_dev, out_dev, _, _ = data_utils.prepare_wmt_data(           
      FLAGS.data_dir, FLAGS.in_vocab_size, FLAGS.out_vocab_size)                     
                                                  

  with tf.Session() as sess:
    

    print("Creating %d layers of %d units." % (FLAGS.num_layers, FLAGS.size))       
    model = create_model(sess, False)                                               

    print ("Reading development and training data (limit: %d)."     
           % FLAGS.max_train_data_size)                                             
    dev_set = read_data(in_dev, out_dev)                                             
    train_set = read_data(in_train, out_train, FLAGS.max_train_data_size)            
                                                                                    
    train_bucket_sizes = [len(train_set[b]) for b in xrange(len(_buckets))]         
    train_total_size = float(sum(train_bucket_sizes))                               

 
    train_buckets_scale = [sum(train_bucket_sizes[:i + 1]) / train_total_size     
                           for i in xrange(len(train_bucket_sizes))]              

    step_time, loss = 0.0, 0.0
    current_step = 0
    previous_losses = []
    while True:
     
      random_number_01 = np.random.random_sample()                     
      bucket_id = min([i for i in xrange(len(train_buckets_scale))      
                       if train_buckets_scale[i] > random_number_01])

      start_time = time.time()
      encoder_inputs, decoder_inputs, target_weights = model.get_batch(   
          train_set, bucket_id)                                           
                                                                          
      _, step_loss, _ = model.step(sess, encoder_inputs, decoder_inputs, 
                                   target_weights, bucket_id, False)      
      step_time += (time.time() - start_time) / FLAGS.steps_per_checkpoint
      loss += step_loss / FLAGS.steps_per_checkpoint
      current_step += 1

      
      if current_step % FLAGS.steps_per_checkpoint == 0:
     
        perplexity = math.exp(loss) if loss < 300 else float('inf')
        print ("global step %d learning rate %.4f step-time %.2f perplexity "
               "%.2f" % (model.global_step.eval(), model.learning_rate.eval(),
                         step_time, perplexity))


        if len(previous_losses) > 2 and loss > max(previous_losses[-3:]):
          sess.run(model.learning_rate_decay_op)
        previous_losses.append(loss)

        checkpoint_path = os.path.join(FLAGS.train_dir, "translate.ckpt")
        model.saver.save(sess, checkpoint_path, global_step=model.global_step)
        step_time, loss = 0.0, 0.0

        for bucket_id in xrange(len(_buckets)):
          encoder_inputs, decoder_inputs, target_weights = model.get_batch(
              dev_set, bucket_id)
          _, eval_loss, _ = model.step(sess, encoder_inputs, decoder_inputs,
                                       target_weights, bucket_id, True)
          eval_ppx = math.exp(eval_loss) if eval_loss < 300 else float('inf')
          print("  eval: bucket %d perplexity %.2f" % (bucket_id, eval_ppx))
        sys.stdout.flush()


def decode():
  with tf.Session() as sess:
    print ("Hello!!")
    model = create_model(sess, True)                         
    model.batch_size = 1  
    
    in_vocab_path = os.path.join(FLAGS.data_dir,
                                 "vocab_in.txt")     
    out_vocab_path = os.path.join(FLAGS.data_dir,
                                 "vocab_out.txt" )
                                                                        
    in_vocab, _ = data_utils.initialize_vocabulary(in_vocab_path)        
    _, rev_out_vocab = data_utils.initialize_vocabulary(out_vocab_path)    

    
    sys.stdout.write("> ")
    sys.stdout.flush()
    sentence = sys.stdin.readline()    
    while sentence:

      token_ids = data_utils.sentence_to_token_ids(sentence, in_vocab)   
      
      bucket_id = min([b for b in xrange(len(_buckets))
                       if _buckets[b][0] > len(token_ids)])               

      encoder_inputs, decoder_inputs, target_weights = model.get_batch(
          {bucket_id: [(token_ids, [])]}, bucket_id)
    
      _, _, output_logits = model.step(sess, encoder_inputs, decoder_inputs,      
                                       target_weights, bucket_id, True)

      outputs = [int(np.argmax(logit, axis=1)) for logit in output_logits]       

      if data_utils.EOS_ID in outputs:
        outputs = outputs[:outputs.index(data_utils.EOS_ID)]                      

      print(" ".join([rev_out_vocab[output] for output in outputs]))
      print("> ", end="")
      sys.stdout.flush()
      sentence = sys.stdin.readline()                                             
                                                                                  

def self_test():
  
  with tf.Session() as sess:
    print("Self-test for neural translation model.")
    
    model = seq2seq_model.Seq2SeqModel(10, 10, [(3, 3), (6, 6)], 32, 2,
                                       5.0, 32, 0.3, 0.99, num_samples=8)
    sess.run(tf.initialize_all_variables())

    
    data_set = ([([1, 1], [2, 2]), ([3, 3], [4]), ([5], [6])],
                [([1, 1, 1, 1, 1], [2, 2, 2, 2, 2]), ([3, 3, 3], [5, 6])])
    for _ in xrange(5):  
      bucket_id = random.choice([0, 1])
      encoder_inputs, decoder_inputs, target_weights = model.get_batch(
          data_set, bucket_id)
      model.step(sess, encoder_inputs, decoder_inputs, target_weights,
                 bucket_id, False)


def main(_):
  if FLAGS.self_test:
    self_test()
  elif FLAGS.decode:
    decode()
  else:
    train()

if __name__ == "__main__":
  tf.app.run()

Courir

python translate.py --data_dir datas --train_dir datas

Tapez pour commencer l'apprentissage et les points de contrôle seront enregistrés dans les données.

Creating 2 layers of 256 units.
Created model with fresh parameters.
Reading development and training data (limit: 0).
  reading data line 50
  reading data line 100
  reading data line 150
  reading data line 50
  reading data line 100
  reading data line 150
global step 100 learning rate 0.5000 step-time 0.77 perplexity 137.46
  eval: bucket 0 perplexity 90.26
  eval: bucket 1 perplexity 176.55
  eval: bucket 2 perplexity 203.59
  eval: bucket 3 perplexity 211.34
global step 200 learning rate 0.5000 step-time 0.73 perplexity 53.88
  eval: bucket 0 perplexity 64.65
  eval: bucket 1 perplexity 161.62
  eval: bucket 2 perplexity 108.95
  eval: bucket 3 perplexity 213.13
                            :
                            :

L'apprentissage progresse comme ça, et la convergence est lente, alors arrondissez-vous à un endroit approprié,

python translate.py --decode --data_dir datas --train_dir datas

Tapez pour entrer en mode interactif.

Pour le moment, je l'ai essayé autour de step1000. > Est l'entrée.

alt

Ce n'est pas du tout une conversation (rires) Les mêmes mots seront retournés. Ce domaine est-il dû au manque de données?

Aussi comme avant

python translate.py --data_dir datas --train_dir datas


Si vous frappez, vous apprendrez de la suite.

Résumé

Il y avait trop peu de données pour faire une conversation.

Recommended Posts

J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé de déplacer le modèle 3D en faisant quelque chose comme la capture de mouvement avec juste un ordinateur portable + une caméra Web
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR.
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
J'ai essayé de prédire le nombre de personnes infectées au niveau national de la nouvelle corona avec un modèle mathématique
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
J'ai essayé de créer une API de reconnaissance d'image simple avec Fast API et Tensorflow
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Battle Edition ~
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé de refactoriser le modèle CNN de TensorFlow en utilisant TF-Slim
J'ai fait une fonction pour vérifier le modèle de DCGAN
Je pensais que je pouvais créer un bon éditeur gitignore, alors j'ai essayé de faire quelque chose comme MVP pour le moment
J'ai essayé d'écrire dans un modèle de langage profondément appris
J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé d'agrandir la taille du volume logique avec LVM
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai créé une API Web
# J'ai essayé quelque chose comme Vlookup avec Python # 2
J'ai essayé de créer un site qui permet de voir facilement les informations mises à jour d'Azure
J'ai essayé de déverrouiller l'entrée 2 lock sésame d'une simple pression sur le bouton AWS IoT
J'ai essayé de transformer l'image du visage en utilisant sparse_image_warp de TensorFlow Addons
J'ai trouvé un moyen de créer un modèle 3D à partir d'une photo.
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
J'ai essayé d'extraire automatiquement les mouvements des joueurs Wiire avec un logiciel
J'ai essayé d'analyser la négativité de Nono Morikubo. [Comparer avec Posipa]
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé de visualiser le texte du roman "Weather Child" avec Word Cloud
J'ai essayé de visualiser le modèle avec la bibliothèque d'apprentissage automatique low-code "PyCaret"
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
J'ai essayé d'afficher la valeur d'altitude du DTM dans un graphique
J'ai essayé de vérifier le résultat du test A / B avec le test du chi carré
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK