原标题:如何用深度学习写诗(用Python生成文本)
报 名
翻译:李雪冬
编辑:李雪冬
前 言
从短篇小说到写5万字的小说,机器不断涌现出前所未有的词汇。web有很多开发人员用机器学习来写文本的例子,效果荒谬而惊人。
自然语言处理(NLP)机器可以自己理解上下文,编造故事。
文本生成的例子包括机器编写流行小说的整个章节,如权力游戏和哈利波特,取得了不同程度的成功。在本文中,我们将使用它python以文本生成的概念构建机器学习模型,可以用莎士比亚风格写十四行诗。让我们看看!
本文的主要内容
1.什么是文本生成?
2.文本生成的不同步骤。
3.入口依赖
4.加载数据
5.创建字符/单词映射
6.数据预处理
7.模型创建
8.生成文本
9.尝试不同的模型
10.更多的训练模型
(1)更深层次的模型
(2).一个更广泛的模型
(3)超大模型
1
文本生成是什么?
现在,有大量的数据可以按顺序分类。它们以音频、视频、文本、时间序列、传感器数据等形式存在。如果两个事件都发生在特定的时间内,A先于B和BA是两个完全不同的场景。然而,在传统的机器学习问题中,在另一个数据点之前是否记录一个特定的数据点并不重要。这一考虑为我们的序列预测提供了新的解决方案。
文本由一个接一个的字符组成,实际上很难处理。这是因为在处理文本时,可以训练一个模型使用之前的序列来做出非常准确的预测,但之前的错误预测可能会使整个句子毫无意义。这就是为什么文本生成器很困难!
请浏览这两篇文章,以便更好地理解代码。LSTM理论背后(链接:https://www.analyticsvidhya.com/blog/2017/12/fundamentals-of-deep-learning-introduction-to-lstm/)
2
文本生成的步骤
文本生成通常包括以下步骤:
导入依赖
加载数据
创建映射
数据预处理
模型构建
生成文本
让我们详细看看每一个。
3
导入依赖
importnumpy as np
importpandas as pd
from keras.models importSequential
from keras.layers importDense
from keras.layers importDropout
from keras.layers importLSTM
from keras.utils importnp_utils
4
加载数据
text=(open( "/Users/pranjal/Desktop/text_generator/sonnets.txt").read())
text=text.lower()
在这里,我们正在加载所有莎士比亚十四行诗的集合,可以从这里(链接:http://www.gutenberg.org/cache/epub/1041/pg1041.txt)下载。我清理了这份文件,删除了开始和结束的学分,并且可以从我git下载存储库。打开并保存文本文件text中。然后将内容转换为小写,以减少可能单词的数量(稍后详细介绍)。
5
创建映射
映射是在文本中分配任何数字的步骤。这样,所有唯一的字符/单词都映射到一个数字中。这一点非常重要,因为机器比文本更能理解数字,这使得训练过程更容易。
characters = sorted( list( set(text)))
n_to_char = {n: charforn, charin enumerate(characters)}
char_to_n = { char:n forn, charin enumerate(characters)}
我创建了一个字典,将一个数字分配给文本中的每个独特字符。所有独特的字符首先存储在字符中,然后被枚举。
这里还必须注意的是,我使用了字符级别的映射,而不是单词映射。然而,与基于字符的模型相比,基于字符的模型比其他模型更准确。这是因为基于字符需要一个更大的网络来学习长期的依赖关系,因为它不仅需要记住单词的顺序,还需要学会预测语法正确的单词。然而,在基于单词的模型中,后者已经得到了处理。
6
数据预处理
在构建LSTM这是模型中最棘手的部分。很难将手头的数据转换为模型训练的格式。我会把这个过程分解成小部分,让你更容易理解。
X = []
Y = []
length = len(text)
seq_length = 100
fori in range( 0, length-seq_length, 1):
sequence = text[i:i seq_length]
label =text[i seq_length]
X.append([char_to_n[ char] forcharin sequence])
Y.append(char_to_n[label])
这里,X是我们的训练序列,Y是我们的目标数组。seq_length在预测特定字符之前,要考虑字符序列的长度。for循环用于遍历文本的整个长度,并创建这样的序列(存储在X中)及其真实值(存储在Y中),以便更好地理解真实值的概念。让我们以一个例子来理解这一点:
对于4的序列长度和文本hello india我们将有X和Y表示如下:
现在,LSTMs接受输入的形式是(number_of_sequence, length_of_sequence, number_of_features),这不是数组的当前格式。此外,我们需要将数组Y转换为一个one-hot编码格式。
X_modified = np.reshape(X, (len(X), seq_length, 1))
X_modified = X_modified / float(len(characters))
Y_modified = np_utils.to_categorical(Y)
我们首先将数组X重构为所需的维度。然后,我们将X_modified缩放值,使我们的神经网络能够更快地训练,并且更少的机会被困在局部最小值中。另外,我们的Y_modified以删除映射字符过程中可能引入的任何顺序关系为热编码。也就是说,与z”相比,“a一个较低的数字可能会被分配,但这并不意味着两者之间有任何关系。
最后的数组将是:
7
建立模型
model = Sequential()
model.add(LSTM( 400, input_shape=(X_modified.shape[ 1], X_modified.shape[ 2]), return_sequences=True))
model.add(Dropout( 0.2))
model.add(LSTM( 400))
model.add(Dropout( 0.2))
model.add(Dense(Y_modified.shape[ 1], activation= 'softmax'))
model.compile(loss= 'categorical_crossentropy', optimizer= 'adam')
我们正在建造一个有两个的LSTM每层有400个单元的序列模型。第一层需要输入形状。为了使下一个LSTM层可以处理相同的序列,我们输入return_sequence参数为真。 此外,设置参数为0.2的dropout检查是否过拟合最后一层输出one-hot提供字符输出的编码矢量。
8
文本生成
string_mapped = X[ 99]
fori in range(seq_length):
x = np.reshape(string_mapped,( 1,len(string_mapped), 1))
x = x / float(len(characters))
pred_index = np.argmax(model.predict(x, verbose= 0))
seq = [n_to_char[value] forvalue in string_mapped]
string_mapped.append(pred_index)
string_mapped = string_mapped[ 1:len(tring_mapped)]
我们从X数组中的随机一行开始,这是一个100个字符的数组。在此之后,我们的目标是预测x后面的另外100个字符,输入将如同前面一样被重新塑造和缩放,预测下一个具有最大概率的字符。seq用于存储到现在为止预测行为用到的字符串的解码格式。接下来,新字符串被更新,这样第一个字符被删除,新的预测字符被包含进来。您可以在这里 找到整个代码。这里提供了训练文件,注释和训练的模型权重供您参考。
9
尝试不同模型
基线模型:
当训练为1个周期,批大小为100时,给出如下输出:
's the riper should by time decease,
his tender heir might bear his memory:
but thou, contracted toet she the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the the the the the the the the the the
thi the the the the the the the the th'
这个输出没有多大意义。它只是重复同样的预测,就好像它被困在一个循环中一样。这是因为与我们训练的微型模型相比,语言预测模型太复杂了。
让我们试着训练同样的模型,但是将时间周期变长。
加强训练时间的模型:
这次我们训练我们的模型为100个周期,批大小设置为50。我们至少得到了一个非重复的字符序列,其中包含了相当数量的合理单词。此外,该模型还学会了生成一个类似14行诗的结构。
'The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own besire,
that in the breath ther doomownd wron to ray,
dorh part nit backn oy steresc douh dxcel;
for that i have beauty lekeng norirness,
for all the foowing of a former sight,
which in the remame douh a foure to his,
that in the very bumees of toue mart detenese;
how ap i am nnw love, he past doth fiamee.
to diserace but in the orsths of are orider,
waie agliemt would have me '
但是,这个模型还不够好,不能产生高质量的内容。所以现在我们要做的是当一个深度学习模型没有产生好的结果时,每个人都会做的事情。建立一个更深层次的架构!
一个更深的模型:
一位机器学习的大牛曾经说过:如果模型做得不好,那就增加层数!我将用我的模型做同样的事情。让我们再添加一个LSTM层,里面有400个单元,然后是一个参数为0.2的dropout层,看看我们得到了什么。
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to the world's false sporoe,
with eyes so dond touls be thy domfornds,
which for memorion of the seasons new;
mike own self-love to shou art constant
how can i then be oy love doth give,
the rose looks fair, but fairer bomments age.
now with the seas that i have seen dychl
that mot to teed of you, if h ho bontent,
and all the ress of the heartai thee;
the world will was iis bound and farty "
结果开始变得有趣。语法实现了自我增强,保持了十四行诗的结构和标点的完整。然而,这仍然需要很大的改进。让我们尝试探索一个更广泛的网络,一个拥有更多单元的网络。
一个更广的模型:
在两个LSTM层中,我将单元的数量增加到700个。这个调整产生了以下的诗歌:
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own bright eyes,
feed'st thy sigh aare so beuider poise,
oor maty dis surre that gairs mot me love thee;
when i braye the would and lays in the eesire.
than thmu disgrmed stand with my bootr still nsentente;
tell ia to thou art thou wilt woon'thy sook,
and touain then tor, give thy soue semping.
whose whod the better of your befaiss nu sante,
though i, suoll oas, and i lose bouh twa"
这个做法并没有令我满意,因为这些词已经失去了意义。但是,有趣的是,这个模型开始尝试建立一些韵脚。模型毕竟是在开始尝试更深层次理解诗歌!但是,对于训练出既有意义又优美的诗歌的目标,我们不能妥协,对吗?
让我们把它放在一个超大的模型中。
一个超大的模型:
我将层数增加到3层,每层有700个单元,并训练了100个周期。产生的结果是一篇宏伟的诗篇。请看:
"The riper should by time decease,
his tender heir might bear his memory:
but thou, contracted to thine own bright eyes,
feed'st thy light's flame with self-substantial fuel,
my beept is she breat oe bath dasehr ill:
tirse do i pine and turfeit day by day,
or gluttoning on all, or all away.
Lxxvi
why is my verse so barren of new pride,
so far from variation or quick change?
why with the time do i not glance aside
to new-found methods, and to compounds strange?
why write i stil"
这篇诗歌不仅用词准确,而且也学会了押韵。我们本可以有一件更宏伟的艺术品,但是作为入门LSTM的一个开始,这就够了。这已经是比大多数人更好地表达了
本文转载自公众号:机器学习算法全栈工程师 (已获授权)
本文翻译自pranjal seivastava的一篇文章
(链接:https://www.analyticsvidhya.com/blog/2018/03/text-generation-using-python-nlp/)原作者保留版权
-END-
图文来自网络、如涉及版权问题,请联系我们以便处理。文章内容纯属作者个人观点,不代表本网观点。返回搜狐,查看更多
责任编辑: