1、数据准备
??最近经常看到网友对新闻的评论,好多评论都说编辑是越来越懒,文章都是让机器人写的,词不达意,语句不通都放上去,骂声一片。突发奇想,使用GRU模型训练一段文本,看能否预测出让大家看得懂的文本。 ??本人对周董的歌比较感兴趣,就收集到周董的歌词,下边就开始实现文本生成任务,让机器给周董写一首歪果仁(中国人估计也不是很懂哦,哇咔咔)听不懂的歌。
1.1 导包
from __future__ import absolute, division, print_function, unicode_litersla
import tensorflow as tf
import numpy as np
import os
1.2 获取文件
取一首歌作为例子
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线乘著风 游荡在蓝天边
一片云掉落在我面前
捏成你的形状
随风跟著我
一口一口吃掉忧愁
载著你 彷彿载著阳光
不管到哪里都是晴天
蝴蝶自在飞
花也布满天
一朵一朵因你而香
试图让夕阳飞翔
带领你我环绕大自然
迎著风 开始共渡每一天
手牵手
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线背著背默默许下心愿
看远方的星是否听的见
手牵手
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线背著背默默许下心愿
看远方的星如果听的见
它一定实现它一定实现
载著你 彷彿载著阳光
不管到哪里都是晴天
蝴蝶自在飞
花也布满天
一朵一朵因你而香
试图让夕阳飞翔
带领你我环绕大自然
迎著风 开始共渡每一天
手牵手
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线背著背默默许下心愿
看远方的星是否听的见
手牵手
一步两步三步四步望著天 看星星
一颗两颗三颗四颗 连成线背著背默默许下心愿
看远方的星如果听的见
它一定实现
它一定实现
file_path = './data/jay_chou.txt'
def prepareData(file_path):
"""文本转换为码表函数"""
text = open(data_path, 'rb').read().decode(encoding="utf-8")
vocab = sorted(set(text))
char2index = {u: i for i, u in enumerate(vocab)}
index2char = np.array(vocab)
text_as_int = np.array([char2index[c] for c in text])
return char2index, index2char, text_as_int, text, vocab
char2index, index2char, text_as_int, text, vocab = prepareData(file_path)
print(char2index)
print(index2char)
print(text_as_int)
print(vocab)
输出结果:
>>> {'\n': 0, ' ': 1, '!': 2, '$': 3, '&': 4, "'": 5, ',': 6, '-': 7, '.': 8, '3': 9, ':': 10, ';': 11, '?': 12, 'A': 13, 'B': 14, 'C': 15, 'D': 16, 'E': 17, 'F': 18, 'G': 19, 'H': 20, 'I': 21, 'J': 22, 'K': 23, 'L': 24, 'M': 25, 'N': 26, 'O': 27, 'P': 28, 'Q': 29, 'R': 30, 'S': 31, 'T': 32, 'U': 33, 'V': 34, 'W': 35, 'X': 36, 'Y': 37, 'Z': 38, 'a': 39, 'b': 40, 'c': 41, 'd': 42, 'e': 43, 'f': 44, 'g': 45, 'h': 46, 'i': 47, 'j': 48, 'k': 49, 'l': 50, 'm': 51, 'n': 52, 'o': 53, 'p': 54, 'q': 55, 'r': 56, 's': 57, 't': 58, 'u': 59, 'v': 60, 'w': 61, 'x': 62, 'y': 63, 'z': 64}
>>>['\n' ' ' '!' '$' '&' "'" ',' '-' '.' '3' ':' ';' '?' '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' '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']
>>>[18 47 56 ... 45 8 0]
>>>['\n', ' ', '!', '$', '&', "'", ',', '-', '.', '3', ':', ';', '?', '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', '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']
1.3 生成训练数据
seq_length = 100
examples_per_epoch = len(text) // seq_length
char_dataset = tf.data.Dataset.from_tensor_slices(text2int)
sequences = char_dataset.batch(seq_length + 1, drop_remainder=True)
def split_input_target(chunk):
"""划分输入序列和目标序列函数"""
input_text = chunk[:-1]
target_text = chunk[1:]
return input_text, target_text
dataset = sequences.map(split_input_target)
print(dataset)
BATCH_SIZE = 64
BUFFER_SIZE = 10000
dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)
print(dataset)
>>> <MapDataset shapes: ((100,), (100,)), types: (tf.int64, tf.int64)>
>>> <BatchDataset shapes: ((64, 100), (64, 100)), types: (tf.int64, tf.int64)>
1.4 构建模型
vocab_size = len(vocab)
embedding_dim = 256
rnn_units = 1024
def gru_model(vocab_size, embedding_dim, rnn_units, batch_size):
model = tf.keras.Sequential([
tf.keras.layers.Embedding(vocab_size, embedding_dim, batch_input_shape=[batch_size, None]),
tf.keras.layers.GRU(rnn_units, return_sequences=True, stateful=True, recurrent_initializer='glorot_uniform'),
tf.keras.layers.Dense(vocab_size)
])
return model
model = gru_model(vocab_size, embedding_dim, rnn_units, BATCH_SIZE)
1.5 构建损失函数
??定义损失函数labels真实标签,logits预测标签,由于模型返回logits,因此需要设置from_logits标志。
def loss(labels, logits):
return tf.keras.losses.sparse_categorical_crossentropy(labels, logits, from_logits=True)
model.compile(optimizer='adam', loss=loss)
1.6 设置检查点
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, 'ckpt_{epoch}')
checkpoint_calback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_prefix, save_weights_only=True)
EPOCHS = 100
history = model.fit(dataset, epochs=EPOCHS, callbacks=[checkpoint_calback])
model = gru_model(vocab_size, embedding_dim, rnn_units, batch_size=1)
model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))
1.7 构建生成函数
def generate_text(model, start_string):
num_generate = 1000
input_eval = [char2index[s] for s in start_string]
input_eval = tf.expand_dims(input_eval, 0)
text_generate = []
temperature = 1.0
model.reset_states()
for i in range(num_generate):
predictions = model(input_eval)
predictions = tf.squeeze(predictions, 0)
predictions = predictions / temperature
predictions_id = tf.random.categorical(predictions, num_samples=1)[-1, 0].numpy()
input_eval = tf.expand_dims([predictions_id], 0)
text_generate.append(index2char[predictions_id])
return (start_string + ''.join(text_generate))
1.7 保存生成的文本
with open('./datasets/generate_text.txt', 'w') as f:
f.write(generate_text(model, start_string='美女'))
1.8 效果展示
美女明白
忘记你对我的期待
读完了依赖
我很快就
我只能永远读着对白
读到我给你的伤害
我原谅不了我
就请你当作我已不在
我睁开双眼看着空白
忘记你对我的期待
读完了依赖
我很快就离开
那混乱的年代
朝廷太腐败
人祸惹天灾
东汉王朝在
一夕之间
你轻把以来
这街上太拥挤
太多人有秘密
玻璃上有雾气在被隐藏起过去
你脸上的情绪
在还原那场雨
这巷弄太过弯曲走不回故事里
这日子不再绿
又斑驳了几句
剩下搬空回忆的我在大房子里
电影院的座椅
隔遥远的距离
是我会感到奖没有知道
我深埋珊瑚海
飘移
教室的那么形状
幻幻想失去
去到哪有外婆家知道
看着的大提琴
安静的旧旧的
我想你已表现的非常明白
我懂我也知道不到
没有你烦 我有多难熬
没有你在我们多难熬 多烦恼 乎伊操心
虽然不关我的代誌 谁叫他是我的兄弟 耶
拢这样的默契很重要听我听你那么会抱
用我心碎你受罪你的美
我不配
天气 冷的让人生闷气
火气 我沮丧的很生气
空气 太糟需要有氧气
太多假义气一想就气
敲门 敲敲门
基本礼貌叩要先问
离开也不随手关灯
生活习惯真有够混
敲门 敲敲门
简单动作叩也不等
你看来虽不像坏蛋
但做事做人却很蠢
你像一团沼气
影响我的士气
损我的英气又那么神气
说话的语气
败坏了风气
我不想为你为你白花了力气
那么会扯去扯铃
扯多你就会上瘾
扯你最善变的表情
我的解释请你务必要听
那么会扯去扯铃
却扯不出个命运
扯你最善变的表情
嘿你这样说我有一点伤心
那么会扯去扯铃
扯多你就会上瘾
扯你最善变的表情
我的解释请你务必要听
那么会扯去扯铃
却扯不出个命运
扯你最善变的表情
嘿你这样说我有一点伤心
我轻轻地尝一口 你说的爱我
还在回味你给过的温柔
我轻轻地尝一口 这香浓的诱惑
我喜欢的样子你都有
你爱过头 竟然答是继续前进
oh oh 我不可能再回头
啦~~~~~
oh oh 我只能一直往前走
我在回家路上
看到路标指着演艺圈
如果选择往前走
我就必须强壮
走着走着 莫名其妙
冲出来好 幸福了这个季节
而你的脸颊象田里熟透的蕃茄
你突然对我说爱七
谁 说我要的是陪伴
而不是六百块
比你给的还简单
外婆她的无奈
无法期待
只有爱才能够明白
走在淡水河衅
听着她的最爱
把温暖放回口袋
外婆她的期待
慢慢变成无奈
大人们始终不明白
她要的是陪伴
而不是六百块
比你
??感兴趣的小伙伴可以搜集不同的文本进行训练,比如全国高考满分作文,只要数据集足够多,让机器写一篇满分作文也不是不可能的。
|