AllenNLP源码学习——Batch与DataIterator

DataIterator类用来把读取数据集类输出的Instance打包为Batch。
子类需要重写_create_batches()方法,把Instances打包成Batch。最常用的子类是BucketIterator。

BucketIterator

  1. 默认情况下,根据每Batch的最大输入长度填充Batch
  2. 可以提供Field名字的List和padding keys,在执行此批处理之前将对数据集进行排序,从而将具有相似长度的输入批处理在一起,提高计算效率(因为在填充元素上浪费的时间更少) 批量
  3. _create_batches()中用Batch类进行打包,得到batches = []
  4. _create_batches()返回对Batch的迭代器(yield from batches)

参数

  1. sorting_keys: List[Tuple[str, str]],即[(field_name, padding_key)], 为了让padding数量相近的放进一个Batch,对padding数量进行排序。例如[(“sentence1”, “num_tokens”), (“sentence2”, “num_tokens”), (“sentence1”,“num_token_characters”)],sentence1和sentence2是field名称,num_tokens是以词为单位,num_token_characters以字符为单位,在List中靠前的,排序优先级高。padding_key的对应:(TextField,num_tokens / num_token_characters)
  2. padding_noise: float = 0.1,对padding长度加噪声(有什么用?)
  3. biggest_batch_first: bool = False,主要为了测试,如果设置为True,最大长度的Batch放到最前面,如果不会超出显存,那么后面的Batch也是可以用。注意,如果设置了max_instances_in_memory,则最大的Batch是max_instances_in_memory约束下的最大值。
  4. batch_size: int = 32,一个Batch中有多少个Instance
  5. instances_per_epoch: int = None,如果不为None,则指定一个epoch有多少个Instance,如果为None,则一个epoch是遍历一遍dataset
  6. max_instances_in_memory: int = None,一次加载多少个instances到内存
  7. cache_instances: bool = False,如果False,每次新的迭代将instance转tensor;如果True,迭代器将tensor存在内存中。保存到self._cache: Dict[int, List[TensorDict]],key为instance的内存地址。
  8. track_epoch: bool = False,如果为True,每个instance加一个MetadataField,保存epoch number
  9. maximum_samples_per_batch: Tuple[str, int] = None,如果不为空,参数为(padding_key, limit),每个Batch会确保batch_size * sequence_length <= limit

Batch

一个Batch的Instances。包含用于将数据转换为tensor张量的辅助函数。

方法

def get_padding_lengths(self)
实际通过instance——>Field,在Field中计算。
得到Dict[str, Dict[str, int]],{field名:{padding_key:padding后的实际长度}}, (padding_key为num_tokens / num_token_characters,因为词 / 字符为单位,填充长度不同)。

def index_instances(self, vocab: Vocabulary)
实际的计算通过instance——>Field,在Field中计算(field.index(vocab))。
Field利用Vocabulary中记录的token与index的转换,把字符转为整数。不同的Field有不同的处理方式。

def as_tensor_dict(self, padding_lengths: Dict[str, Dict[str, int]] = None,verbose: bool = False)

将Batch转为tensor。
得到{field name: tensor},更为复杂的情况下(TextField同时有词嵌入与字符嵌入)可能返回{field name:{TokenIndexer的key: tensor}}
例如,N个instances中有[“question”] field和[“answer”]field,最后两个field分别拼成一个整个的tensor,维度为N*padding length。

Instances到Tensor的过程

  1. index
  2. padding,这样才能构成完成的tensor
  3. batch

猜你喜欢

转载自blog.csdn.net/m0_38133212/article/details/88234813
今日推荐