|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| """Loads dataset for the question answering (e.g, SQuAD) task."""
|
| import dataclasses
|
| from typing import Mapping, Optional
|
|
|
| import tensorflow as tf, tf_keras
|
| from official.common import dataset_fn
|
| from official.core import config_definitions as cfg
|
| from official.core import input_reader
|
| from official.nlp.data import data_loader
|
| from official.nlp.data import data_loader_factory
|
|
|
|
|
| @dataclasses.dataclass
|
| class QADataConfig(cfg.DataConfig):
|
| """Data config for question answering task (tasks/question_answering)."""
|
|
|
|
|
| input_path: str = ''
|
| global_batch_size: int = 48
|
| is_training: bool = True
|
| seq_length: int = 384
|
|
|
| version_2_with_negative: bool = False
|
|
|
| input_preprocessed_data_path: str = ''
|
| doc_stride: int = 128
|
| query_length: int = 64
|
|
|
|
|
| vocab_file: str = ''
|
| tokenization: str = 'WordPiece'
|
| do_lower_case: bool = True
|
| xlnet_format: bool = False
|
| file_type: str = 'tfrecord'
|
|
|
|
|
| @data_loader_factory.register_data_loader_cls(QADataConfig)
|
| class QuestionAnsweringDataLoader(data_loader.DataLoader):
|
| """A class to load dataset for sentence prediction (classification) task."""
|
|
|
| def __init__(self, params):
|
| self._params = params
|
| self._seq_length = params.seq_length
|
| self._is_training = params.is_training
|
| self._xlnet_format = params.xlnet_format
|
|
|
| def _decode(self, record: tf.Tensor):
|
| """Decodes a serialized tf.Example."""
|
| name_to_features = {
|
| 'input_ids': tf.io.FixedLenFeature([self._seq_length], tf.int64),
|
| 'input_mask': tf.io.FixedLenFeature([self._seq_length], tf.int64),
|
| 'segment_ids': tf.io.FixedLenFeature([self._seq_length], tf.int64),
|
| }
|
| if self._xlnet_format:
|
| name_to_features['class_index'] = tf.io.FixedLenFeature([], tf.int64)
|
| name_to_features['paragraph_mask'] = tf.io.FixedLenFeature(
|
| [self._seq_length], tf.int64)
|
| if self._is_training:
|
| name_to_features['is_impossible'] = tf.io.FixedLenFeature([], tf.int64)
|
|
|
| if self._is_training:
|
| name_to_features['start_positions'] = tf.io.FixedLenFeature([], tf.int64)
|
| name_to_features['end_positions'] = tf.io.FixedLenFeature([], tf.int64)
|
| else:
|
| name_to_features['unique_ids'] = tf.io.FixedLenFeature([], tf.int64)
|
| example = tf.io.parse_single_example(record, name_to_features)
|
|
|
|
|
|
|
| for name in example:
|
| t = example[name]
|
| if t.dtype == tf.int64:
|
| t = tf.cast(t, tf.int32)
|
| example[name] = t
|
|
|
| return example
|
|
|
| def _parse(self, record: Mapping[str, tf.Tensor]):
|
| """Parses raw tensors into a dict of tensors to be consumed by the model."""
|
| x, y = {}, {}
|
| for name, tensor in record.items():
|
| if name in ('start_positions', 'end_positions', 'is_impossible'):
|
| y[name] = tensor
|
| elif name == 'input_ids':
|
| x['input_word_ids'] = tensor
|
| elif name == 'segment_ids':
|
| x['input_type_ids'] = tensor
|
| else:
|
| x[name] = tensor
|
| if name == 'start_positions' and self._xlnet_format:
|
| x[name] = tensor
|
| return (x, y)
|
|
|
| def load(self, input_context: Optional[tf.distribute.InputContext] = None):
|
| """Returns a tf.dataset.Dataset."""
|
| reader = input_reader.InputReader(
|
| params=self._params,
|
| dataset_fn=dataset_fn.pick_dataset_fn(self._params.file_type),
|
| decoder_fn=self._decode,
|
| parser_fn=self._parse)
|
| return reader.read(input_context)
|
|
|