[PYTHON] [TensorFlow] J'ai senti que j'étais capable de produire en masse des messages de style "jugement posthume" en utilisant Seq2Seq.

introduction

Dans un article précédent, j'ai expérimenté la création de texte semblable au «signe du Christ» en utilisant le LSTM basé sur des caractères. [\ TensorFlow ] J'ai essayé de produire en masse des messages de style "jugement posthume" avec LSTM --Qiita

Étant donné que divers problèmes sont apparus, j'aimerais essayer un modèle qui utilise la phrase entière comme entrée. En fin de compte, ce serait bien d'essayer un modèle de génération basé sur le GAN (SeqGAN [^ 1], etc.), mais du coup cela semble frustrant, alors essayez d'abord le modèle Seq2Seq tout en pratiquant également l'idée d'entrer et de sortir en unités de phrase. Je vais essayer.

Environnement de vérification

Cette fois, l'apprentissage est difficile sans GPU, je vais donc l'exécuter avec Google Colaboratory, qui peut être utilisé gratuitement.

stratégie

Utilisons le modèle Seq2Seq utilisé dans la traduction automatique. Les bases sont basées sur ce tutoriel. Keras: Ex-Tutorials: Seq2Seq Introduction à l'apprentissage - PyTorch Puisque l'entrée est un mot cette fois, modifiez le code en vous référant à "Si vous souhaitez utiliser un modèle de niveau mot avec une séquence d'entiers".

Lors de la génération de phrases avec Seq2Seq, il y a un problème de saisie, mais reportez-vous à la méthode décrite dans un autre article.

Je vais l'utiliser de cette manière. Génération de phrases à l'aide de Seq2Seq (les données Wikipédia sont utilisées pour la formation) --Qiita

L'explication du modèle Encoder-Decoder, y compris le modèle Seq2Seq, était facile à comprendre, donc je l'ai jeté tout autour. Encoder-Decoder --Qiita avec PyTorch

Selon cet article, chaque mot des données d'entrée est d'abord converti en vecteur par la couche Embedding, puis entraîné à l'aide de cette séquence de représentations vectorielles. À l'origine, la représentation vectorielle de chaque mot doit également être apprise à partir des données, mais comme il n'y a pas beaucoup de données, nous remplacerons le modèle Word2Vec formé.

Cette fois, j'ai utilisé ce modèle Word2Vec. [^ w2v] shiroyagicorp/japanese-word2vec-model-builder: A tool for building gensim word2vec model for Japanese.

[^ w2v]: Il existe différents modèles Word2Vec appris en japonais, vous devriez donc pouvoir en utiliser d'autres tant que l'unité de morphologie (comme la division de la fin de l'inflexion) correspond aux données d'entraînement. → À propos du japonais appris word2vec et de son évaluation --Blog de Hoxom Co., Ltd.

A trained word2vec model is available at: http://public.shiroyagi.s3.amazonaws.com/latest-ja-word2vec-gensim-model.zip

Il y en a, alors téléchargez ce fichier zip et utilisez-le.

Ce modèle contient des données dans lesquelles environ 330 000 mots sont représentés par des vecteurs à 50 dimensions. Avec ce modèle, n'importe quel mot contenu ici peut être sorti. Puisqu'il est appris sur la base de l'expression de Word2Vec, des mots avec des significations similaires peuvent apparaître avec une certaine probabilité même s'ils ne figurent pas dans les données d'apprentissage. ** "Se réconcilier avec le chat" n'est-il pas un rêve? ** **

programme

D'abord, à partir du module requis «import».

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Activation, LSTM, Embedding
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
import numpy as np
import random
import sys
import pickle
from gensim.models import Word2Vec

Préparation des données

Dans un sens, les données les plus importantes.

** Nous utiliserons le panneau affiché par la "Bible Distribution Cooperation Association" et le texte (une copie) de la pancarte qu'ils placent lorsqu'ils sont actifs dans la rue. (Le meme que la derniere fois) **

text = """
Oh, écoute les paroles du dieu du monde
La récompense du mal est la mort
Une personne avide ne reconnaît pas Dieu
Celui qui sème le mal récolte la calamité
Votre dieu est le seul
Préparez-vous à rencontrer votre créateur
Souvenez-vous de votre créateur
Jésus-Christ est votre créateur
Jésus-Christ donne l'espérance éternelle
Jésus-Christ est le Fils unique de Dieu
Jésus-Christ est le Fils de Dieu
Jésus-Christ est le seul Dieu
Jésus-Christ juge le monde correctement
Ceux qui invoquent Jésus-Christ seront sauvés
vie éternelle
Source de vie éternelle
Dieu éternel
Source du salut éternel
Espoir pour l'éternité
Tenez-vous devant Dieu dans les derniers jours
Dans les derniers jours, l'homme se tient devant Dieu
Le jour où Dieu jugera l'humanité est proche
Réconcilier avec Dieu
Repentez-vous de vos péchés contre Dieu
Cherchez le Royaume de Dieu et la Justice de Dieu
Cherchez le royaume de Dieu et la justice
Le royaume de Dieu approche
Le royaume de Dieu approche, repentez-vous
Ceux qui rejettent la Parole de Dieu préfèrent la mort
Le jugement de Dieu vient soudainement
Le jour du juste jugement de Dieu est proche
Jésus-Christ, le Fils unique de Dieu, est le Sauveur
Dieu dit qu'il n'y a pas de stipulation pour mourir ici
Dieu voit le cœur
Dieu punit le péché
Dieu a envoyé Christ le Fils unique au monde
Dieu a envoyé son Fils Christ dans le monde
Dieu est le seul
Dieu a trompé la sagesse du monde
Dieu a fixé le jour pour juger le monde
Repentez-vous de votre attitude envers Dieu
Peur de Dieu
Peur de Dieu
Ceux qui s'éloignent de Dieu entrent dans le chemin du mal
Reconnaissez Dieu
Cherche Dieu
Pensez à votre destination après la mort
Aujourd'hui est le jour du salut
Il n'y a pas d'autre salut que le Christ
Le jour où le Christ juge les gens est proche
Le Christ est le vrai Dieu
Christ est le chemin de la vie de vérité
Le retour du Christ est proche
Purifier le péché de sang du Christ
Le sang du Christ purifie le péché
Le sang du Christ purifie le péché
Le sang du Christ purifie le péché
Le sang du Christ enlève le péché
Il n'y a de dieu que Christ
La résurrection du Christ est une confirmation du salut
Le Christ vous donne la vie éternelle
Christ vous justifie
Christ vous libère du péché
Le Christ donne la vie éternelle
Christ est le Fils de Dieu
Christ a péché l'homme sur la croix
Le Christ est l'alter ego du vrai Dieu
Christ viendra bientôt
Christ viendra bientôt
Le Christ annule le péché et donne la vie
Christ révoque le péché
Le Christ pardonne le péché et donne la vie éternelle
Le Christ est ressuscité de la tombe
Le Christ est ressuscité de la tombe
Christ a péché au nom de l'homme
Christ reviendra et jugera le monde
Christ reviendra et jugera le monde
Christ reviendra
Christ reviendra
Le Christ est ressuscité
Christ est le vrai Dieu
Le Christ est l'alter ego du vrai Dieu
Christ a péché à sa place
Christ est le chemin de la vie de vérité
Le Christ ressuscité et donne la vie éternelle
Le Christ a ressuscité et a vaincu la mort
Ceux qui croient en Christ seront sauvés
Ceux qui croient au Christ ont la vie éternelle
Ceux qui invoquent le Christ seront sauvés
Se repentir
Se repentir
L'adoration des idoles est un péché
Heureusement ceux qui ont le cœur pur
Croyez en Dieu du fond de mon cœur
Dieu juge les péchés du cœur
Échapper au feu indélébile de l'enfer
L'enfer est une souffrance éternelle
L'enfer est la seconde mort
Il y a un jugement après la mort
Rencontrez le jugement après la mort
Rencontrez le jugement après la mort
Pensez à votre destination après la mort
Pensez à votre destination après la mort
Dieu voit la vie privée
Il y a un chemin de mort et un mode de vie
La mort est la récompense du péché
Le retour du Seigneur Jésus-Christ est proche
La résurrection du Seigneur Jésus-Christ est une confirmation du salut
Le Seigneur Jésus-Christ est le créateur de toutes choses
Le jour du Seigneur vient soudainement
La vie est courte, le paradis est long
Personne n'a raison
Crois juste
Crois juste
La société corrompue ne reconnaît pas Dieu
La terre et l'homme sont de Dieu
N'adorez pas les choses «faites»
Heureusement ceux qui ont été purifiés de leurs péchés
Heureusement ceux qui ont été purifiés du péché
Illumination sur le péché, la justice et le jugement
Si tu meurs dans le péché, tu iras en enfer éternel
Si tu meurs dans le péché, tu iras en enfer éternel
La récompense du péché est la mort
La récompense du péché est le don du dieu de la mort, la vie éternelle
La récompense du péché est le don du dieu de la mort. Le don de Dieu est dans le Christ Vie éternelle
Obtenez le pardon du péché
Obtenez le pardon des péchés
Cherchez le pardon des péchés
Dieu punit le péché
Heureusement ceux qui ont été purifiés de leurs péchés
Repentez-vous de vos péchés
Repentez-vous de vos péchés
Le paradis ou l'enfer ou votre destination
Le paradis est la vie éternelle L'enfer est la mer de feu
Même si les cieux et la terre périssent, mes paroles ne périront pas
Le créateur de toutes choses
La terre du paradis, l'enfer, ou tout le peuple est ressuscité
Le royaume des cieux se repent de ses péchés proches
Attention aux faux
Au commencement, Dieu créa les cieux et la terre
Les objets créés par l'homme ne sont pas des dieux
Débarrassez-vous du mal humain
Le péché habite les gens
Se débarrasser du péché d'une personne
Dieu voit les voies et les actes des gens
L'étang de feu est la seconde mort
Racheter l'iniquité
Dieu juge l'immoralité et les rapports sexuels
Dieu juge l'infidélité et les rapports sexuels
Il y a un chemin de mort et un mode de vie
Je ne reconnais pas Dieu à l'époque tordue
Le vrai Dieu aime les gens et enlève leurs péchés
Croyez au vrai Dieu
Croyez au vrai Dieu
Michi vérité vie
Voici, je viendrai bientôt
Le monde et la cupidité du monde meurent
La fin du monde est proche
La fin du monde vient soudainement
Le Christ ressuscité donne la vie éternelle
Jugez le monde correctement
Est-ce une catastrophe? Une personne qui appelle le mal bien
Adorateurs qui adorent les idoles
Malheur au héros de la boisson
Je me demande si ce sera un désastre
Je suis la vie de vérité
Il y a la vie éternelle dans mes paroles
Je suis la vie
Je suis le pain de la vie
Je suis le pain de la vie
J'ai les clés de la mort et de l'enfer
Je suis la vérité
Je suis la vérité
Je suis la lumière du monde
Ceux qui croient en moi ont la vie éternelle
Ceux qui croient en moi ont la vie éternelle
Ceux qui croient en moi ont la vie éternelle
Ceux qui croient en moi vivent même s'ils meurent
Je suis la vérité et la vie
Souvenez-vous de votre créateur
Il n'y a pas d'autre salut que Jésus-Christ
Appelez Dieu avant qu'il ne soit trop tard
Dans les derniers jours, l'homme se tient devant Dieu
Le Christ juge les choses cachées
Le Christ envoyé par Dieu est le sauveur
Si vous retournez à Dieu, Dieu vous pardonnera abondamment
Repentez-vous de vos péchés contre Dieu
Le royaume de Dieu approche, repentez-vous
Le jour du jugement de Dieu est proche
Le don de Dieu est la vie éternelle
Dieu aime les gens et enlève leurs péchés
Craignez Dieu et obéissez à la parole
Reconnaissez Dieu et ayez peur de quitter le péché
Le Christ a la parole de la vie éternelle
Acceptez le salut du Christ
Le sang du Christ purifie le péché
Christ reviendra et jugera le monde
Christ a péché l'homme sur la croix
Le Christ sauve les pécheurs
Le Christ donne à l'homme la vie éternelle
Christ a été puni pour la substitution de l'homme
Christ libère les gens du péché
Croyez en Christ et soyez sauvé
Ceux qui invoquent le Christ seront sauvés
Repentez-vous et croyez en l'évangile
Se repentir
Soyez nouveau du fond de votre cœur
Pensez à votre destination après la mort
Heureusement ceux qui ont été purifiés du péché
La récompense du péché est la mort
Veuillez me pardonner mes péchés
Débarrassez-vous du péché
Reconnaissez vos péchés et retournez à Dieu
Christ a été ressuscité pour l'amour de l'homme justice
Dieu voit le cœur et l'esprit des gens
Les gens rencontrent le jugement après la mort
Le monde et la cupidité du monde sont partis
Il n'y a pas d'autre dieu que moi
Je suis le chemin de la vie de vérité
Ceux qui croient en moi ont la vie éternelle
"""

input_texts = [[w for w in s.split(" ")] for s in text.strip().split("\n")] * 10

Ici, en gros, le résultat de l'analyse du texte original avec mecab -Owakati '' est collé dans texte ''. Cependant, je corrige visuellement ce que le résultat de l'analyse est incorrect et j'efface les signes de ponctuation et les symboles. En outre, les mots qui ne sont pas inclus dans le modèle Word2Vec ont été modifiés en raison de fluctuations de notation et d'utilisation. Par exemple

―― "Worry" → "Catastrophe" ―― "Aganau" → "Rédemption" ―― "Takaburu" → "Takaburu" ―― "Ma" "Ta" → "Mama" "Just" ―― "Repentez-vous" → "Repentez-vous" ("Yo" est une terminaison impérative, donc je ne peux pas la diviser à l'origine, mais ce n'était pas dans le modèle Word2Vec utilisé par "Repentez")

Il y avait des modèles tels que (ce n'est pas tout).

De plus, «input_texts» suppose que chaque ensemble est répété 10 fois. Comme nous le verrons plus tard, nous nous entraînerons à renvoyer des déclarations aléatoires dans ces données lors de leur saisie. Préparez un ensemble de données pouvant générer environ 10 voies à partir d'une entrée.

Modèle Word2Vec

Chargez le modèle Word2Vec. Supposons que le modèle ci-dessus a été extrait dans le répertoire `` latest-ja-word2vec-gensim-model ''. Veuillez modifier le chemin en conséquence. Je pense qu'il est pratique de mettre le modèle sur Google Drive, de le monter et de l'utiliser. Montez Google Colaboratory sur Google Drive et exécutez Python. --Qiita

#Modèle Word2Vec de chèvre blanche
model = Word2Vec.load("latest-ja-word2vec-gensim-model/word2vec.gensim.model")
words = ["<PAD>"] + model.wv.index2word
mat_embedding = np.insert(model.wv.vectors, 0, 0, axis=0)
input_token_index = target_token_index = dict((w, i) for i, w in enumerate(words))
num_encoder_tokens = num_decoder_tokens = mat_embedding.shape[0] # for Masking
max_encoder_seq_length = max(len(txt) for txt in input_texts)
max_decoder_seq_length = max_encoder_seq_length + 1 # BOS/EOS
latent_dim = mat_embedding.shape[1]

Lorsque vous chargez un modèle avec gensim '', vous obtenez deux informations: model.wv.index2word '' et `` model.wv.vectors ''.

-- model.wv.index2word contient le vocabulaire (liste de mots) contenu dans le modèle. -- model.wv.vectors contient une matrice (`` ndarray '') qui répertorie les représentations vectorielles de chaque mot.

Pour la commodité de plus tard, je veux réserver l'ID: 0 pour le remplissage (en remplissant la partie manquante) car je vais entrer des données de longueur variable, donc je vais le facturer à ID: 0 avec le code suivant Insère le mot et la représentation vectorielle de. Cela décale l'ID de mot par un par rapport au modèle Word2Vec.

words = ["<PAD>"] + model.wv.index2word
mat_embedding = np.insert(model.wv.vectors, 0, 0, axis=0)

La taille du vocabulaire contenu dans ce modèle et le nombre de dimensions du vecteur déterminent la taille du modèle à apprendre (excluant le nombre de dimensions de la couche cachée (état interne) du LSTM). La taille de chaque variable doit être la suivante (à partir du 05/01/2020).

Ici, max_decoder_seq_length '' est 1 plus grand que max_encoder_seq_length '' car il faut ajouter `` '' au début lors de l'apprentissage du côté du décodeur. [^ 3]

num_encoder_tokens '' et num_decoder_tokens '' sont respectivement les tailles de vocabulaire d'entrée et de sortie (types de mots). Compte tenu de la tâche de traduction, etc., num_encoder_tokens '' correspond à la taille du vocabulaire de la source de traduction et num_decoder_tokens '' correspond à la taille du vocabulaire de la destination de la traduction, donc les deux valeurs sont généralement différentes, mais cette fois elles sont les mêmes car l'entrée et la sortie sont dans la même langue. C'est une valeur.

[^ 3]: Juste au cas où, <BOS> '' et '' sont différents. <BOS> '' est un symbole qui représente le début d'une phrase et est une cible d'apprentissage, tandis que '' est un symbole pour plus de commodité pour s'adapter à la longueur d'une chaîne de mots après de courtes données. Ce n'est pas une cible d'apprentissage.

Définition du modèle

hidden_dim = 64

# Embedding
layer_emb = Embedding(num_encoder_tokens, latent_dim, trainable=False, mask_zero=True)

# Encoder
encoder_inputs = Input(shape=(None,), dtype=tf.int32)
x = layer_emb(encoder_inputs)
_, state_h, state_c = LSTM(hidden_dim, return_sequences=True, return_state=True)(x)
encoder_states = [state_h, state_c]

# Decoder
decoder_inputs = Input(shape=(None,), dtype=tf.int32)
x = layer_emb(decoder_inputs)
x, _, _ = LSTM(hidden_dim, return_sequences=True, return_state=True)(x, initial_state=encoder_states)
decoder_outputs = Dense(num_decoder_tokens)(x)

def accuracy_masking(y_true, y_pred):
    return tf.keras.metrics.sparse_categorical_accuracy(tf.gather_nd(y_true, tf.where(y_pred._keras_mask)), tf.gather_nd(y_pred, tf.where(y_pred._keras_mask)))

model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = RMSprop(lr=0.01)
model.compile(optimizer=opt, loss=lambda y_true, y_pred: tf.nn.softmax_cross_entropy_with_logits(tf.one_hot(tf.cast(y_true, tf.int32), num_decoder_tokens), y_pred),
              metrics=[accuracy_masking])
# set embedding matrix
layer_emb.set_weights([mat_embedding])

La chaîne d'ID de mot saisie est convertie en une représentation vectorielle dans la couche «Embedding» et transmise à LSTM. Cette matrice intégrée (représentation vectorielle de chaque mot) utilise les valeurs apportées par le modèle Word2Vec entraîné comme décrit ci-dessus [^ 2], utilisez donc trainable = False pour éviter que la matrice intégrée ne soit mise à jour pendant la formation. faire. Ajoutez également mask_zero = True pour traiter l'ID: 0 comme un remplissage.

[^ 2]: Immédiatement après la création du calque, la matrice de poids n'est pas initialisée et `` set_weights () '' ne peut pas être fait, alors définissez-la après la construction du modèle.

Après cela, la création d'un modèle est presque la même que le didacticiel Keras. Cependant, je veux donner l'étiquette par ID de mot (plutôt qu'un vecteur One-hot), donc je définis moi-même la fonction de perte. Je veux manipuler la partition pour faciliter la création de divers mots plus tard, j'ai donc décidé de ne pas mettre Softmax dans la couche de sortie (Dense '') du modèle, et tf.nn.sparse_softmax_cross_entropy_with_logits () Calculez la fonction de perte avec. [^ 4]

[^ 4]: Si vous n'avez pas besoin de manipuler le score, vous pouvez utiliser `` loss = 'sparse_categorical_crossentropy' '. Dans ce cas, placez Softmax dans la couche de sortie du modèle.

De plus, en ce qui concerne la valeur de précision affichée pendant l'entraînement, même les données qui doivent être traitées comme du remplissage (doivent être ignorées) sont incluses dans le calcul, j'ai donc fait des métriques '' pour le corriger. Vous pouvez obtenir le masque en vous référant à la propriété _keras_mask '' de Tensor. Masking and padding with Keras | TensorFlow Core

Mise en forme des données pour l'apprentissage

# create data
encoder_input_data = np.zeros(
    (len(input_texts), max_encoder_seq_length),
    dtype='int32')
decoder_input_data = np.zeros(
    (len(input_texts), max_decoder_seq_length),
    dtype='int32')
decoder_target_data = np.zeros(
    (len(input_texts), max_decoder_seq_length),
    dtype='int32')

output_texts = list(input_texts)
random.shuffle(output_texts)
# input one text and randomly output another text
for i, (input_text, target_text) in enumerate(zip(input_texts, output_texts)):
    for t, w in enumerate(input_text):
        encoder_input_data[i, t] = input_token_index[w]

    decoder_input_data[i, 0] = target_token_index['@'] # BOS
    for t, w in enumerate(target_text):
        # decoder_target_data is ahead of decoder_input_data by one timestep
        decoder_input_data[i, t + 1] = target_token_index[w]
        decoder_target_data[i, t] = target_token_index[w]
    decoder_target_data[i, t + 1:] = target_token_index['。'] # EOS

Créez trois ndarray, ```encoder_input_data, decoder_input_dataet decoder_target_data. Comme tous sont préparés sous forme de chaînes d'ID de mot, dtype = 'int32' '' est défini.

Comme mentionné ci-dessus, ʻinput_texts`` est une donnée dans laquelle une chaîne d'entrée est répétée 10 fois. En mélangeant ceci et en le rendant ʻoutput_texts``, nous créons des données d'entraînement qui retournent aléatoirement une chaîne de sortie pour une certaine chaîne d'entrée (jusqu'à 10 chaînes de sortie différentes pour la même chaîne d'entrée). Est associée à).

Lors de l'entraînement du côté décodeur avec le modèle Encoder-Decoder, assurez-vous que la chaîne de sortie est un mot plus rapide que la chaîne d'entrée (représentation vectorielle). Comme mentionné ci-dessus, le début de la phrase côté entrée commence par <BOS> '', mais cette fois, j'ai décidé d'utiliser le mot '@' '' pour indiquer le début de la phrase (est-ce que ça va?) .. Au contraire, la fin de la phrase du côté sortie est `` ''. Il sera représenté par ''.

Apprentissage

Exécutez simplement la méthode `` fit () '' et attendez un moment. Cela prend environ 10 minutes dans l'environnement GPU de Google Colab.

batch_size = 64  # Batch size for training.
epochs = 50  # Number of epochs to train for.

cp_cb = ModelCheckpoint(
    filepath="model.{epoch:02d}.hdf5",
    verbose=1,
    mode="auto")

reduce_cb = ReduceLROnPlateau()

# Run training
model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
          batch_size=batch_size,
          epochs=epochs,
          validation_split=0.2,
          callbacks=[cp_cb, reduce_cb])

L'apprentissage se déroulera comme suit.

Epoch 1/50
28/28 [==============================] - ETA: 0s - loss: 2.7266 - accuracy_masking: 0.1383
Epoch 00001: saving model to model.01.hdf5
28/28 [==============================] - 11s 390ms/step - loss: 2.7266 - accuracy_masking: 0.1383 - val_loss: 1.9890 - val_accuracy_masking: 0.1918 - lr: 0.0100
(Omis)
Epoch 50/50
28/28 [==============================] - ETA: 0s - loss: 0.2723 - accuracy_masking: 0.8259
Epoch 00050: saving model to model.50.hdf5
28/28 [==============================] - 9s 329ms/step - loss: 0.2723 - accuracy_masking: 0.8259 - val_loss: 0.4014 - val_accuracy_masking: 0.7609 - lr: 1.0000e-03

inférence

C'est une préparation pour générer réellement des phrases en utilisant le modèle appris.

encoder_model = Model(encoder_inputs, encoder_states)

decoder_lstm = model.layers[4]
decoder_dense = model.layers[5]

decoder_state_input_h = Input(shape=(hidden_dim,))
decoder_state_input_c = Input(shape=(hidden_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(
    layer_emb(decoder_inputs), initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model(
    [decoder_inputs] + decoder_states_inputs,
    [decoder_outputs] + decoder_states)

Créez un encodeur et un décodeur séparément. Le côté encodeur prend une chaîne de mots comme entrée et sort l'état une fois l'entrée terminée. Le côté Decoder prend la chaîne de mots et l'état comme entrée (bien que vous ne puissiez en fait entrer qu'un seul mot à la fois) et sort la chaîne de sortie et le nouvel état.

def decode_sequence(input_seq):
    # Encode the input as state vectors.
    states_value = encoder_model.predict([input_seq])
    # Generate empty target sequence of length 1. (batch x sample x time)
    target_seq = np.zeros((1, 1, 1), dtype=np.int32)
    # Populate the first character of target sequence with the start character.
    target_seq[0, 0, 0] = target_token_index['@']

    # Sampling loop for a batch of sequences
    # (to simplify, here we assume a batch of size 1).
    stop_condition = False
    decoded_sentence = []
    temperature = 1.2
    while not stop_condition:
        output_tokens, h, c = decoder_model.predict(
            [target_seq] + states_value)

        # Sample a token (with temperature)
        logits = output_tokens[0, 0, :]
        prob = np.exp(logits / temperature)
        prob /= (prob.sum() * 1.00001)
        sampled_token_index = np.argmax(np.random.multinomial(1, prob))
        sampled_word = words[sampled_token_index]
        decoded_sentence.append(sampled_word)

        # Exit condition: either hit max length
        # or find stop character.
        if (sampled_word == '。' or
           len(decoded_sentence) > max_decoder_seq_length):
            stop_condition = True

        # Update the target sequence (of length 1).
        target_seq[0, 0, 0] = sampled_token_index

        # Update states
        states_value = [h, c]

    return decoded_sentence

Nous traiterons la chaîne d'entrée à l'aide de l'encodeur et du décodeur pour l'inférence. states_value '' correspond à l'état du codeur lorsque la colonne d'entrée est entrée dans le codeur. Donnez au décodeur cet état et le premier mot '' '@' ''. Le mot d'entrée est défini sur target_seq '', mais la forme est `` (1, 1, 1) car le modèle suppose une entrée par lots et génère un échantillon et un mot dans l'ordre. ) ''.

Le décodeur renvoie le score du mot de sortie (la sortie de la couche Dense '') pour le mot saisi et l'état précédent. Vous pouvez convertir cela en probabilité avec Softmax, mais pour faciliter l'obtention de mots avec des scores faibles, modifiez le score pour qu'il soit divisé par la constante température '', puis insérez-le dans Softmax. Un mot est échantillonné en fonction de la probabilité obtenue et utilisé comme sortie. Ce mot de sortie est la fin de la phrase `` '. '' 'rompra la boucle.

Faisons le!

Je suis enfin prêt. Générez autant que vous le souhaitez! Décidez de la première phrase de manière appropriée.

s = ["chat", "Quand", "règlement", "Seyo"]
for i in range(50):
    gen = decode_sequence([input_token_index[w] for w in s])
    print("".join(gen))
    s = gen

50 phrases sont sorties comme ça.

Le Christ vous donne la vie du Christ.
Repentez-vous de vos péchés contre Dieu.
L'adoration des idoles est un péché.
Péché de la destination du Christ.
Il n'y a de dieu que Christ.
Repentez-vous de vos péchés.
Le Christ est près de vous.
Une société corrompue ne reconnaît pas Dieu.
Repentez-vous et croyez en l'évangile.
Débarrassez-vous du péché.
L'adoration des idoles est un péché.
Le ciel est une vie éternelle Le don de l'enfer.
Le don de Dieu est la vie éternelle.
Christ a été ressuscité pour que l'homme soit justifié.
Dieu pèche le principe global local.
Au commencement, Dieu a des choses célestes.
Seigneur des péchés d'Evian.
Le feu donne le chemin et la vie éternelle.
Repentez-vous et croyez en l'évangile.
Le jour de battre Mogura vient soudainement.
L'ère cachée est proche.
Même si les cieux et la terre périssent, l'enfer de l'homme ne périt pas.
Le Christ est ressuscité de la tombe.
Heureusement, ceux qui sont purs faux.
Dieu est le seul.
Christ reviendra.
Une personne lubrique ne reconnaît pas Dieu.
Dieu est le seul.
Le Christ est le vrai Dieu.
Pensez à votre destination après la mort.
Il y a une manière d'Anastasia et une manière de vivre.
J'ai les clés de la mort et de l'enfer.
Dieu est le seul.
Dieu voit le cœur.
Dieu a envoyé son Fils Christ dans le monde.
Paradis ou enfer ou où vas-tu?
Jugez le monde correctement.
Aujourd'hui est le jour du salut.
Dieu est le seul.
Le Christ sauve les pécheurs.
Une personne qui adore une idole.
Rencontrez le jugement après la mort.
Le Christ est ressuscité.
Dieu punit le péché.
Débarrassez-vous du mal humain.
Le Christ est le seul dieu.
Croyez au vrai Dieu.
Donnez le sang du Christ.
Il n'y a de dieu que Christ.
Le fond des cieux et de la terre appelle le dieu de la mort lundi soir.

Il y a un peu de sortie similaire au texte d'origine, mais ** certains mots ne sont pas dans les données d'entraînement **. ** "Le jour où j'ai frappé Mogura vient soudainement" ** rit. ** "Même si les cieux et la terre périssent, l'enfer de l'homme ne périt pas" ** ne peut être sauvé. ** "Le fond des cieux et de la terre appelle le dieu de la mort lundi soir" ** Est-ce un comédien ou l'histoire de quelqu'un?

Étant donné que la chaîne de sortie des données d'entraînement n'est que le libellé du panneau, honnêtement, on a l'impression que ** peu importe ce que vous entrez, le libellé sortira **. ** La valeur initiale est presque sans importance. Peut-être. ** Cela peut être bien (je ne pense pas que ce soit l'utilisation originale de Seq2Seq, mais ça va)

Résumé

Même s'il y a plus de variations que la dernière fois, il y a encore des sorties qui se sont effondrées en japonais, et des phrases similaires ont été faites à plusieurs reprises. Même ainsi, on peut dire que c'est comme prévu que les mots scandaleux apparaissent et viennent à vous.

Avec ce genre de sentiment, j'espère continuer à profiter de divers modèles à l'avenir. Parce que ce sont de longues vacances. C'est assez difficile d'étudier sur un ordinateur portable, mais Colab dispose d'un GPU gratuit, vous pouvez donc l'essayer comme un passe-temps. Vraiment gros. image.png Générateur de signes de la résurrection du Christ (v2)

Recommended Posts

[TensorFlow] J'ai senti que j'étais capable de produire en masse des messages de style "jugement posthume" en utilisant Seq2Seq.
[TensorFlow] J'ai essayé de produire en masse un message comme "Rencontrez le jugement après la mort" avec LSTM
J'ai essayé de classer le texte en utilisant TensorFlow
Python: j'ai pu récurer en lambda
[Je veux classer les images à l'aide de Tensorflow] (2) Classifions les images
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de noter la syntaxe trop humoristique et humoristique en utilisant l'API COTOHA.
Une histoire à laquelle j'étais accro chez np.where
J'ai senti que j'avais porté le code Python en C ++ 98.
Python: peut être répété en lambda
Ce à quoi j'étais accro lors de l'utilisation de Python tornado