Gated Neural Network (GRU) — это тип нейронной сети RNN, в которой используется приложение, пересекающееся с различными приложениями на естественном языке, одним из которых является генерация текста. Мы будем реализовывать генерацию котировок с использованием закрытой рекуррентной нейронной сети. Это альтернатива долговременной короткой памяти (LSTM), которая используется для борьбы с проблемой, присущей рекуррентной нейронной сети. Они используют ячейку и ворота, чтобы выбрать информацию, которую нужно забыть, и записать в следующее скрытое состояние в своем методе работы по RNN. По сравнению с LSTM, GRU более эффективен и быстрее вычисляется, потому что он не имеет состояния ячейки, но обновляет и сбрасывает ворота, поэтому мы будем использовать GRU!!

Мы будем реализовывать в TensorFlow и будем работать с набором данных котировок в формате json, который можно получить с помощью набора данных kaggle https://www.kaggle.com/akmittal/quotes-dataset. » .

Импортируйте библиотеки

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import numpy as np
import os
import io
import time
import json

Загрузите набор данных котировок, поскольку я загружаю проект со своего компьютера, я использовал:

from google.colab import files
uploaded = files.upload()

Чтение файла JSON

file_name = "quotes.json"
io.StringIO(uploaded[file_name].decode("utf-8"))
json.loads(uploaded[file_name].decode("utf-8"))

Прочтите файл JSON и извлеките список в список цитат и просмотрите первые 4списка.

dataset = json.loads(uploaded[file_name].decode("utf-8"))
text_list = []
for item in dataset:
text_list.append(item['Quote'])
text_list[:4]

[«Не плачь, потому что это закончилось, улыбнись, потому что это было», «Я эгоистичная, нетерпеливая и немного неуверенная в себе. Я делаю ошибки, я теряю контроль, и иногда мне трудно совладать. Но если ты не можешь справиться со мной в худшем случае, то ты, черт возьми, не заслуживаешь меня в моем лучшем», «Будь собой; все остальные уже заняты». «Две вещи бесконечны: вселенная и человеческая глупость; и я не уверен насчет вселенной».]

используя понимание списка, преобразуйте список в строку

text = ' '.join([str(elem) for elem in text_list])

Посмотрите на первые 50 символов в тексте.

print(text[:50])
Don’t cry because it’s over, smile because it happened. I’m selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can’t handle me

Создайте уникальный набор слов из корпуса

vocab = sorted(set(text))
print ('{} unique characters'.format(len(vocab)))

Векторизировать текст

Мы будем отображать строки в числовое представление. Создайте две таблицы поиска: одна сопоставляет символы с числами, а другая — для чисел с символами.

char2idx = {u:i for i, u in enumerate(vocab)}
idx2char = np.array(vocab)
text_as_int = np.array([char2idx[c] for c in text])
print('{')
for char,_ in zip(char2idx, range(20)):
print('  {:4s}: {:3d},'.format(repr(char), char2idx[char]))
print('  ...\n}')

Мы покажем, как первые 13 символов текста преобразуются в целые числа.

"Don't cry bec" ---- characters mapped to int ---- > [36 78 77  7 83  0 66 81 88  0 65 68 66]

Построение модели

Мы будем использовать построение модели генерации символов с учетом последовательности следующего вероятного символа.

Создание обучающих примеров и целей. Для каждой входной последовательности соответствующие цели содержат текст одинаковой длины, за исключением смещения на один символ вправо. seq_length — это максимальная длина, которую мы хотим для каждого символа.

seq_length = 100
examples_per_epoch = len(text)//(seq_length+1)
char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)
for i in char_dataset.take(5):
print(idx2char[i.numpy()])

Наш результат печати

D
o
n
'
t

Для каждой последовательности продублируйте и сдвиньте ее, чтобы сформировать входной и целевой текст, используя метод карты, чтобы применить простую функцию к каждому пакету:

def split_input_target(chunk):
    input_text = chunk[:-1]
    target_text = chunk[1:]
    return input_text, target_text
    dataset = sequences.map(split_input_target)
for input_example, target_example in  dataset.take(1):
print ('Input data: ', repr(''.join(idx2char[input_example.numpy()])))
print ('Target data:', repr(''.join(idx2char[target_example.numpy()])))

Результат печати

Input data:  "Don't cry because it's over, smile because it happened. Don't cry because it's over, smile because i"
Target data: "on't cry because it's over, smile because it happened. Don't cry because it's over, smile because it"

Создать тренировочную группу:

BATCH_SIZE = 64
BUFFER_SIZE = 10000
dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE,drop_remainder=True)
vocab_size = len(vocab)
embedding_dim = 256
Number of RNN units
rnn_units = 1024

Построить модель

def build_model(vocab_size, embedding_dim, rnn_units, batch_size):
    model = tf.keras.Sequential([
    tf.keras.layers.Embedding(vocab_size,embedding_dim,
    batch_input_shape=[batch_size, None]),
    tf.keras.layers.GRU(rnn_units,return_sequences=True,
    stateful=True,recurrent_initializer='glorot_uniform'),
    tf.keras.layers.Dense(vocab_size)])
    
return model
model = build_model(vocab_size =   len(vocab),
      embedding_dim=embedding_dim,rnn_units=rnn_units,
      batch_size=BATCH_SIZE)

Запустите модель и посмотрите, как она себя ведет

Прогноз:

def generate_text(model, start_string):
# Evaluation step (generating text using the learned model)
# Number of characters to generate
num_generate = 700
# Converting our start string to numbers (vectorizing)
input_eval = [char2idx[s] for s in start_string]
input_eval = tf.expand_dims(input_eval, 0)
# Empty string to store our results
text_generated = []
# Low temperatures results in more predictable text.
# Higher temperatures results in more surprising text.
# Experiment to find the best setting.
temperature = 0.27
# Here batch size == 1
model.reset_states()
for i in range(num_generate):
predictions = model(input_eval)
# remove the batch dimension
predictions = tf.squeeze(predictions, 0)
# using a categorical distribution to predict the word returned by the model
predictions = predictions / temperature
predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()
# We pass the predicted word as the next input to the model
# along with the previous hidden state
input_eval = tf.expand_dims([predicted_id], 0)
text_generated.append(idx2char[predicted_id])
return (start_string + ''.join(text_generated))
print(generate_text(model, start_string=u"Strenth comes from with the mind, reach out from the strength in me"))

Результат предсказания:

Strenth comes from with the mind, reach out from the strength in mercy. I don't want to be a person who does not attempt to be a professional consciousness. I will not be able to be a professional world. I want you to know that I am not a single beginning and a free will. I want to be a professional writer and then the only thing that is the best of all things to be happy. I want you to know that I am not a bad memory of the most powerful thing in the world. Be a profound fact. I will be a person who can say is to be a possession of the earth. In a world where there is no such thing as a poet. The secret of life is the power of love and the universe is the way to get the charges. Do you think I have a promises. I think we can change the world of empty consc