文章目录

  • 1、读取数据集
  • 2、建立字符索引
    • 2.1 删除数据集中重复的字符
    • 2.2 将字符映射到索引
    • 2.3 得到词典大小
    • 2.4 将字符转化成索引
  • 3、时序数据的采样
    • 3.1 随机采样
      • 代码解释
    • 3.2 相邻采样
      • 代码解释

1、读取数据集

import tensorflow as tf
import random
import zipfilewith zipfile.ZipFile('../../data/jaychou_lyrics.txt.zip') as zin:with zin.open('jaychou_lyrics.txt') as f:corpus_chars = f.read().decode('utf-8')
corpus_chars[:40]
'想要有直升机\n想要和你飞到宇宙去\n想要和你融化在一起\n融化在宇宙里\n我每天每天每'

这个数据集有6万多个字符。为了打印方便,我们把换行符替换成空格,然后仅使用前1万个字符来训练模型。

corpus_chars = corpus_chars.replace('\n', ' ').replace('\r', ' ')
corpus_chars = corpus_chars[0:10000]

2、建立字符索引

我们将每个字符映射成一个从0开始的连续整数,又称索引,来方便之后的数据处理。为了得到索引,我们将数据集里所有不同字符取出来,然后将其逐一映射到索引来构造词典。接着,打印 vocab_size,即词典中不同字符的个数,又称词典大小。

2.1 删除数据集中重复的字符

使用set()函数将数据集中重复的字符删掉,然后放入列表中。

idx_to_char = list(set(corpus_chars))
len(idx_to_char)
1027

所以在数据集中由1027个不重复的字符。

2.2 将字符映射到索引

char_to_idx = dict([(char, i) for i, char in enumerate(idx_to_char)])

得到的字典 char_to_idx 的键为字符,值为索引值,如 {‘容’: 0, ‘午’: 1, ‘蜘’: 2, ‘蓝’: 3, ‘美’: 4, ‘印’: 5 ……}。

2.3 得到词典大小

vocab_size = len(char_to_idx)
vocab_size
1027

2.4 将字符转化成索引

corpus_indices = [char_to_idx[char] for char in corpus_chars]
len(corpus_indices)
10000

corpus_indices 中是 原数据集corpus_chars 中所有字符的索引值。
我们可以打印前20个字符机器对应的索引:

sample = corpus_indices[:20]
print('chars:', ''.join([idx_to_char[idx] for idx in sample]))
print('indices:', sample)
chars: 想要有直升机 想要和你飞到宇宙去 想要和
indices: [986, 669, 467, 984, 473, 554, 491, 986, 669, 881, 83, 420, 690, 750, 306, 55, 491, 986, 669, 881]

3、时序数据的采样

在训练中我们需要每次随机读取小批量样本和标签。与其他实验数据不同的是,时序数据的一个样本通常包含连续的字符。假设时间步数为5,样本序列为5个字符,即“想”“要”“有”“直”“升”。该样本的标签序列为这些字符分别在训练集中的下一个字符,即“要”“有”“直”“升”“机”。我们有两种方式对时序数据进行采样,分别是随机采样相邻采样

3.1 随机采样

下面的代码每次从数据里随机采样一个小批量。其中批量大小 batch_size 指每个小批量的样本数,num_steps 为每个样本所包含的时间步数。 在随机采样中,每个样本是原始序列上任意截取的一段序列。相邻的两个随机小批量在原始序列上的位置不一定相邻。因此,我们无法用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态。在训练模型时,每次随机采样前都需要重新初始化隐藏状态。

def data_iter_random(corpus_indices, batch_size, num_steps, ctx=None):num_examples = (len(corpus_indices) - 1) // num_stepsepoch_size = num_examples // batch_sizeexample_indices = list(range(num_examples))random.shuffle(example_indices)def _data(pos):return corpus_indices[pos: pos + num_steps]for i in range(epoch_size):# 每次读取batch_size个随机样本i = i * batch_sizebatch_indices = example_indices[i: i + batch_size]X = [_data(j * num_steps) for j in batch_indices]Y = [_data(j * num_steps + 1) for j in batch_indices]yield np.array(X, ctx), np.array(Y, ctx)

让我们输入一个从0到29的连续整数的人工序列。设批量大小和时间步数分别为2和6。打印随机采样每次读取的小批量样本的输入 X 和标签 Y。可见,相邻的两个随机小批量在原始序列上的位置不一定相毗邻。

my_seq = list(range(30))
for X, Y in data_iter_random(my_seq, batch_size=2, num_steps=6):print('X: ', X, '\nY:', Y, '\n')
X:  tensor([[18., 19., 20., 21., 22., 23.],[12., 13., 14., 15., 16., 17.]])
Y: tensor([[19., 20., 21., 22., 23., 24.],[13., 14., 15., 16., 17., 18.]]) X:  tensor([[ 0.,  1.,  2.,  3.,  4.,  5.],[ 6.,  7.,  8.,  9., 10., 11.]])
Y: tensor([[ 1.,  2.,  3.,  4.,  5.,  6.],[ 7.,  8.,  9., 10., 11., 12.]])

代码解释

用上面的 my_seqbatch_size=2num_steps=6 对代码进行解释。

num_examples = (len(corpus_indices) - 1) // num_steps

num_examples 是指有多少个样本,此时 num_examples=29 // 6=4
减1是因为输出的索引(标签)是相应输入的索引(样本)加1。也就是说,如果不减1的话,一旦 X 取到 [24 25 26 27 28 29],Y 就只能取 [25 26 27 28 29],因为 corpus_indices (即 my_seq)就只到29。

epoch_size = num_examples // batch_size

epoch_size 是指遍历一遍数据集需要训练的次数,因为训练一次输入的样本数为 batch_size=2,那么遍历一次需要的次数为 epoch_size=2

example_indices = list(range(num_examples))

example_indices 是一个包含着四个样本各自索引的列表,即 example_indices=[0, 1, 2, 3]

random.shuffle(example_indices)

打乱 example_indices 列表的顺序。

def _data(pos):return corpus_indices[pos: pos + num_steps]

这个函数返回的是从 pos 开始的长为 num_steps 的序列。

for i in range(epoch_size):# 每次读取batch_size个随机样本i = i * batch_sizebatch_indices = example_indices[i: i + batch_size]X = [_data(j * num_steps) for j in batch_indices]Y = [_data(j * num_steps + 1) for j in batch_indices]yield np.array(X), np.array(Y)

epoch_size 是2,所以总共循环两次,每次循环的具体操作:

  • 读取 batch_size=2 个随机样本,比如读取到 batch_indices=[0, 1]
  • 利用 _data(pos) 函数,从 my_seq 中提取样本 X 和对应的标签 Y

yield 是指将 np.array(X), np.array(Y) 迭代输出。也就是说,每次只输出一个批次的样本和标签。

3.2 相邻采样

除对原始序列做随机采样之外,我们还可以令相邻的两个随机小批量在原始序列上的位置相邻。
这时候,我们就可以用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态,从而使下一个小批量的输出也取决于当前小批量的输入,并如此循环下去。
这对实现循环神经网络造成了两方面影响:

  • 一方面, 在训练模型时,我们只需在每一个迭代周期开始时初始化隐藏状态;
  • 另一方面,当多个相邻小批量通过传递隐藏状态串联起来时,模型参数的梯度计算将依赖所有串联起来的小批量序列。

同一迭代周期中,随着迭代次数的增加,梯度的计算开销会越来越大。 为了使模型参数的梯度计算只依赖一次迭代读取的小批量序列,我们可以在每次读取小批量前将隐藏状态从计算图中分离出来。

def data_iter_consecutive(corpus_indices, batch_size, num_steps, ctx=None):corpus_indices = np.array(corpus_indices)data_len = len(corpus_indices)batch_len = data_len // batch_sizeindices = corpus_indices[0: batch_size*batch_len].reshape((batch_size, batch_len))epoch_size = (batch_len - 1) // num_stepsfor i in range(epoch_size):i = i * num_stepsX = indices[:, i: i + num_steps]Y = indices[:, i + 1: i + num_steps + 1]yield X, Y

同样的设置下,打印相邻采样每次读取的小批量样本的输入 X 和标签 Y。相邻的两个随机小批量在原始序列上的位置相邻。

my_seq = list(range(30))
for X, Y in data_iter_random(my_seq, batch_size=2, num_steps=6):print('X: ', X, '\nY:', Y, '\n')
X:  tensor([[ 0.,  1.,  2.,  3.,  4.,  5.],[15., 16., 17., 18., 19., 20.]])
Y: tensor([[ 1.,  2.,  3.,  4.,  5.,  6.],[16., 17., 18., 19., 20., 21.]]) X:  tensor([[ 6.,  7.,  8.,  9., 10., 11.],[21., 22., 23., 24., 25., 26.]])
Y: tensor([[ 7.,  8.,  9., 10., 11., 12.],[22., 23., 24., 25., 26., 27.]])

代码解释

同样用上面的 my_seqbatch_size=2num_steps=6 对代码进行解释。

corpus_indices = np.array(corpus_indices)

将列表转换成数组,方便之后的 reshape 操作。

data_len = len(corpus_indices)

data_len=30 表明样本一共有30个。

batch_len = data_len // batch_size

batch_len=15 表明一个批次中有15个字符。

indices = corpus_indices[0: batch_size*batch_len].reshape((batch_size, batch_len))

得到的 indices 为:

array([[ 0,  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]])

即将数据集分成了两个数组。

epoch_size = (batch_len - 1) // num_steps

epoch_size 是指遍历一遍数据集需要训练的次数,因为训练一次输入的样本数为 batch_size=2,那么遍历一次需要的次数为 epoch_size=2

for i in range(epoch_size):i = i * num_stepsX = indices[:, i: i + num_steps]Y = indices[:, i + 1: i + num_steps + 1]yield X, Y

进一步将每个数组的前6个字符放到位于同一批次的两个样本中;后6个字符放到位于另一批次的两个样本中。即:
第一个批次中的样本:

[[ 0,  1,  2,  3,  4,  5],[15, 16, 17, 18, 19, 20]]

第二个批次中的样本:

[[ 6,  7,  8,  9, 10, 11],[21, 22, 23, 24, 25, 26]]

Tensorflow2.0之语言模型数据集(周杰伦专辑歌词)预处理相关推荐

  1. 【从零开始学习深度学习】34. Pytorch-RNN项目实战:RNN创作歌词案例--使用周杰伦专辑歌词训练模型并创作歌曲【含数据集与源码】

    目录 RNN项目实战使用周杰伦专辑歌词训练模型并创作歌曲 1.语言模型数据集预处理 1.1 读取数据集 1.2 建立字符索引 1.3 时序数据的2种采样方式 1.3.1 随机采样 1.3.2 相邻采样 ...

  2. Tensorflow2.0泰坦尼克数据集的python分析以及离散化数据处理(含数据集下载地址)

    泰坦尼克数据集下载 训练集 测试集 导入需要的库 import matplotlib.pyplot as plt %matplotlib inline import numpy as np impor ...

  3. Tensorflow2.0之用循环神经网络生成周杰伦歌词

    文章目录 1.导入需要的库 2.加载数据集 3.相邻采样 4.定义模型 4.1 定义循环神经网络层 4.2 定义循环神经网络 5.定义预测函数 6.裁剪梯度 7.定义模型训练函数 7.1 困惑度 7. ...

  4. tensorflow2.0实现IMDB文本数据集学习词嵌入

    1. IMDB数据集示例如下所示 [{"rating": 5, "title": "The dark is rising!", " ...

  5. 第0章【序】--动手学深度学习【Tensorflow2.0版本】

    项目地址:https://github.com/TrickyGo/Dive-into-DL-TensorFlow2.0 这个项目将<动手学深度学习> 原书中MXNet代码实现改为Tenso ...

  6. 【TensorFlow2.0】数据读取与使用方式

    大家好,这是专栏<TensorFlow2.0>的第三篇文章,讲述如何使用TensorFlow2.0读取和使用自己的数据集. 如果您正在学习计算机视觉,无论你通过书籍还是视频学习,大部分的教 ...

  7. TensorFlow2.0学习笔记2-tf2.0两种方式搭建神经网络

    目录 一,TensorFlow2.0搭建神经网络八股 1)import  [引入相关模块] 2)train,test  [告知喂入网络的训练集测试集以及相应的标签] 3)model=tf.keras. ...

  8. scrapy遇上ajax,抓取QQ音乐周杰伦专辑与歌词

    目录 序言 分析网页 分析请求 代码实现 瞎比比 序言 好久没写原创文章,早就手痒痒了,所以挤出时间写了这篇,这是下面这五篇文章的连载文章: 爬虫利器初体验(1) 听说你的爬虫又被封了?(2) 爬取数 ...

  9. scrapy遇上ajax,抓取QQ音乐周杰伦专辑与歌词(6)

    目录 序言 分析网页 分析请求 代码实现 瞎比比 序言 好久没写原创文章,早就手痒痒了,所以挤出时间写了这篇,这是下面这五篇文章的连载文章: (1) (2) 那这段时间我都去干嘛了呢?时间都用在写小程 ...

  10. 笔记3:Tensorflow2.0实战之MNSIT数据集

    最近Tensorflow相继推出了alpha和beta两个版本,这两个都属于tensorflow2.0版本:早听说新版做了很大的革新,今天就来用一下看看 这里还是使用MNSIT数据集进行测试 导入必要 ...

最新文章

  1. AUP2敏捷统一过程之一:序言及降低过程的总体拥有成本
  2. 【maven】mvn -pl 指定模块
  3. android2.2桌面,手机桌面课表软件
  4. 每日一题(26)—— 无限循环的几种形式
  5. rabbitMQ linux 安装步骤
  6. JavaScript设计模式-工厂方法模式
  7. java 顺序输出_java输出顺序
  8. 10 分钟看懂消息队列 RocketMQ
  9. smarty 模板不能正常加载css,js的问题
  10. 苏州旅游网站的设计与实现 毕业论文+Html静态源码
  11. B46 - STM32太阳能充电智能心率监测骑行仪
  12. 百度网盘等相关百度产品账号不存在问题
  13. scikit-learn回归类库使用
  14. 打不死的又如何能毁灭呢?尴尬的 Windows XP 是升级还是保留?
  15. My Visual DataBase(数据库编程软件)v5.3免费版
  16. Guitar Pro8苹果mac最新版本下载安装教程
  17. HFSS激励类型----电流源激励
  18. 范数(Norm)和谱半径(Spectral Radii)
  19. EXT前端数据传不到后台
  20. MapReduce概述及MapReduce详细实现

热门文章

  1. 2019_Generative Adversarial Networks for Extreme Learned Image Compression
  2. matlab空间杜宾模型命令,空间计量模型,包括空间滞后模型、空间误差模型、空间杜宾模型的matlab代码...
  3. parse_url() vul
  4. xctf攻防世界 MISC高手进阶区 MISCall
  5. 六级考研单词之路-三十八
  6. python透视表画图_如何用Python实现透视表?
  7. python读有中文的文件_在python中pandas读文件,有中文字符的方法
  8. yarn : 无法加载文件 C:\Users\L\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本
  9. 为什么说人间值得,因为有这么多美好让我们留恋。金秋十月初九于指南山村 。...
  10. Linux CentOS服务器时间同步阿里云北京时间