fastNLP.core.dataset

DataSet 是fastNLP中用于承载数据的容器。可以将DataSet看做是一个表格, 每一行是一个sample (在fastNLP中被称为 instance ), 每一列是一个feature (在fastNLP中称为 field )。

Following is a demo layout of DataSet

sentence

words

seq_len

This is the first instance .

[This, is, the, first, instance, .]

6

Second instance .

[Second, instance, .]

3

Third instance .

[Third, instance, .]

3

...

[...]

...

在fastNLP内部每一行是一个 Instance 对象; 每一列是一个 FieldArray 对象。

1.DataSet的创建

创建DataSet主要有以下的3种方式

1.1 传入dict

from fastNLP import DataSet
data = {'sentence':["This is the first instance .", "Second instance .", "Third instance ."],
        'words': [['this', 'is', 'the', 'first', 'instance', '.'], ['Second', 'instance', '.'], ['Third', 'instance', '.'],
        'seq_len': [6, 3, 3]}
dataset = DataSet(data)
# 传入的dict的每个key的value应该为具有相同长度的list

1.2 通过 Instance 构建

from fastNLP import DataSet
from fastNLP import Instance
dataset = DataSet()
instance = Instance(sentence="This is the first instance",
                    words=['this', 'is', 'the', 'first', 'instance', '.'],
                    seq_len=6)
dataset.append(instance)
# 可以继续append更多内容,但是append的instance应该和第一个instance拥有完全相同的field

1.3 通过 List[Instance] 构建

from fastNLP import DataSet
from fastNLP import Instance
instances = []
instances.append(Instance(sentence="This is the first instance",
                    ords=['this', 'is', 'the', 'first', 'instance', '.'],
                    seq_len=6))
instances.append(Instance(sentence="Second instance .",
                    words=['Second', 'instance', '.'],
                    seq_len=3))
dataset = DataSet(instances)

2.DataSet与预处理

常见的预处理有如下几种

2.1 从某个文本文件读取内容

from fastNLP import DataSet
from fastNLP import Instance
dataset = DataSet()
filepath='some/text/file'
# 假设文件中每行内容如下(sentence  label):
#    This is a fantastic day    positive
#    The bad weather    negative
#    .....
with open(filepath, 'r') as f:
    for line in f:
        sent, label = line.strip().split('\t')
        dataset.append(Instance(sentence=sent, label=label))

注解

直接读取特定数据集的数据请参考 使用Loader和Pipe加载并处理数据集

2.2 对DataSet中的内容处理

from fastNLP import DataSet
data = {'sentence':["This is the first instance .", "Second instance .", "Third instance ."]}
dataset = DataSet(data)
# 将句子分成单词形式, 详见DataSet.apply()方法
dataset.apply(lambda ins: ins['sentence'].split(), new_field_name='words')
# 或使用DataSet.apply_field()
dataset.apply_field(lambda sent:sent.split(), field_name='sentence', new_field_name='words')
# 除了匿名函数,也可以定义函数传递进去
def get_words(instance):
    sentence = instance['sentence']
    words = sentence.split()
    return words
dataset.apply(get_words, new_field_name='words')

2.3 删除DataSet的内容

from fastNLP import DataSet
dataset = DataSet({'a': list(range(-5, 5))})
# 返回满足条件的instance,并放入DataSet中
dropped_dataset = dataset.drop(lambda ins:ins['a']<0, inplace=False)
# 在dataset中删除满足条件的instance
dataset.drop(lambda ins:ins['a']<0)  # dataset的instance数量减少
#  删除第3个instance
dataset.delete_instance(2)
#  删除名为'a'的field
dataset.delete_field('a')

2.4 遍历DataSet的内容

for instance in dataset:
    # do something

2.5 一些其它操作

#  检查是否存在名为'a'的field
dataset.has_field('a')  # 或 ('a' in dataset)
#  将名为'a'的field改名为'b'
dataset.rename_field('a', 'b')
#  DataSet的长度
len(dataset)

3.DataSet与自然语言处理(NLP)

在目前深度学习的模型中,大都依赖于随机梯度下降法(SGD)进行模型的优化。随机梯度下降需要将数据切分成一个个的 batch, 一个batch进行一次前向计算(forward)与梯度后向传播(backward)。在自然语言处理的场景下,往往还需要对数据进行pad。这是 由于句子的长度一般是不同的,但是一次batch中的每个field都必须是一个tensor,所以需要将所有句子都补齐到相同的长度。

3.1 DataSet与DataSetIter

我们先看fastNLP中如何将数据分成一个一个的batch的例子, 这里我们使用随机生成的数据来模拟一个二分类文本分类任务, words和characters是输入,labels是文本类别

from fastNLP import DataSet
from fastNLP import DataSetIter
from fastNLP import SequentialSampler
from fastNLP import EngChar2DPadder

num_instances = 100
# 假设每句话最少2个词,最多5个词; 词表的大小是100个; 一共26个字母,每个单词最短1个字母,最长5个字母
lengths = [random.randint(2, 5) for _ in range(num_instances)]
data = {'words': [[random.randint(1, 100) for _ in range(lengths[idx]) ] for idx in range(num_instances)],
        'chars': [
                    [[random.randint(1, 27) for _ in range(random.randint(1, 5))]
                    for _ in range(lengths[idx])]
             for idx in range(num_instances)],
        'label': [random.randint(0, 1) for _ in range(num_instances)]}

d = DataSet(data)
d.set_padder('chars', EngChar2DPadder())  # 因为英文character的pad方式与word的pad方式不一样

d.set_target('label')
d.set_input('words', 'chars')

for batch_x, batch_y in DataSetIter(d, sampler=SequentialSampler(), batch_size=2):
    print("batch_x:", batch_x)
    print("batch_y:", batch_y)
    break
    # 输出为
    # {'words': tensor([[49, 27, 20, 36, 63],
    #     [53, 82, 23, 11,  0]]), 'chars': tensor([[[13,  3, 14, 25,  1],
    #      [ 8, 20, 12,  0,  0],
    #      [27,  8,  0,  0,  0],
    #      [ 1, 15, 26,  0,  0],
    #      [11, 24, 17,  0,  0]],
    #
    #     [[ 6, 14, 11, 27, 22],
    #      [18,  6,  4, 19,  0],
    #      [19, 22,  9,  0,  0],
    #      [10, 25,  0,  0,  0],
    #      [ 0,  0,  0,  0,  0]]])}
    # {'label': tensor([0, 0])}

其中 DataSetIter 是用于从DataSet中按照batch_size为大小取出batch的迭代器, SequentialSampler 用于指示 DataSetIter 以怎样的 顺序从DataSet中取出instance以组成一个batch, 更详细的说明请参照 DataSetIterSequentialSampler 文档。

通过 DataSet.set_input('words', 'chars') , fastNLP将认为 wordschars 这两个field都是input,并将它们都放入迭代器 生成的第一个dict中; DataSet.set_target('labels') , fastNLP将认为 labels 这个field是target,并将其放入到迭代器的第 二个dict中。如上例中所打印结果。分为input和target的原因是由于它们在被 Trainer 所使用时会有所差异, 详见 Trainer

当把某个field设置为 target 或者 input 的时候(两者不是互斥的,可以同时设为两种),fastNLP不仅仅只是将其放 置到不同的dict中,而还会对被设置为 inputtarget 的 field 进行类型检查。类型检查的目的是为了看能否把该 field 转为 pytorch的 torch.LongTensortorch.FloatTensor 类型 (也可以在 DataSetIter 中设置输出numpy类型,参考 DataSetIter )。

如上例所示,fastNLP已将 wordscharslabel 转为了 Tensor 类型。 如果 field 在每个 instance 都拥有相同的维度(不能超过两维),且最内层的元素都为相同的 type(int, float, np.int*, np.float*), 则fastNLP默认将对该 field 进行pad。也支持全为str的field作为target和input,这种情况下,fastNLP默认不进行pad。 另外,当某个 field 已经被设置为了 target 或者 input 后,之后 appendinstance 对应的 field 必须要和前面已有的内容一致,否则会报错。

可以查看field的dtype:

from fastNLP import DataSet

d = DataSet({'a': [0, 1, 3], 'b':[[1.0, 2.0], [0.1, 0.2], [3]]})
d.set_input('a', 'b')
d.a.dtype
>> numpy.int64
d.b.dtype
>> numpy.float64
# 默认情况下'a'这个field将被转换为torch.LongTensor,但如果需要其为torch.FloatTensor可以手动修改dtype
d.a.dtype = float  #  请确保该field的确可以全部转换为float。

如果某个field中出现了多种类型混合(比如一部分为str,一部分为int)的情况,fastNLP无法判断该field的类型,会报如下的 错误:

from fastNLP import DataSet

d = DataSet({'data': [1, 'a']})
d.set_input('data')
>> RuntimeError: Mixed data types in Field data: [<class 'str'>, <class 'int'>]

可以通过设置以忽略对该field进行类型检查:

from fastNLP import DataSet
d = DataSet({'data': [1, 'a']})
d.set_ignore_type('data')
d.set_input('data')

当某个field被设置为忽略type之后,fastNLP将不对其进行pad。

3.2 DataSet与pad

在fastNLP里,pad是与一个field绑定的。即不同的field可以使用不同的pad方式,比如在英文任务中word需要的pad和 character的pad方式往往是不同的。fastNLP是通过一个叫做 Padder 的子类来完成的。 默认情况下,所有field使用 AutoPadder 。可以通过使用以下方式设置Padder(如果将padder设置为None,则该field不会进行pad操作)。 大多数情况下直接使用 AutoPadder 就可以了。 如果 AutoPadderEngChar2DPadder 无法满足需求, 也可以自己写一个 Padder

from fastNLP import DataSet
from fastNLP import EngChar2DPadder
import random
dataset = DataSet()
max_chars, max_words, sent_num = 5, 10, 20
contents = [[
                [random.randint(1, 27) for _ in range(random.randint(1, max_chars))]
                    for _ in range(random.randint(1, max_words))
            ]  for _ in range(sent_num)]
#  初始化时传入
dataset.add_field('chars', contents, padder=EngChar2DPadder())
#  直接设置
dataset.set_padder('chars', EngChar2DPadder())
#  也可以设置pad的value
dataset.set_pad_val('chars', -1)

3.3 根据DataSet中多个field合成新的field

DataSet支持在进行batch时,默认只能看到当前的field的值,但在某些训练中可能存在以下的情况: (1)需要两个field拼接成为一个field; (2)需要在batch中进行负采样。这时候就需要能够同时利用多个field进行batch的操作,DataSet中的add_collate_fn()函数支持添加 自定义涉及多个field的collate_fn函数。例如下例中将两个field拼接成一个field的场景

from fastNLP import DataSet, DataSetIter
import torch

data = DataSet({
    'x1': [[0, 1],
           [2]],
    'x2': [[3],
           [2, 4, 5]],
    'y': [0, 1]
})
data.set_target('y')

# 所有的collate_fn函数都接受list[(ind1, instance1), (ind2, instance2), ...]作为输入,其中ind1/ind2是该instance在dataset中
#   的index,instance1/instance2是这次batch取出来的数据,包含了所有的field.
def concat_collate_fn(ins_list):
    x1 = [ins['x1'] for ind,ins in ins_list]
    x2 = [ins['x2'] for ind,ins in ins_list]
    xs = []
    for i in range(len(ins_list)):
        xs.append(torch.LongTensor(x1[i] + x2[i]))
    # 需要自行pad并转换为tensor,但不需要移动到gpu
    arr = torch.nn.utils.rnn.pad_sequence(xs, batch_first=True, padding_value=0)
    b_x = {'x': arr}
    b_y = {}
    # 返回值一定是两个dict,第一个dict的值会认为是input,第二个dict的值会认为是target. 若名称与已有input或target重复,则
    #   采用返回值。
    return b_x, b_y

data.add_collate_fn(concat_collate_fn)

for batch_x, batch_y in DataSetIter(data, sampler=SequentialSampler(), batch_size=2):
    print("batch_x:", batch_x)
    print("batch_y:", batch_y)
    # batch_x: {'x': tensor([[0, 1, 3, 0],
    #                        [2, 2, 4, 5]])}
    # batch_y: {'y': array([0, 1])}

# 如果取batch过程含有一些参数,可以通过类来实现
class ConCollateFn:
    def __init__(self, max_len=3):
        self.max_len = max_len

    def __call__(self, ins_list):  # 实现该类的__call__函数
        x1 = [ins['x1'] for ind, ins in ins_list]
        x2 = [ins['x2'] for ind, ins in ins_list]
        xs = []
        for i in range(len(ins_list)):
            xs.append(torch.LongTensor(x1[i] + x2[i])[:self.max_len])
        arr = torch.nn.utils.rnn.pad_sequence(xs, batch_first=True, padding_value=0)
        b_x = {'x': arr}
        b_y = {}
        return b_x, b_y
data.delete_collate_fn()  # 删除之前的collate_fn
data.add_collate_fn(ConCollateFn(max_len=3))
for batch_x, batch_y in DataSetIter(data, sampler=SequentialSampler(), batch_size=2):
    print("batch_x:", batch_x)
    print("batch_y:", batch_y)
    # batch_x: {'x': tensor([[0, 1, 3],
    #                        [2, 2, 4]])}
    # batch_y: {'y': array([0, 1])}
class fastNLP.core.dataset.DataSet(data=None)[源代码]

别名 fastNLP.DataSet fastNLP.core.dataset.DataSet

fastNLP的数据容器,详细的使用方法见文档 fastNLP.core.dataset

__init__(data=None)[源代码]
参数

data -- 如果为dict类型,则每个key的value应该为等长的list; 如果为list, 每个元素应该为具有相同field的 Instance

print_field_meta()[源代码]

输出当前field的meta信息, 形似下列的输出:

+-------------+-------+-------+
| field_names |   x   |   y   |
+=============+=======+=======+
|   is_input  |  True | False |
|  is_target  | False | False |
| ignore_type | False |       |
|  pad_value  |   0   |       |
+-------------+-------+-------+

str field_names: DataSet中field的名称 bool is_input: field是否为input bool is_target: field是否为target bool ignore_type: 是否忽略该field的type, 一般仅在该field至少为input或target时才有意义 int pad_value: 该field的pad的值,仅在该field为input或target时有意义 :return:

append(instance)[源代码]

将一个instance对象append到DataSet后面。

参数

instance (Instance) -- 若DataSet不为空,则instance应该拥有和DataSet完全一样的field。

add_fieldarray(field_name, fieldarray)[源代码]

将fieldarray添加到DataSet中.

参数
  • field_name (str) -- 新加入的field的名称

  • fieldarray (FieldArray) -- 需要加入DataSet的field的内容

返回

add_field(field_name, fields, padder=<fastNLP.core.field.AutoPadder object>, is_input=False, is_target=False, ignore_type=False)[源代码]

新增一个field

参数
  • field_name (str) -- 新增的field的名称

  • fields (list) -- 需要新增的field的内容

  • padder (None,Padder) -- 如果为None,则不进行pad,默认使用 AutoPadder 自动判断是否需要做pad。

  • is_input (bool) -- 新加入的field是否是input

  • is_target (bool) -- 新加入的field是否是target

  • ignore_type (bool) -- 是否忽略对新加入的field的类型检查

delete_instance(index)[源代码]

删除第index个instance

参数

index (int) -- 需要删除的instance的index,序号从0开始。

delete_field(field_name)[源代码]

删除名为field_name的field

参数

field_name (str) -- 需要删除的field的名称.

copy_field(field_name, new_field_name)[源代码]

深度copy名为field_name的field到new_field_name

参数
  • field_name (str) -- 需要copy的field。

  • new_field_name (str) -- copy生成的field名称

返回

self

has_field(field_name)[源代码]

判断DataSet中是否有名为field_name这个field

参数

field_name (str) -- field的名称

Return bool

表示是否有名为field_name这个field

get_field(field_name)[源代码]

获取field_name这个field

参数

field_name (str) -- field的名称

返回

FieldArray

get_all_fields()[源代码]

返回一个dict,key为field_name, value为对应的 FieldArray

Return dict

返回如上所述的字典

get_field_names() → list[源代码]

返回一个list,包含所有 field 的名字

Return list

返回如上所述的列表

get_length()[源代码]

获取DataSet的元素数量

返回

int: DataSet中Instance的个数。

rename_field(field_name, new_field_name)[源代码]

将某个field重新命名.

参数
  • field_name (str) -- 原来的field名称。

  • new_field_name (str) -- 修改为new_name。

set_target(*field_names, flag=True, use_1st_ins_infer_dim_type=True)[源代码]

将field_names的field设置为target

Example:

dataset.set_target('labels', 'seq_len')  # 将labels和seq_len这两个field的target属性设置为True
dataset.set_target('labels', 'seq_lens', flag=False) # 将labels和seq_len的target属性设置为False
参数
  • field_names (str) -- field的名称

  • flag (bool) -- 将field_name的target状态设置为flag

  • use_1st_ins_infer_dim_type (bool) -- 如果为True,将不会check该列是否所有数据都是同样的维度,同样的类型。将直接使用第一 行的数据进行类型和维度推断本列的数据的类型和维度。

set_input(*field_names, flag=True, use_1st_ins_infer_dim_type=True)[源代码]

将field_names的field设置为input:

dataset.set_input('words', 'seq_len')   # 将words和seq_len这两个field的input属性设置为True
dataset.set_input('words', flag=False)  # 将words这个field的input属性设置为False
参数
  • field_names (str) -- field的名称

  • flag (bool) -- 将field_name的input状态设置为flag

  • use_1st_ins_infer_dim_type (bool) -- 如果为True,将不会check该列是否所有数据都是同样的维度,同样的类型。将直接使用第一 行的数据进行类型和维度推断本列的数据的类型和维度。

set_ignore_type(*field_names, flag=True)[源代码]

将field设置为忽略类型状态。当某个field被设置了ignore_type, 则在被设置为target或者input时将不进行类型检查, 默认情况下也不进行pad。如果仍需要pad该field,可通过自定义Padder实现,若该field需要转换为tensor,需要在padder 中转换,但不需要在padder中移动到gpu。

参数
  • field_names (str) -- field的名称

  • flag (bool) -- 将field_name的ignore_type状态设置为flag

返回

set_padder(field_name, padder)[源代码]

为field_name设置padder:

from fastNLP import EngChar2DPadder
padder = EngChar2DPadder()
dataset.set_padder('chars', padder)  # 则chars这个field会使用EngChar2DPadder进行pad操作
参数
  • field_name (str) -- 设置field的padding方式为padder

  • padder (None,Padder) -- 设置为None即删除padder, 即对该field不进行pad操作。

set_pad_val(field_name, pad_val)[源代码]

为某个field设置对应的pad_val.

参数
  • field_name (str) -- 修改该field的pad_val

  • pad_val (int) -- 该field的padder会以pad_val作为padding index

get_input_name()[源代码]

返回所有is_input被设置为True的field名称

Return list

里面的元素为被设置为input的field名称

get_target_name()[源代码]

返回所有is_target被设置为True的field名称

Return list

里面的元素为被设置为target的field名称

apply_field(func, field_name, new_field_name=None, **kwargs)[源代码]

将DataSet中的每个instance中的名为 field_name 的field传给func,并获取它的返回值。

参数
  • func (callable) -- input是instance中名为 field_name 的field的内容。

  • field_name (str) -- 传入func的是哪个field。

  • new_field_name (None,str) -- 将func返回的内容放入到 new_field_name 这个field中,如果名称与已有的field相同,则覆 盖之前的field。如果为None则不创建新的field。

  • kwargs (optional) --

    支持输入is_input,is_target,ignore_type

    1. is_input: bool, 如果为True则将名为 new_field_name 的field设置为input

    2. is_target: bool, 如果为True则将名为 new_field_name 的field设置为target

    3. ignore_type: bool, 如果为True则将名为 new_field_name 的field的ignore_type设置为true, 忽略其类型

    4. use_tqdm: bool, 是否使用tqdm显示预处理进度

    5. tqdm_desc: str, 当use_tqdm为True时,可以显示当前tqdm正在处理的名称

Return List[Any]

里面的元素为func的返回值,所以list长度为DataSet的长度

apply_field_more(func, field_name, modify_fields=True, **kwargs)[源代码]

DataSet 中的每个 Instance 中的名为 field_name 的field 传给 func,并获取它的返回值。 func 可以返回一个或多个 field 上的结果。

注解

apply_field_moreapply_field 的区别参考 apply_more() 中关于 apply_moreapply 区别的介绍。

参数
  • func (callable) -- 参数是 DataSet 中的 Instance ,返回值是一个字典,key 是field 的名字,value 是对应的结果

  • field_name (str) -- 传入func的是哪个field。

  • modify_fields (bool) -- 是否用结果修改 DataSet 中的 Field, 默认为 True

  • kwargs (optional) --

    支持输入is_input,is_target,ignore_type

    1. is_input: bool, 如果为True则将被修改的field设置为input

    2. is_target: bool, 如果为True则将被修改的field设置为target

    3. ignore_type: bool, 如果为True则将被修改的field的ignore_type设置为true, 忽略其类型

    4. use_tqdm: bool, 是否使用tqdm显示预处理进度

    5. tqdm_desc: str, 当use_tqdm为True时,可以显示当前tqdm正在处理的名称

Return Dict[str:Field]

返回一个字典

apply_more(func, modify_fields=True, **kwargs)[源代码]

DataSet 中每个 Instance 传入到func中,并获取它的返回值。func可以返回一个或多个 field 上的结果。

注解

apply_moreapply 的区别:

  1. apply_more 可以返回多个 field 的结果, apply 只可以返回一个field 的结果;

  2. apply_more 的返回值是一个字典,每个 key-value 对中的 key 表示 field 的名字,value 表示计算结果;

  3. apply_more 默认修改 DataSet 中的 field ,apply 默认不修改。

参数
  • func (callable) -- 参数是 DataSet 中的 Instance ,返回值是一个字典,key 是field 的名字,value 是对应的结果

  • modify_fields (bool) -- 是否用结果修改 DataSet 中的 Field , 默认为 True

  • kwargs (optional) --

    支持输入is_input,is_target,ignore_type

    1. is_input: bool, 如果为True则将被修改的的field设置为input

    2. is_target: bool, 如果为True则将被修改的的field设置为target

    3. ignore_type: bool, 如果为True则将被修改的的field的ignore_type设置为true, 忽略其类型

    4. use_tqdm: bool, 是否使用tqdm显示预处理进度

    5. tqdm_desc: str, 当use_tqdm为True时,可以显示当前tqdm正在处理的名称

Return Dict[str:Field]

返回一个字典

apply(func, new_field_name=None, **kwargs)[源代码]

将DataSet中每个instance传入到func中,并获取它的返回值.

参数
  • func (callable) -- 参数是 DataSet 中的 Instance

  • new_field_name (None,str) -- 将func返回的内容放入到 new_field_name 这个field中,如果名称与已有的field相同,则覆 盖之前的field。如果为None则不创建新的field。

  • kwargs (optional) --

    支持输入is_input,is_target,ignore_type

    1. is_input: bool, 如果为True则将 new_field_name 的field设置为input

    2. is_target: bool, 如果为True则将 new_field_name 的field设置为target

    3. ignore_type: bool, 如果为True则将 new_field_name 的field的ignore_type设置为true, 忽略其类型

    4. use_tqdm: bool, 是否使用tqdm显示预处理进度

    5. tqdm_desc: str, 当use_tqdm为True时,可以显示当前tqdm正在处理的名称

Return List[Any]

里面的元素为func的返回值,所以list长度为DataSet的长度

add_seq_len(field_name: str, new_field_name='seq_len')[源代码]

将使用len()直接对field_name中每个元素作用,将其结果作为sequence length, 并放入seq_len这个field。

参数
  • field_name -- str.

  • new_field_name -- str. 新的field_name

返回

drop(func, inplace=True)[源代码]

func接受一个Instance,返回bool值。返回值为True时,该Instance会被移除或者不会包含在返回的DataSet中。

参数
  • func (callable) -- 接受一个Instance作为参数,返回bool值。为True时删除该instance

  • inplace (bool) -- 是否在当前DataSet中直接删除instance;如果为False,将返回一个新的DataSet。

返回

DataSet

split(ratio, shuffle=True)[源代码]

将DataSet按照ratio的比例拆分,返回两个DataSet

参数
  • ratio (float) -- 0<ratio<1, 返回的第一个DataSet拥有 (1-ratio) 这么多数据,第二个DataSet拥有`ratio`这么多数据

  • shuffle (bool) -- 在split前是否shuffle一下

返回

[ 读取后的DataSet , 读取后的DataSet ]

save(path)[源代码]

保存DataSet.

参数

path (str) -- 将DataSet存在哪个路径

static load(path)[源代码]

从保存的DataSet pickle文件的路径中读取DataSet

参数

path (str) -- 从哪里读取DataSet

返回

读取后的 读取后的DataSet

add_collate_fn(fn, name=None)[源代码]

添加 CollateFn,collate_fn允许在生成的batch的过程中动态生成一些数据(在DataSetIter作为迭代器的情况下有效,默认情况下就是用的 这个)。支持依次添加多个collate_fn, 如果相同的key,后面的collate_fn的结果覆盖前面的collate_fn的结果。

参数
  • fn (callable) -- 传入一个可调用的function, 该function可接受的参数为List[(ind1, instance1), (ind2, instance2)] (某个batch被选中的所有的indice以及instance),其中ind1/ind2是该instance在dataset中的index,instance1/instance2是 这次batch取出来的数据,包含了所有的field。返回值需要为两个dict,第一个dict的值将被认为是input,第二个dict的值被认为是 target,返回的值至多允许一个空dict。若返回的dict中包含了被设置为input或target的field的名称,将覆盖dataset中的field。 fastNLP不会将collate_fn的返回结果pad和转换为tensor,需要在collate_fn中完成pad和转换为tensor(不需要将tensor移动到 gpu中,fastNLP会自动将其移动到特定gpu)。不要修改传入collate_fn中的数据,否则可能导致未知问题。

  • name (str,int) -- collate_fn的名称,如果不传入,默认使用自增长的数字作为key。相同的name会覆盖之前的collate_fn。

delete_collate_fn(name=None)[源代码]

删除某个collate_fn

参数

name (str,int) -- 如果为None,则删除最近加入的collate_fn

返回

concat(dataset, inplace=True, field_mapping=None)[源代码]
将当前dataset与输入的dataset结合成一个更大的dataset,需要保证两个dataset都包含了相同的field。结合后的dataset的input,target

以及collate_fn以当前dataset为准。当dataset中包含的field多于当前的dataset,则多余的field会被忽略;若dataset中未包含所有 当前dataset含有field,则会报错。

参数
  • dataset (DataSet,) -- 需要和当前dataset concat的dataset

  • inplace (bool,) -- 是否直接将dataset组合到当前dataset中

  • field_mapping (dict,) -- 当dataset中的field名称和当前dataset不一致时,需要通过field_mapping把输入的dataset中的field 名称映射到当前field. field_mapping为dict类型,key为dataset中的field名称,value是需要映射成的名称

返回

DataSet