diff --git a/fastNLP/core/dataloaders/jittor_dataloader/fdl.py b/fastNLP/core/dataloaders/jittor_dataloader/fdl.py index 32d1d290..78479ce3 100644 --- a/fastNLP/core/dataloaders/jittor_dataloader/fdl.py +++ b/fastNLP/core/dataloaders/jittor_dataloader/fdl.py @@ -21,7 +21,7 @@ from fastNLP.core.dataset import DataSet as FDataSet class _JittorDataset(Dataset): """ - 对用户传的dataset进行封装,以便JittorDataLoader能够支持使用自定义的dataset使用jittor的dataset + 对用户传的dataset进行封装,以便JittorDataLoader能够支持使用自定义的dataset """ def __init__(self, dataset) -> None: @@ -35,7 +35,10 @@ class _JittorDataset(Dataset): class JittorDataLoader: """ - 提供给使用jittor框架的DataLoader函数,提供了auto_collate的功能, 支持实现了__getitem__和__len__的dataset + 提供给使用jittor框架的DataLoader函数,其能够自动检测数据的类型并判断是否能够pad,若能会自动pad数据,默认pad_val=0; + 用户可以调用set_pad方法来更改pad_val的值,也可以自定义针对某个field的callate_fn传入到set_field;若用户不想自动pad某个field, + 则可以调用set_ignore来忽略对某个field的检测和pad。值得注意的是JittorDataLoader输入dataset只要是实现了__getitem__和__len__方法即可。 + """ def __init__(self, dataset, batch_size: int = 16, shuffle: bool = False, @@ -44,16 +47,25 @@ class JittorDataLoader: collate_fn: Union[None, str, Callable] = "auto") -> None: """ - :param dataset: 实现__getitem__和__len__的dataset + :param dataset: 实现``__getitem__``和``__len__``的dataset :param batch_size: 批次大小 :param shuffle: 是否打乱数据集 - :param drop_last: 是否去掉最后一个不符合batch_size的数据 - :param num_workers: 进程的数量,当num_workers=0时不开启多进程 - :param buffer_size: + :param drop_last: 是否去掉最后一个不符合``batch_size``的数据 + :param num_workers: 进程的数量,当``num_workers=0``时不开启多进程 + :param buffer_size: 每个进程占用的内存空间,默认为512M。主要是配合num_workers使用,用户可以自定义每个进程的内存大小。 :param stop_grad: - :param keep_numpy_array: - :param endless: - :param collate_fn: 对取得到的数据进行打包的callable函数 + :param keep_numpy_array: 返回的数据是``np.array`类`型而不是``jittor.array``类型,默认为``False`` + :param endless: 是否让``JittorDataLoader``无限返回数据,也就是将dataset循环使用使得返回数据是没有限制的。默认为``False``. + :param collate_fn: 用来对从dataset取到的数据进行打包处理成batch的callable函数,其值应该为一下三个:``[None, "auto", callable]``. + + * ``callate_fn=None``时,第一点值得注意的是此时传进来的datset不能为``fastNLP``的dataset,采用fastNLP的dataset时,``collate_fn``不能为``None``; + 第二点注意的是此时``JittorDataLoader``会调用默认的`callate_batch`函数对sampler到的数据进行简单打包,组成一个batch返回。` + * ``callate_fn="auto"``时,``JittorDataLoader``会自动调用``fastNLP``自带的``Collator``,其会自动检测dataset的每个``field``, + 并判断是否能够pad处理,若能则会自动进行pad操作,默认``pad_val=0``。若想要更改其值,可调用``set_pad``方法;若不想自动pad某个field, + 可以调用``set_ignore``方法忽略某个field。 + * ``callate_fn=callable``时,callable函数是用户自定义的callate_fn函数,此时``JittorDataLoader``会调用传进来的callable函数对 + 数据进行打包处理并返回。值得注意的是用户自定义的callable函数的输入为batch,batch为list类型数据,其中batch的每一条数据都为dataset的一条数据。 + """ # TODO 验证支持replacesampler (以后完成) 增加Sampler # 将内部dataset批次设置为1 diff --git a/fastNLP/core/dataloaders/mix_dataloader.py b/fastNLP/core/dataloaders/mix_dataloader.py index 7ff3eb32..d6f6a9be 100644 --- a/fastNLP/core/dataloaders/mix_dataloader.py +++ b/fastNLP/core/dataloaders/mix_dataloader.py @@ -23,7 +23,6 @@ class _MixDataset: """ def __init__(self, datasets: list = None) -> None: """ - :param datasets: 数据集的列表 """ self.datasets = datasets @@ -36,8 +35,9 @@ class _MixDataset: def __getitem__(self, idx: Union[int, List[int]]) -> Union[Tuple[Instance, int], Tuple[DataSet, int]]: """ + 根据index索引获取数据 - :param idx: + :param idx: 整数类型的index或者列表 :return: """ if isinstance(idx, int): diff --git a/fastNLP/core/dataloaders/paddle_dataloader/fdl.py b/fastNLP/core/dataloaders/paddle_dataloader/fdl.py index ce1159fb..b0676a74 100644 --- a/fastNLP/core/dataloaders/paddle_dataloader/fdl.py +++ b/fastNLP/core/dataloaders/paddle_dataloader/fdl.py @@ -1,3 +1,31 @@ +""" +``PaddleDataLoader``是专门提供给``paddle``框架的``DataLoader``,其集成了``fastNLP``的``Collator``并对``paddle``的``DataLoader``进行了 +封装,使得其具备以下功能:1.``PaddleDataLoader``支持输入的dataset是无框架的,只要实现了``__getitem__``和``__len__``方法即可,当不使用``fastNLP``的 +``DataSet``时候也能够自动检测数据的类型并进行padding,只需要将``collate_fn="auto"``即可,例如:: + + from fastNLP import PaddleDataLoader + class MyDataset: + def __init(self, data_lens=100): + self.data_lens = 100 + def __getitem__(self, item): + if item % 2 == 0: + return {'x':[101, 256, 453], 'y': 0} + else: + return {'x': [101, 200], 'y': 1} + def __len__(self): + return self.data_lens + dataset = MyDataset() + paddle_dl = PaddleDataLoader(dataset, collate_fn="auto") + for batch in paddle_dl: + ... + +2.当设置``collate_fn="auto"``时,``PaddleDataLoader``会调用fastNLP的Collator对数据进行自动pad处理,此时可以调用``set_pad``和``set_ignore``方法 +来设置field的pad_val或者忽略某个field的pad操作。 +.. note:: + 当传入的dataset为fastNLP的DataSet时,collate_fn不能为None。默认可以是"auto"或者自定义callable函数。 + +""" + __all__ = [ 'PaddleDataLoader', 'prepare_paddle_dataloader' @@ -23,7 +51,7 @@ from fastNLP.core.samplers import ReproducibleBatchSampler, RandomBatchSampler class _PaddleDataset(Dataset): """ - 对用户传的dataset进行封装,以便Fdataloader能够支持使用自定义的dataset使用paddle的dataloader + 对用户传的dataset进行封装,以便PaddleDataLoader能够支持使用自定义的dataset """ def __init__(self, dataset) -> None: @@ -44,6 +72,10 @@ class _PaddleDataset(Dataset): class PaddleDataLoader(DataLoader): + """ + 提供给``paddle``框架使用的``DataLoader``函数,``PaddleDataLoader``提供了``Collator``的功能,用户可以通过设置``collate_fn="auto"``来 + 使用,并可以配套使用``set_pad``和``set_ignore``方法设置p``ad_val``和忽略某个field的pad操作。 + """ def __init__(self, dataset, feed_list=None, places=None, return_list: bool = True, batch_sampler=None, @@ -52,6 +84,51 @@ class PaddleDataLoader(DataLoader): num_workers: int = 0, use_buffer_reader: bool = True, use_shared_memory: bool = True, timeout: int = 0, worker_init_fn: Callable = None, persistent_workers=False) -> None: + """ + + :param dataset: 实现了__getitem__和__len__的数据容器 + :param feed_list: (list(Tensor)|tuple(Tensor)): feed Tensor list. + The Tensors should be created by :code:`paddle.static.data()`. + :attr:`feed_list` must be set if :attr:`return_list` is + False. Default None. + :param places: (list(Place)|tuple(Place)|list(str)|optional): a list of Place, + to put data onto, :attr:`places` can be None, if + :attr:`places` is None, default place(CPUPlace or CUDAPlace(0)) + will be used. Default None. If ``places`` is list of string, + the string in the list can be ``cpu``, ``gpu:x`` and ``gpu_pinned``, + where ``x`` is the index of the GPUs. + :param return_list: whether the return value on each device is + presented as a list. If :attr:`return_list=False`, the return + value on each device would be a dict of str -> Tensor, where + the key of the dict is the name of each fed Tensors. If + :attr:`return_list=True`, the return value on each device would + be a list(Tensor). :attr:`return_list` can only be True + in dynamic graph mode. Default True. + :param batch_sampler: 实现了``__iter__``和``__len__``方法的实例化对象,它的功能是根据dataset生成数据indices并组成一个batch数据。 + :param batch_size: dataloader每次获得数据的批次大小 + :param shuffle: 是否将数据打乱,若``shuffle=True``则会将dataset打乱;若否则什么也不做。 + :param drop_last: 当``drop_last=True``时,``PaddleDataLoader``会扔掉最后一个不能组成``batch_size``大小的batch数据; + 若``drop_last=False``, 则什么也不做。 + :param collate_fn:用来对从dataset取到的数据进行打包处理成batch的callable函数,其值应该为一下三个:``[None, "auto", callable]``. + + * ``callate_fn=None``时,第一点值得注意的是此时传进来的datset不能为``fastNLP``的dataset,采用fastNLP的dataset时,``collate_fn``不能为``None``; + 第二点注意的是此时``PaddleDataLoader``会调用默认的`default_collate_fn`函数对sampler到的数据进行简单打包,组成一个batch返回。` + * ``callate_fn="auto"``时,``PaddleDataLoader``会自动调用``fastNLP``自带的``Collator``,其会自动检测dataset的每个``field``, + 并判断是否能够pad处理,若能则会自动进行pad操作,默认``pad_val=0``。若想要更改其值,可调用``set_pad``方法;若不想自动pad某个field, + 可以调用``set_ignore``方法忽略某个field。 + * ``callate_fn=callable``时,callable函数是用户自定义的callate_fn函数,此时``PaddleDataLoader``会调用传进来的callable函数对 + 数据进行打包处理并返回。值得注意的是用户自定义的callable函数的输入为batch,batch为list类型数据,其中batch的每一条数据都为dataset的一条数据。 + + :param num_workers: 开启多进程的数量,当``num_workers=0``时不开启多进程 + :param use_buffer_reader: 是否开启buffer_reader。如果``use_buffer_reader=True``,那么``PaddleDataLoader``将会异步的预取下一个batch的 + 数据,因此它将会加快数据传输的速度,但是将会占用更多的内存或者显存。默认值是``True``。如果``use_buffer_reader=False``,那么什么也不错 + :param use_shared_memory: 是否使用共享内存。当``use_shared_memory=True``时,将采用共享内存来加快将数据放进进程队列。建议仅当计算机上的 + 共享空间足够大时。(例如Linux上的/dev/shm/空间足够大)共享内存仅在多进程模式(num_workers>0)下生效。 + :param timeout: 从子进程的输出队列获取数据的超时值 + :param worker_init_fn: init函数,如果不设置为None,则将会在每个子进程初始化时调用该函数。 + :param persistent_workers: + + """ # FastNLP Datset, collate_fn not None if isinstance(dataset, FDataSet) and collate_fn is None: raise ValueError("When use FastNLP DataSet, collate_fn must be not None") diff --git a/fastNLP/core/vocabulary.py b/fastNLP/core/vocabulary.py index 9fe8d3c8..f7eccf97 100644 --- a/fastNLP/core/vocabulary.py +++ b/fastNLP/core/vocabulary.py @@ -11,6 +11,7 @@ __all__ = [ from collections import Counter from functools import partial from functools import wraps +from typing import List, Callable, Union from fastNLP.core.dataset import DataSet from fastNLP.core.utils.utils import Option @@ -20,6 +21,9 @@ import io class VocabularyOption(Option): + """ + + """ def __init__(self, max_size=None, min_freq=None, @@ -33,8 +37,11 @@ class VocabularyOption(Option): ) -def _check_build_vocab(func): - r"""A decorator to make sure the indexing is built before used. +def _check_build_vocab(func: Callable): + r""" + A decorator to make sure the indexing is built before used. + + :param func: 传入的callable函数 """ @@ -48,7 +55,10 @@ def _check_build_vocab(func): def _check_build_status(func): - r"""A decorator to check whether the vocabulary updates after the last build. + r""" + A decorator to check whether the vocabulary updates after the last build. + + :param func: 用户传入要修饰的callable函数 """ @@ -69,27 +79,30 @@ class Vocabulary(object): r""" 用于构建, 存储和使用 `str` 到 `int` 的一一映射:: + from fastNLP.core import Vocabulary vocab = Vocabulary() word_list = "this is a word list".split() + # vocab更新自己的字典,输入为list列表 vocab.update(word_list) vocab["word"] # str to int vocab.to_word(5) # int to str + """ - def __init__(self, max_size=None, min_freq=None, padding='', unknown=''): + def __init__(self, max_size:int=None, min_freq:int=None, padding:str='', unknown:str=''): r""" - - :param int max_size: `Vocabulary` 的最大大小, 即能存储词的最大数量 + :param max_size: `Vocabulary` 的最大大小, 即能存储词的最大数量 若为 ``None`` , 则不限制大小. Default: ``None`` - :param int min_freq: 能被记录下的词在文本中的最小出现频率, 应大于或等于 1. + :param min_freq: 能被记录下的词在文本中的最小出现频率, 应大于或等于 1. 若小于该频率, 词语将被视为 `unknown`. 若为 ``None`` , 所有文本中的词都被记录. Default: ``None`` - :param str optional padding: padding的字符. 如果设置为 ``None`` , + :param padding: padding的字符. 如果设置为 ``None`` , 则vocabulary中不考虑padding, 也不计入词表大小,为 ``None`` 的情况多在为label建立Vocabulary的情况. Default: '' - :param str optional unknown: unknown的字符,所有未被记录的词在转为 `int` 时将被视为unknown. + :param unknown: unknown的字符,所有未被记录的词在转为 `int` 时将被视为unknown. 如果设置为 ``None`` ,则vocabulary中不考虑unknow, 也不计入词表大小. 为 ``None`` 的情况多在为label建立Vocabulary的情况. Default: '' + """ self.max_size = max_size self.min_freq = min_freq @@ -121,45 +134,50 @@ class Vocabulary(object): self._word2idx = value @_check_build_status - def update(self, word_lst, no_create_entry=False): - r"""依次增加序列中词在词典中的出现频率 + def update(self, word_lst: list, no_create_entry:bool=False): + r""" + 依次增加序列中词在词典中的出现频率 - :param list word_lst: a list of strings - :param bool no_create_entry: 如果词语来自于非训练集建议设置为True。在使用fastNLP.TokenEmbedding加载预训练模型时,没有从预训练词表中找到这个词的处理方式。 + :param word_lst: 列表形式的词语,如word_list=['I', 'am', 'a', 'Chinese'],列表中的每个词会计算出现频率并加入到词典中。 + :param no_create_entry: 如果词语来自于非训练集建议设置为True。 如果为True,则不会有这个词语创建一个单独的entry,它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独 的entry。如果这个word来自于dev或者test,一般设置为True,如果来自与train一般设置为False。以下两种情况: 如果新 加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary中且并不是no_create_entry的,则还是会为这 个词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary中且并不是no_create_entry的, 则这个词将认为是需要创建单独的vector的。 + """ self._add_no_create_entry(word_lst, no_create_entry) self.word_count.update(word_lst) return self @_check_build_status - def add(self, word, no_create_entry=False): + def add(self, word:str, no_create_entry:bool=False): r""" 增加一个新词在词典中的出现频率 - :param str word: 新词 - :param bool no_create_entry: 如果词语来自于非训练集建议设置为True。在使用fastNLP.TokenEmbedding加载预训练模型时,没有从预训练词表中找到这个词的处理方式。 + :param word: 要添加进字典的新词, word为一个字符串 + :param no_create_entry: 如果词语来自于非训练集建议设置为True。 如果为True,则不会有这个词语创建一个单独的entry,它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独 的entry。如果这个word来自于dev或者test,一般设置为True,如果来自与train一般设置为False。以下两种情况: 如果新 加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary中且并不是no_create_entry的,则还是会为这 个词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary中且并不是no_create_entry的, 则这个词将认为是需要创建单独的vector的。 + """ self._add_no_create_entry(word, no_create_entry) self.word_count[word] += 1 return self - def _add_no_create_entry(self, word, no_create_entry): + def _add_no_create_entry(self, word:Union[str, List[str]], no_create_entry:bool): r""" 在新加入word时,检查_no_create_word的设置。 - :param str List[str] word: - :param bool no_create_entry: + :param word: 要添加的新词或者是List类型的新词,如word='I'或者word=['I', 'am', 'a', 'Chinese']均可 + :param no_create_entry: 如果词语来自于非训练集建议设置为True。如果为True,则不会有这个词语创建一个单独的entry, + 它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独的entry :return: + """ if isinstance(word, str) or not _is_iterable(word): word = [word] @@ -170,32 +188,32 @@ class Vocabulary(object): self._no_create_word.pop(w) @_check_build_status - def add_word(self, word, no_create_entry=False): + def add_word(self, word:str, no_create_entry:bool=False): r""" 增加一个新词在词典中的出现频率 - :param str word: 新词 - :param bool no_create_entry: 如果词语来自于非训练集建议设置为True。在使用fastNLP.TokenEmbedding加载预训练模型时,没有从预训练词表中找到这个词的处理方式。 - 如果为True,则不会有这个词语创建一个单独的entry,它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独 - 的entry。如果这个word来自于dev或者test,一般设置为True,如果来自与train一般设置为False。以下两种情况: 如果新 - 加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary中且并不是no_create_entry的,则还是会为这 - 个词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary中且并不是no_create_entry的, - 则这个词将认为是需要创建单独的vector的。 + :param word: 要添加进字典的新词, word为一个字符串 + :param no_create_entry: 如果词语来自于非训练集建议设置为True。如果为True,则不会有这个词语创建一个单独的entry, + 它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独的entry。如果这个word来自于dev或者test,一般设置为True, + 如果来自与train一般设置为False。以下两种情况: 如果新加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary + 中且并不是no_create_entry的,则还是会为这词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary + 中且并不是no_create_entry的,则这个词将认为是需要创建单独的vector的。 + """ self.add(word, no_create_entry=no_create_entry) @_check_build_status - def add_word_lst(self, word_lst, no_create_entry=False): + def add_word_lst(self, word_lst: List[str], no_create_entry:bool=False): r""" 依次增加序列中词在词典中的出现频率 - :param list[str] word_lst: 词的序列 - :param bool no_create_entry: 如果词语来自于非训练集建议设置为True。在使用fastNLP.TokenEmbedding加载预训练模型时,没有从预训练词表中找到这个词的处理方式。 - 如果为True,则不会有这个词语创建一个单独的entry,它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独 - 的entry。如果这个word来自于dev或者test,一般设置为True,如果来自与train一般设置为False。以下两种情况: 如果新 - 加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary中且并不是no_create_entry的,则还是会为这 - 个词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary中且并不是no_create_entry的, - 则这个词将认为是需要创建单独的vector的。 + :param word_lst: 需要添加的新词的list序列,如word_lst=['I', 'am', 'a', 'Chinese'] + :param no_create_entry: 如果词语来自于非训练集建议设置为True。如果为True,则不会有这个词语创建一个单独的entry, + 它将一直被指向unk的表示; 如果为False,则为这个词创建一个单独的entry。如果这个word来自于dev或者test,一般设置为True, + 如果来自与train一般设置为False。以下两种情况: 如果新加入一个word,且no_create_entry为True,但这个词之前已经在Vocabulary + 中且并不是no_create_entry的,则还是会为这词创建一个单独的vector; 如果no_create_entry为False,但这个词之前已经在Vocabulary + 中且并不是no_create_entry的,则这个词将认为是需要创建单独的vector的。 + """ self.update(word_lst, no_create_entry=no_create_entry) return self @@ -238,7 +256,7 @@ class Vocabulary(object): return len(self._word2idx) @_check_build_vocab - def __contains__(self, item): + def __contains__(self, item:str): r""" 检查词是否被记录 @@ -247,7 +265,7 @@ class Vocabulary(object): """ return item in self._word2idx - def has_word(self, w): + def has_word(self, w:str): r""" 检查词是否被记录:: @@ -255,7 +273,7 @@ class Vocabulary(object): # equals to has_abc = 'abc' in vocab - :param item: the word + :param item: 输入的str类型的词 :return: ``True`` or ``False`` """ return self.__contains__(w) @@ -263,7 +281,7 @@ class Vocabulary(object): @_check_build_vocab def __getitem__(self, w): r""" - To support usage like:: + 支持从字典中直接得到词语的index,例如:: vocab[w] """ @@ -275,15 +293,15 @@ class Vocabulary(object): raise ValueError("word `{}` not in vocabulary".format(w)) @_check_build_vocab - def index_dataset(self, *datasets, field_name, new_field_name=None): + def index_dataset(self, *datasets, field_name:Union[List, str], new_field_name:Union[List, str, None]=None): r""" 将DataSet中对应field的词转为数字,Example:: # remember to use `field_name` vocab.index_dataset(train_data, dev_data, test_data, field_name='words') - :param ~fastNLP.DataSet,List[~fastNLP.DataSet] datasets: 需要转index的一个或多个数据集 - :param list,str field_name: 需要转index的field, 若有多个 DataSet, 每个DataSet都必须有此 field. + :param datasets: 其类型为:~fastNLP.core.Dataset或者List[~fastNLP.core.Dataset] 需要转index的一个或多个数据集 + :param field_name: 需要转index的field, 若有多个 DataSet, 每个DataSet都必须有此 field. 目前支持 ``str`` , ``List[str]`` :param list,str new_field_name: 保存结果的field_name. 若为 ``None`` , 将覆盖原field. Default: ``None``. @@ -333,17 +351,16 @@ class Vocabulary(object): def _no_create_word_length(self): return len(self._no_create_word) - def from_dataset(self, *datasets, field_name, no_create_entry_dataset=None): + def from_dataset(self, *datasets, field_name:Union[str,List[str]], no_create_entry_dataset=None): r""" 使用dataset的对应field中词构建词典:: # remember to use `field_name` - vocab.from_dataset(train_data1, train_data2, field_name='words') + vocab.from_dataset(train_data1, train_data2, field_name='words', no_create_entry_dataset=[test_data1, test_data2]) - :param ~fastNLP.DataSet,List[~fastNLP.DataSet] datasets: 需要转index的一个或多个数据集 - :param str,List[str] field_name: 可为 ``str`` 或 ``List[str]`` . - 构建词典所使用的 field(s), 支持一个或多个field,若有多个 DataSet, 每个DataSet都必须有这些field. 目前支持的field结构 - : ``str`` , ``List[str]`` + :param 其类型为:~fastNLP.core.Dataset或者List[~fastNLP.core.Dataset] 需要转index的一个或多个数据集 + :param field_name: 构建词典所使用的 field(s), 支持一个或多个field,若有多个 DataSet, 每个DataSet都必须有这些field. + 目前支持的field结构: ``str`` , ``List[str]`` :param no_create_entry_dataset: 可以传入DataSet, List[DataSet]或者None(默认), 建议直接将非训练数据都传入到这个参数。该选项用在接下来的模型会使用pretrain 的embedding(包括glove, word2vec, elmo与bert)且会finetune的情况。如果仅使用来自于train的数据建立vocabulary,会导致test与dev 中的数据无法充分利用到来自于预训练embedding的信息,所以在建立词表的时候将test与dev考虑进来会使得最终的结果更好。 @@ -351,7 +368,8 @@ class Vocabulary(object): finetune embedding的话,这个词在更新之后可能会有更好的表示; 而如果这个词仅出现在了dev或test中,那么就不能为它们单独建立vector, 而应该让它指向unk这个vector的值。所以只位于no_create_entry_dataset中的token,将首先从预训练的词表中寻找它的表示, 如果找到了,就使用该表示; 如果没有找到,则认为该词的表示应该为unk的表示。 - :return self: + :return Vocabulary自身 + """ if isinstance(field_name, str): field_name = [field_name] @@ -395,15 +413,16 @@ class Vocabulary(object): dataset.apply(partial_construct_vocab) return self - def _is_word_no_create_entry(self, word): + def _is_word_no_create_entry(self, word:str): r""" 判断当前的word是否是不需要创建entry的,具体参见from_dataset的说明 - :param word: str - :return: bool + + :param word: 输入的str类型的词语 + :return: bool值的判断结果 """ return word in self._no_create_word - def to_index(self, w): + def to_index(self, w:str): r""" 将词转为数字. 若词不再词典中被记录, 将视为 unknown, 若 ``unknown=None`` , 将抛出 ``ValueError`` :: @@ -411,8 +430,8 @@ class Vocabulary(object): # equals to index = vocab['abc'] - :param str w: a word - :return int index: the number + :param w: 需要输入的词语 + :return 词语w对应的int类型的index """ return self.__getitem__(w) @@ -420,7 +439,7 @@ class Vocabulary(object): @_check_build_vocab def unknown_idx(self): r""" - unknown 对应的数字. + 获得unknown 对应的数字. """ if self.unknown is None: return None @@ -430,14 +449,14 @@ class Vocabulary(object): @_check_build_vocab def padding_idx(self): r""" - padding 对应的数字 + 获得padding 对应的数字 """ if self.padding is None: return None return self._word2idx[self.padding] @_check_build_vocab - def to_word(self, idx): + def to_word(self, idx: int): r""" 给定一个数字, 将其转为对应的词. @@ -460,7 +479,8 @@ class Vocabulary(object): return self def __getstate__(self): - r"""Use to prepare data for pickle. + r""" + 用来从pickle中加载data """ len(self) # make sure vocab has been built @@ -470,7 +490,8 @@ class Vocabulary(object): return state def __setstate__(self, state): - r"""Use to restore state from pickle. + r""" + 支持pickle的保存,保存到pickle的data state """ self.__dict__.update(state) @@ -485,11 +506,11 @@ class Vocabulary(object): for index in range(len(self._word2idx)): yield self.to_word(index), index - def save(self, filepath): + def save(self, filepath: [str, io.StringIO]): r""" - - :param str,io.StringIO filepath: Vocabulary的储存路径 + :param filepath: Vocabulary的储存路径 :return: + """ if isinstance(filepath, io.IOBase): assert filepath.writable() @@ -521,10 +542,11 @@ class Vocabulary(object): f.close() @staticmethod - def load(filepath): + def load(filepath: Union[str,io.StringIO]): r""" + 从文件路径中加载数据 - :param str,io.StringIO filepath: Vocabulary的读取路径 + :param filepath: Vocabulary的读取路径 :return: Vocabulary """ if isinstance(filepath, io.IOBase): diff --git a/pad_val b/pad_val new file mode 100644 index 00000000..e69de29b