Path: blob/master/examples/generative/lstm_character_level_text_generation.py
3507 views
"""1Title: Character-level text generation with LSTM2Author: [fchollet](https://twitter.com/fchollet)3Date created: 2015/06/154Last modified: 2020/04/305Description: Generate text from Nietzsche's writings with a character-level LSTM.6Accelerator: GPU7"""89"""10## Introduction1112This example demonstrates how to use a LSTM model to generate13text character-by-character.1415At least 20 epochs are required before the generated text16starts sounding locally coherent.1718It is recommended to run this script on GPU, as recurrent19networks are quite computationally intensive.2021If you try this script on new data, make sure your corpus22has at least ~100k characters. ~1M is better.23"""2425"""26## Setup27"""28import keras29from keras import layers3031import numpy as np32import random33import io3435"""36## Prepare the data37"""3839path = keras.utils.get_file(40"nietzsche.txt",41origin="https://s3.amazonaws.com/text-datasets/nietzsche.txt",42)43with io.open(path, encoding="utf-8") as f:44text = f.read().lower()45text = text.replace("\n", " ") # We remove newlines chars for nicer display46print("Corpus length:", len(text))4748chars = sorted(list(set(text)))49print("Total chars:", len(chars))50char_indices = dict((c, i) for i, c in enumerate(chars))51indices_char = dict((i, c) for i, c in enumerate(chars))5253# cut the text in semi-redundant sequences of maxlen characters54maxlen = 4055step = 356sentences = []57next_chars = []58for i in range(0, len(text) - maxlen, step):59sentences.append(text[i : i + maxlen])60next_chars.append(text[i + maxlen])61print("Number of sequences:", len(sentences))6263x = np.zeros((len(sentences), maxlen, len(chars)), dtype="bool")64y = np.zeros((len(sentences), len(chars)), dtype="bool")65for i, sentence in enumerate(sentences):66for t, char in enumerate(sentence):67x[i, t, char_indices[char]] = 168y[i, char_indices[next_chars[i]]] = 1697071"""72## Build the model: a single LSTM layer73"""7475model = keras.Sequential(76[77keras.Input(shape=(maxlen, len(chars))),78layers.LSTM(128),79layers.Dense(len(chars), activation="softmax"),80]81)82optimizer = keras.optimizers.RMSprop(learning_rate=0.01)83model.compile(loss="categorical_crossentropy", optimizer=optimizer)8485"""86## Prepare the text sampling function87"""888990def sample(preds, temperature=1.0):91# helper function to sample an index from a probability array92preds = np.asarray(preds).astype("float64")93preds = np.log(preds) / temperature94exp_preds = np.exp(preds)95preds = exp_preds / np.sum(exp_preds)96probas = np.random.multinomial(1, preds, 1)97return np.argmax(probas)9899100"""101## Train the model102"""103104epochs = 40105batch_size = 128106107for epoch in range(epochs):108model.fit(x, y, batch_size=batch_size, epochs=1)109print()110print("Generating text after epoch: %d" % epoch)111112start_index = random.randint(0, len(text) - maxlen - 1)113for diversity in [0.2, 0.5, 1.0, 1.2]:114print("...Diversity:", diversity)115116generated = ""117sentence = text[start_index : start_index + maxlen]118print('...Generating with seed: "' + sentence + '"')119120for i in range(400):121x_pred = np.zeros((1, maxlen, len(chars)))122for t, char in enumerate(sentence):123x_pred[0, t, char_indices[char]] = 1.0124preds = model.predict(x_pred, verbose=0)[0]125next_index = sample(preds, diversity)126next_char = indices_char[next_index]127sentence = sentence[1:] + next_char128generated += next_char129130print("...Generated: ", generated)131print("-")132133134