动手学深度学习(Pytorch版)代码实践 -循环神经网络-53语言模型和数据集

53语言模型和数据集

1.自然语言统计

引入库和读取数据:

python 复制代码
import random
import torch
from d2l import torch as d2l
import liliPytorch as lp
import numpy as np
import matplotlib.pyplot as plt

tokens = lp.tokenize(lp.read_time_machine())

一元语法:

python 复制代码
# 一元语法
# 因为每个文本行不一定是一个句子或一个段落,因此我们把所有文本行拼接到一起
corpus = [token for line in tokens for token in line]
vocab = lp.Vocab(corpus)
# print(vocab.token_freqs[:5])
# [('the', 2261), ('i', 1267), ('and', 1245), ('of', 1155), ('a', 816)]
freqs = [freq for token, freq in vocab.token_freqs]
d2l.plot(freqs, xlabel='token: x', ylabel='frequency: n(x)',
         xscale='log', yscale='log')
plt.show()

二元语法:

python 复制代码
# 二元语法
bigram_tokens = [pair for pair in zip(corpus[:-1], corpus[1:])]
bigram_vocab = lp.Vocab(bigram_tokens)
# print(bigram_vocab.token_freqs[:5])
# [(('of', 'the'), 309), (('in', 'the'), 169), (('i', 'had'), 130),
# (('i', 'was'), 112), (('and', 'the'), 109)]
freqs = [freq for token, freq in bigram_vocab.token_freqs]
d2l.plot(freqs, xlabel='token: x', ylabel='frequency: n(x)',
         xscale='log', yscale='log')
plt.show()

三元语法:

python 复制代码
# 三元语法
trigram_tokens = [triple for triple in zip(corpus[:-2], corpus[1:-1], corpus[2:])]
trigram_vocab = lp.Vocab(trigram_tokens)
# print(trigram_vocab.token_freqs[:5])
# [(('the', 'time', 'traveller'), 59), (('the', 'time', 'machine'), 30), (('the', 'medical', 'man'), 24),
#  (('it', 'seemed', 'to'), 16), (('it', 'was', 'a'), 15)]
freqs = [freq for token, freq in trigram_vocab.token_freqs]
d2l.plot(freqs, xlabel='token: x', ylabel='frequency: n(x)',
         xscale='log', yscale='log')
plt.show()


对比:

python 复制代码
# 一元语法、二元语法和三元语法对比
freqs = [freq for token, freq in vocab.token_freqs]
bigram_freqs = [freq for token, freq in bigram_vocab.token_freqs]
trigram_freqs = [freq for token, freq in trigram_vocab.token_freqs]
d2l.plot([freqs, bigram_freqs, trigram_freqs], xlabel='token: x',
         ylabel='frequency: n(x)', xscale='log', yscale='log',
         legend=['unigram', 'bigram', 'trigram'])
plt.show()
2.读取长序列数据
python 复制代码
# n元语法,n 等于 num_steps
# 读取长序列数据
# 随机采样
def seq_data_iter_random(corpus, batch_size, num_steps):  #@save
    """使用随机抽样生成一个小批量子序列"""
    # 从随机偏移量开始对序列进行分区,随机范围包括num_steps-1
    # 从一个随机位置开始截取corpus,以生成一个新的子列表
    # random.randint(a, b) 会生成一个范围在 a 到 b 之间的整数,并且包括 a 和 b
    corpus = corpus[random.randint(0, num_steps - 1) : ]
    # 减去1,是因为我们需要考虑标签
    num_subseqs = (len(corpus) - 1) // num_steps
    # 长度为num_steps的子序列的起始索引
    initial_indices = list(range(0, num_subseqs * num_steps, num_steps))
    # 在随机抽样的迭代过程中,
    # 来自两个相邻的、随机的、小批量中的子序列不一定在原始序列上相邻
    random.shuffle(initial_indices)

    def data(pos):
        # 返回从pos位置开始的长度为num_steps的序列
        return corpus[pos: pos + num_steps]

    num_batches = num_subseqs // batch_size
    for i in range(0, batch_size * num_batches, batch_size):
        # 在这里,initial_indices包含子序列的随机起始索引
        initial_indices_per_batch = initial_indices[i: i + batch_size]
        X = [data(j) for j in initial_indices_per_batch]
        Y = [data(j + 1) for j in initial_indices_per_batch]
        yield np.array(X), np.array(Y)

my_seq = list(range(35))
# for X, Y in seq_data_iter_random(my_seq, batch_size=3, num_steps=5):
#     print('X: ', X, '\nY:', Y)
"""
X:  [[14 15 16 17 18]
 [19 20 21 22 23]
 [ 9 10 11 12 13]]
Y: [[15 16 17 18 19]
 [20 21 22 23 24]
 [10 11 12 13 14]]
X:  [[24 25 26 27 28]
 [29 30 31 32 33]
 [ 4  5  6  7  8]]
Y: [[25 26 27 28 29]
 [30 31 32 33 34]
 [ 5  6  7  8  9]]
"""

# 顺序分区
def seq_data_iter_sequential(corpus, batch_size, num_steps):  #@save
    """使用顺序分区生成一个小批量子序列"""
    # 从随机偏移量开始划分序列
    # random.randint(a, b) 会生成一个范围在 a 到 b 之间的整数,并且包括 a 和 b
    offset = random.randint(0, num_steps-1)
    # 根据偏移量和批量大小计算出可以使用的令牌数量,确保所有批次中的样本数量一致
    num_tokens = ((len(corpus) - offset - 1) // batch_size) * batch_size
    Xs = np.array(corpus[offset: offset + num_tokens]) # 数组
    Ys = np.array(corpus[offset + 1: offset + 1 + num_tokens])
    Xs, Ys = Xs.reshape(batch_size, -1), Ys.reshape(batch_size, -1)
    # print(Xs)
    #  [[ 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 30 31 32 33]]
    num_batches = Xs.shape[1] // num_steps
    for i in range(0, num_steps * num_batches, num_steps):
        X = Xs[:, i: i + num_steps]
        Y = Ys[:, i: i + num_steps]
        yield X, Y

# for X, Y in seq_data_iter_sequential(my_seq, batch_size=2, num_steps=5):
#     print('X: ', X, '\nY:', Y)
"""
X:  [[ 4  5  6  7  8]
 [19 20 21 22 23]]
Y: [[ 5  6  7  8  9]
 [20 21 22 23 24]]
X:  [[ 9 10 11 12 13]
 [24 25 26 27 28]]
Y: [[10 11 12 13 14]
 [25 26 27 28 29]]
X:  [[14 15 16 17 18]
 [29 30 31 32 33]]
Y: [[15 16 17 18 19]
 [30 31 32 33 34]]
"""

# 将上面的两个采样函数包装到一个类中, 以便稍后可以将其用作数据迭代器。
class SeqDataLoader:  #@save
    """加载序列数据的迭代器"""
    def __init__(self, batch_size, num_steps, use_random_iter, max_tokens):
        if use_random_iter:
            self.data_iter_fn = seq_data_iter_random
        else:
            self.data_iter_fn = seq_data_iter_sequential
        self.corpus, self.vocab = lp.load_corpus_time_machine(max_tokens)
        self.batch_size, self.num_steps = batch_size, num_steps

    def __iter__(self):
        return self.data_iter_fn(self.corpus, self.batch_size, self.num_steps)
    

def load_data_time_machine(batch_size, num_steps,  #@save
                           use_random_iter=False, max_tokens=10000):
    """返回时光机器数据集的迭代器和词表"""
    data_iter = SeqDataLoader(batch_size, num_steps, use_random_iter, max_tokens)
    return data_iter, data_iter.vocab
相关推荐
凳子花❀1 小时前
强化学习与深度学习以及相关芯片之间的区别
人工智能·深度学习·神经网络·ai·强化学习
泰迪智能科技013 小时前
高校深度学习视觉应用平台产品介绍
人工智能·深度学习
Jeremy_lf5 小时前
【生成模型之三】ControlNet & Latent Diffusion Models论文详解
人工智能·深度学习·stable diffusion·aigc·扩散模型
冰蓝蓝6 小时前
深度学习中的注意力机制:解锁智能模型的新视角
人工智能·深度学习
wydxry8 小时前
LoRA(Low-Rank Adaptation)模型微调
深度学习
唐小旭8 小时前
python3.6搭建pytorch环境
人工智能·pytorch·python
一只Black10 小时前
LSTM实现天气模型训练与预测
人工智能·rnn·lstm
IT古董10 小时前
【漫话机器学习系列】019.布里(莱)尔分数(Birer score)
人工智能·深度学习·机器学习
醒了就刷牙11 小时前
transformer用作分类任务
深度学习·分类·transformer
四口鲸鱼爱吃盐11 小时前
Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类
人工智能·pytorch·分类