循环神经网络也可以用作生成模型。
这意味着,除了用于预测模型(进行预测)之外,它们还可以学习问题的序列,然后生成全新的、符合领域逻辑的序列。
像这样的生成模型不仅有助于研究模型在多大程度上学习了一个问题,还有助于更多地了解问题领域本身。
在本教程中,您将学习如何使用Keras的Python LSTM循环神经网络,逐字符地创建一个文本生成模型。
阅读本文后,你将了解:
- 在哪里下载免费的文本语料库,可用于训练文本生成模型
- 如何将文本序列问题框架化以用于循环神经网络生成模型
- 如何开发一个LSTM来为给定问题生成可行的文本序列
启动您的项目,阅读我的新书《自然语言处理深度学习》,其中包括分步教程以及所有示例的Python源代码文件。
让我们开始吧。
注意:LSTM循环神经网络可能训练缓慢,强烈建议在GPU硬件上进行训练。您可以使用Amazon Web Services以非常低廉的价格访问云端的GPU硬件。此处查看教程。
- 2016年8月:首次发布
- 更新于2016年10月:修复了代码中一些细小的评论拼写错误
- 2017 年 3 月更新:更新至 Keras 2.0.2、TensorFlow 1.0.1 和 Theano 0.9.0
- 2019 年 9 月更新:更新至 Keras 2.2.5 API
- 2022 年 7 月更新:更新至 TensorFlow 2.x API

使用Keras的Python LSTM循环神经网络进行文本生成
图片来自Russ Sanderlin,部分权利保留。
问题描述:Project Gutenberg
许多经典作品已不再受版权保护。
这意味着您可以免费下载这些书籍的所有文本,并在实验中使用它们,例如创建生成模型。或许获取免费书籍(不再受版权保护)的最佳地点是Project Gutenberg。
在本教程中,您将使用儿时最喜欢的书作为数据集:《爱丽丝梦游仙境》,作者刘易斯·卡罗尔。
您将学习字符之间的依赖关系以及序列中字符的条件概率,以便您可以生成全新的、原创的字符序列。
这很有趣,建议您使用Project Gutenberg上的其他书籍重复这些实验。这是网站上最受欢迎的书籍列表。
这些实验不仅限于文本;您还可以尝试其他ASCII数据,例如计算机源代码、LaTeX、HTML或Markdown格式的标记文档,以及更多。
您可以免费下载此书的完整ASCII格式文本(纯文本UTF-8),并将其放在工作目录中,文件名为wonderland.txt。
现在,您需要准备好用于建模的数据集。
Project Gutenberg会在每本书开头添加标准的头部和尾部,这部分不是原文的一部分。用文本编辑器打开文件,删除头部和尾部。
头部很明显,以以下文本结尾
1 |
*** START OF THIS PROJECT GUTENBERG EBOOK ALICE'S ADVENTURES IN WONDERLAND *** |
尾部是说“THE END”的那一行之后的所有文本
1 |
THE END |
您应该留下一个包含大约3,330行文本的文本文件。
需要 LSTM 帮助进行序列预测吗?
参加我的免费7天电子邮件课程,了解6种不同的LSTM架构(附代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
开发一个小型LSTM循环神经网络
在本节中,您将开发一个简单的LSTM网络来学习《爱丽丝梦游仙境》的字符序列。在下一节中,您将使用此模型生成新的字符序列。
让我们开始导入将用于训练模型的类和函数。
1 2 3 4 5 6 7 8 9 |
import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import LSTM from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.utils import to_categorical ... |
接下来,您需要将书的ASCII文本加载到内存中,并将所有字符转换为小写,以减小网络需要学习的词汇量。
1 2 3 4 5 |
... # load ascii text and covert to lowercase filename = "wonderland.txt" raw_text = open(filename, 'r', encoding='utf-8').read() raw_text = raw_text.lower() |
现在书已加载,您必须通过将字符转换为整数来准备神经网络的建模数据。您不能直接建模字符;相反,您必须首先创建书中所有唯一字符的集合,然后创建每个字符到唯一整数的映射。
您可以轻松地通过首先创建书中所有唯一字符的集合,然后创建每个字符到唯一整数的映射来做到这一点。
1 2 3 4 |
... # create mapping of unique chars to integers chars = sorted(list(set(raw_text))) char_to_int = dict((c, i) for i, c in enumerate(chars)) |
例如,书中唯一的小写排序字符列表如下
1 |
['\n', '\r', ' ', '!', '"', "'", '(', ')', '*', ',', '-', '.', ':', ';', '?', '[', ']', '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\xbb', '\xbf', '\xef'] |
您可以看到,可能有一些字符我们可以删除以进一步清理数据集,从而减少词汇量,这可能会改进建模过程。
现在书籍已加载并且映射已准备好,您可以总结数据集。
1 2 3 4 5 |
... n_chars = len(raw_text) n_vocab = len(chars) print "Total Characters: ", n_chars print "Total Vocab: ", n_vocab |
运行到此处的代码会产生以下输出。
1 2 |
Total Characters: 147674 Total Vocab: 47 |
您可以看到这本书有将近15万个字符,转换为小写后,网络需要学习的词汇量只有47个不同的字符,这比字母表中的26个多得多。
您现在需要定义训练数据。对于如何分割文本并将其暴露给网络进行训练,存在很大的灵活性。
在本教程中,您将把书本文本分割成固定长度为100个字符的子序列,这是一个任意长度。您同样可以将数据按句子分割,对较短的序列进行填充,对较长的序列进行截断。
网络中的每个训练模式都包含100个时间步的一个字符(X)和一个输出字符(y)。在创建这些序列时,您将这个窗口沿整本书一次一个字符地滑动,让每个字符都有机会从其前面的100个字符中学习(当然,除了前100个字符)。
例如,如果序列长度为5(为简化起见),那么前两个训练模式如下
1 2 |
CHAPT -> E HAPTE -> R |
在将书本分割成这些序列时,您将使用之前准备好的查找表将字符转换为整数。
1 2 3 4 5 6 7 8 9 10 11 12 |
... # 准备编码为整数的输入到输出对数据集 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 |
运行到此处的代码显示,当您将数据集分割为网络学习的训练数据时,您有将近15万个训练模式。这是合理的,因为排除前100个字符,您有一个训练模式来预测剩余的每个字符。
1 |
Total Patterns: 147574 |
现在您已经准备好了训练数据,您需要将其转换为适合Keras使用的格式。
首先,您必须将输入序列列表转换为LSTM网络期望的[样本, 时间步, 特征]格式。
接下来,您需要将整数重新缩放到0到1的范围,以便LSTM网络更容易学习这些模式(默认使用sigmoid激活函数)。
最后,您需要将输出模式(转换为整数的单个字符)转换为one-hot编码。这样,您就可以将网络配置为预测词汇表中47个不同字符中每个字符的概率(一种更简单的表示),而不是试图强迫它精确地预测下一个字符。每个y值被转换为一个长度为47的稀疏向量,其中包含全零,除了表示该模式的字母(整数)所在列为1。
例如,当“n”(整数值为31)进行one-hot编码时,它看起来像这样
1 2 3 |
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] |
您可以按如下方式实现这些步骤
1 2 3 4 5 6 7 |
... # 将 X 重塑为 [样本,时间步长,特征] 的形式 X = np.reshape(dataX, (n_patterns, seq_length, 1)) # 归一化 X = X / float(n_vocab) # one hot encode the output variable y = to_categorical(dataY) |
您现在可以定义您的LSTM模型。在这里,您定义了一个具有256个记忆单元的单个隐藏LSTM层。该网络使用20%的dropout概率。输出层是一个Dense层,使用softmax激活函数来输出每个47个字符的概率预测,概率在0到1之间。
这个问题实际上是一个单一字符分类问题,有47个类别,因此定义为优化对数损失(交叉熵),并使用ADAM优化算法以提高速度。
1 2 3 4 5 6 7 |
... # define the LSTM model model = Sequential() model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]))) model.add(Dropout(0.2)) model.add(Dense(y.shape[1], activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam') |
没有测试数据集。您正在对整个训练数据集进行建模,以学习序列中每个字符的概率。
您并不关心训练数据集中最准确的模型(分类准确率)。那将是一个完美预测训练数据集中每个字符的模型。相反,您关心的是最小化所选损失函数的对数据集的泛化。您正在寻求泛化和过拟合之间的平衡,但又不过度记忆。
该网络训练速度很慢(在Nvidia K520 GPU上每轮约300秒)。由于训练速度慢以及优化需求,请使用模型检查点来记录每次在epoch结束时观察到损失改进时网络权重到文件。您将使用最佳权重集(最低损失)在下一节中实例化您的生成模型。
1 2 3 4 5 |
... # define the checkpoint filepath="weights-improvement-{epoch:02d}-{loss:.4f}.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] |
您现在可以拟合您的模型到数据。在这里,您使用适中的20个epoch和128个模式的大批量大小。
1 |
model.fit(X, y, epochs=20, batch_size=128, callbacks=callbacks_list) |
完整的代码清单如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# Small LSTM Network to Generate Text for Alice in Wonderland import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import LSTM from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.utils import to_categorical # load ascii text and covert to lowercase filename = "wonderland.txt" raw_text = open(filename, 'r', encoding='utf-8').read() raw_text = raw_text.lower() # create mapping of unique chars to integers chars = sorted(list(set(raw_text))) char_to_int = dict((c, i) 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) # 准备编码为整数的输入到输出对数据集 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) # 将 X 重塑为 [样本,时间步长,特征] 的形式 X = np.reshape(dataX, (n_patterns, seq_length, 1)) # 归一化 X = X / float(n_vocab) # one hot encode the output variable y = to_categorical(dataY) # define the LSTM model model = Sequential() model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]))) model.add(Dropout(0.2)) model.add(Dense(y.shape[1], activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam') # define the checkpoint filepath="weights-improvement-{epoch:02d}-{loss:.4f}.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # 拟合模型 model.fit(X, y, epochs=20, batch_size=128, callbacks=callbacks_list) |
注意:您的结果可能会有所不同,这取决于算法的随机性、评估程序或数值精度的差异。考虑运行该示例几次并比较平均结果。
运行该示例后,您应该会在本地目录中看到多个权重检查点文件。
您可以删除除损失值最小的那个之外的所有文件。例如,当运行此示例时,您可以看到下面实现的最小损失检查点。
1 |
weights-improvement-19-1.9435.hdf5 |
网络损失几乎每个epoch都在下降,所以网络可能从训练更多epoch中受益。
在下一节中,您将学习如何使用此模型生成新的文本序列。
使用LSTM网络生成文本
使用训练好的LSTM网络生成文本相对简单。
首先,您将以完全相同的方式加载数据并定义网络,不同之处在于网络权重将从检查点文件中加载,并且网络不需要进行训练。
1 2 3 4 5 |
... # load the network weights filename = "weights-improvement-19-1.9435.hdf5" model.load_weights(filename) model.compile(loss='categorical_crossentropy', optimizer='adam') |
另外,在准备唯一字符到整数的映射时,您还必须创建一个反向映射,以便将整数转换回字符,这样您就可以理解预测结果。
1 2 |
... int_to_char = dict((i, c) for i, c in enumerate(chars)) |
最后,您需要实际进行预测。
使用Keras LSTM模型进行预测的最简单方法是,首先以一个种子序列作为输入,生成下一个字符,然后更新种子序列,将生成的字符添加到末尾并截去第一个字符。这个过程会重复进行,直到您想要预测新字符(例如,生成一个1000个字符长度的序列)。
您可以选择一个随机的输入模式作为您的种子序列,然后在生成过程中打印出生成的字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... # pick a random seed start = np.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 = np.reshape(pattern, (1, len(pattern), 1)) x = x / float(n_vocab) prediction = model.predict(x, verbose=0) index = np.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.") |
下面列出了使用已加载的 LSTM 模型生成文本的完整代码示例,以供参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# 加载 LSTM 网络并生成文本 import sys import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import LSTM from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.utils import to_categorical # load ascii text and covert to lowercase filename = "wonderland.txt" raw_text = open(filename, 'r', encoding='utf-8').read() raw_text = raw_text.lower() # 创建唯一字符到整数的映射以及反向映射 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) # 准备编码为整数的输入到输出对数据集 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) # 将 X 重塑为 [样本,时间步长,特征] 的形式 X = np.reshape(dataX, (n_patterns, seq_length, 1)) # 归一化 X = X / float(n_vocab) # one hot encode the output variable y = to_categorical(dataY) # define the LSTM model model = Sequential() model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]))) model.add(Dropout(0.2)) model.add(Dense(y.shape[1], activation='softmax')) # load the network weights filename = "weights-improvement-19-1.9435.hdf5" model.load_weights(filename) model.compile(loss='categorical_crossentropy', optimizer='adam') # pick a random seed start = np.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 = np.reshape(pattern, (1, len(pattern), 1)) x = x / float(n_vocab) prediction = model.predict(x, verbose=0) index = np.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.") |
运行此示例首先会输出选定的随机种子,然后输出生成的每个字符。
注意:您的结果可能会有所不同,这取决于算法的随机性、评估程序或数值精度的差异。考虑运行该示例几次并比较平均结果。
例如,下面是此文本生成器一次运行的结果。随机种子是
1 2 |
毫无疑问:那是一头猪,她 觉得可以把它 |
生成的文本(已清理以供展示)和随机种子是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
毫无疑问:那是一头猪,她 觉得可以把它变成了它,她知道自己是一点想去 ano a grtpersent to the tas a little war th tee the tase oa teettee the had been tinhgtt a little toiee at the cadl in a long tuiee aedun thet sheer was a little tare gereen to be a gentle of the tabdit soenee the gad ouw ie the tay a tirt of toiet at the was a little anonersen, and thiu had been woite io a lott of tueh a tiie and taede bot her aeain she cere thth the bene tith the tere bane to tee toaete to tee the harter was a little tire the same oare cade an anl ano the garee and the was so seat the was a little gareen and the sabdit, and the white rabbit wese tilel an the caoe and the sabbit se teeteer, and the white rabbit wese tilel an the cade in a lonk tfne the sabdi ano aroing to tea the was sf teet whitg the was a little tane oo thete the sabeit she was a little tartig to the tar tf tee the tame of the cagd, and the white rabbit was a little toiee to be anle tite thete ofs and the tabdit was the wiite rabbit, and |
让我们注意一些关于生成文本的观察结果。
- 它通常符合原始文本中观察到的行格式,即每行少于 80 个字符。
- 字符被分成类似单词的组,大多数组是实际的英语单词(例如,“the”、“little”和“was”),但许多不是(例如,“lott”、“tiie”和“taede”)。
- 一些连续的单词是有意义的(例如,“and the white rabbit”),但许多没有(例如,“wese tilel”)。
这个基于字符的图书模型能产生这样的输出,这一点非常令人印象深刻。它让你对 LSTM 网络有很好的了解。
但是,结果并不完美。
在下一节中,您将通过开发一个更大的 LSTM 网络来提高结果的质量。
更大的 LSTM 循环神经网络
在上文中,您获得了结果,但不是优秀的结果。现在,您可以通过创建一个更大的网络来尝试提高生成文本的质量。
我们将把内存单元的数量保持在 256 个,但添加第二个层。
1 2 3 4 5 6 7 8 |
... 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')) model.compile(loss='categorical_crossentropy', optimizer='adam') |
我们还将更改检查点权重的文件名,以便区分这两个网络的权重(通过在文件名中添加“bigger”一词)。
1 |
filepath="weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5" |
最后,我们将训练轮数从 20 增加到 50,并将批处理大小从 128 减小到 64,以让网络有更多机会进行更新和学习。
完整的代码列表如下,以供参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 用于生成《爱丽丝梦游仙境》文本的更大 LSTM 网络 import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import LSTM from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.utils import to_categorical # load ascii text and covert to lowercase filename = "wonderland.txt" raw_text = open(filename, 'r', encoding='utf-8').read() raw_text = raw_text.lower() # create mapping of unique chars to integers chars = sorted(list(set(raw_text))) char_to_int = dict((c, i) 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) # 准备编码为整数的输入到输出对数据集 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) # 将 X 重塑为 [样本,时间步长,特征] 的形式 X = np.reshape(dataX, (n_patterns, seq_length, 1)) # 归一化 X = X / float(n_vocab) # one hot encode the output variable y = 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')) model.compile(loss='categorical_crossentropy', optimizer='adam') # define the checkpoint filepath = "weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min') callbacks_list = [checkpoint] # 拟合模型 model.fit(X, y, epochs=50, batch_size=64, callbacks=callbacks_list) |
运行此示例需要一些时间,每个 epoch 至少需要 700 秒。
注意:您的结果可能会有所不同,这取决于算法的随机性、评估程序或数值精度的差异。考虑运行该示例几次并比较平均结果。
运行此示例后,您可能会获得大约 1.2 的损失。例如,运行此模型达到的最佳结果存储在一个名为
1 |
weights-improvement-47-1.2219-bigger.hdf5 |
这在 epoch 47 时达到了 1.2219 的损失。
与上一节一样,您可以使用此模型来生成文本。
您需要对上一节的文本生成脚本进行的唯一更改是网络拓扑的规格以及从哪个文件开始进行网络权重播种。
完整的代码清单如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# 加载更大的 LSTM 网络并生成文本 import sys import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import LSTM from tensorflow.keras.callbacks import ModelCheckpoint from tensorflow.keras.utils import to_categorical # load ascii text and covert to lowercase filename = "wonderland.txt" raw_text = open(filename, 'r', encoding='utf-8').read() raw_text = raw_text.lower() # 创建唯一字符到整数的映射以及反向映射 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) # 准备编码为整数的输入到输出对数据集 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) # 将 X 重塑为 [样本,时间步长,特征] 的形式 X = np.reshape(dataX, (n_patterns, seq_length, 1)) # 归一化 X = X / float(n_vocab) # one hot encode the output variable y = 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 = np.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 = np.reshape(pattern, (1, len(pattern), 1)) x = x / float(n_vocab) prediction = model.predict(x, verbose=0) index = np.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.") |
此文本生成脚本的一个运行示例产生以下输出。
注意:您的结果可能会有所不同,这取决于算法的随机性、评估程序或数值精度的差异。考虑运行该示例几次并比较平均结果。
随机选择的种子文本是
1 2 |
d herself lying on the bank, with her head in the lap of her sister, who was gently brushing away s |
生成的文本(已清理以供展示)和种子是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
herself lying on the bank, with her head in the lap of her sister, who was gently brushing away so siee, and she sabbit said to herself and the sabbit said to herself and the sood way of the was a little that she was a little lad good to the garden, and the sood of the mock turtle said to herself, 'it was a little that the mock turtle said to see it said to sea it said to sea it say it the marge hard sat hn a little that she was so sereated to herself, and she sabbit said to herself, 'it was a little little shated of the sooe of the coomouse it was a little lad good to the little gooder head. and said to herself, 'it was a little little shated of the mouse of the good of the courte, and it was a little little shated in a little that the was a little little shated of the thmee said to see it was a little book of the was a little that she was so sereated to hare a little the began sitee of the was of the was a little that she was so seally and the sabbit was a little lad good to the little gooder head of the gad seared to see it was a little lad good to the little good |
您可以发现,拼写错误通常更少,文本看起来更逼真,但仍然相当无意义。
例如,相同的短语会一遍又一遍地重复,例如“said to herself”和“little”。引号被打开但未关闭。
这些是更好的结果,但仍有很大的改进空间。
10 个改进模型的扩展思路
以下是十个可以进一步改进模型的想法,您可以尝试一下:
- 为给定的种子预测少于 1,000 个字符的输出
- 从源文本中删除所有标点符号,从而从模型的词汇表中删除
- 尝试输入序列的 one-hot 编码
- 在填充的句子上训练模型,而不是在随机字符序列上训练
- 将训练轮数增加到 100 或几百轮
- 向可见输入层添加 dropout,并考虑调整 dropout 百分比
- 调整批处理大小;尝试将批处理大小设为 1(作为(非常慢的)基线),然后从那里增大
- 向层添加更多内存单元和/或更多层
- 在解释预测概率时,尝试使用尺度因子(temperature)
- 将 LSTM 层设置为“有状态”,以在批处理之间维护状态
您尝试过这些扩展中的任何一个吗?在评论中分享您的结果。
资源
这个字符文本模型是使用循环神经网络生成文本的一种流行方式。
如果您有兴趣深入了解,以下是一些关于该主题的更多资源和教程。也许最流行的是 Andrej Karpathy 的题为“循环神经网络的非凡有效性”的教程。
- 使用循环神经网络生成文本 [pdf],2011
- Keras 用于文本生成的代码示例
- Lasagne 用于文本生成的代码示例
- MXNet 用于文本生成的 LSTM 教程
- 使用循环神经网络自动生成吸引眼球的标题
总结
在这篇文章中,您将了解如何使用 Keras 深度学习库在 Python 中开发用于文本生成的 LSTM 循环神经网络。
阅读本文后,您将了解:
- 在哪里免费下载经典书籍的 ASCII 文本用于训练
- 如何训练 LSTM 网络处理文本序列以及如何使用训练好的网络生成新序列
- 如何开发堆叠式 LSTM 网络并提升模型的性能
您对 LSTM 网络文本生成或本文有任何疑问吗?在下面的评论中提出您的问题,我会尽力回答。
非常棒的文章。谢谢!
不客气,Avi。
我们这里得到的损失是否等于每字符的比特数???
损失代表预期概率分布与预测概率分布之间的平均差异。
你好,
当我尝试运行代码时,我收到一个关于权重文件的错误。
ValueError: Dimension 1 in both shapes must be equal, but are 52 and 44 for Assign_13 with input shapes [256,52], [256,44].
您能告诉我发生了什么吗?
确认您已复制并运行所有代码,并且您的环境和库都是最新的。
嗨,Jason,
刚刚更新了所有库。仍然收到相同的错误。
谢谢!
--
抱歉,我不清楚您的错误可能是什么。
Jason,
谢谢。我弄好了!!!但我的结果是随机的,我会继续研究。但我觉得这是一个不错的开始。感谢代码!
谢谢!
恭喜取得进展,坚持下去!
您必须使形状相等,即 [256,44], [256,44](或)[256,52], [256,52]。
这是由于 weights.hdf5 文件与存储库中的新数据不兼容造成的。我已经更新了存储库,现在应该可以正常工作了。
我也遇到了同样的问题。在哪里可以下载 hdf5 文件?谢谢。
请问你是如何更新存储库的?
我很兴奋能尝试将这个与 nltk 结合……这可能会漫长而令人沮丧,但我会尝试告知我的结果。
感谢分享!
祝你好运,Max,回来告诉我你的进展。
你好,Max,
你有没有进展将 NLTK 与此结合?
只是好奇……
我非常喜欢您的文章,感谢分享。我可以运行您的代码,但在完成第一个 epoch 后会崩溃。
—————————————————
回溯(最近一次调用)
File “train.py”, line 61, in
model.fit(X, y, nb_epoch=20, batch_size=128, callbacks=callbacks_list)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/models.py”, line 620, in fit
sample_weight=sample_weight)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/engine/training.py”, line 1104, in fit
callback_metrics=callback_metrics)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/engine/training.py”, line 842, in _fit_loop
callbacks.on_epoch_end(epoch, epoch_logs)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/callbacks.py”, line 40, in on_epoch_end
callback.on_epoch_end(epoch, logs)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/callbacks.py”, line 296, in on_epoch_end
self.model.save(filepath, overwrite=True)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/engine/topology.py”, line 2427, in save
save_model(self, filepath, overwrite)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/models.py”, line 56, in save_model
model.save_weights_to_hdf5_group(model_weights_group)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/keras/engine/topology.py”, line 2476, in save_weights_to_hdf5_group
dtype=val.dtype)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/h5py/_hl/group.py”, line 108, in create_dataset
self[name] = dset
File “_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper (/scratch/pip_build_sbilokin/h5py/h5py/_objects.c:2513)
File “_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper (/scratch/pip_build_sbilokin/h5py/h5py/_objects.c:2466)
File “/afs/in2p3.fr/home/s/sbilokin/.local/lib/python2.7/site-packages/h5py/_hl/group.py”, line 277, in __setitem__
h5o.link(obj.id, self.id, name, lcpl=lcpl, lapl=self._lapl)
File “_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper (/scratch/pip_build_sbilokin/h5py/h5py/_objects.c:2513)
File “_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper (/scratch/pip_build_sbilokin/h5py/h5py/_objects.c:2466)
File “h5o.pyx”, line 202, in h5py.h5o.link (/scratch/pip_build_sbilokin/h5py/h5py/h5o.c:3726)
RuntimeError: Unable to create link (Name already exists)
—————————————————–
文件名是唯一的,可能是 keras 或 h5py 的名称冲突。
你能帮帮我吗?
找到了我的错误,我没有正确编辑 Keras 的 topology.py 来修复另一个问题。
这是我第二次学习神经网络,但总是遇到版本、错误、依赖项的问题,这让我望而却步。
例如,现在我加载权重时遇到了问题,使用的是上面关于 python 3 和中间权重文件的示例
回溯(最近一次调用)
File “bot.py”, line 49, in
model.load_weights(filename)
File “.local/lib/python3.3/site-packages/keras/engine/topology.py”, line 2490, in load_weights
self.load_weights_from_hdf5_group(f)
File “.local/lib/python3.3/site-packages/keras/engine/topology.py”, line 2533, in load_weights_from_hdf5_group
weight_names = [n.decode(‘utf8’) for n in g.attrs[‘weight_names’]]
File “h5py/_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper (/scratch/pip_build_/h5py/h5py/_objects.c:2691)
File “h5py/_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper (/scratch/pip_build_/h5py/h5py/_objects.c:2649)
File “/.local/lib/python3.3/site-packages/h5py/_hl/attrs.py”, line 58, in __getitem__
attr = h5a.open(self._id, self._e(name))
File “h5py/_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper (/scratch/pip_build_/h5py/h5py/_objects.c:2691)
File “h5py/_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper (/scratch/pip_build_/h5py/h5py/_objects.c:2649)
File “h5py/h5a.pyx”, line 77, in h5py.h5a.open (/scratch/pip_build_/h5py/h5py/h5a.c:2179)
KeyError: “Can’t open attribute (Can’t locate attribute)”
我不认为我可以为您修改 Keras 框架文件提供有用的建议。
祝你好运!
嗨,Jason,
我遵循了您的教程,然后构建了自己的序列到序列模型,并在单词级别进行了训练。
可能很快会分享结果和代码,但首先想感谢您提供这篇很棒的文章,它帮助我入门 Keras。
继续做精彩的工作!
太棒了,Alex,做得好。如果你能发布或链接你的代码就太好了。
你好
我知道这是一篇旧帖子,但 Alex 你有没有分享过你关于单词级别训练的代码?
谢谢
Cristiano
我的博客上有一些例子
https://machinelearning.org.cn/?s=language+model&submit=Search
当我尝试获取唯一字符集时
我得到以下结果:
[‘\n’, ‘ ‘, ‘!’, ‘”‘, “‘”, ‘(‘, ‘)’, ‘*’, ‘,’, ‘-‘, ‘.’, ‘:’, ‘;’, ‘?’, ‘[‘, ‘]’, ‘_’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘\xbb’, ‘\xbf’, ‘\xef’]
请注意,‘\r’ 丢失了,为什么?
谢谢你
在某些平台(如 Unix 及其衍生系统)上不需要。只有 Windows 使用 CRLF。
感谢您的回复。
我正在使用 Windows。
我正在输入时进行拟合。
🙂
太棒了!
感谢您的回复,Jason。
问题
我可以使用相同的方法生成一本像《爱丽丝梦游仙境》一样大的书吗?
如果可以,如何做?
例如,我生成 50,000 个字符吗?
以及如何使用“SEED”来实际生成这样的文本?
在示例中,您使用 100 个字符来分割文本并暴露给网络。增加字符数是否有助于产生更有意义的文本?
还有另一个问题?
我应该运行多少个 epoch 进行拟合?100,200?因为损失一直在下降,但如果它接近于零,那是否是一件好事?
抱歉问了这么多问题。
非常非常感谢您:)
很好的问题,但这些是研究问题。
您需要自己进行实验。
我做了一个类似的项目,我删除了非 ASCII 字符,方法是:
ascii_values = ascii_values[np.where(ascii_values < 128)]
好建议!
嘿,不错的文章。你能解释一下为什么使用 256 作为 LSTM 的输出维度吗?256 的原因是否来自其他参数?
网络只输出一个字符。
LSTM 层中有 256 个节点,我选择了一个较大的数字来增加网络的表示能力。我选择它时是任意的。您可以尝试不同的值。
很棒的解释。感谢分享。
很高兴您觉得它有用,Lino。
感谢您写了这篇精彩的文章。为什么我们必须预先在 LSTM 中指定时间步长(在 input_shape 中)?如果不同的数据点具有不同的序列长度怎么办?在这种情况下,我们如何让 Keras LSTM 工作?
你好,Shamit,
网络需要知道数据的大小,以便为模型准备高效的数据结构(后端计算)。
如果您有可变长度的序列,您需要用零进行填充。Keras 提供了一个用于此目的的填充函数。
https://keras.org.cn/preprocessing/sequence/
嗨 Jason
非常感谢您的代码和简单的解释。
只有一条简短的通知:对于模型检查点,您需要 h5py 模块,它没有与我的 python 一起预装。我显然只在第一个 epoch 之后才注意到这一点,当时 keras 试图导入它。对于人们来说,在他们浪费时间在像我这样的慢硬件上运行代码之前检查这一点可能是一个好主意:)
说得好,谢谢 Julian!
嗨 Jason
我将您的精简 LSTM 网络代码在同一本书(wonderland.txt)上运行了 20 个 epoch。但在我的情况下,生成的文本没有意义。以下是其中的片段:
Seed
” e chin.
æiÆve a right to think,Æ said alice sharply, for she was beginning to
feel a little worried ”
up!uif!tbccju!xp!cf!b!mpsu!pg!uif!tbbufs!bos!uif!ebsufs-!boe!uifo!tif
xbt!bom!uif!ebuufs!xiui!uif!sbtu!po!uif!!boe!uif!xbt!bpmjoh!up!uif!
bpvme-
uif!nbuuf!xbt!b!mpsumf!ujfff!up!cf!b!mpsu!pg!uif!tbbufs!bos!uif!ibouf
uif!tbt!pg!uif!xbt!tp!tff!pg!uif!xbt!pp!bo!bo!pg!tifof!!bou!uif!xbt!bom
!tif!ibe!tv!co!bo!uif!sbccju!xpvme!cf!bspmpvt!up!tffff!
uif!ibe!tp!cfe
您能就为什么会发生这种情况以及如何修复它提供一些见解吗?
哎呀,Bruce,好像有些事情不对劲。
也许确认 Keras 1.1.0 和 TensorFlow 0.10。
看起来网络可能没有训练足够长的时间,或者从整数到字符的转换有问题。
另外,请确认没有复制粘贴错误。
嘿 Bruce,关于这个有什么更新吗?我尝试使用 one-hot 向量作为输入,而不是帖子中提到的那些。我的输出与您的类似。
xxw’?,p?9l5),d-?l?sxwx?fbb?flw?g5ps-up ?’xx?,)lqc?lrex?fqp,)xw?gfu-fwf ,,x?up ?bxvcxexw?)fwgxg?,pq54d-;wp9?ql5),[?p ,?p;?,)x?;pwwfs)-lq?bp’x?l’
如何从用户那里获取种子,而不是由程序生成随机文本?
例如,您可以从sys.stdin读取。
对于用户输入,您可以使用 userinput = stdin.readline()
例如,输入是
userinput = “Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to”
sort_sen = sorted(list(p))
pattern = [char_to_int[value.lower()] for value in sort_sen]
这就是您可以处理用户输入的方式。希望有所帮助。
感谢分享!
嗨,Jason,
非常感谢您的精彩博文!
您能解释一下为什么需要重塑 X 吗?
列表的列表的初始形状有什么问题?
谢谢!
你好 Victor,问得好。
所有 LSTM 的输入都必须是 [samples, timesteps, features] 的形式。数据被加载为 [samples, timesteps]。与其说是时间步,不如说是序列——它们是同一回事。
希望这能有所帮助。
使用类似的方法:是否可以从时间序列数据生成数字序列,就像生成句子一样?我认为我们可以。任何输入都将受到Jason的赞赏。谢谢。
当然,将输出从一个节点更改为 n 个节点。
对于序列输出,您将需要更多的数据和更多的训练。
谢谢,但为什么要改为 n 个节点?考虑到您生成了一个文本序列,我不能用相同的 1 个节点设置得到一个数字序列吗?
此外,我不理解“index = numpy.argmax(prediction)
result = int_to_char[index]”这段代码。您能解释一下为什么有必要吗?
我是您网站的新用户……继续保持出色的工作!期待您的回复。
你好 ATM,
是的,有几种方法可以构建序列预测问题。您可以多次使用单步预测模型。另一种方法是立即预测部分或整个序列,以及介于两者之间的所有级别。
代码行
选择具有最大输出值的节点。节点的索引与要预测的类的索引相同。
希望这能有所帮助。
谢谢您的解释,Jason:我的代码运行正常,对时间序列数据进行了不错的预测。
您可能想在教程中添加,预测通常仅对统计平稳性较高的数据集效果好,而与训练大小无关?
我已在平稳和非平稳数据集上都试过,并得出了这个结论(这是有道理的)。时间序列数据,无论是来自金融还是科学数据集,通常都不是平稳的,因此 LSTM 必须非常谨慎地使用。
谢谢 ATM!我同意,我将在接下来的博客文章中详细介绍平稳时间序列以及如何使非平稳数据平稳。
你好 jason,
我一直在运行这个。但是 loss 并没有减少,反而一直在增加。到目前为止,我已经运行了 20 个 epoch。您认为可能是什么原因?我并没有更改程序中的任何内容。
祝好,
Sban
也许您的网络太小了?也许是过拟合?
你好,
如何处理更大的数据集?我抓取了法国政府近几年的所有公开声明,因此我的语料库是:总字符数:465163150
总词汇量:146
dataX 和 dataY 可能会因为大小限制而崩溃,我该如何规避这个问题并使用完整的数据集?
也许可以从磁盘分批读取数据——我认为 Keras 具有图像数据生成器的功能,也许也适用于文本?我暂时不确定。
嗨,Jason,
感谢您的示例。我想知道损失函数:分类交叉熵。我尝试查找源代码但没有成功。您知道损失值为 1.2 实际意味着什么吗?这个数字有单位吗?
据我所知,目标是某种程度上让网络学习一个概率分布,使其尽可能地接近训练数据的分布。但是 1.2 有多接近呢?
显然,损失值为 0 意味着网络能够以 100% 的准确率准确预测给定样本的目标,这已经很难想象了,因为该网络的输出不是二元的,而是对词汇表中所有字符值的数组进行 softmax。
再次感谢。
你好 Julian,
问得好。我需要专门写一篇博文来回答这个问题,谢谢您的提示。
交叉熵在您的搜索中也称为对数损失,数学原理在这里
https://en.wikipedia.org/wiki/Cross_entropy
我会尽快写一篇。
嘿,谢谢您的博文,这在 Theano 上也能用,而不是 TensorFlow 吗?我知道 Keras 可以同时使用两者,而我在 Mac 上安装 TensorFlow 时遇到一些困难。
是的,代码可以在任一后端上运行。
谢谢,TensorFlow 最终还是可以了。我正在用一个像这本书一样大的数据集进行训练,这些消息是
总字符数:237084
总词汇量:50
总模式:236984
在第 13 个 epoch 时,loss 是 1.5。我不得不停在那里,因为它需要我的 MacBook Pro 2013 年的 13 个 epoch 耗时 20 小时。无论如何,这是我的结果,请注意它在某个点开始重复
is all the love and the sain on my baby
bnd i love you to be a line to be a line
to be a line to me, i’m she way the lov
es me down and i do and i do and i do an
d i do and i do and i do and i do and i
do and i do and i do and i do and i do a
nd i do and i do and i do and i do and i
do and i do and i do and i do and i do
and i do and i do and i do and i do and
这是另一次程序运行的结果
oe mine i want you to ban tee the sain o
f move and i do and i do and i love you
to be a line to me, i’m she way the way
the way the way the way the way the way
the way the way the way the way the way
the way the way the way the way the way
the way the way the way the way the way
the way the way the way the way the way
这很令人沮丧(尽管仍然令人难以置信的棒),您认为为什么会这样吗?
无论如何,这是一篇很棒的博文,以一种很棒的方式介绍了 RNN 和 LSTM!
可能是过拟合?
干得好!
网络可能需要更大的表示能力。尝试更多的层和/或每层更多的神经元。
也可以尝试在 AWS 上运行,让您可怜的笔记本电脑休息一下。
https://machinelearning.org.cn/develop-evaluate-large-deep-learning-models-keras-amazon-web-services/
谢谢!我也会尝试将数据分解成单词而不是字母。我会更新的:)
如果我们以单词级别而不是字符级别训练网络,是否会获得更好的结果?我们将数据集拆分成单词,然后对它们进行索引,就像我们对字符所做的那样,并将它们用作输入。这是否至少可以消除生成文本中虚构的单词,使其看起来更合理?
是的。试试 Jack!我很想看看结果。
我同意单词级别的建模会更直观,句子也可能显示出一些有意义的结果。
一个问题是,如果您选择字符级别,您有 47 个特征可供选择。然而,独特单词的数量比独特字符的数量大几个数量级。因此,您的网络会变得更大。您可以添加一个嵌入层来减小输入维度,但是,输出 softmax 仍然很大。
这项任务是否有任何基准数据集来实际评估模型?
据我所知, Fateh 没有。
嗨 Jason,非常棒的博文!我有一个疑问。我尝试了以下方法:而不是用《爱丽丝漫游奇境》进行训练,我用这个条形码列表进行训练。唯一条形码在一个纯文本中(例如,123455,143223,等等),它们可能长度不同。这种方法仍然有效吗?我想做的是输入一个可能带有错误的条形码(可能丢失了一个字符),然后 LSTM 返回“正确的那个”。有什么建议吗?非常感谢!
好主意 Don。
LSTM 确实可以纠正序列,但它们需要记住所有的条形码。然后您需要训练它来填补缺失值(0)。
好主意!
您也可以尝试使用自动编码器来做同样的事情。
我很想听听您的进展。
谢谢 Jason!当然,我会回来的:)
您有什么关于 LSTM 作为“单词校正器”或用于此任务的自动编码器的推荐阅读吗?
最棒的!
抱歉,Don,我没有。祝您的项目好运!
嗨 Jason,非常感谢您的博文。
我正在考虑将输入和输出更改为坐标,这是一个 2D 向量(x 和 y 位置)来预测运动。
我理解我们可以将输入更改为向量而不是标量。例如,使用 one-hot 向量,就像您建议的那样。
但是,我不明白当我们要将输出变为 2D 向量时该怎么做。这是否意味着我不需要使用 softmax 层作为输出?
谢谢你的帮助。
你好 Alex,有趣的构想——运动生成器。
您可以通过更改输出层中的神经元数量来输出向量。
嗨,Jason,
练习中的特征是字符,它们被映射到整数。这就像用连续变量替换名义变量。这有问题吗?
另外,您是否会考虑使用 Embedding 作为模型的第一层——为什么或为什么不。
谢谢,您的博文非常有帮助。
你好 Ashok,
输入数据是序数型的,可以是字符或整数。神经网络期望处理数字数组而不是字符,所以我们这里使用整数。
Embedding 层会将字符投影到高维空间。这里没有用,因为我们试图学习和泛化字符序列的组合方式。
不过我可能错了,试试看是否能成功——也许是单词序列的投影?
谢谢 Jason。这很有帮助。
关于 Embedding 层,我还有一个问题——这些投影是如何学习的?是像乘以已知矩阵这样的简单方法,还是它们是迭代学习的?如果是迭代学习,那么它们是 a) 在学习其他权重之前先学习,还是 b) 嵌入投影权重与其它权重一起学习。
Ashok
问得好 Ashok。
Keras 文档对 Embedding 层的描述并不太好。
https://keras.org.cn/layers/embeddings/
这个 Stack Overflow 帖子有帮助。
http://stackoverflow.com/questions/38189713/what-is-an-embedding-in-keras
Jason
以下用于文本生成的代码将字符视为名义变量,因此为每个字符分配一个单独的维度。由于这是一种更复杂的方法,我将检查它是否能带来改进。
再次感谢您的回复。它只增加了我的好奇心。
https://github.com/fchollet/keras/blob/master/examples/lstm_text_generation.py
我很想听听 Ashok,在实践中表示方法如何进行比较。
Jason,您能解释一下输入数据为什么是序数型吗?而不是 one-hot 编码,我们只是简单地枚举字符。
我也有同样的问题。您找到答案了吗?
如果您的输入是文本,您可以使用
– 序列的整数编码
– 词袋模型编码(例如,TF-IDF 计数)
– 整数编码的 one-hot 编码
– 词嵌入(word2vec、glove 或学习到的)
这有帮助吗?
你好,Jason!
做得不错。但我不太明白为这个特定任务应用 RNN 的意义。如果一个人想预测一个 100 个字符序列的下一个字符,我认为任何其他常见的回归任务都可以实现这一点,即在训练时输入训练序列和接下来的单个字符作为输出。您的方法有什么额外的功能?
是的,有很多方法可以解决这个问题。
LSTM 在对文本语料库中的字符或单词的底层 PDF 进行建模方面特别擅长。
该示例在 TensorFlow 1.0.0 下已不再运行。(之前的版本没问题,至少在 0.10.0rc0 上是这样)。
Hendrik,您看到什么错误了吗?
精彩的博文 Jason,我尝试做几乎相同的事情,您的博文提供了很多帮助。正如一些评论所建议的,RNN 似乎很快就会陷入循环。我想知道您说“为可见输入层添加 dropout 并考虑调整 dropout 百分比”是什么意思,这似乎可以解决这个问题。
您可以对 LSTM 的递归和输入连接应用正则化。
在其他项目中,我发现为 LSTM 的输入连接添加大约 40% 的 dropout 非常有用。
更多细节在此
https://keras.org.cn/layers/recurrent/#lstm
实际上 Jason,
我推进了我的实验,发现了一些有趣的东西,我可能会在 Medium 上写一篇关于它的文章。
对于循环问题,正如 http://karpathy.github.io/2015/05/21/rnn-effectiveness/ 中所述,在生成过程中总是使用 argmax 没有意义。由于网络输出一个概率列表,因此很容易使用此分布随机采样字母。
def sample_prediction(char_map, prediction)
rnd_idx = np.random.choice(len(prediction), p=prediction)
return char_map[rnd_idx]
这个简单的改变使网络避免了循环,并变得更加多样化。(如您所提到的,使用
temperature 会更好)。
这是一个单层网络(与您的相同)的示例,使用塞万提斯的《唐
吉诃德》训练了 20 个 epoch
=====
from its beginning to its end, and above all manner; as so able to be almost unable to repeat the, which he had protected him to leave it. As now, for her face because I will be, that he ow her its missing their resckes my eyes, proved
for the descance in the mouth as saying, to eat for a
shepherdess and this knight ais, they
did so that was rockly than to possess the new lose of, that in a sword of now another
golden without a change on which not this; if shore of the Micomicona his dame, ‘To know some little why as capacquery; I will make any ammorimence is seen in their
countless
soicour and the adventure of her damsel a pearls that shows and vonquished callshind him, away itself, her fever and evil comrisoness by where they
will show not in time in which all the chain
himself of the
solmings of the hores of this
your nyiugh and it,
should have punisented, not to portion for, as it
just be-with his sort rich as the shaken of the
sun to
three lady male love?”
Am I he will not believe. I will disreel her more so knight, for
=====
这不是很酷吗?我希望这能帮助其他人。
非常酷 Gustavo,感谢分享!
首先,非常感谢Jason如此有价值的博文。
我有一个问题
致 Gustavo Führ 和 Jason Brownlee
您能否详细解释一下您在那里做了什么?我不太明白,您是如何在一个单层上获得如此好的输出的。
我在训练中使用这本书作为我的数据 -> http://www.gutenberg.org/cache/epub/5200/pg5200.txt
下面是我的输出结果。
Seed (种子)
see it coming. we can’t all work as hard as we have to and then come hometo be tortured like this, we can’t endure it. i can’t endure it anymore.” and she broke out so heavily in tears that they flo
Prediction (预测)
led to het hemd and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and she was so the door and
正如您在这里看到的,文本在重复。这是在双层LSTM(256个单元,序列长度为200个字符)中训练第20个epoch的结果。
这是我在所有训练中都看到的模式,我相信我在这里做错了什么。您能帮我解决一下吗?
根据上面的代码,它之所以重复,是因为在这一行上的MOST PROBABLE (argmax):
index = numpy.argmax(prediction)
而应该是:
index = numpy.random.choice(len(prediction[0]),p=prediction[0])
现在这样可行了,但它给出了“gobeldegook”(胡言乱语),而不是像英语一样重复的词语。也许我需要训练更长时间,并且loss < 2.5?
我自己的实验中也有类似的经历。这条评论验证了我发现的内容——感谢Jatin分享!
为什么需要归一化?
# 归一化
X = X / float(n_vocab)
这会用最大的整数值来缩放整数值。所有值都会被重缩放到0-1。
是因为它使用了ReLU激活函数吗?还是因为通常需要输入值在0-1之间?
LSTM更喜欢归一化的输入——通过一些实验可以确认这一点(我已经做过了)。
你好~ 我是您的粉丝之一。
我有一个关于LSTM设置的问题,我可能会以不同的方式应用您的文本生成模型。
您的模型通过添加(更新)一个字符来生成文本。
您认为是否有可能通过添加一个词而不是一个字符来生成文本?
如果可能,添加word_embedding层对文本生成的性能有效吗?
是的,我认为它甚至可能效果更好,June。请告诉我您的进展。
谢谢,杰森。
我将尝试一下!
您知道,我是一名管理信息系统专业的博士生。
我的研究兴趣包括医疗信息学和医疗保健业务分析。
您优秀的博客文章对我帮助很大。
我非常感激!
听到您这么说我很高兴。感谢您的支持和美言,我非常感激。
你好,
非常有趣的例子——迫不及待想尝试在其他文本上进行训练!
我有一个关于训练这个,或者事实上任何神经网络在GPU上的问题——我已经写了一些CNN,但无法执行:(。
假设我使用的是Amazon EC2或Google Cloud,我可以成功登录实例并仅使用CPU运行简单的ANN,但我完全不明白如何让GPU工作。我从Windows 10访问实例。您能告诉我我需要执行的确切步骤吗?——我想我需要获取CUDA和CUDNN吗?然后我还需要做其他事情吗,还是我可以只pip安装必要的包然后执行我的代码?
非常感谢。
我最好的建议是使用已经配置好使用GPU的AMI。
我在这里有详细的步骤说明
https://machinelearning.org.cn/develop-evaluate-large-deep-learning-models-keras-amazon-web-services/
好帖子!
两个问题:
1) 第63行“seq_in = [int_to_char[value] for value in pattern]”的作用是什么(循环中似乎没有使用它),以及
2) 您能否详细说明Gustavo的修复在哪里以及如何需要?(我也通过argmax得到重复的预测)
您的深度学习书籍是否在这方面(2)针对LSTM有更详细的介绍?
输出不同输入的相同预测似乎有问题。
seq_in 是预测中使用的输入序列。同意,在示例的后半部分不需要它。
他的修复不是必需的,它只能减小可能值集合的大小。我的书没有更详细地介绍这一点。
我正在写一本关于LSTM的新书,可能在下个月发布时对您有帮助。
这是我实现Gustavo建议的代码,以便预测输出倾向于避免重复的模式
def sample_prediction(prediction)
“””根据其概率分布从预测中获取随机索引。
参数
——
prediction (array (array)): 长度为1的数组,包含总和为1的概率数组
返回值
——-
rnd_idx (int): prediction[0]中的随机索引
注意事项
—–
有助于解决重复输出的问题。
len(prediction) = 1
len(prediction[0]) >> 1
"""
X = prediction[0] # sum(X) 约等于 1
rnd_idx = np.random.choice(len(X), p=X)
return rnd_idx
for i in range(num_outputs)
x = np.reshape(pattern, (1, len(pattern), 1))
x = x / float(n_vocab)
prediction = model.predict(x, verbose=0)
#index = numpy.argmax(prediction)
#根据Gustavo的建议,我们不应该在这里使用argmax
index = sample_prediction(prediction)
result = int_to_char[index]
#seq_in = [int_to_char[value] for value in pattern]
#不确定seq_in为什么在这里
sys.stdout.write(result)
pattern.append(index)
pattern = pattern[1:len(pattern)]
print “\nDone.”
太棒了!
嗨 Jason,很棒的帖子。
我想问您,是否有办法训练这个系统,或者使用当前的设置进行动态输入长度的训练。
原因是,如果一个人要将其用于真实的文本生成,给定一个可变长度的随机种子,比如“I have a dream”或“To be or not to be”,如果使用动态长度进行训练,是否仍然能够生成连贯的句子?
我尝试在预测阶段(而不是训练阶段)使用padding来匹配较短句子的输入长度,但这似乎不起作用。
此致
是的,你的思路是正确的。
我建议将所有序列用零填充到相同的长度,然后看看模型的表现如何。
你可以尝试Masking输入层,看看它有什么影响。
你也可以尝试截断序列。
我有一篇关于处理不同长度输入序列的多种方法的帖子,可能几周后会发布。
那将非常感谢。期待它。
你好,感谢您的帖子。我想知道关于实现动态大小用户输入的后续帖子(在此问题串中讨论)是否发布了?如果发布了,是哪篇文章?谢谢!
您可以使用填充或截断。
https://machinelearning.org.cn/data-preparation-variable-length-input-sequences-sequence-prediction/
你好,
我可以问一下这两行代码吗?
seq_in = raw_text[i:i + seq_length]
seq_out = raw_text[i + seq_length]
模型应该预测下一个字母d,而不是c,对吗?
你好,
我需要感谢您在Keras上所做的所有出色工作,这是一个很棒的包。
但是,我遇到了浮点异常(core dumped)运行代码。请,我需要您的建议来解决这些问题。我已经将我的keras从1.0.8升级到了2.0.1,但问题仍然存在。
88/200 [============>……………..] – ETA: 27s – loss: 11.3334 – acc: 0.0971{‘acc’: array(0.10470587760210037, dtype=float32), ‘loss’: array(9.283703804016113, dtype=float32), ‘batch’: 88, ‘size’: 17}
89/200 [============>……………..] – ETA: 26s – loss: 11.3103 – acc: 0.0972Floating point exception (core dumped)
此致
我很抱歉听到这个消息。
也许您可以尝试不同的后端(theano或tensorflow)?
也许您可以尝试发布到stackoverflow或keras用户组?
谢谢你,Jason。
大家好,
使用Tensorflow后端,我遇到了不同的错误消息。在第二个epoch大约89个batch后,loss变成NaN,accuracy也一样。有什么建议或意见吗?
87/200 [============>……………..] – ETA: 113s – loss: 9.4303 – acc: 0.0947{‘acc’: 0.10666667, ‘loss’: 9.2033749, ‘batch’: 87, ‘size’: 32}
88/200 [============>……………..] – ETA: 112s – loss: 9.4277 – acc: 0.0949{‘acc’: 0.10862745, ‘loss’: 9.2667055, ‘batch’: 88, ‘size’: 17}
89/200 [============>……………..] – ETA: 110s – loss: 9.4259 – acc: 0.0950{‘acc’: nan, ‘loss’: nan, ‘batch’: 89, ‘size’: 0}
90/200 [============>……………..] – ETA: 108s – loss: nan – acc: nan {‘acc’: nan, ‘loss’: nan, ‘batch’: 90, ‘size’: 0}
91/200 [============>……………..] – ETA: 106s – loss: nan – acc: nan{‘acc’: nan, ‘loss’: nan, ‘batch’: 91, ‘size’: 0}
92/200 [============>……………..] – ETA: 105s – loss: nan – acc: nan{‘acc’: nan, ‘loss’: nan, ‘batch’: 92, ‘size’: 0}
这可能会发生,并且是由梯度爆炸或消失引起的。
尝试在优化算法中使用clipnorm。
https://keras.org.cn/optimizers/
感谢您的示例。Piush。
不客气。
嗨,Jason,
我尝试了您的建议,但问题仍然存在,在第二个epoch后loss和accuracy变为NaN,而batch size为39/50。
我也尝试了所有激活函数和正则化,但仍然存在相同的问题。太糟糕了!
嗨,Jason,
loss和accuracy在几个epoch后变成NaN的问题与batch generator有关。我现在已经解决了。
非常感谢。
很高兴听到这个消息。
你好 Jason,
我想知道如何添加更多的隐藏层。我想知道这是否能帮助生成更高效的文本?
我尝试再次使用model.add(LSTM(some_number)),但失败了并给出了错误
“Input 0 is incompatible with layer lstm_3: expected ndim=3, found ndim=2”
你好 Jason,
感谢您出色的帖子,它对我帮助很大。自从我读完您的帖子后,我一直在思考如何实现词级别而不是字符级别。我只是不确定如何实现,因为字符只有几个,而词可能有10000个甚至更多。您能否分享您的想法?我真的很期待看到词级别的结果并进行进一步改进。
好主意。
我建议按频率对所有单词进行排名,然后根据排名为每个单词分配整数。未包含在语料库中的新单词也可以稍后分配整数。
你好Jason,感谢您写下如此出色的帖子。
我一直收到错误信息
ImportError: `load_weights` requires h5py。
即使我已经安装了h5py,是否还有其他人遇到过这个错误?请帮忙。
也许您的环境看不到h5py库?
确认您已为您使用的环境正确安装了它。
尝试导入库本身,并精炼环境直到它能工作。
告诉我进展如何。
已经解决了,我安装h5py后重新启动了python。
当我使用模型进行预测时,它输出像这样的字符,为什么会出现1?
t1
h1
e1
1
s1
e1
r1
e1
1
t1
o1
1
t1
e1
e1
1
w1
e1
r1
1
i1
n1
1
a1
n1
d1
我不知道。确认您使用的是教程中的原始代码,没有进行修改。
我们可以用print()代替sys.stdout.write()吗?
当然可以。
嗨,Jason,
请,我需要您的帮助。我尝试使用模型已训练好的结果来验证我的测试数据,但我遇到了以下错误:
##################
AttributeError Traceback (最近一次调用)
in ()
1 # load weights into new model
—-> 2 model_info.load_weights(save_best_weights)
3 predictions = model.predict([test_q1, test_q2, test_q1, test_q2,test_q1, test_q2], verbose = True)
AttributeError: ‘History’ object has no attribute ‘load_weights’
In [ ]
#####################
以下是我的代码片段:
###Fitting model(拟合模型)
保存最佳权重用于预测测试问题对
save_best_weights = “weights-pairs1.h5”
checkpoint = ModelCheckpoint(filepath, monitor=’loss’, verbose=1, save_best_only=True, mode=’min’)
callbacks = [ModelCheckpoint(save_best_weights, monitor=’val_loss’, save_best_only=True),
EarlyStopping(monitor=’val_loss’, patience=5, verbose=1, mode=’auto’)]
start = time.time()
model_info=merged_model.fit([x1, x2, x1, x2, x1, x2], y=y, batch_size=64, epochs=3, verbose=True,
validation_split=0.33, shuffle=True, callbacks=callbacks)
end = time.time()
print(“Minutes elapsed: %f” % ((start – end) / 60.))
#####evaluting(评估)
#将权重加载到新模型中
model_info.load_weights(save_best_weights)
predictions = model.predict([test_q1, test_q2, test_q1, test_q2,test_q1, test_q2], verbose = True)
此致
请参阅本教程,了解如何加载已保存的模型。
https://machinelearning.org.cn/save-load-keras-deep-learning-models/
你好 Jason,
很棒的教程。我只有一个疑问,在np.reshape命令中,“feature”是什么意思?
为什么它被设置为1?
原始数据是整数序列。每个时间步只有一个观测值(特征),它是一个整数。这就是为什么第一个reshape指定一个特征。
出色的教程!
我有一个问题。我需要根据您的代码使用LSTM和二进制编码来预测文本中的某些词。您认为使用n个词作为上下文和k个词作为预测词的后续上下文是一个好习惯吗?
用这种方式训练模型是否合适,还是我们应该只使用我们预测的上下文数据?
尝试几种方法,看看哪种最适合您的项目。
谢谢,这对我来说是个很好的参考。
很高兴听到这个消息。
为什么不进行独热编码?
好的,试试看吧。
也可以尝试一个编码层。
有很多方法可以改进这个示例,Joe,请告诉我您的进展。
Jason,
好帖子。非常感谢。我对LSTM非常陌生。我试图重现这里的代码。如何增加epoch的数量?
谢谢
更改“epochs=”后面的值。
嗨,Jason,
非常感谢您的这些指南和教程!我觉得它们非常有帮助。
听到您这么说很高兴,Greg。
嗨,Jason,
感谢您的精彩帖子,以及其他所有精彩帖子。我想在填充的句子上训练模型,而不是随机的字符序列,但这不清楚如何实现。您能详细说明一下并举例说明吗?
非常感谢!
Don
Keras有一个很棒的pad函数可以做到这一点。
https://keras.org.cn/preprocessing/sequence/
这有帮助吗?
再次感谢您的帖子和所有信息!我还有另一个问题。如果我想通过输入一个短于100个字符的字符串进行预测,我该怎么办?
再次非常感谢!
使用填充。
https://machinelearning.org.cn/data-preparation-variable-length-input-sequences-sequence-prediction/
谢谢!
我有一个关于模型参数数量和数据量的问题。当我查看最简单模型的摘要时,我看到:Total params: 275,757.0, Trainable params: 275,757.0, and Non-trainable params: 0.0(出于某种原因,我无法发送包含完整摘要的回复)。
《爱丽丝梦游仙境》这本书中的字符数约为150,000。那么,参数数量难道不是大于字符数(数据)吗?
再次感谢!
是的。
这会不会是过拟合?我之所以这样问,是因为您建议通过开发一个更大的LSTM网络来提高结果质量。但如果在一个简单的LSTM网络中,参数数量已经超过了数据量,那么您不应该进一步简化网络吗?
非常感谢所有建议!
更简单的模型是首选,但过拟合仅发生在测试/验证数据的技能比训练数据差的情况下。
谢谢Jason博士,
如果我想输出一个训练模型下的序列概率,而不是找到最可能的下一个字符,该怎么办?
我设想的用例是输入测试句子,模型会打印出该句子在模型下为真的概率。
提前非常感谢。
那将是对问题的不同表述,或者你可以一步一步地收集每个字符的概率。
那么,当我在训练时,Xs也是类似的序列,但Ys会是什么呢?
谢谢!
序列中的下一个字符或单词。
如果我们这样做,那与最初的问题表述有什么区别?我的意思是,结果的概率将衡量字符X是下一个的可能性,而不是训练模型下已见序列的概率。
例如,如果我们用“I am”输入模型,下一个词是[egg或Sam]。根据上面的回复,输出将是egg或Sam成为下一个的概率。相反,我需要找到整个片段“I am Sam”和“I am egg”的概率,以便能够分辨哪一个更有意义。
是的,这是相同的问题表述。区别在于你如何处理概率。抱歉,我应该说得更清楚些。
例如,你可以通过每个单词/字符的概率进行束搜索,或者输出特定输出序列的概率,或者列出最可能的n个输出序列。
这有道理吗?
嗨,Jason,
感谢教程。当我使用one-hot编码的输入时,我的准确率和损失没有提高,并且停滞不前。
函数
def one_hot_encode(sequences, next_chars, char_to_idx)
X = np.zeros((n_patterns, seq_length, N_CHARS),dtype=float)
y = np.zeros((n_patterns, N_CHARS),dtype=float)
for i, sequence in enumerate(sequences)
for t, char in enumerate(sequence)
X[i, t, char] = 1
#print(i,t,char)
y[i,[next_chars[i]]] = 1
return X, y
X, y = one_hot_encode(dataX, dataY, char_to_int)
是层大小还是one_hot_encoding中的错误?
错误对我来说并不明显,抱歉。
也许这个想法列表可以给你一些提升模型技能的方法。
https://machinelearning.org.cn/improve-deep-learning-performance/
你好,感谢这个很棒的教程!
如果我从一个随机字符开始,然后使用训练好的模型来预测下一个字符,那么网络如何通过相同的第一个字符生成不同的句子呢?
它将预测所有输出字符的概率,你可以通过这些概率进行束搜索,得到多个不同的输出序列。
你好,
我正在尝试运行最后一个完整的代码示例,以使用加载的LSTM模型生成文本。
但是,第59行在整个1000个范围内只会产生相同的数字(实际上是一个空格字符)。
不知道我哪里做错了?
Sam,听到这个消息我很难过。
你尝试过运行几次示例吗?
你确认过你的环境是最新的吗?
我用不同的文本语料库做了实验:莎士比亚十四行诗,两个256个单元的LSTM层,以及20个epoch(可能需要更长时间)。我发现你帖子中那种只选择最大输出的下一个字符的方法,很快就会产生非常重复的文本——相同的两行在一段时间后会重复,像这样
Seed
“raise is crowned,
but those same tongues that give thee so thine own,
in other accents do this p ”
oor so me
the world with the shee the world with thee,
the world with the shee the world wour self stolne,
the world with the shee the world with thee shee steel.
12
the world with the the world with the dearty see,
the world with the shee the world with thee wour self,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with the shee the world with thee shee shee,
the world with the shee the world wour self so bear,
the world with t
但是,如果你通过随机抽样预测概率分布来引入一些随机性,你就能得到更有趣的结果——尽管是胡言乱语,但有很多可发音的胡言乱语的单词——而不是随机选择的单词,而且整体效果看起来像是中世纪英语,甚至在某些地方像德语。随机性意味着有时它不会将换行符放在大致正确的位置。尽管如此,这是一个非常有趣的结果,而且它不会循环。
我喜欢它把十四行诗的编号放在正确位置的方式!
Seed
“nd s to the course of alt’ring things
alas why fearing of time’s tyranny,
might i not then say ‘ ”
to sof bn bde,
the iroelge gatesds bever neagne brmions
ph puspper stais, delcs tien love ahena,
thich thi derter worndsm hin fafn’sianlu thee
shese blunq so me for they fadr mnhit creet.
64
cscv thy swbiss io ht the yanjes sast,
mftt pwr thet thai, io mengdvr to mehpt
nadengoes’dflret, acseriog of shein puonl.
to slobn of wourt)s fron shy fort siou mavt dr chotert fold (mn heart oo shoedh stcete,
that hil bu toun fass rrunhng of aeteinen
rie trilg mf prinlenlss, and ge voids,
batse mi tey betine out le il your wou,
these own taref in formuiers wien,io hise)
h eaar nonlhng uhe wari her bfsriite,
ming oat,s al she wantero wo me.
96
theteeo i fave shee wout fnler fiselgct
sreanind,
whthsu doom that brss nn len; a
tekl of me
tr pfngslcs,tien gojeses tore dothen,
o beau aal wierefe, oo ttomnaei ofs.
au in doace fiasss eireen thae despered,
thv urut ninyak wtaprr’ and thereoo dlg hns
cooh,
afaonyt o
附言:这只是为了测试——我真的想生成合成时间序列数据,但我发现仅仅预测下一个值然后生成性地运行总是会导致衰减到恒定值。
附言——粘贴到这个博客上时,十四行诗的编号放错了位置,位于行首。在生成的文本中,十四行诗的编号是居中的,即前面有一定数量的空格,如原始文本中的一样。
非常好,感谢分享。
也许你可以使用束搜索来更好地采样输出概率,并获得一个最大化似然性的序列。
这听起来是个好主意,而且也适用于我的目标——生成合成传感器数据。
很高兴听到这个,Iain。
嗨,Jason,
感谢您在深度学习方面的出色工作。
我正在我的机器上运行你的代码,它抛出了一个hdf5错误。
File “C:/Users/CPL-Admin/PycharmProjects/Tensor/KerasCNN.py”, line 59, in
model.load_weights(filename)
File “C:\Users\CPL-Admin\AppData\Local\Programs\Python\Python36\lib\site-packages\keras\models.py”, line 707, in load_weights
f = h5py.File(filepath, mode=’r’)
File “C:\Users\CPL-Admin\AppData\Local\Programs\Python\Python36\lib\site-packages\h5py\_hl\files.py”, line 269, in __init__
fid = make_fid(name, mode, userblock_size, fapl, swmr=swmr)
File “C:\Users\CPL-Admin\AppData\Local\Programs\Python\Python36\lib\site-packages\h5py\_hl\files.py”, line 99, in make_fid
fid = h5f.open(name, flags, fapl=fapl)
File “h5py\_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper
File “h5py\_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper
File “h5py\h5f.pyx”, line 78, in h5py.h5f.open
OSError: Unable to open file (unable to open file: name = ‘weights-improvement-47-1.2219-bigger.hdf5’, errno = 2, error message = ‘No such file or directory’, flags = 0, o_flags = 0)
看起来文件或路径不存在。
也许检查一下该文件是否存在于当前工作目录中。
感谢这篇有趣的帖子。我遇到了和Vibhu完全一样的错误。当你说工作目录时,你指的是代码所在的目录吗?在包里?
你正在工作的目录,也就是你保存代码文件的目录。
你好。
我目前正试图将你使用字符作为信息单元的过程,转换为一个我使用单词作为信息单元的系统。我目前正在涉足神经网络领域,我想弄清楚为什么我会得到一个重复的单词序列而没有任何变化,而且我可能有一些线索。
– 类太多?用字母的话,我们大约有30个类(因为我们有字母表+剩余的撇号/反撇号)。这是否真的对学习和生成有影响,导致出现这种重复的结果?
+ 马尔可夫链的一些概念仍然留在我的脑海中,我有一个假设,为什么系统在这种情况下会重复:也许单词之间的联系不够明显,以至于生成器除了提供给它的之外,无法选择其他任何东西?
– 参数错误?我尝试了学习过程的多种设置,例如将seq_length更改为10或50或别的什么,以及/或者更改批次大小?
– 语料库太小?我应该再找些书吗?
– 训练时间太短?60个epoch是相对较短还是重要过程?
– 注意:我目前正在使用一个集合来移除重复的序列,一旦文本被标记化。当seq_len很小时,它确实有帮助,我认为它对基于字符的处理也有帮助。这会增加额外的初始化开销,但我认为这是值得的。
我将代码复制到了这个gist中,以避免进一步弄乱评论日志:https://gist.github.com/anonymous/28f30611bb0849ef0d99fd341e6e1d7b
感谢这篇文章,它非常有趣,让我学到了很多我忘记或不理解的概念。我期待学习更多并理解如何进步!
祝你有美好的一天!
做得好,我建议测试每种假设。
我们能否将每个单独的单词映射到一个数字,而不是字母?然后我们可以使用几个单词的上下文来预测下一个单词。
所以我们可以把[“I”,”am”,”a”]作为输入,把[“human”]作为输出。
我还在学习一些概念,所以可能是我错了。
当然!
书籍文本链接已失效。新的位置似乎是:http://www.gutenberg.org/files/11/11-0.txt
算了,我完全错了。请删除。
你可能需要访问链接两次来设置/使用cookie。
只是想说你是一个了不起的人,你让很多人能够学习复杂的材料,否则他们可能无法做到。我也对你回复每一个评论的奉献精神感到震惊,而且回复速度很快。你让世界变得更美好。
谢谢你,Ari,我非常感谢你的支持和认可!
你好,Jason,非常感谢这篇很棒的帖子!
我在同一本书(wonderland.txt)上运行了你这个小型LSTM网络的完全相同的代码。
运行了20个epoch。
但是我在这一行遇到了一个错误:
“model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]))) ”
错误是:
“TypeError: Expected int32, got list containing Tensors of type ‘_Message’ instead.”
你能否给我一些关于为什么会发生这种情况以及如何解决的见解?
非常感谢!
Tensorflow: 0.10.0rc0
Keras: 2.1.1
抱歉,我以前没有见过这个错误。
也许可以仔细检查一下你是否从示例中复制了所有代码?
你好 Jason,
我一直在看LSTM文本生成的例子,我有一个问题:
一旦网络被训练,并且所有权重都被固定在某个可接受的值上,网络在每次输入相同的种子文本(例如,“What would happen”)时会生成不同的文本吗?或者,对于相同的输入种子,输出文本序列是否总是相同的,因为序列“What would happen”之后具有最高概率的下一个字符会因为网络的固定权重而在每次运行时都预测为相同,然后将前一个预测的字符追加到输入中,依此类推?
我正在Tensorflow中为序列标注问题开发一个类似的LSTM网络,到目前为止,看起来我的生成输出序列对于固定的起始输入总是完全相同的。有什么方法可以为相同的输入种子生成不同的输出序列吗?
一旦网络被训练,它就会做出确定的预测。
感谢你的回答。我想我描述的是一个随机神经网络。
嘿,Jason
我可以问一下为什么你使用归一化的X向量作为输入而不是one-hot编码的输入吗?也有其他人这样做吗?只是好奇,因为我真的没看到与one-hot编码相比有什么优势。
如今,我建议使用one-hot编码。
你能提供你的预训练权重吗?
是的,你可以使用预训练权重。
我们不应该使用word2vec代替one-hot编码吗?
你可以的,试试看。
嗨,Jason,
感谢这篇很棒的文章。您是否有使用LSTM作为遗传编程的模型来进一步改进输出的经验?或者您听说过吗?那将类似于EDA-GP。如果您知道任何关于它的信息,我很乐意您告诉我!
提前感谢!
大卫
我没听说过将LSTM与GP结合使用。这是个有趣的想法。
是什么让你想探索这种组合?
哦,我只是好奇。我最近看到了一些其他的文本生成工作,他们实现了与你的方法非常相似,但他们得出的结论是,未来可以通过使用LSTM作为遗传程序模型来改进,以增加更多的约束,从而改进输出。我只是想知道是否已经实现了类似的东西。昨天我偶然发现了一篇非常有趣的论文。(https://arxiv.org/pdf/1602.07776.pdf)他们发明了一种新方法:递归神经网络语法(RNNGs)。他们在语言建模和解析方面都报告了重大改进。我可能会尝试这个,作为我硕士论文的一个主题。
感谢您的及时回复!
新年快乐!
大卫
看起来很有趣,感谢分享。
嗨Jason,感谢您的精彩网站和您提供的所有材料。
我一直在尝试修改LSTM来预测单词而不是字母。我从文本中去除了所有特殊字符和数字,并将单词向量化。总共有26386个单词,2771个不同的单词。模型可以被训练,但它总是只预测单词“the”作为下一个单词。我尝试了简单模型和复杂模型不同的序列长度,但结果不变。虽然“the”是最常见的词,有1600次出现,但模型难道不应该仍然能够预测其他东西吗?或者语料库太小了?你觉得呢?
这篇帖子有一个基于单词的语言生成器的例子。
https://machinelearning.org.cn/develop-word-based-neural-language-models-python-keras/
嗨,感谢提供的好内容,我有一个问题。
使用RNN能否生成类似的句子?
例如,种子句子:“The rabbit-hole went straight on like a tunnel for some way”
生成几个类似的句子
” The rabbit is go straight on like a tunnel”
” The rabbit hole went straight”
“The rabbit straight for some way”
我不关注句子的语义,只需要生成训练数据并进行标记,以解决其他文本领域问题。
是的,多次生成,或者生成一次然后使用束搜索来读取多行输出。
这个教程对我帮助很大。谢谢。但是关于深度学习我有一个问题。由于深度神经网络需要大量时间来训练,我该如何轻松地调整模型的不同超参数?
你可以使用云中的多台计算机并行执行参数调优。
你也可以尝试使用较少的数据进行调优,这样训练时间会更短。但这可能会影响结果的质量。
谢谢,杰森。
嗨 Jason,非常感谢您的博客。它非常易于理解,并且真正巩固了理论方面的内容。我最近才接触RNN,而且很惊讶它们如此有效。它们似乎也用于音乐音符生成。
我正在阅读你的改进部分,我不太明白你的意思
‘在填充后的句子上训练模型,而不是随机的字符序列。’
你的意思是将文本分割成句子,然后用零填充每个句子以匹配最长的句子吗?
是的,正是如此。
由于你使用了100个字符来预测下一个字符,我想知道是否有任何方法可以去除这个限制。我希望用户能够输入任何长度的句子并使用它来生成句子。谢谢。
除了填充句子之外,还有其他方法吗?我真的不想这样做。
你可以填充然后使用掩码来忽略填充。
你也可以改变模型使其一次处理一个时间步,并手动重置状态。
当然,您可以按任何您喜欢的方式配置它。模型需要针对您的具体框架进行调整。
你好,Jason。感谢您这篇精彩的博文。
顺便说一句,当我运行这段代码时,我收到了一个ValueError消息。
它说:“ValueError:您试图加载一个包含3个层的权重文件,但模型只有2个层。”
我以为我运行的代码和您的一模一样,但却收到了这样的消息。
是我做错了什么吗?
不用了。我弄错了。问题解决了。
很高兴听到这个消息。
听到这个消息我很难过,我没见过这个错误。也许API已经改变了?
你是怎么解决的?
你好 Jason,
当您将输入序列转换为 [samples, time steps, features] 的形式
使用 X = numpy.reshape(dataX, (n_patterns, seq_length, 1)) 时,为什么 features 等于 1? 我原以为它会等于字符的数量
因为我们提供的是一个整数序列。
在使用我自己的数据进行训练时,我注意到大约25个 epoch 后,损失开始增加。我尝试添加一个 batchnorm 层,但它没有多大作用。有什么想法吗?
这可能是100件事中的一件。看看这篇帖子,里面有一些想法。
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨 Jason
这是一篇很棒的文章,我是神经网络的新手。我完全实现了您的代码。运行了20个 epoch。但是,在打印下一个预测的字符时,它只是反复重复同一个字符。我打印了预测矩阵(在 argmax 行之前)并检查了,发现预测矩阵对于每个预测都有相同的数值顺序。您认为是什么出了问题?
[[ 1.91119227e-08 1.16459273e-01 1.62738379e-05 2.84793477e-19
3.71392664e-26 1.29606026e-25 8.98123726e-28 1.22408485e-12
4.26335023e-27 1.49551446e-13 6.07275735e-24 7.06751049e-01
1.82651810e-10 4.56609821e-04 7.45972931e-19 1.12589063e-25
8.50236564e-26 4.02262855e-25 4.94167675e-24 2.13961749e-23
1.36306586e-25 2.24255431e-25 1.49555098e-25 7.40160183e-24
4.36129492e-25 2.62904668e-05 6.99173128e-08 1.21143455e-06
4.55503128e-20 1.59668721e-27 2.71070909e-24 9.95265099e-24
1.40039655e-11 2.50412119e-15 8.04228073e-11 5.80116819e-07
1.76183641e-01 7.31929057e-13 4.60703950e-06 1.45222771e-06
1.41010821e-06 8.60679574e-17 5.74646819e-09 3.02204597e-07
8.52235157e-11 7.89179467e-05 1.59914478e-07 3.00487274e-10
1.23463905e-19 5.40685824e-06 5.15879286e-08 5.95685590e-09
1.24319504e-05 5.76499569e-14 1.03425171e-14 1.20372456e-15
7.63502825e-08 6.09846451e-10]]
11
,[[ 1.80287671e-07 2.36380938e-02 2.51635304e-03 4.06853066e-14
1.85676736e-18 1.52850751e-17 6.71450574e-21 5.60100522e-10
1.99784797e-20 1.19577592e-09 7.35863182e-18 9.02304709e-01
4.51892888e-08 1.19447969e-02 2.06239065e-13 9.34988509e-19
2.99471357e-19 3.93370166e-18 9.95959604e-17 1.55780542e-16
3.49815963e-18 8.74736384e-18 1.30014977e-18 8.46453788e-17
5.59418112e-18 3.94404633e-03 1.59909483e-04 5.36000647e-04
8.32731372e-14 2.82467025e-20 2.60687211e-17 3.69919471e-17
2.15683293e-09 3.75411101e-13 1.86202476e-09 2.00714544e-06
5.37619703e-02 6.46848131e-10 4.58007389e-06 1.08297354e-05
1.26086352e-05 1.41199541e-12 3.86868749e-07 4.80629433e-06
1.67563452e-09 4.32701403e-04 3.21613561e-06 2.57872514e-08
1.72215827e-15 7.51974294e-05 1.74515321e-07 1.23122863e-08
6.45807479e-04 5.92429439e-11 6.11113677e-12 5.76062505e-12
8.02828595e-07 6.99018585e-07]]
11
该算法是随机的,所以每次运行时可能会得到不同的结果。
也许可以尝试拟合模型几次?
嗨,Jason,
我执行了代码。构建模型没有问题。但是在使用模型时出现了一个错误
ValueError: Dimension 1 in both shapes must be equal, but are 60 and 47 for ‘Assign_5’ (op: ‘Assign’) with input shapes: [256,60], [256,47]。
错误发生在代码行
# load the network weights
filename = “weights-improvement-20-1.9161.hdf5”
model.load_weights(filename)
model.compile(loss=’categorical_crossentropy’, optimizer=’adam’)
当然,weights-improvement-20-1.9161.hdf5 是我的文件。
也许可以先测试一下预测,然后再保存,然后使用相同的代码加载,这样您就知道它是否有效。
这是由于 weights.hdf5 文件与存储库中的新数据不兼容造成的。我已经更新了存储库,现在应该可以正常工作了。
index = numpy.argmax(prediction) 只输出最大值 1。当它将索引值转换为字符,即 int_to_char[index] 在字典 int_to_char 中,键 1 是换行符。我该如何解决这个问题?
在较小的数据集上工作会引起所有这些问题。当我使用较大的数据集进行训练时,它确实开始产生文本。感谢 @Jason 的这篇博文:)
干得好!
也许模型需要针对您的问题进行进一步的调整?
为什么您没有将批大小(64)分配给序列大小(100)?
我仍然不理解序列和批次在不匹配时如何工作。
一个批次由许多序列组成。
一个序列是一个样本或一个时间步的列表。
这有帮助吗?
您的帖子和您对评论的细致回复都很棒。非常感谢。
我用单词而不是字符训练模型取得了一些成功。我认为用合成特征(例如词性)来增强每个单词会很有趣。但是,我无法理解如何正确地做到这一点?在我看来,可能需要一个带有词性标注的第二个稀疏数组。也许这个变量会给它一个某种权重。这有意义吗?Keras LSTM 模型可以实现这一点吗?
是的,这很有意义。输入会很混乱,难以理清。
分开输入流并使用多输入模型可能会更容易。只是一个想法。
https://machinelearning.org.cn/keras-functional-api-deep-learning/
如果您走这条路,我很想听听您的进展。
谢谢您的回复。我会在此基础上进行工作,并一定会分享结果。我还有一些其他的推测性特征想尝试。
告诉我进展如何。
嗨,Jason,
如果我们有100万个单词需要预测,我们是否仍然应该使用one hot encoding和softmax作为输出层?这可能会导致内存问题。有什么方法可以解决这个问题吗?
谢谢,
雷
好问题。
我见过一些论文研究将大的one-hot编码向量分成多个部分。也许可以尝试在Google Scholar上搜索一下?
我不确定这段代码如何工作?
seq_length = 100
n_patterns = len(dataX)
print “Total Patterns: “, n_patterns
# 将 X 重塑为 [样本,时间步长,特征] 的形式
X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
这不应该会出错吗?
您可以在这里了解更多关于列表和重塑的信息。
https://machinelearning.org.cn/index-slice-reshape-numpy-arrays-machine-learning-python/
先生,感谢您提供的精彩教程,这些教程真的很有帮助……
先生,从一组关键词生成句子的过程是怎样的……我拥有以下数据……
“no_result, sorry, suggest”
根据这些我需要生成一个像下面这样的句子
“Hi…I checked a few options for you, and unfortunately, we do not currently have any trips that meet this criteria. Would you like to book an alternate travel option?”
谢谢
好问题,我没有处理过这类问题。也许可以调研一下文献,看看您有什么选择?
在哪里以及如何更改“温度”,即比例因子?
你具体指的是什么?
你好,
我目前正在做一个项目。这个想法是从特征和关键词生成产品描述。
我的学习基础是一组产品描述。
我想给我的模型一些特征、关键词,让它从中生成描述。
例如
特征:“冰箱、博世、美式、不锈钢、2个抽屉、531L、2个蔬菜托盘”
生成:“我们的专家为您挑选了博世冰箱:一款美式不锈钢冰箱,物有所值。这款产品总有效容积为531升,非常可观。它拥有2个抽屉和2个蔬菜托盘,可以存放最多的新鲜农产品。”
哇,很棒的问题!
第一步是准备成千上万的例子,以某种方式。
你好!
我正在尝试做类似的事情,您找到方法了吗?
可以使用 Seq2Seq 模型来完成这个任务吗?
您花时间回复每个问题,这真的很棒。在当今世界这是很不寻常的。
谢谢。
嗨,Jason!
您为什么没有使用任何验证集或测试集?不使用任何验证集或测试集是否是一个有效的论点,因为我只想根据训练数据本身生成文本?假设我想根据所有哈利波特书籍生成文本。我只想根据我的模型已经学习和知道的内容来生成文本、单词、短语、句子,因为验证集和测试集只是用来验证您训练好的模型可以对未知内容进行分类和预测,所以它们已经没有用了?
测试一个应该生成新的/不同但相似的输出序列的生成模型是一个挑战。
您好,非常棒的教程。我想知道预测时 x 是什么?预测时我们输入什么?
这取决于模型的定义方式,例如模型期望的输入是什么。
在本教程中,它期望一个包含100个单词的种子序列。
很棒的教程。使用one-hot编码的输入序列,可以在不到10个 epoch 内获得1.22的损失。
太棒了!
顺便说一句,主要是为了给其他读者,完成这个的代码很简单。只需替换以下几行:
X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
X = X / float(n_vocab)
用
X = [e for lst in dataX for e in lst]
X = np_utils.to_categorical(X)
enc_length = len(X[0])
X = numpy.reshape(X, (n_patterns, seq_length, enc_length))
别忘了在文本生成部分也这样做,在生成种子的 one-hot 编码时,使用 enc_length 作为第二个参数。
另外,不一定要从实际数据中获取种子。您可以像这样构造种子/模式
in_phrase = ‘her name was ‘
in_phrase = [char_to_int[c] for c in in_phrase]
pattern = list(np.ones(100 – len(in_phrase)).astype(int)) + in_phrase
再说一遍,这是一个非常有趣且直接的例子。谢谢 Jason。
很好,谢谢分享!
感谢您提供的精彩教程。我不太明白为什么您只对输出字符使用 one-hot 编码?为什么例如您不使用整数编码作为输出模式,即使这样它也会计算输出概率?
输入使用了整数编码,并直接传递给了 LSTM。
我还有另一个问题,我们可以使用 word2vec 代替将字符转换为整数然后进行缩放吗?或者它将不再是字符到字符的模型?
也许吧,我还没见过字符的嵌入模型,但我敢打赌有人尝试过。
你好 Jason,
我已将您的代码改编到 kaggle.com 上,以尝试拟合莎士比亚戏剧的 project gutenberg txt 文件,并提到了您和本网站。
谢谢,干得好!
您好,感谢您的博文!
我创建了这个模型并在一个不同的数据集上进行了训练。结果是序列无限循环重复。您能分享一些见解吗?
也许模型过拟合了?
也许尝试再次拟合模型?
当我尝试运行最终的完整代码时,它显示了一个错误,说我试图加载一个包含2个层的权重文件到一个具有3个层的模型中。
我没见过这个,您确定您复制了所有代码而没有修改吗?
您确定安装了最新版本的库吗?
int to char 抛出错误
我用 utf 8 编码了文件。
我在这里有一些建议
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
result = int_to_char[index] 我在运行最终代码中的这一行时出错
当我运行最终代码时
我像这样读取文件
raw_text = open(filename,encoding=’utf-8′).read()
您能否确认您的所有库都已更新,并且您从教程中复制了所有代码?
是的Jason,但是在转换成字符的 result 行出现错误,值为 3425。
你好,先生。这与本帖无关,而是与您关于RNN的帖子有关。我读了您关于RNN及其权重如何生成的帖子。那么,我们如何得到 WHy 矩阵呢?对于 WXy 矩阵,我们进行初始化。但是对于 WHy 矩阵,我不明白。您能帮帮我吗?
什么是“WXy?”
您是如何确定隐藏层为 256×256 的?
我问这个问题是因为我想保留大写字母,而我学习的词汇量已扩展到132个字符。在此过程中,我将损失降低到1.3,但生成的文本仍然有很多拼写错误。
如果我增加 LSTM 层的神经元数量,机器人能否改进?有多少个神经元?
或者让网络在当前的 256×256 网络上训练到更低的损失会更有益吗?
反复试验。
我建议测试一套配置,看看哪种最适合您的问题,更多信息请参见此处。
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
嗨,Jason,
正如您所提到的,我们还可以尝试其他 ASCII 数据,例如计算机源代码。
因此,我需要使用此帖子来创建一个程序修复模型。
输入将是错误的程序代码,输出将是修复后的程序代码。
我有一些易受攻击/有 bug 的例子及其修复方法,但我不知道如何生成数据集并进行训练。
请帮忙。
谢谢
听起来是个很酷的项目。
抱歉,我没有用 LSTM 修复错误代码的例子,也许将来会有。
你好。感谢您的这篇博文。我有一个问题。为什么您没有为每个时间步提供输出标签?例如,当输入是‘HelloWorl’时,输出是‘elloWorld’,如果我们使用9个时间步。对于您的例子,每个样本只有一个字母。那么在训练期间,您将如何为时间步提供相应的输出?
谢谢
我不确定我是否明白,抱歉?
嘿 Jason,看看我写的一篇博文,它借鉴了您的一些方法!
这篇博文太棒了!
http://overslant.com/2018/07/22/deep-nba-nicknames/
谢谢。
嗨,Jason,
感谢您提供的精彩文章。它让我豁然开朗……哈哈。
不过我有一个问题。我不太理解“生成 LSTM 网络文本”部分完整代码清单第 65 行的必要性
seq_in = [int_to_char[value] for value in pattern]
seq_in
被设置了,但似乎没有被使用。如果它没有被使用,您可以忽略它,删除这一行。
你好…… Jason
请提供运行 3D-Unet-Pytorch 进行 2D/3D 图像分类所需的笔记本电脑的最低规格(内存、处理器等)信息。另外,我能否尝试使用 MINST 数据集进行 3D 图像分类?
谢谢。
此致,
Verdy
您可以在 CPU 上进行训练,或者在需要访问 GPU 时使用 AWS。
我在这里解释了如何操作
https://machinelearning.org.cn/develop-evaluate-large-deep-learning-models-keras-amazon-web-services/
我用与您相同的代码训练了模型,但在测试时遇到了这个…
ValueError: You are trying to load a weight file containing 1 layers into a model with 2 layers.
您知道是什么问题吗?
我在这里有一些建议
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
输入序列和 LSTM 的大小应该相同,例如,这里因为样本输入是 100 个字符,所以 LSTM 应该也设置为 100 而不是 256。
第一个隐藏层的节点数与单元数(由 input_shape 定义)无关。
您是如何决定隐藏单元的数量的?我们可以使用 128 而不是 256 吗?
反复试验。
在这里了解更多
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
Jason,您好,一如既往地精彩教程!
我尝试在 Kaggle 上运行此代码,训练效果很好,保存了权重。但是,在生成过程中,我遇到了一个错误,并且似乎无法确定原因。
“—————————————————————————
KeyError 回溯(最近的调用在最后)
in ()
79 prediction = model.predict(X, verbose=0)
80 index = numpy.argmax(prediction)
—> 81 result = int_to_char[index]
82 seq_in = [int_to_char[value] for value in pattern]
83 sys.stdout.write(result)
KeyError: 2463279”
很抱歉听到这个消息,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
嗨,Jason,
好文章!
我只是好奇这里实现序列挖掘用例的可能性。
我们能否为序列挖掘使用生成式 LSTM 网络?目的是抑制事件。
我有一个包含 200 万个事件序列的数据集,其中包含根事件和子事件。我们需要根据根事件的存在来抑制所有子事件。这个模式需要由在整个数据 70% 上训练的生成式 LSTM 模型来捕获。然后将这个训练好的模型应用于测试数据 (30%) 以执行事件抑制,从而减少事件的总数。
谢谢,
Uday Vakalapudi
抱歉,我不知道什么是“序列挖掘”?
很棒的文章。它启发我思考解决方案的应用,所以,看看您对 LSTM 预测如下数组中下一个值的能力有什么看法:[5.3, 2.2, 3.1, 8.33, 2.32, 2.01, 4, 12.2, 12.2, 4, 4, 3, 2.30, 13.30…]?如果从这个角度看,它就像句子一样
– 前三个数字的连接方式如下:第一个数字是第二个和第三个数字的总和;
– 第四个数字与前面的数字无关,它是后面三个数字的总和;
…
对数组的总体结论:存在一些数字组,它们通过加法和减法的数学运算连接,但组之间没有连接,除了它们代表簿记中的期刊条目。
感谢您的帮助
这可能是可能的,也许可以尝试一下看看。
使用您的代码时我遇到了这个错误,您能提供任何帮助或建议吗?
https://i.gyazo.com/69b94f1f42990146b27050dd2459a3f3.png
您必须将文件名更改为代码中保存的文件。
我可能没有注意到这一部分,您能告诉我那是哪个文件吗?我没有看到关于保存文件的部分。
谢谢,我不小心漏掉了一部分,祝您有美好的一天,谢谢您的帮助!
不客气。
我是新来的,我能否使用这个模型来训练一个基于时间的文本文件集,然后预测未来时间点将生成的文件?
也许,您需要做一些实验来找到合适的模型。
您能推荐一些这样做的论文或文档给我吗?谢谢 Jason。
不,抱歉,也许可以在 scholar.google.com 上搜索一下。
您能推荐一些关于使用 LSTM 和 LDA 预测技术主题趋势的论文吗?我卡在这里了。非常感谢。
Jason,您好,我一直关注您的帖子,它们非常棒。但我正在尝试使用 tensorFlow 生成文本。
我使用 TensorFlow 的原始 RNN 代码训练了我的模型:https://tensorflowcn.cn/tutorials/sequences/recurrent#tutorial_files;但我不知道如何预测和测试我的模型。期待您的回复。
感谢您的出色工作!
抱歉,我没有 TensorFlow 的教程,我专注于运行在 TensorFlow 之上的 Keras。
谢谢!
不客气。
Jason,您好,感谢您提供如此精彩的教程。
不客气,我很高兴它有所帮助。
你好,
在此教程中,如果您一直训练直到获得非常好的准确率,例如 99%,这不就是记忆数据吗?最终目标是生成新的东西,对吗?
是的,其思想是拥有足够大的数据集或足够强的模型,使其无法被记忆。
嗨,Jason,
我看了您的教程并尝试了一下。
我现在正在使用一个不同的项目,我们希望将 LSTM 网络投入生产。
换句话说,我们有一个时间序列预测网络,并且希望将其部署到 AWS 或 Azure。我们也看到了 Tensorflow Serving 作为在线部署这些网络的一种方式。
我唯一担心的是 LSTM 的性能。
我来详细说明一下
在训练 LSTM 网络时,长期和短期记忆至关重要。权重也会得到调整,所以它们很重要。
如果我们像您在教程中那样保存模型,那么当我们尝试将测试种子输入其中运行时,我们是否仍能获得好的结果?
某些它从未见过的种子,例如某种用户输入?我担心它不会取得很好的结果,因为隐藏状态现在丢失了,而种子会产生新的隐藏状态,这些隐藏状态完全不同。
或者我完全错了?
提前感谢您花时间回复!
也许可以尝试使用最终模型的集成来降低方差?
也许在部署到生产环境之前(例如,良好的工程实践)为系统设计测试。
考虑使用一个变换,将一个单词(或几个单词)转换为一个二进制向量,多热编码。
现在,我想将二进制向量转换回原始单词(或单词)。
这是否可以使用 RNN/LSTM 完成?
当然,我可以使用训练集训练模型(给定单词及其对应的二进制向量),然后用预测的二进制向量对其进行测试,希望能够预测出正确的单词。
是的,计算每个向量的 argmax(),然后将整数映射到词汇表中的单词(反向查找)。
我相信我在许多教程中都有这方面的例子。
嗨,Jason,
是否可以使用 return_sequence=False 来生成序列?
也就是说,在训练中只有最后一个时间步被预测——生成会是什么样子?
谢谢
抱歉,我不确定是否理解您的问题,您能详细说明一下吗?
您可以根据需要构建任何序列预测问题,并测试 LSTM 是否表现良好。
在您的示例中,您使用了这行代码
model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]), return_sequences=True))
据我理解,return_sequences=True 意味着序列中的每个项目都会有一个输出(多对多),并且 Tx=Ty。如果 return_sequences=False,则序列只有一个输出(最后一个),并且只会在损失函数中计入。
那么,return_sequences=False 是否可以用于此类生成任务?
是的,但直接使用 LSTM 层的输出来进行预测时,结果会很差。最好使用一个或多个全连接层来解释 LSTM 的输出。
你好 jason,
感谢您提供信息丰富的教程。
我使用的是 python 2.7、tensorflow 1.12 和 keras 2.2.3
我遇到了以下错误:
maximum_iterations=input_length)
TypeError: while_loop() 收到意外的关键字参数 ‘maximum_iterations’
ERROR:tensorflow:==================================
Object was never used (type )
抱歉,我没见过这个错误。也许可以尝试在 stackoverflow 上搜索/提问?
嗨,Jason,
感谢您的教程。
我正在重新利用这个模型来生成 SMILES 字符串,它们是药物和分子的字符表示。
它们看起来像这样
Nc1nc(Nc2ccc(cc2)S(N)(=O)=O)nn1C(=O)c1c(F)cccc1F
CO[C@H]1[C@H]
我已经训练了模型并保存了权重。
现在我如何让模型生成可变长度的 SMILES 字符串?
谢谢,
约翰
也许可以在零填充但可变长度的内容输入上训练模型,这些输入有一个“字符串结束”字符(例如,像句号一样)。然后生成新序列,并在遇到该字符时停止。
这有帮助吗?
嗨,Jason,
感谢您的建议,但如果模型理解序列的结尾或结尾有特定模式很重要,该怎么办?
抱歉,我不明白,具体有什么担忧?
Jason Brownlee,您好。
感谢您对文本生成精彩的解释,并提供附带逐点解释的代码。
不客气,我很高兴它有所帮助。
我正在运行这个模型(简单的 LSTM),但是使用了您称之为庞大数据集的文件。一个约 3.5 亿字节的文件,包含如此多的信息
muiruri_samuel@instance-1:~/rap-generator$ python new_model.py
使用 TensorFlow 后端。
(‘Total Characters: ‘, 307478020)
(‘Total Vocab: ‘, 177)
Killed
顺便说一句,我正在一个拥有 120 GB RAM 的 Google Cloud 实例上运行它,但它耗尽了所有内存。
这是到目前为止的文件 https://bitbucket.org/muiruri_samuel/rap-generator/src/master/new_model.py
我曾考虑过只在包含 100 万行文本的文件上训练,这变成了 10 个较小的 30 MB 文件,但我想知道是否可以知道主文件(lyrics.txt)需要多少 RAM,以及我是否可以使用批量方法,例如使用较小的文件和某种 fit_generator 方法来使其工作。
您可以根据字符数和 8 位或 16 位编码的选择来估算 RAM。
也许渐进式加载和自定义数据生成器是可行的方法?
嗨,Jason,
这是一篇非常棒的文章,感谢分享。我有一个不同的问题需要解决,想知道是否可以使用您的解决方案。
我有一个数值数据(结构化)的语料库以及相应的文章(可读文本)。也就是说,一个简单的包含数字的表格和一个解释表格的段落。如何使用这个数据集来训练模型,然后根据任何表格形式的输入来生成段落?
Sanjeev
哇,这是一个很棒的问题。
尝试一个可能使用 MLP、CNN 或 LSTM 来读取数字的模型,然后使用解码器来输出文本——也许一个输出表格,一个输出文本。
你好 Jason,
感谢您写下如此精彩的文章。我完成了一个完整的 TensorFlow 版本。
如果您能写一些关于 BERT 和 GPT 的博客就好了。
非常赞赏您为 AI 社区所做的工作。
此致,
LK
很棒的建议,谢谢。
Jason,您好,感谢您的教程。
您能否为我阐明一下我应该如何处理以下问题?
我有一组词。这些词可能拼写错误。
从这组词中,我想生成一个句子。
这组词的顺序可能(在大多数情况下)与句子的形成顺序一致,但可能缺少一些词。
例如:A dog is running behind a car. (原始句子)
word_set={‘a’, ‘dot’, ‘runni’, ‘ehin’, ‘ar’}
我在处理多种非英语语言,这些语言中没有词性标注器等工具。
对于一种语言,我有一些相当可观的语料库。而对于另一种语言,语料库非常少。
我需要使用这组词生成的句子可能存在于语料库中,也可能不存在。
(任何步骤或教程指南都将有所帮助)。
感谢您的时间。
我认为需要一些开发和原型设计——没有现成的分步教程。
也许您可以从相关的文本纠错论文中获得一些灵感?
我曾考虑过拼写纠错,然后是文本序列生成。无论如何,我会研究一下。谢谢!
您好,我想知道您对逐字母预测文本和逐词预测文本哪个更好的看法。
我正在尝试用意大利文写一个文本生成器,用《小王子》这本书,逐字母和逐词的结果都不同,但没有一个我喜欢。
逐字母我能得到更有全局意义的句子,但字母不正确。逐词则会得到不连贯的句子。
此致!
很好的问题。
我不知道,也许您可以设计一些实验来帮助区分原因和结果。
也许这与输入/输出的基数有限(字母与单词)有关。
嗨,很棒的博客,谢谢!
我参考了您的博客也实现了。我使用了莎士比亚的诗。
使用 30 个 epoch 和 64 个批次大小,我得到了“weights-improvement-30-1.4482.hdf5”
错误损失 1.4482
我有一个请求,您能否写一篇关于使用 Keras 的 RNN LSTM 进行推荐系统的博客?
再次感谢!
干得好!
感谢您的建议。
嗨,Jason,
在我找到的所有 LSTM 文本生成模型中,都有一个文本文件,它们正在预测下一个序列。在我的情况下,我有一个 CSV 文件中的输入列和输出列。对于特定的输入,我希望模型生成相应的输出。我该如何处理?以及涉及哪些预处理步骤?
您可以先将数据加载到内存中,然后按需处理。
我真的没明白。我所做的是,我将输入和输出列转换为两个单独的文本文件,分别对它们进行字符映射,然后根据序列长度取 X 和 y。但模型无法拟合。我遇到了输入样本数量不匹配输出样本数量的问题。
您能否详细说明需要执行的步骤。再说一遍,我有一个输入文本列和一个相关的输出文本列。基于输入序列,模型需要生成输出列的文本。
也许可以从教程中的代码开始,然后慢慢修改它以适应您的数据集?
嗨 Jason。不错的文本生成帖子。
我关于我正在进行的项目的几个问题
如何解析/处理结构化数据(数据框格式)用于文本生成,其中我可以将输出文本作为句子。例如:假设我有一个 CSV/Excel 格式的财务数据,一旦我将其加载到 NLP 中,我应该以叙述/句子的形式获得数据的洞察。
我知道这更多的是 NLG 任务,但我无法设置从解析数据到生成叙述的管道。
请帮助解决这个问题,或者至少给我一些技巧来开始我的项目。
我不确定,需要进行实验。
谢谢 Jason,这真是一篇很棒的文章!我修改了代码,将字符视为实际的单词,因为我的基础数据集非常小,大约有 200 个句子。我计划在 Github 上发布我的示例。您是否有特定的引用方式?
谢谢!
我想尝试这个例子。您提到使用 GPU,对于 2 个隐藏层的 LSTM,每个 epoch 大约需要 700 秒。如果您能给出粗略的估计,它需要多少秒(或小时)才能在 Intel i5 CPU 上运行?
对不起,我不知道。也许可以测试一下然后找出答案?
嘿,杰森,
为什么您使用种子句子(来测试模型)是从您用来训练/拟合模型的文本(语料库)中提取出来的?如果模型在训练数据中看到相同的字符序列,那么训练好的模型在测试时会产生相同的输出,这不是很明显吗!!!真正的测试应该是使用与语料库不同的句子,或者它没有那么重要吗???
这关系不大。
谢谢您的代码,先生
由于您的教程,我学到了很多关于神经网络的知识。
不客气。很高兴听到你这么说。
感谢这篇易于理解的文章。
不过有 1 个问题:一个改进建议是在可见输入层添加 dropout。
这是否意味着 LSTM 函数的 dropout 参数?
在第一个 LSTM 层之前,例如将 dropout 作为第一个隐藏层。
谢谢 Jason 的快速回复。但在 LSTM 层前添加 Dropout 没有看到任何改进。
在您的代码中,输入是 100 个字符的滑动窗口,输出是第 101 个字符。
现在,要在填充后的句子上训练模型,我已经将输入转换为 100 个单词的填充句子。但我该如何建模输入和输出?对于每个 100 个单词的句子,输出是第 101 个单词。有什么更好的方法吗?
您可能需要发挥创意,探索一系列想法,看看哪些效果最好。
这里的问题是:即使探索 1 个想法,也需要至少 50 个 epoch 才能看到其证据,每个 epoch 大约需要 12 分钟。所以我在问您是否有任何经验。
再次感谢您的精彩帖子和及时的回复。
意见没有帮助,因为模型和数据可以有很大的差异,我鼓励您进行实验。
也许您可以减小数据集或模型的大小以提高测试想法的速度?
先生,在 spyder 中它显示
无法打开文件(无法打开文件:名称='weights-improvement-19-1.9435.hdf5',errno = 2,错误消息='No such file or directory',flags = 0,o_flags = 0)
如何解决这个问题?
@jasonBrownlee,我们能否要求模型根据几个输入的关键字生成句子,而不是随机种子句子?
这将是一个不同的问题,例如,从关键字生成序列。
这就像文本摘要的反向操作。
Jason 兄弟,它在打印空字母。有什么建议吗?
也许尝试再次拟合模型?
嗨,非常好的网站!
我正试图通过学习我所做的所有游泳练习来生成游泳训练计划。我认为这个模型可以应用。您认为它可以改编吗?我现在有一个基础设置,可以提供一些结果,但我想为每个练习添加更多数据,例如时间。您认为我走在正确的道路上吗?
对不起,我不知道。也许可以实验一下看看能达到什么目标?
先生,如何确定正确的批量大小?
好问题,我建议测试一系列不同的批量大小,看看在您的具体问题上哪种效果好。
请看这篇文章
https://machinelearning.org.cn/how-to-control-the-speed-and-stability-of-training-neural-networks-with-gradient-descent-batch-size/
嗨,Jason,
我尝试运行第二个练习,进行 50 个 epoch,但在我的 PC 上它根本无法完成,它在 2 小时后崩溃。我甚至尝试在 AWS 机器(ml.m4.xlarge)上运行,但它也挂起。
您能否帮助我解决两个问题?
1.- 我需要在哪种类型的机器上运行练习?拥有 GPU 是否是强制性的?
2.- 您能否分享您获得的“weights-improvement-47-1.2219-bigger.hdf5”文件,这样我就可以用它来生成文本了。
提前感谢并致以问候,
不需要 GPU,但它有帮助。
抱歉,我无法分享训练好的模型。
嗨,Jason,
您能否向我解释一下,在计算损失函数后,哪些权重被更新了?例如,在 MLP 中,输入层的权重和偏差在网络计算结束时被更新,但在 LSTM 的情况下,如果我们有“内部”单元,哪些权重会被重新计算?
提前感谢,
是的,这是时间反向传播。您可以在这里了解更多关于它的信息。
https://machinelearning.org.cn/gentle-introduction-backpropagation-time/
谢谢你,Jason。
还有另一个问题,请🙂
我的笔记本电脑无法运行所有 epoch,所以,有没有一种方法可以加载最后一个 hdf5 文件并从中继续训练模型?例如加载第 10 个 epoch 的文件,总共 20 个。
提前感谢,
是的,您可以保存模型,然后稍后加载它并继续训练。
这会有帮助
https://machinelearning.org.cn/save-load-keras-deep-learning-models/
我可以使用相同的步骤和相同的代码来处理除英语以外的另一种语言吗?
我看不出为什么不。
嗨,我想通过 Seq2seq 学习进行表格到文本的生成,我该如何表示具有序列的表格数值数据?
也许一行一行或一列一列?
也许可以头脑风暴并测试问题的每种表述?
例如,关于天气的数据,如温度、湿度、风速等等,以及描述每个实例的相应文本。
为了构建模型,文本数据被转换为具有固定长度 L 的输入序列列表,并进行单字预测。
我们可以重复数值数据及其对应的序列作为模型的输入吗?
例如,数值数据是 37、40、20,相应的文本是“炎热且湿度适中”,可以表示为
X Y
37、40、20、炎热、-、- 和
37、40、20、炎热、和、-、的
37、40、20、炎热、和、的 湿度
37、40、20、和、的、湿度 是
37、40、20、的、湿度、是 适中
不,我不推荐这种表述方式。
嗨,Jason,
这篇文章真的很有趣。我读过几篇使用 LSTM 预测标点符号的文章。我想知道如何做到这一点?您能写一篇关于它的帖子吗?
谢谢。
也许是 seq2seq,文本输入文本,标点符号输出。
使用 TensorFlow 后端。
非法指令(核心转储)
听起来您可能需要重新安装 tensorflow?
嗨,Jason,
有趣的帖子,我试了您的代码,但是在 dataX 的 reshape 上遇到了一个错误。
(ValueError: cannot reshape array of size 167418 into shape (167418,100,1))
代码如下:
import gzip
import urllib
dataurl=”http://www.gutenberg.org/cache/epub/11/pg11.txt”
urllib.request.urlretrieve(dataurl, “wonderland.txt.gz”)
with gzip.open(‘wonderland.txt.gz’) as f
data=f.read()
chars = sorted(list(set(data)))
len_data = len(data)
print(‘Total Characters:’, len(data))
len_chars = len(chars)
print(‘Total Of Unique chars:’, len(chars))
#Converting the characters to integers
char_to_int = dict((c, i) for i, c in enumerate(chars))
SEQ_LEN = 100
STEP = 1
dataX = []
dataY = []
for i in range(0, len_data-SEQ_LEN, STEP)
input_chars = data[i:i+SEQ_LEN]
label_chars = data[i+SEQ_LEN]
dataX.append(char_to_int[char] for char in input_chars)
dataY.append(char_to_int[label_chars])
len_dataX = len(dataX)
print(‘Total Of dataX:’, len(dataX))
X = np.reshape(dataX, (len_dataX, SEQ_LEN, 1))
dataY = np_utils.to_categorical(dataY) # convert the target character into one hot encoding
很抱歉听到您遇到了这个问题,我这里有一些建议可能会有所帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
我读了您的书并提交了它的代码,这真的很棒。现在我想让您推荐一本我认为对这个领域有用的深度学习书籍。
谢谢。
您可以在这里查看全部 17 本书和图书组合的目录。
https://machinelearning.org.cn/products/
太棒了!我正在做一个 RNN(多对多)项目,其中输入文本句子的长度不等于输出文本的长度。您能否为我提供这方面的任何示例?
谢谢!
是的,您可以使用编码器-解码器模型。我有很多示例,从这里开始。
https://machinelearning.org.cn/start-here/#nlp
嗨 Jason。我遵循了您的指南(“开发一个小型 LSTM 循环神经网络”部分),但没有使用单个字母,而是使用了整个单词作为我的样本。我这样做的原因是我也准备了一些测试用例,我想在尝试使用 model.predict() 时使用它们。我遇到的问题是,网络总是建议使用标点符号(99% 的时间)。我的训练数据并没有充斥着标点符号,但确实标点符号经常出现在许多不同的词性之后,这对于我们人类来说并不奇怪。如果我故意从我的训练数据中删除标点符号,那么模型就会 95% 的时间建议使用介词。这看起来就像网络在给我展示最常用的词性,而不是猜测正确的词性。
我的训练数据序列长度是 10(单词),其中 1-9 是样本,第 10 个是输出。我大约有 50 万个样本。
您认为可能是什么原因导致了这个问题?
干得不错。
也许可以尝试此处描述的一些语言建模方法。
https://machinelearning.org.cn/start-here/#nlp
嗨,Jason,
谢谢
我开发了相同的模型(epoch=20),但模型正在预测一些重复的单词。
例如
模型的输入是:“For some minutes the whole court was in confusion getting the Dormouse turned out”
模型输出是:“for some minutes the whole court was in confusion getting the dormouse turned off the terms the mock turtle said the mock turtle said the”
为了解决这个问题:
我需要增加数据集并添加更多层和更多神经元吗?
Please suggest.
我尝试增加上下文窗口大小,但没有成功。
谢谢,
Dinesh
这可能会发生。
也许尝试再次拟合模型?
也许可以尝试调整模型的学习率或容量?
请帮我解决这个值错误
输入 0 与层 lstm_13 不兼容:预期 ndim=3,找到 ndim=2
也许将您的代码和错误发布到 stackoverflow。
亲爱的 Jason,
这是我第一次向您表达您为我们这些学习者所做的出色工作。您的工作的价值是无法估量的。
言归正传,我已开始研究 seq2seq 模型。在这方面,我遇到了您这篇文章,就像您的其他帖子和书籍一样。
我的问题是,训练 LSTM/GRU/任何 RNN,可以
i) 多对多:输入序列是 S[ t : t+N],输出序列是 S[ t+1 : t+1+N],其中 S[ t+1+N ] 是在最后一个时间步预测和生成的下一个字符。
ii) 多对一:正如您在这篇文章中提到的——输入是 S[ t : t+N ],输出是 S[ t+N+1 ]。
关于这两种训练程序,我感到很困惑——
a) RNN 是否默认总是将隐藏状态传递给它自己的下一个时间步?
b) 在此上下文中,“stateful”参数的目的是什么?
c) 是否有任何概念可以让我更新 LSTM 在每个时间步的初始状态?如果有,我该如何编码?
我期待您的帮助。
再次感谢您所做的一切。
是的。
更多关于 stateful 的信息
https://machinelearning.org.cn/stateful-stateless-lstm-time-series-forecasting-python/
无需手动更新状态,模型会处理。
嗨,Jason,
《爱丽丝梦游仙境》书籍的文本格式链接似乎是
http://www.gutenberg.org/files/11/11-0.txt
而不是
http://www.gutenberg.org/cache/epub/11/pg11.txt
并感谢您的文章:)
此致
Amal
谢谢。
有人能告诉我如何安装 NumPy 吗?我试过所有方法了!!!
本教程将向您展示如何设置工作站,包括安装 anaconda 中的 numpy。
https://machinelearning.org.cn/setup-python-environment-machine-learning-deep-learning-anaconda/
(1) 我想知道如何将此示例扩展到多对多模型,或者您能否链接到您在此网站上涵盖的任何文章。
(2)
在您针对第一个通用模型的第一行代码的第 33 行,您有,
X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
这个 1 是否对应于您正在预测的字符数,即 num_features = num_predictions,如 CHAPT -> E?
如果我们将其扩展到 2,即 CHAPT -> ER,会怎样?
我尝试扩展您的代码以适应这些更改,例如这一行。
seq_out = raw_text[i + seq_length: i + seq_length + 2]
但问题是我们不能从序列中创建分类变量,因为这会导致“ValueError: setting an array element with a sequence。”
源代码:https://pastebin.com/dTu5GnZr
(3)
from keras.utils import to_categorical,适用于截至 2020 年 7 月的最新 keras。
这里的例子可能会有帮助
https://machinelearning.org.cn/?s=word+embedding&post_type=post&submit=Search
最终的维度是特征的数量,即1,因为它是一个字符序列。在此了解更多信息
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨
我可以使用LSTM为特定材料类型生成数据曲线吗?如果可以。我该如何做?
也许,您需要进行实验,看看它是否合适/可行。
嗨,Brownlee先生,
一如既往地感谢您的精彩教程。
我有一个问题
在您的模型中,它根据输入序列学习一个字符
CHAPTE->R
当我查看TensorFlow文档中的文本生成教程时,有一个如下所示的映射。基本上,在每个时间步,输入是当前字符,标签是下一个字符。在预测阶段,仅考虑最后一个时间步的输出。
CHAPTE->HAPTER
您认为哪种方法比另一种更好?
是的,有许多不同的方法。
也许采用最适合您特定应用的方法。
非常感谢您,先生。
不客气。
我通过查看您发布的材料学到了很多。
但是有一个问题。
在最后一个“更大的LSTM递归神经网络”部分0中,由于变量形状(256, 58)和值形状(256, 44)不兼容
由于数据数组不匹配,它无法工作。您能否告知我什么样的数据材料适合您,或者如何更改它?
您也可以通过电子邮件回复至qwqw8919@gmail.com。
也许这些建议可以作为第一步有所帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
你好,Jason!
太棒的帖子!
很喜欢!
我在尝试在本地执行时遇到了一些问题。
我的数据集是9GB。在尝试在超级计算机上运行时。
Python程序在shell中运行内存不足。
您能否建议我如何将迭代器/生成器与此脚本一起使用以处理大型数据集?
谢谢!
也许可以尝试使用渐进式加载,例如,不要将所有数据加载到内存中,只加载您需要顺序加载的部分。
请分享代码 -
1.
如何使用LSTM进行形态分析
2.单词生成
感谢您的建议。目前还没有这些的现有代码。
你好 Jason,
这是一篇有用的文章,而且我认为从其他评论中可以看出,这篇文章写得很好且很有用。继续保持良好的工作。
嗨Jason,我运行了这里提供的代码,但遇到了这个错误。
无法打开文件(无法打开文件:名称=“weights-improvement-47-1.2219-bigger.hdf5”,errno = 2,错误消息=“没有这样的文件或目录”,flags = 0,o_flags = 0)。
可能是什么问题?。抱歉,如果这是一个非常天真的问题,但我对此是新手。希望能尽早回复。谢谢。
嗨Adam…这个错误发生在文件名路径未正确指定时。下载文本文件时,请注意您将其保存在计算机上的哪个位置。下面的示例显示了存储在“filename”变量中的路径名。
filename = “c:/temp/wonderland.txt”
raw_text = open(filename, ‘r’, encoding=’utf-8‘).read()
raw_text = raw_text.lower()
如果您有任何其他问题,请告诉我。
此致,
这篇文章非常有信息量,而且评论也很有趣。谢谢。
感谢您的反馈和好话。不客气!
嗨,Jason,
这段代码在我的文本生成项目中帮助了我很多。但是,我想将生成的输出保存起来,而不是打印出来!有没有什么方法可以将生成的文本保存在另一个变量中?
嗨Amulya…以下内容可能会让您感兴趣
https://www.geeksforgeeks.org/saving-text-json-and-csv-to-a-file-in-python/
https://wikibooks.cn/wiki/Python_Programming/Variables_and_Strings
您好,非常感谢您提供如此出色的教程。
我该如何改变您建议的作为可能扩展的Softmax激活函数的温度?
您好,感谢您提供如此清晰且有帮助的教程。
我尝试使用意大利语文本而不是英语来制作相同的东西。我保留了所有超参数,就像您的教程一样。出乎意料的是,结果却大相径庭:它实际上生成了几个几乎正确的单词,之后它会重复这些单词直到生成的文本结束(类似“i don’t know i don’t know i don’t know i don’t know…”)。奇怪的是,无论我给出什么种子,我只能得到这两个强迫症句子。通过使用“温度”(将softmax层的输入除以T,其中T大于1)可以缓解这种情况,但我认为这是否可以被视为过拟合,以及如何用更好的超参数来解决它:增加LSTM层中的单元数是否有帮助?
嗨Guido…我强烈建议增加更多的LSTM单元。以下资源中提供了一些其他注意事项
https://www.analyticsvidhya.com/blog/2015/10/6-practices-enhance-performance-text-classification-model/
嗨Guido…也许以下资源可以帮助您决定尝试哪些选项
https://machinelearning.org.cn/impressive-applications-of-generative-adversarial-networks/
HI sir,我想问一下这个RNN模型到底在做什么,这个模型的主要目的是什么?
我无法理解是什么让我们的最终结果有所不同,以及我们在这个模型结束时取得了什么。
因为我正在训练瑞典语序列来通过这个模型进行训练和测试,但我对我的结果并不满意。
嗨Usama…您可能会发现以下内容很有趣
https://www.techtarget.com/searchenterpriseai/definition/recurrent-neural-networks#:~:text=Recurrent%20neural%20networks%20recognize%20data's,activity%20in%20the%20human%20brain.
你好,抱歉,如果这个问题之前有人问过,但…
由于保存了检查点,我想知道是否有可能在程序停止后稍后重新启动,因为它一次运行20个或更多epoch需要太多小时。
谢谢
嗨delgado…以下内容可能会让您感兴趣
https://machinelearning.org.cn/setting-breakpoints-and-exception-hooks-in-python/
非常感谢James
非常感谢您的文章;它极大地帮助我理解了LSTM在文本生成中的实现。
不客气,ChaLin!我们感谢您的支持!