Files
rushter--mlalgorithms/examples/nnet_rnn_text_generation.py
2026-07-13 13:39:55 +08:00

83 lines
2.2 KiB
Python

from __future__ import print_function
import logging
import random
import numpy as np
import sys
from mla.datasets import load_nietzsche
from mla.neuralnet import NeuralNet
from mla.neuralnet.constraints import SmallNorm
from mla.neuralnet.layers import Activation, Dense
from mla.neuralnet.layers.recurrent import LSTM, RNN
from mla.neuralnet.optimizers import RMSprop
logging.basicConfig(level=logging.DEBUG)
# Example taken from: https://github.com/fchollet/keras/blob/master/examples/lstm_text_generation.py
def sample(preds, temperature=1.0):
# helper function to sample an index from a probability array
preds = np.asarray(preds).astype("float64")
preds = np.log(preds) / temperature
exp_preds = np.exp(preds)
preds = exp_preds / np.sum(exp_preds)
probas = np.random.multinomial(1, preds, 1)
return np.argmax(probas)
X, y, text, chars, char_indices, indices_char = load_nietzsche()
# Round the number of sequences for batch processing
items_count = X.shape[0] - (X.shape[0] % 64)
maxlen = X.shape[1]
X = X[0:items_count]
y = y[0:items_count]
print(X.shape, y.shape)
# LSTM OR RNN
# rnn_layer = RNN(128, return_sequences=False)
rnn_layer = LSTM(128, return_sequences=False)
model = NeuralNet(
layers=[
rnn_layer,
# Flatten(),
# TimeStepSlicer(-1),
Dense(X.shape[2]),
Activation("softmax"),
],
loss="categorical_crossentropy",
optimizer=RMSprop(learning_rate=0.01),
metric="accuracy",
batch_size=64,
max_epochs=1,
shuffle=False,
)
for _ in range(25):
model.fit(X, y)
start_index = random.randint(0, len(text) - maxlen - 1)
generated = ""
sentence = text[start_index : start_index + maxlen]
generated += sentence
print('----- Generating with seed: "' + sentence + '"')
sys.stdout.write(generated)
for i in range(100):
x = np.zeros((64, maxlen, len(chars)))
for t, char in enumerate(sentence):
x[0, t, char_indices[char]] = 1.0
preds = model.predict(x)[0]
next_index = sample(preds, 0.5)
next_char = indices_char[next_index]
generated += next_char
sentence = sentence[1:] + next_char
sys.stdout.write(next_char)
sys.stdout.flush()
print()