FLORIZEL:
Should she kneel be?
In shall not weep received; unleased me
And unrespective greeting than dwell in, thee,
look’d on me, son in heavenly properly.
这是谁写的,莎士比亚还是机器学习模型?
答案是后者!上面这篇文章是一个经过TensorFlow训练的循环神经网络的产物,经过30个epoch的训练,并给出了一颗“FLORIZEL:”的种子。在本文中,我将解释并给出如何训练神经网络来编写莎士比亚戏剧或任何您希望它编写的东西的代码!
导入和数据首先导入一些基本库
import tensorflow as tf import numpy as np import os import timeTensorFlow内置了莎士比亚作品。如果您在像Kaggle这样的在线环境中工作,请确保连接了互联网。
path_to_file = tf.keras.utils.get_file(\'shakespeare.txt\', \'https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt\')数据需要用utf-8进行解码。
text = open(path_to_file, \'rb\').read().decode(encoding=\'utf-8\') # length of text is the number of characters in it print (\'Length of text: {} characters\'.format(len(text)))[输出]:
Length of text: 1115394 characters
它里面有很多的数据可以用!
我们看看前250个字符是什么
print(text[:250]) 向量化首先看看文件里面有多少不同的字符:
vocab = sorted(set(text)) print (\'{} unique characters\'.format(len(vocab)))[输出]:
65 unique characters
在训练之前,字符串需要映射到数字表示。
下面创建两个表—一个表将字符映射到数字,另一个表将数字映射到字符。
查看向量字典:
print(\'{\') for char,_ in zip(char2idx, range(20)): print(\' {:4s}: {:3d},\'.format(repr(char), char2idx[char])) print(\' ...\n}\')[输出]:
{
\'\n\': 0,
\' \' : 1,
\'!\' : 2,
\'$\' : 3,
\'&\' : 4,
"\'" : 5,
\',\' : 6,
\'-\' : 7,
\'.\' : 8,
\'3\' : 9,
\':\' : 10,
...
}
每一个不一样的字符都有了编号。
我们看看向量生成器如何处理作品的前两个单词 \'First Citizen\'
print (\'{} ---- characters mapped to int ---- > {}\'.format(repr(text[:13]), text_as_int[:13]))这些单词被转换成一个数字向量,这个向量可以很容易地通过整数到字符字典转换回文本。
制造训练数据给定一个字符序列,该模型将理想地找到最有可能的下一个字符。
文本将被分成几个句子,每个输入句子将包含文本中的一个可变的seq_length字符。
任何输入语句的输出都将是输入语句,向右移动一个字符。
例如,给定一个输入“Hell”,输出将是“ello”,从而形成单词“Hello”。
首先,我们可以使用tensorflow的.from_tensor_slices函数将文本向量转换为字符索引。
# The maximum length sentence we want for a single input in characters seq_length = 100 examples_per_epoch = len(text)//(seq_length+1) # Create training examples / targets char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int) for i in char_dataset.take(5): print(idx2char[i.numpy()])[输出]:
F
i
r
s
t
批处理方法允许这些单个字符成为确定大小的序列,形成段落片段。
sequences = char_dataset.batch(seq_length+1, drop_remainder=True) for item in sequences.take(5): print(repr(\'\'.join(idx2char[item.numpy()])))[输出]:
\'First Citizen:\nBefore we proceed any further, hear me speak.\n\nAll:\nSpeak, speak.\n\nFirst Citizen:\nYou \' \'are all resolved rather to die than to famish?\n\nAll:\nResolved. resolved.\n\nFirst Citizen:\nFirst, you k\' "now Caius Marcius is chief enemy to the people.\n\nAll:\nWe know\'t, we know\'t.\n\nFirst Citizen:\nLet us ki" "ll him, and we\'ll have corn at our own price.\nIs\'t a verdict?\n\nAll:\nNo more talking on\'t; let it be d" \'one: away, away!\n\nSecond Citizen:\nOne word, good citizens.\n\nFirst Citizen:\nWe are accounted poor citi\'
对于每个序列,我们将复制它并使用map方法移动它以形成一个输入和一个目标。
def split_input_target(chunk): input_text = chunk[:-1] target_text = chunk[1:] return input_text, target_text dataset = sequences.map(split_input_target)