使用 RNN/LSTM 连续生成文本

Posted

技术标签:

【中文标题】使用 RNN/LSTM 连续生成文本【英文标题】:Continiously text generation with RNN/LSTM 【发布时间】:2018-06-13 21:02:55 【问题描述】:

我发现了很多使用 LSTM 生成文本的例子 这是他们中的一个:

# Load Larger LSTM network and generate text
import sys
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.callbacks import ModelCheckpoint
from keras.utils import np_utils
# load ascii text and covert to lowercase
filename = "wonderland.txt"
raw_text = open(filename).read()
raw_text = raw_text.lower()
# create mapping of unique chars to integers, and a reverse mapping
chars = sorted(list(set(raw_text)))
char_to_int = dict((c, i) for i, c in enumerate(chars))
int_to_char = dict((i, c) for i, c in enumerate(chars))
# summarize the loaded data
n_chars = len(raw_text)
n_vocab = len(chars)
print "Total Characters: ", n_chars
print "Total Vocab: ", n_vocab
# prepare the dataset of input to output pairs encoded as integers
seq_length = 100
dataX = []
dataY = []
for i in range(0, n_chars - seq_length, 1):
    seq_in = raw_text[i:i + seq_length]
    seq_out = raw_text[i + seq_length]
    dataX.append([char_to_int[char] for char in seq_in])
    dataY.append(char_to_int[seq_out])
n_patterns = len(dataX)
print "Total Patterns: ", n_patterns
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
# normalize
X = X / float(n_vocab)
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# define the LSTM model
model = Sequential()
model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(256))
model.add(Dropout(0.2))
model.add(Dense(y.shape[1], activation='softmax'))
# load the network weights
filename = "weights-improvement-47-1.2219-bigger.hdf5"
model.load_weights(filename)
model.compile(loss='categorical_crossentropy', optimizer='adam')
# pick a random seed
start = numpy.random.randint(0, len(dataX)-1)
pattern = dataX[start]
print "Seed:"
print "\"", ''.join([int_to_char[value] for value in pattern]), "\""
# generate characters
for i in range(1000):
    x = numpy.reshape(pattern, (1, len(pattern), 1))
    x = x / float(n_vocab)
    prediction = model.predict(x, verbose=0)
    index = numpy.argmax(prediction)
    result = int_to_char[index]
    seq_in = [int_to_char[value] for value in pattern]
    sys.stdout.write(result)
    pattern.append(index)
    pattern = pattern[1:len(pattern)]
print "\nDone."

在训练之后,网络可以正常工作:在随机播种之后,它会生成一些文本。但它进入了无限循环,因此生成的文本片段一次又一次地重复。我知道它应该以这种方式工作,因为我们将生成文本的最后一部分输入到网络中,因此它会根据之前的数据预测序列。

但我想让网络不断生成不同的文本。怎么做?也许我需要多次制作随机种子,或者最好使用经过不同训练的第二个网络,以便 2 个网络将输出作为种子相互提供?

【问题讨论】:

【参考方案1】:

使用不同的sampling strategy。

现在您正在使用贪婪搜索,您总是选择最可能的字符作为下一个字符。

您可以改为使用随机抽样来根据您的网络产生的概率来选择新字符。为了更好地控制采样过程,通常会引入temperature parameter。这使您可以控制生成文本的多样性。

【讨论】:

以上是关于使用 RNN/LSTM 连续生成文本的主要内容,如果未能解决你的问题,请参考以下文章

使用 RNN/LSTM 检测速度变化(给定当前 xy 位置)

几种常见的循环神经网络结构RNN、LSTM、GRU

使用keras构建LSTM分类器

Tensorflow - Tutorial : 利用 RNN/LSTM 进行手写数字识别

RNN 的中间隐藏状态有啥用处?

自用RNN+LSTM笔记