d2l语言模型--生成小批量序列

news2025/1/23 13:58:57

对语言模型的数据集处理做以下汇总与总结

目录

1.k元语法

1.1一元

1.2 二元

1.3 三元

2.随机抽样

 2.1各bs之间随机

2.2各bs之间连续

3.封装


1.k元语法

1.1一元

tokens = d2l.tokenize(d2l.read_time_machine())
# 因为每个⽂本⾏不⼀定是⼀个句⼦或⼀个段落,因此我们把所有⽂本⾏拼接到⼀起
corpus = [token for line in tokens for token in line]
vocab = d2l.Vocab(corpus)

  看看得到了什么:corpus为原txt所有词汇拉成一维list;token_freqs为按1元语法统计的token-freqs列表。

vocab.token_freqs[:10], corpus[:20]

'''
([('the', 2261),
  ('i', 1267),
  ('and', 1245),
  ('of', 1155),
  ('a', 816),
  ('to', 695),
  ('was', 552),
  ('in', 541),
  ('that', 443),
  ('my', 440)],
 ['the',
  'time',
  'machine',
  'by',
  'h',
  'g',
  'wells',
  'i',
  'the',
  'time',
  'traveller',
  'for',
  'so',
  'it',
  'will',
  'be',
  'convenient',
  'to',
  'speak',
  'of'])
'''

1.2 二元

  二元即为将前后两词连在一起当作一个词元,其token为一个包含tuple的list,其中每个tuple为元txt各2个相邻词组成。

bigram_tokens = [pair for pair in zip(corpus[:-1], corpus[1:])]
bigram_vocab = d2l.Vocab(bigram_tokens)
# 返回
bigram_vocab.token_freqs[:10],bigram_tokens[:5]

'''
([(('of', 'the'), 309),
  (('in', 'the'), 169),
  (('i', 'had'), 130),
  (('i', 'was'), 112),
  (('and', 'the'), 109),
  (('the', 'time'), 102),
  (('it', 'was'), 99),
  (('to', 'the'), 85),
  (('as', 'i'), 78),
  (('of', 'a'), 73)],
 [('the', 'time'),
  ('time', 'machine'),
  ('machine', 'by'),
  ('by', 'h'),
  ('h', 'g')])
'''

  其中,讲一下相邻2词的实现:

bigram_tokens = [pair for pair in zip(corpus[:-1], corpus[1:])]
bigram_tokens[:5]

'''
[('the', 'time'),
 ('time', 'machine'),
 ('machine', 'by'),
 ('by', 'h'),
 ('h', 'g')]
'''

  传入Vocab的tokens为一个list,如果是2维list则会展平成1维;如果本身就为1维则直接对里面的每个元素进行操作

 注意,二元语法中传入Vocab的bigram_tokens是如图组成的二元语法,里面每个元素为前后相邻两个字符串为元组的list,在计数的时候不会被拉成1维的list,因为其本身每个需要计数的元素就是bigram_tokens里面的每个元素(二元元组)

1.3 三元

类似的操作:

trigram_tokens = [triple for triple in zip(
    corpus[:-2], corpus[1:-1], corpus[2:])]
trigram_vocab = d2l.Vocab(trigram_tokens)
trigram_vocab.token_freqs[:10]

'''
[(('the', 'time', 'traveller'), 59),
 (('the', 'time', 'machine'), 30),
 (('the', 'medical', 'man'), 24),
 (('it', 'seemed', 'to'), 16),
 (('it', 'was', 'a'), 15),
...]
'''

实现细节:

corpus[-7:], corpus[:-2][-5:], corpus[1:-1][-5:], corpus[2:][-5:]

'''
(['lived', 'on', 'in', 'the', 'heart', 'of', 'man'],
 ['lived', 'on', 'in', 'the', 'heart'],
 ['on', 'in', 'the', 'heart', 'of'],
 ['in', 'the', 'heart', 'of', 'man'])
'''

2.随机抽样

  任务,给定一个corpus为所有单词拼起来的一维list,输出X,Y,尺寸为(bs,T),实现如下的分割,注意前k个和最后若不足以配T个的就都扔了。

 2.1各bs之间随机

def seq_data_iter_random(corpus, batch_size, num_steps): #@save
    """使⽤随机抽样⽣成⼀个⼩批量⼦序列"""
    # 从随机偏移量开始对序列进⾏分区,随机范围包括num_steps-1
    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 torch.tensor(X), torch.tensor(Y)

  num_steps相当于T,表示切分的每个子块中含有多少个词
  corpus考虑对前K个,随机切除,前K个就不要了
  num_subseqs是看切后的corpus能组成多少个T的块,采用向下取整。在这里为31//5=6
  initial_indices计算每个子序列块起始位置的索引
  num_batches表示用块的个数除bs,向下取整
  for loop 里面i的分割是bs,保证后面取bs个起始位置时不会取重:(见下图例子)

 initial_indices_per_batch表示从块起始索引位置list中,抽取bs个起始位置。

my_seq = list(range(35))
for X, Y in seq_data_iter_random(my_seq, batch_size=2, num_steps=5):
    print('X: ', X, '\nY:', Y)

'''
X:  tensor([[22, 23, 24, 25, 26],
        [ 2,  3,  4,  5,  6]]) 
Y: tensor([[23, 24, 25, 26, 27],
        [ 3,  4,  5,  6,  7]])
X:  tensor([[17, 18, 19, 20, 21],
        [ 7,  8,  9, 10, 11]]) 
Y: tensor([[18, 19, 20, 21, 22],
        [ 8,  9, 10, 11, 12]])
X:  tensor([[12, 13, 14, 15, 16],
        [27, 28, 29, 30, 31]]) 
Y: tensor([[13, 14, 15, 16, 17],
        [28, 29, 30, 31, 32]])
'''

  X,Y均为(bs,T).

  22预测23;22,23预测24;22,23,24预测25...

2.2各bs之间连续

def seq_data_iter_sequential(corpus, batch_size, num_steps): #@save
    """使⽤顺序分区⽣成⼀个⼩批量⼦序列"""
    # 从随机偏移量开始划分序列
    offset = random.randint(0, num_steps)
    num_tokens = ((len(corpus) - offset - 1) // batch_size) * batch_size
    Xs = torch.tensor(corpus[offset: offset + num_tokens])
    Ys = torch.tensor(corpus[offset + 1: offset + 1 + num_tokens])
    Xs, Ys = Xs.reshape(batch_size, -1), Ys.reshape(batch_size, -1)
    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

  num_batches表示能输出几个bs,后面不够bs的都扔掉:

  对应这3个:

 与random一样,核心都是块数//bs,其中块数=cor//num_step(T)

3.封装

class SeqDataLoader: #@save
    """加载序列数据的迭代器"""
    def __init__(self, batch_size, num_steps, use_random_iter, max_tokens):
        if use_random_iter:
            self.data_iter_fn = d2l.seq_data_iter_random
        else:
            self.data_iter_fn = d2l.seq_data_iter_sequential
        self.corpus, self.vocab = d2l.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)

对于其中的iter:

 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

认识C++指针

目录 前言: 1.指针未初始化的危险性 2.指针与十六进制数字 3.使用new分配内存空间 4.使用delete释放内存 5.使用new来创建动态数组 6.使用动态数组 7.指针运算 前言: 期待已久的指针篇来啦,这篇全都是有关指针的知识,喜欢…

【Matlab算法】粒子群算法求解二维线性优化问题(附MATLAB代码)

MATLAB求解二维线性优化问题前言正文函数实现可视化结果前言 二维线性优化问题指的是在二维空间中,对于一个由线性函数构成的目标函数,通过限制自变量的范围或满足特定的约束条件,寻找一个最优解(最小值或最大值)。这…

【精华】表格结构识别模型研究进展

表格结构识别模型研究进展 合合信息:表格识别与内容提炼技术理解及研发趋势 OCR之表格结构识别综述 表格识别技术综述 用于表检测和结构识别的深度学习:综述 (1)PP-Structure 速度提升11倍,一键PDF转Word PP-St…

MATLAB | 这些各种各样的花里胡哨的折线填充图咋画

这些各种各样的花里胡哨的折线填充图咋画? 折线下面填充纯色的话area函数很容易做到,但上面那些各种花里胡哨的填充图就没那么容易做到了,本期就来讲讲这些玩意都是咋画的: 事先说明,为了绘图好看本文绝大多数图像都使…

Vue3步骤条(Steps)

Vue2步骤条&#xff08;Steps&#xff09; 可自定义设置以下属性&#xff1a; 步骤数组&#xff08;steps&#xff09;&#xff0c;类型&#xff1a;Array<{title?: string, description?: string}>&#xff0c;默认 [] 当前选中的步骤&#xff0c;设置 v-model 后&a…

Java13-多线程

一&#xff1a;基本概念&#xff1a;程序&#xff0c;进程&#xff0c;线程 程序&#xff1a; 是完成特定任务&#xff0c;用某种语言编写的一组指令集合&#xff0c;即指一段静态的代码。 进程&#xff1a;是程序的一次执行过程&#xff0c;或是正在运行的一个程序。 线程&…

Linux系统之MobaXterm远程连接centos的GNOME桌面环境

Linux系统之MobaXterm远程连接centos的GNOME桌面环境一、MobaXterm介绍1.MobaXterm简介2.MobaXterm功能特点二、centos安装GNOME桌面1.本地环境介绍2.安装GNOME桌面环境3.本地进入Linux桌面三、MobaXterm远程连接centos1.打开MobaXterm软件2.远程连接本地Linux系统四、远程连接…

如何利用ChatGPT辅助优化刷题性能

根据土著刷题共建群里的一个小伙伴反馈&#xff0c;刷题会出现切题卡顿的情况&#xff0c;有时会出现滑不动的情况。 定位问题 为了定位切题卡顿问题的具体原因&#xff0c;测试了高低端手机&#x1f4f1;、切换2G、3G、4G低网络状态等各种影响切题的现实情况&#xff0c;经过借…

门店零售系统有哪些功能模块?能带来哪些帮助?

门店零售系统是一种用于管理门店销售、库存、采购等业务的软件系统&#xff0c;可以帮助门店提高管理效率、降低操作风险、优化运营决策&#xff0c;从而增强市场竞争力和顾客满意度。 一、门店零售系统的4大功能 1、商品管理 该模块主要用于管理门店的商品信息&#xff0c;包…

arcgis中地理配准之栅格平移

背景 前面写过一篇文章,是针对有两个对应的栅格数据进行配准的 Arcgis地理配准栅格数据 有时候需要没有对应的栅格数据,只有单幅栅格数据,而且知道平移参数,这时候可以通过平移参数来平移栅格,而且在unity中不能直接识别坐标值很大的数据,只能通过平移将坐标值减少,才…

【分布式事务AT模式 SpringCloud集成Seata框架】分布式事务框架Seata详细讲解

前言 上篇文章我们讲述了如何启动seata的本地服务&#xff0c;并且注册到nacos使用&#xff0c;这篇文章将在SpringCloud中整合Seata框架 上篇文章传送门&#xff1a;https://blog.csdn.net/Syals/article/details/130102851?spm1001.2014.3001.5501 本篇主要内容&#xff…

Docker几个概念

Docker几个概念&#xff0c;有不正确地方欢迎指正 一、首先来看一句话&#xff1a;没有Cgroups就没有LXC&#xff0c;没有LXC就没有Docker。 1、什么是Cgroup呢&#xff1f;Cgroup又名Control group&#xff0c;是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理…

VLAN 基础与划分及配置

我们都知道 VLAN 的中文名为"虚拟局域网"&#xff0c;VLAN 是一种将局域网设备从逻辑上划分成一个个不同的网段&#xff0c;从而实现虚拟工作组的新兴数据交换技术。这一新兴技术主要应用于交换机和路由器中&#xff0c;但主流应用还是在交换机之中。那今天咱们就和海…

Linux网络连接出现问题

报错截图 1.先查看NetworkManager是否启动 systemctl status NetworkManager如果输出结果中包含 "active (running)" 表示 NetworkManager 已经启动并正在运行 2.查看DNS是否配置 cat vim /etc/resolv.conf 1.查看是否有配置信息&#xff0c;如果没有请配置DNS …

华为ACL配置

模拟场景 服务器&#xff1a;192.168.3.100 销售部&#xff1a;192.168.1.1 开发部&#xff1a;192.168.2.1 模拟互联网&#xff1a;1.1.1.1 要求1&#xff1a;销售部不允许访问服务器 要求2&#xff1a;开发部可以访问服务器 要求3&#xff1a;互联网不可以访问服务器 拓扑图…

栈和队列经典题题解

目录 &#x1f349;一.括号匹配问题&#x1f349; &#x1f348;二.用队列实现栈&#x1f348; &#x1f34f;三.用栈实现队列&#x1f34f; &#x1f353;四.设计循环队列&#x1f353; &#x1f349;一.括号匹配问题&#x1f349; OJ链接力扣 题目描述&#xff1a; 思路&…

77-Linux_网络编程

网络编程一.主机字节序列和网络字节序列二.套接字地址结构1.通用socket地址结构2.专用的socket地址结构3.IP地址转换函数一.主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序&#xff0c;不同的主机采用的字节序列可能不同。 大端字节序是指一个整数的高位…

开店必备的5款超实用零售管理软件,第1个新手也能轻松使用!

现在越来越多的零售店老板都开始用零售管理软件来管理门店&#xff0c;提升效率&#xff0c;节约人力和时间成本。 但对于刚刚接触零售管理软件的老板来说&#xff0c;应用市场上的零售管理软件那么多&#xff0c;究竟哪些好用&#xff0c;哪些容易上手……还不太了解。 别着急…

CMake项目使用ctest+gtest进行单元测试

随着CMake工具越来越强大便捷&#xff0c;越来越多的C/C项目转而使用CMake来进行编译管理&#xff0c;它还提供了用于测试的ctest命令来执行项目中编写的单元测试。 本文就以一个实例来介绍如何使用ctest来进行单元测试。 一、环境准备 本文实例环境VSCodeMinGW64CMakegtest…

Qt程序CPU过高怎么定位解决?性能优化

自己开发的一个程序采用多线程调用url从网络上下载股票数据&#xff0c;一旦开启程序就特别的卡&#xff1b;想着优化一下&#xff1b;授之于鱼&#xff0c;不如 授之以渔&#xff1b; 1.CPU过高排查方法 &#xff08;1&#xff09;打开vs的性能探测器&#xff1b; &#xff…