Python_lab-HW5-根据已有文本预测接下来的文本

使用RNN文本预测-依据莎士比亚文本

使用RNN预测文本,将会使用莎士比亚的文字来训练。将会分成两份,一份是九成的文字作为训练,还有一成作为验证。训练集是用来训练模型的参数,验证集是用来算出训练出来的模型的准确率,用最优的模型作为最后的模型。这次没有测试数据集。网络结构使用老师提供的LSTM。

首先下载莎士比亚文本
import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np
text_url = 'https://homl.info/shakespeare'
filepath = tf.keras.utils.get_file('shakespeare.txt', origin=text_url)
with open(filepath) as f:
  input_text = f.read()

input_text 

在这里插入图片描述
出来的文字有点乱码,比如换行符号。还有大小写不统一。需要修正才方便训练

对input_text进行统一,比如大小写统一
tokenizer = tf.keras.preprocessing.text.Tokenizer(lower=True, char_level=True)
#lower=True 统一为小写字母
#char_level: 如果为 True,则每个字符都将被视为标记
tokenizer.fit_on_texts(input_text)
#train set for 90% and test set for 10%
total_count = tokenizer.document_count 
train_size = total_count * 90 // 100
valid_size =  total_count-train_size

print(f'train_size is:{train_size}, and valid size is {valid_size}')

train_size is:1003854, and valid size is 111540

开始把字符变成数字 即word2int
int2word = {}
word2int = {}
for word, index in tokenizer.word_index.items():
  int2word[index-1] = word
  word2int[word] = index-1

int2word是跟每个单独不重复的字符都有相对应的数字

在这里插入图片描述

把莎士比亚所有字符转变成数字
[encoded] = np.array(tokenizer.texts_to_sequences([input_text])) - 1 
#把所有的字符变成数字

在这里插入图片描述
然后把分成训练集和验证集

x_train = tf.data.Dataset.from_tensor_slices(encoded[:train_size])
x_valid = tf.data.Dataset.from_tensor_slices(encoded[train_size:])
print(f'len of x_train is {len(x_train)}, and the len of x_valid is {len(x_valid)}')

len of x_train is 1003854, and the len of x_valid is 111540

开始训练

首先 使用window函数来实现单移动窗口,首先理解window函数先

window(size, shift=None, stride=1, drop_remainder=False)

size:表示拆分后每个窗口包含多少个采样点,即窗口宽度。
shift:表示滑动窗口中输入元素的跨度,即滑动步长。
stride:表示采样点之间的跨度;可选参数,默认为 None
drop_remainder=True 表示丢弃不足窗口宽度的数据

使用window函数来做训练

train_set = x_train.window(size=100, shift=1, drop_remainder=True)

即 是取100个数字作为一个区间,然后移动一个数字,再取100个数字,持续下去。
显示结果

train_set = x_train.window(size=100, shift=1, drop_remainder=True)
for window in train_set: 
    print(list(window.as_numpy_iterator())) 

在这里插入图片描述
接下来是合成批次
其中
batch可以将数据集的连续元素合成批次。
函数形式:batch(batch_size,drop_remainder=False)
参数batch_size:表示要在单个批次中合并的此数据集的连续元素个数。

train_set = x_train.window(size=100, shift=1, drop_remainder=True)
train_set = train_set.flat_map(lambda element: element.batch(100))
#valid
valid_set = x_valid.window(size=100, shift=1, drop_remainder=True)
valid_set = valid_set.flat_map(lambda element: element.batch(100))

其中flat_map和Batch处理的结果是

list(valid_set.as_numpy_iterator())

在这里插入图片描述
为后续的训练做好数据处理。变成了array格式,然后再变成one hot code格式
先写一个函数来定义 one hot coding

#变成one hot 模式 
def preprocess(element):
  x, y = element[:-1], element[1:]
  return tf.one_hot(x, depth=39),y

再打乱数据防止过度拟合

train_ds = train_set.map(preprocess).shuffle(1000, seed=123).repeat().batch(128).prefetch(1)
valid_ds = valid_set.map(preprocess).batch(128).prefetch(1)
现开始创建模型
model = tf.keras.Sequential([
            tf.keras.layers.LSTM(256, return_sequences=True, input_shape=[None,39]),
            tf.keras.layers.Dropout(0.2),
            tf.keras.layers.LSTM(256, return_sequences=True),
            tf.keras.layers.Dropout(0.2),
            tf.keras.layers.LSTM(256, return_sequences=True),
            tf.keras.layers.Dropout(0.2),
            tf.keras.layers.Dense(39, activation='softmax')
])
model.summary()

在这里插入图片描述
开始选优化器 Adam

opt = tf.keras.optimizers.Adam(0.001)
model.compile(optimizer=opt, loss='sparse_categorical_crossentropy')
model.fit(train_ds, epochs=10,validation_data= valid_ds)

训练完毕

使用trained model 来预测
def one_hot(x):
  return tf.one_hot(x, depth=39)

写预测的函数

def pred(model,start_string):
  #预测的数量,这里选择预测200个文字
  num_generate = 200
  id_list = []
  text_generated= []
  #这里录用 开始的几个数字
  [input_eval] = np.array(tokenizer.texts_to_sequences([start_string])) - 1
  for i in input_eval:
    id_list.append(i)

  #increase one dim 
  input_eval = tf.expand_dims(input_eval, 0)
  input_t = tf.data.Dataset.from_tensor_slices(input_eval)
  input_t = input_t.map(one_hot).batch(128)

  for i in range(num_generate):
    predictions = model.predict(input_t)
    index = np.argmax(predictions,axis = 2)[0][-1]  #take the last one as predictor character 
    
    id_list.append(index)
    text_generated.append(int2word[index])

    input_t = np.array(id_list)
    input_t = tf.expand_dims(input_t, 0)
    input_t = tf.data.Dataset.from_tensor_slices(input_t)
    input_t = input_t.map(one_hot).batch(128)
  return (start_string + ''.join(text_generated))

预测

start_string='Queen:'
print(pred(model,start_string))

在这里插入图片描述

start_string='ROMEO:'
print(pred(model,start_string))

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianafeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值