有一篇帖子总结了一下学习处理NLP问题中间的坑。NLP数据预处理要比CV的麻烦很多。
- 去除停用词,建立词典,加载各种预训练词向量,Sentence -> Word ID -> Word Embedding的过程(Tobias Lee:文本预处理方法小记),其中不仅需要学习pytorch,可能还要学习spacy,NLTK,numpy,pandas,tensorboardX等常用python包。
- 用到RNN时,还要经过pad,pack,pad的过程,像这样的很多函数在使用时需要有数学基础加上简单的实践,感觉对一个新人来说,高维数据的流动有点抽象,不容易理解。
- 数据集的读取,tensorboardX的使用。。。。各种东西要学习。在运行别人的代码后打印出信息,不仅看着上档次,而且可以看到很多实用的信息。。。
AllenNLP是在pytorch基础上的封装,它的目标是处理NLP任务,可以减少很多额外的学习。
- 分词,帮你用spacy,NLTK,或者简单的按空格分词处理。
- 数据集的读取,它内置了很多数据集的读取,你可以在通过学习它的读取方式,在它的基础上对自己需要的数据集进行读取。 、
- 在Sentence -> Word ID -> Word Embedding的过程中,Glove,ELMo,BERT等常用的都可以直接使用,需要word,char粒度的都可以。
- log打印输出,在内置的输出项之外,你可以很方便地加入想要输出的信息。模型的各个组件中的参数都可以存在一个json/jsonnet文件中,修改参数进行实验很方便。
1. Getting Started
Laziness in AllenNLP(懒惰的AllenNLP?)
正常情况下DatasetReader返回的是一个包含有数据集中每一个实例的list,但是在以下情况下,你可能不想用这个操作:
- 数据集过大,无法放入内存中
- 希望每次迭代通过数据集进行某种抽样
- 希望数据马上进入训练,而不是等待数据集加载完成
在这些情况下,你会希望你的DatasetReader“懒惰”;可以尽可能地创建和生成实例。本文就是为了说明如何进行操作。
在DatasetReader构造函数中指定laziness
可以看到DatasetReader构造函数只有一个参数,lazy: bool = False
def __init__(self, lazy: bool = False) -> None:
self.lazy = lazy
表明如果希望DatasetReader的子类使用laziness,其构造函数需要将一个lazy值传递给DatasetReader构造函数,并且其from_params方法需要允许这样的参数。
AllenNLP中包含的所有数据集读取器都是以这种方式构建的。
在DatasetReader.read中的laziness
DatasetReader的一个主要接口是read方法,是基于以下基础类实现
def read(self, file_path: str) -> Iterable[Instance]:
if self.lazy:
return _LazyInstances(lambda: iter(self._read(file_path)))
else:
return ensure_list(self._read(file_path))
这意味着结果是一个迭代,可以使用lambda进行传递,每次传递都会调用self._read(file_path)。
另一方面,如果用户需要调用自己的数据集,可以像下面这样使用
reader = MyDatasetReader(lazy=True)
instances = reader.read('my_instances.txt')
for epoch in range(10):
for instance in instances:
process(instance)
每次迭代,"for instance in instances"的结果都会新调用DatasetReader.read(),新的实例从磁盘中读取10次。
在YourDatasetReader._read()中的laziness
实现一个新的DatasetReader子类,需要覆盖私有方法
def _read(self, file_path:str)-> Iterable[Instance]:
使用逻辑生成数据集中所有实例。
这种实现会返回一个列表,但是要强烈考虑将_read实现为一次生成一个实例的生成器;否则数据集读取器不能以lazy的方式使用。 (实际上,如果_read()实现返回一个列表,如果您尝试在数据集读取器中设置lazy = True,则会收到错误。)
def _read(self, file_path: str) -> Iterable[Instance]:
# logic to iterate over file
# some kind of for loop
# instance = ...
yield instance
网友评论