RNN/LSTM (三) 学习torchtext源码

news2024/11/27 2:30:43

文章目录

  • 包装dataset
  • 构建词库
    • 1.列举数据源
    • 2. 遍历数据
    • 3. 列举特殊符号
    • 4. 构建词库 Field::vocab_cls
      • load_vectors
  • 构建读指针 data.BucketIterator

在上一文,我们学习了基于torchtext编写lstm模型的实践案例,本文将结合上文案例,深入案例代码,并借此学习torchtext的源码。

包装dataset

深入调试可知,首先DataFrameDataset.splits会要对train、test或val数据集调用构造函数,

@classmethod
def splits(cls, fields, train_df, val_df=None, test_df=None, **kwargs):
    train_data, val_data, test_data = (None, None, None)
    data_field = fields

    if train_df is not None:
        train_data = cls(train_df.copy(), data_field, **kwargs)
    if val_df is not None:
        val_data = cls(val_df.copy(), data_field, **kwargs)
    if test_df is not None:
        test_data = cls(test_df.copy(), data_field, True, **kwargs)

    return tuple(d for d in (train_data, val_data, test_data) if d is not None)

构造函数中会对这个dataframe遍历,调用data.Example.fromlist

class DataFrameDataset(data.Dataset):

    def __init__(self, df, fields, is_test=False, **kwargs):
        examples = []
        for i, row in df.iterrows():
            label = row.target if not is_test else None
            text = row.text
            examples.append(data.Example.fromlist([text, label], fields))

再深入这个fromlist方法,会被调用的if-else语句用注释进行了标注。

@classmethod
def fromlist(cls, data, fields):
    ex = cls()
    for (name, field), val in zip(fields, data):
        if field is not None:
            if isinstance(val, str):
                val = val.rstrip('\n')  # 被调用处
            # Handle field tuples
            if isinstance(name, tuple):
                for n, f in zip(name, field):
                    setattr(ex, n, f.preprocess(val))
            else:
                setattr(ex, name, field.preprocess(val))  # 被调用处
    return ex

截屏调试时的变量情况:

  • data有两个元素,分别是str形式的评论和0-1标签。
  • fields也有两个tuple元素,key为"text"的Field对象和key为"label"的LabelField对象。

preprocess函数会被调用,深入代码,下图中的红框部分被调用。调用了Field::tokenize后就返回x了,所以该函数只做了调用tokenize一件事。从下方截图也能看出,处理后的变量x是一个list的单词。

并没有调用self.preprocessing(x)

然后,这里的tokenize变量是一个partial偏函数,它在构造函数里赋值,调用的是torchtext的_spacy_tokenize函数。

self.tokenize = get_tokenizer(tokenize, tokenizer_language)

该函数使用了spacy的分词器功能,spacy是一个nlp工具库,可参考nlp工具库spacy。

所以总结而言,tochtext的data.Example.fromlist会将dataframe的单行数据转化为Example对象。每一列数据(句子和标签),都接受对应Field的预处理,然后设置到Example的属性中。而Dataset会持有这一组Example对象。

构建词库

这一步的核心是Field::build_vocab被调用,用于构建词库。

该函数的行为有4步,分别用红框标记了:

  1. 列举数据源
  2. 遍历每个数据源的每条数据。在本例中,只有一个数据源,它的效果相当于遍历train_ds.text,而每条数据x都是字符串的list
  3. 列举特殊符号,比如unk_token, pad_token等等。

1.列举数据源

看向第一个红框,为了编程鲁棒性,写的很复杂。sources保存的是一个个数据源,可供遍历。我们只按简单情况分析,在调用TEXT.build_vocab(train_ds,...时,只传入了一个Dataset参数,所以只有该对象的text成员会被添加到sources中。

2. 遍历数据

虽然为了编程鲁棒性,有两层for循环,但由于本文情况只有一个数据源,所以for循环的效果相当于下图。每个x都是字符串数组而已。

函数维护了一个Counter对象,它会对每种单词作计数。其Counter::update的demo如下:

from collections import Counter

c = Counter()
c.update(["the", "apple", "tree"])

# Counter({'the': 1, 'apple': 1, 'tree': 1})
print(c)  

所以当这一步执行完时,Counter维护了每个单词的出现次数。

3. 列举特殊符号


这一步写得复杂,只要管specials是一个字符串的list就好,内容是单纯的['<unk>', '<pad>']。不明白为什么要这么麻烦地将list转换为dict,又转换回list。

4. 构建词库 Field::vocab_cls

深入self.vocab_cls来到了Vocab对象的构造函数(没明白为什么,没看到对该变量的赋值)。
这个函数太长,此处就不截图了,仅讲结论。感兴趣可以自行调试。

  1. 准备变量。初始化min_freqmax_size等参数。
  2. 将单词按频率、字典序排序,得到words_and_frequencies
  3. 生成self.itosself.stoi,前者是list,用于将编号转换为单词;后者是dict,用于将单词转换为编号。
  4. 调用load_vectors,为每个词库里的单词加载向量,这些向量都是预先训练好的。

其它讲解如下:
specials_first会控制进行编号时,特殊符号编到头号(占据0号、1号等等),还是编到尾号(占据25000号、25001号)。在本例该值为True,所以编号时先编给specials符号。

defaultdict(self._default_unk_index)的用法可参考详解python中defaultdict用法、python中defaultdict用法详解。这里的函数在遇到未知单词时会直接返回0。_default_unk_index被调用会返回self.unk_index·,而后者在上一行被赋值了0。

def _default_unk_index(self):
      return self.unk_index

words_and_frequencies的大小为14278,而itos的大小为14280,相差的2就是特殊符号<unk><pad>。下面是三个变量的截图。

每次调试时,变量counter的单词数都不同,这并不是因为spacy的分词策略不幂等,而是因为train_test_split的分割具有随机性,所以每次运行时,分得的train_df和valid_df内容都不一样。

load_vectors

Field::vocab_cls在最后调用了load_vectors,其作用顾名思义,只是为了将词向量从已训练词库(本文是"‘glove.6B.200d’")中读出,并赋值给self.vectors。每个单词序号都有对应的词向量(包括特殊词汇<unk><pad>

该函数

下图是load_vectors的调试截屏。由于只使用一个词库,vectors长度仅为1。而从焦点行的行为可知,当使用了多个词库时,向量会横向拼接。

构建读指针 data.BucketIterator

train_iterator, valid_iterator = data.BucketIterator.splits(
        (train_ds, val_ds),
        batch_size = BATCH_SIZE,
        sort_within_batch = True,
        device = device)

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

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

相关文章

Python自动化之Excel利器openpyxl

文章目录前言一、Workbook1.1 读取xlsx文件1.2 保存二、Sheet2.1 创建Sheet2.2 遍历Sheet2.3 移动Sheet2.4 删除Sheet2.5 插入、删除行列三、单元格3.1 获取某个单元格3.2 遍历单元格3.3 获取范围单元格3.4 单元格赋值3.5 合并/解除合并单元格3.6 单元格数据格式3.7 单元格数字…

[附源码]Python计算机毕业设计Django儿童早教课程管理系统论文2022

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

算法设计与分析 SCAU19180 集合划分问题

19180 集合划分问题 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC;JAVA Description 教材课后习题2-8 n个元素的集合{1,2,…,n}可以划分若干个非空子集。例如&#xff0c;当n4时&#xff0c;集合{1,2,3,4}可以划分为15个不同的非…

微信小程序开发学习文档(万字总结,一篇搞定前端开发)

一、微信小程序简介 与网页开发不同&#xff0c;小程序有自己的一套标准开发模式&#xff1a;-申请小程序开发账号-安装小程序开发工具-创建和配置小程序项目 1.1 创建第一个小程序 1.2 主界面的5个组成部分 1.3小程序项目的基本构成 pages 用来存放所有小程序的页面&#xf…

Java并发编程—Thread类中的start()方法如何启动一个线程【原理分析】?

一、java线程的介绍&#xff1a; 在java的开发过程中&#xff0c;很多铁子对于java线程肯定不感到陌生&#xff0c;作为java里面重要的组成部分&#xff0c;这里就从如何创建一个线程给大家进行分析&#xff1b; 二、相关知识引入&#xff1a; ​ 之前我了解过&#xff0c;j…

2022年浙江省中职组“网络空间安全”赛项模块B--Windows渗透测试

2022年中职组浙江省“网络空间安全”赛项 B-1:Windows渗透测试一、竞赛时间 420分钟 共计7小时 吃饭一小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第①阶段: 单兵模式系统渗透测试 任务一: Windows操作系统渗透测试 任务二: Linux操作系统渗透测试 任务三…

[附源码]Python计算机毕业设计SSM科技项目在线评审系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

segmenter

patch embedding&#xff1a;例如输入图片大小为224x224&#xff0c;将图片分为固定大小的patch&#xff0c;patch大小为16x16&#xff0c;则每张图像会生成224x224/16x16196个patch&#xff0c;即输入序列长度为196&#xff0c;每个patch维度16x16x3768&#xff0c;线性投射层…

hexo+github手把手教你部署个人博客

一、安装并配置Node.js&#xff08;原本就有安装&#xff09; 参考&#xff1a;(1条消息) Node.js安装与配置&#xff08;详细步骤&#xff09;_普通网友的博客-CSDN博客_nodejs安装配置 一、下载Node.js官网下载 安装位置与环境变量配置 系统属性-环境变量-系统变量-Path 验…

129页4万字某智慧能源集团数字化管控平台项目 建设方案

目录 数字化管控平台相关项目建议书 1 目录&#xff1a; 1 一、相关项目背景 2 二、需求理解 3 2.1 需求理解 3 三、方案设计 5 3.1 整体方案设计 7 3.3.1 整体架构 7 3.3.2 解决方案说明 8 3.3.3 需求应答 10 3.2 数据仓库 11 3.2.1 数据仓库架构 11 3.2.2 数据仓库产品说明 1…

springMVC01,【第一个springMVC例子(注解版):HelloWorld】

springMVC01,【第一个springMVC例子-注解版&#xff1a;HelloWorld】创建项目1.配置web.xml2.编写spring配置文件3.controller层3.1RequestMapping注解4.运行测试5.小结链接: springMVC01,springMVC的执行流程【第一个springMVC例子&#xff08;XML配置版本&#xff09;&#x…

一种多引擎可视化数据流实现方案

企业大数据处理的挑战 随着大数据时代的到来&#xff0c;数据量迅猛增长&#xff0c;给传统的分析技术带来了巨大的冲击和挑战&#xff0c;企业面临着大数据处理的巨大挑战。将复杂的大数据处理问题进行简化&#xff0c;以便企业有更多人能够进行大数据处理&#xff0c;进而整…

使用azure-data factory

data-fatory介绍 Azure Data Factory&#xff08;简写 ADF&#xff09;是Azure的云ETL服务&#xff0c;简单的说&#xff0c;就是云上的SSIS。ADF是基于云的ETL&#xff0c;用于数据集成和数据转换&#xff0c;不需要代码&#xff0c;直接通过UI&#xff08;code-free UI&…

[附源码]SSM计算机毕业设计疫情防控期间人员档案追寻系统设计与实现论文JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

操作系统实验5:信号量的实现与应用

写在最前的总结 下面的实验内容是在完整做完实验时候补充的&#xff0c;这里先把踩过的坑记录一下。 调试总结 先在Ubuntu上模拟生产者—消费者问题。这个实验分为两大部分&#xff0c;一个是实现信号量&#xff0c;另一个是验证信号量。对于第二个&#xff0c;建议先在Ubun…

银河麒麟 linux V10 安装JDK

1、安装JDK之前&#xff0c;先查看系统是否已安装JDK相关软件包&#xff1a; 2. 如果已经安装过&#xff0c;可以先卸载&#xff08;可以跳过&#xff09; 3. 下载并解压jdk包 # 将下载好的jdk压缩包解压到指定目录/usr/local/jdk8 mkdir /usr/local/jdk8 cp jdk-8u271-linu…

详解设计模式:享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;&#xff0c;是对象池的一种体现&#xff0c;也是 GoF 的 23 种设计模式中的一种结构型设计模式。 享元模式 主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象…

[附源码]Python计算机毕业设计SSM跨移动平台的新闻阅读应用(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

二、Eureka服务注册与发现

Eureka服务注册与发现 Eureka基础知识 什么是服务治理 SpringCloud封装了Netflix公司开发的Eureka模块来实现服务治理。 在传统的RPC远程调用框架中&#xff0c;管理每个服务与服务之间依赖关系比较复杂、所以需要进行服务治理&#xff0c;管理服务与服务之间依赖关联&…

网上商店商城购物系统(asp.net,sqlserver,三层架构)

网上商店商城购物系统(asp.net,sqlserver,三层)(毕业论文10000字以上,程序代码,SqlServer数据库) 【运行环境】 VisualStudio SqlServer 代码下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1gzX_-Dzrt5jDHvQOCTN7qQ 提取码&#xff1a;8888 【项目包含内容…