class _NamespaceDependentDefaultDict(defaultdict)
记录non_padded_namespaces(哪些namespace不需要pad,例如tags,labels),以及如何进行pad(padded_function),或者不pad(non_padded_function)
def missing(self, key: str): 处理
如果key在non_padded_namespaces中,返回_non_padded_function
如果key不在non_padded_namespaces中,返回_padded_function

defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值
defaultdict类除了接受类型名称作为初始化函数的参数之外,还可以使用任何不带参数的可调用函数,到时该函数的返回结果作为默认值,这样使得默认值的取值更加灵活。
defaultdict类中通过__missing__()实现默认值的功能,当访问不存在的键时,dict[key]会调用__missing__()方法取得默认值。
python中defaultdict方法的使用

class _TokenToIndexDefaultDict
从_NamespaceDependentDefaultDict派生,padded_function为lambda: {padding_token: 0, oov_token: 1},即pad(无意义的填充词)为0,oov(词典中没有的词)为1

class _IndexToTokenDefaultDict
从_NamespaceDependentDefaultDict派生,padded_function为lambda: {0: padding_token, 1: oov_token},即0为pad(无意义的填充词),1为oov(词典中没有的词)

以上两个词典实际为两层的词典,例如{"labels":{"@@PADDING@@":0,"@@UNKNOWN@@":1}},{"tokens":{"word":10}}
一个巧妙的地方在于,基类的__missing__()方法中,判断如果某个命名空间不在词典中,则在添加命名空间时,判断它是不是需要pad,如果需要pad,则先把{"@@PADDING@@":0,"@@UNKNOWN@@":1}设置为这个命名空间的值。

_read_pretrained_tokens(embeddings_file_uri: str)
从txt或者压缩文件(zip/tar/…)获得所有token,返回值tokens: List[str]
文件中存embedding的形式为word XXXXXX,即词与对应的embedding中间有一个空格,一行是一个词的。

def pop_max_vocab_size(params: Params)
从配置中获得词典中值的数量,返回int或Dict[str, int](多个词典)

class Vocabulary(Registrable)

  1. 词汇表将字符串映射到整数,允许将字符串映射到词典外的标记(OOV)。
  2. 词汇表匹配特定的数据集,用它来判断哪些token是在词典内。
  3. 词汇表还允许使用多个不同的命名空间,因此可以将“a”作为单词和“a”作为单词使用单独的索引,因此可以使用此命名空间将标记和标签字符串映射到索引(通过Field.index方法)。统一地,class:fields.field.Field (各种Field的基类), 此类中的大多数方法都允许传入命名空间;默认使用’tokens’命名空间,可以省略命名空间参数,只使用默认值。
  4. 命名空间:Instance的key(根据Instance向词典添加元素时获得命名空间),Indexer的namespace属性(token转index时添加命名空间)
  5. Vocabulary类只是管理token与index的关系,OOV,PAD,而index,计数,转tensor的工作在Field类中进行。

构造参数

  1. counter: Dict[str, Dict[str, int]] = None,计数器,用来初始化内部两个词典,具体地,Dict[str(命名空间), Dict[str(词), int(数量)]] 。Vocabulary只是记录token和index的关系,用这个counter传入instance最终在Field进行计数。
  2. min_count: Dict[str, int] = None,对于某个词的计数少于一个值时,不加入词典;可以对不同的命名空间设置不同的最小值
  3. max_vocab_size: Union[int, Dict[str, int]] = None,限制词典最大词数;可以对不同的命名空间设置不同的最大值
  4. non_padded_namespaces: Iterable[str] = DEFAULT_NON_PADDED_NAMESPACES,默认为("*tags", “*labels”),命名空间为tags、labels或后缀是tags/labels,在后面的处理中,不进行pad
  5. pretrained_files: Optional[Dict[str, str]] = None,命名空间中的词都可以从已有的embedding文件获取。如果6为False,那么数据集中新出现的词会加入词典;如果为True,则词典中只用embedding文件中加载的词。
  6. only_include_pretrained_words: bool = False
  7. tokens_to_add: Dict[str, List[str]] = None,手动向命名空间添加词
  8. min_pretrained_embeddings: Dict[str, int] = None,如果不为None,则从命名空间对应的预训练embedding文件中取出前k个词,加入词典

词典

Vocabulary中用两个词典记录token到index,index到token。
他们是两层的词典,第一层是{命名空间:词典},第二层词典是token和index的对应。
self._token_to_index = _TokenToIndexDefaultDict
self._index_to_token = _IndexToTokenDefaultDict

方法

_extend():向初始化的Vocabulary传数据建立词典,或拓展已有的词典,把tokens填充进词典,需要注意的是,用来创建词典的词有三个来源:1.数据集(instances)得到的(counter),2.预训练词嵌入文件(pretrained_files), 3.手动添加的词(tokens_to_add),3是最后加入词典的。
如果数据集中得到token先用词数进行排序,因此出现多的词在前面。
预训练词嵌入文件在counter中没有出现的词,没有加入词典。

add_token_to_namespace(self, token: str, namespace: str = ‘tokens’):把单词(按顺序,而不是插入加入到指定的命名空间中,

建立词典

一、读取词典文件

def from_files(cls, directory: str) -> 'Vocabulary’
读取vocabulary目录下的所有文件,例如non_padded_namespaces.txt,tokens.txt,token_characters.txt。。。最后调用vocab.set_from_file(filename, is_padded, namespace=namespace),由一个个命名空间构造出词典。

def set_from_file(self,filename: str,is_padded: bool = True,oov_token: str = DEFAULT_OOV_TOKEN,namespace: str = "tokens")

filename为non_padded_namespaces.txt这些文件的路径
is_padded指这个命名空间是不是需要pad的(tags与labels为False),如果需要pad,则词典的0号位置为@@PADDING@@
oov_token用哪个词代表OOV词,默认为@@UNKNOWN@@,在txt文件中可以看到第一个位置是@@UNKNOWN@@,如果is_padded=True,则@@UNKNOWN@@在1号位置。
namespace表示在那个命名空间。

读取embedding文件是逐行进行的,加入到词典时也是按照顺序的,因此词典中的词与文件中词的顺序对应,用来进行词嵌入。

二、从实例(instances)创建词典

Instance(Mapping[str, Field]),Instance包含若干个Field,Field的count_vocab_items方法各自不同。

每个instance调用count_vocab_items
namespace_token_counts: Dict[str(命名空间), Dict[str(词), int(数量)]]instance.count_vocab_items(namespace_token_counts)-------------->count_vocab_items()内部调用每个field的count_vocab_items()for field in self.fields.values():field.count_vocab_items(counter)

例如TextField,类中包括List[Token],token_indexers: Dict[str, TokenIndexer]。
token_indexers可以将tokens进行不同的转换,例如cat可以转换为34,也可以根据字符转换为[23, 10, 18],还有其他的方式。。。

    def count_vocab_items(self, counter: Dict[str, Dict[str, int]]):for indexer in self._token_indexers.values():for token in self.tokens:indexer.count_vocab_items(token, counter)

indexs下次单独学习,这里只是了解一下count_vocab_items做了什么。
以SingleIdTokenIndexer为例,在这里词作为一个整体。count_vocab_items方法中用一个计数器对单词进行计数,计数结果存在indexer设置的namespace中。
counter[self.namespace][text] += 1

三、配置文件创建词典

读取配置文件创建Vocabulary部分可以在trainer.py的TrainerPieces类的from_params方法中找到。

 if recover and os.path.exists(os.path.join(serialization_dir, "vocabulary")):vocab = Vocabulary.from_files(os.path.join(serialization_dir, "vocabulary"))params.pop("vocabulary", {})else:vocab = Vocabulary.from_params(params.pop("vocabulary", {}),(instance for key, dataset in all_datasets.items()for instance in datasetif key in datasets_for_vocab_creation))
  1. 如果上次训练中断,这次训练设置-r,即恢复之前的训练,则词典通过Vocabulary.from_files读取建立好的词典文件建立。
  2. 如果直接建立词典,则先读取数据集,词典通过Vocabulary.from_params,把Vocabulary的参数和读取数据集得到的Instances传入from_params。在from_params中进行一系列参数设置,进入Vocabulary.from_instances,通过数据集,建立词典。

AllenNLP源码学习——Vocabulary相关推荐

  1. ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ★★★ 本文源自AlStudio社区精品项目,[点击此处]查看更多精品内容 >>> ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由 ...

  2. 文心ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由ERNIE发展起来的文心大模型,是GPT3.0的强劲竞争对手,未来还会挑战ChatGPT的江湖地位! ...

  3. Shiro源码学习之二

    接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws Authent ...

  4. Shiro源码学习之一

    一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId&g ...

  5. mutations vuex 调用_Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)...

    前言 Vuex源码系列不知不觉已经到了第六篇.前置的五篇分别如下: 长篇连载:Vuex源码学习(一)功能梳理 长篇连载:Vuex源码学习(二)脉络梳理 作为一个Web前端,你知道Vuex的instal ...

  6. vue实例没有挂载到html上,vue 源码学习 - 实例挂载

    前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...

  7. 2021-03-19Tomcat源码学习--WebAppClassLoader类加载机制

    Tomcat源码学习--WebAppClassLoader类加载机制 在WebappClassLoaderBase中重写了ClassLoader的loadClass方法,在这个实现方法中我们可以一窥t ...

  8. jQuery源码学习之Callbacks

    jQuery源码学习之Callbacks jQuery的ajax.deferred通过回调实现异步,其实现核心是Callbacks. 使用方法 使用首先要先新建一个实例对象.创建时可以传入参数flag ...

  9. JDK源码学习笔记——Integer

    一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...

最新文章

  1. python一年365天、初始水平值_2020年11月7日,20201107
  2. 软件工程导论 银行储蓄系统_独家:重庆农商行客户存款被盗刷 银行却责怪客户用卡不规范...
  3. 1_1 FactoryMode 工厂模式
  4. 记录: 开发中的2个线程的使用问题
  5. python——函数 11、命名空间
  6. 又拍云 php5月18号那,又拍云文档中心
  7. php config(),php config
  8. 微服务和数据库到底是什么关系?
  9. [20170604]12c Top Frequency histogram补充.txt
  10. stm32运行java_STM32之——3种启动方式学习
  11. 「leetcode」257. 二叉树的所有路径(详解)
  12. Android源码打patch
  13. Eastfax使用技巧
  14. Pandas的crosstab函数
  15. 每日一支TED——Ethan Nadelmann:为什么我们应该终止禁毒战争
  16. 产品经理如何建立和促进心理安全
  17. 2019年程序员最值得选择的100家互联网公司排名
  18. raid卷的作用_Raid卷详解
  19. Java SE 网络编程
  20. [编程题] 创造新世界

热门文章

  1. 计算机里的公共汽车(总线)
  2. vc应用程序——个性化的工具条图标
  3. 因为计算机中丢失pff,PFF文件扩展名 - 什么是.pff以及如何打开? - ReviverSoft
  4. faric区块链浏览器搭建
  5. RemoteViews的作用和工作原理
  6. mysql s1009_mysql 学习笔记
  7. 数据中心的基本模块包括服务器,模块化数据中心的主要组成部分
  8. 如何避免成为一个油腻的前端
  9. python3 字体颜色_python3使用xlwt时写入文档字体颜色和边框样式
  10. 树莓派CM4_3xPCIE扩展板(SSD+WIFI6+USB3.0+5G+4G)——SSD固态盘测速