Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keras-team
GitHub Repository: keras-team/keras-io
Path: blob/master/examples/generative/lstm_character_level_text_generation.py
3507 views
1
"""
2
Title: Character-level text generation with LSTM
3
Author: [fchollet](https://twitter.com/fchollet)
4
Date created: 2015/06/15
5
Last modified: 2020/04/30
6
Description: Generate text from Nietzsche's writings with a character-level LSTM.
7
Accelerator: GPU
8
"""
9
10
"""
11
## Introduction
12
13
This example demonstrates how to use a LSTM model to generate
14
text character-by-character.
15
16
At least 20 epochs are required before the generated text
17
starts sounding locally coherent.
18
19
It is recommended to run this script on GPU, as recurrent
20
networks are quite computationally intensive.
21
22
If you try this script on new data, make sure your corpus
23
has at least ~100k characters. ~1M is better.
24
"""
25
26
"""
27
## Setup
28
"""
29
import keras
30
from keras import layers
31
32
import numpy as np
33
import random
34
import io
35
36
"""
37
## Prepare the data
38
"""
39
40
path = keras.utils.get_file(
41
"nietzsche.txt",
42
origin="https://s3.amazonaws.com/text-datasets/nietzsche.txt",
43
)
44
with io.open(path, encoding="utf-8") as f:
45
text = f.read().lower()
46
text = text.replace("\n", " ") # We remove newlines chars for nicer display
47
print("Corpus length:", len(text))
48
49
chars = sorted(list(set(text)))
50
print("Total chars:", len(chars))
51
char_indices = dict((c, i) for i, c in enumerate(chars))
52
indices_char = dict((i, c) for i, c in enumerate(chars))
53
54
# cut the text in semi-redundant sequences of maxlen characters
55
maxlen = 40
56
step = 3
57
sentences = []
58
next_chars = []
59
for i in range(0, len(text) - maxlen, step):
60
sentences.append(text[i : i + maxlen])
61
next_chars.append(text[i + maxlen])
62
print("Number of sequences:", len(sentences))
63
64
x = np.zeros((len(sentences), maxlen, len(chars)), dtype="bool")
65
y = np.zeros((len(sentences), len(chars)), dtype="bool")
66
for i, sentence in enumerate(sentences):
67
for t, char in enumerate(sentence):
68
x[i, t, char_indices[char]] = 1
69
y[i, char_indices[next_chars[i]]] = 1
70
71
72
"""
73
## Build the model: a single LSTM layer
74
"""
75
76
model = keras.Sequential(
77
[
78
keras.Input(shape=(maxlen, len(chars))),
79
layers.LSTM(128),
80
layers.Dense(len(chars), activation="softmax"),
81
]
82
)
83
optimizer = keras.optimizers.RMSprop(learning_rate=0.01)
84
model.compile(loss="categorical_crossentropy", optimizer=optimizer)
85
86
"""
87
## Prepare the text sampling function
88
"""
89
90
91
def sample(preds, temperature=1.0):
92
# helper function to sample an index from a probability array
93
preds = np.asarray(preds).astype("float64")
94
preds = np.log(preds) / temperature
95
exp_preds = np.exp(preds)
96
preds = exp_preds / np.sum(exp_preds)
97
probas = np.random.multinomial(1, preds, 1)
98
return np.argmax(probas)
99
100
101
"""
102
## Train the model
103
"""
104
105
epochs = 40
106
batch_size = 128
107
108
for epoch in range(epochs):
109
model.fit(x, y, batch_size=batch_size, epochs=1)
110
print()
111
print("Generating text after epoch: %d" % epoch)
112
113
start_index = random.randint(0, len(text) - maxlen - 1)
114
for diversity in [0.2, 0.5, 1.0, 1.2]:
115
print("...Diversity:", diversity)
116
117
generated = ""
118
sentence = text[start_index : start_index + maxlen]
119
print('...Generating with seed: "' + sentence + '"')
120
121
for i in range(400):
122
x_pred = np.zeros((1, maxlen, len(chars)))
123
for t, char in enumerate(sentence):
124
x_pred[0, t, char_indices[char]] = 1.0
125
preds = model.predict(x_pred, verbose=0)[0]
126
next_index = sample(preds, diversity)
127
next_char = indices_char[next_index]
128
sentence = sentence[1:] + next_char
129
generated += next_char
130
131
print("...Generated: ", generated)
132
print("-")
133
134