===================== 快速实现序列标注模型 ===================== 这一部分的内容主要展示如何使用fastNLP 实现序列标注任务。你可以使用fastNLP的各个组件快捷,方便地完成序列标注任务,达到出色的效果。 在阅读这篇Tutorial前,希望你已经熟悉了fastNLP的基础使用,包括基本数据结构以及数据预处理,embedding的嵌入等,希望你对之前的教程有更进一步的掌握。 我们将对CoNLL-03的英文数据集进行处理,展示如何完成命名实体标注任务整个训练的过程。 载入数据 =================================== fastNLP可以方便地载入各种类型的数据。同时,针对常见的数据集,我们已经预先实现了载入方法,其中包含CoNLL-03数据集。 在设计dataloader时,以DataSetLoader为基类,可以改写并应用于其他数据集的载入。 .. code-block:: python class Conll2003DataLoader(DataSetLoader): def __init__(self, task:str='ner', encoding_type:str='bioes'): assert task in ('ner', 'pos', 'chunk') index = {'ner':3, 'pos':1, 'chunk':2}[task] #ConllLoader是fastNLP内置的类 self._loader = ConllLoader(headers=['raw_words', 'target'], indexes=[0, index]) self._tag_converters = None if task in ('ner', 'chunk'): #iob和iob2bioes会对tag进行统一,标准化 self._tag_converters = [iob2] if encoding_type == 'bioes': self._tag_converters.append(iob2bioes) def load(self, path: str): dataset = self._loader.load(path) def convert_tag_schema(tags): for converter in self._tag_converters: tags = converter(tags) return tags if self._tag_converters: #使用apply实现convert_tag_schema函数,实际上也支持匿名函数 dataset.apply_field(convert_tag_schema, field_name=Const.TARGET, new_field_name=Const.TARGET) return dataset 输出数据格式如: {'raw_words': ['on', 'Friday', ':'] type=list, 'target': ['O', 'O', 'O'] type=list}, 数据处理 ---------------------------- 我们进一步处理数据。将数据和词表封装在 :class:`~fastNLP.DataBundle` 类中。data是DataBundle的实例。 我们输入模型的数据包括char embedding,以及word embedding。在数据处理部分,我们尝试完成词表的构建。 使用fastNLP中的Vocabulary类来构建词表。 .. code-block:: python word_vocab = Vocabulary(min_freq=2) word_vocab.from_dataset(data.datasets['train'], field_name=Const.INPUT) word_vocab.index_dataset(*data.datasets.values(),field_name=Const.INPUT, new_field_name=Const.INPUT) 处理后的data对象内部为: dataset vocabs dataset保存了train和test中的数据,并保存为dataset类型 vocab保存了words,raw-words以及target的词表。 模型构建 -------------------------------- 我们使用CNN-BILSTM-CRF模型完成这一任务。在网络构建方面,fastNLP的网络定义继承pytorch的 :class:`nn.Module` 类。 自己可以按照pytorch的方式定义网络。需要注意的是命名。fastNLP的标准命名位于 :class:`~fastNLP.Const` 类。 模型的训练 首先实例化模型,导入所需的char embedding以及word embedding。Embedding的载入可以参考教程。 也可以查看 :mod:`~fastNLP.modules.encoder.embedding` 使用所需的embedding 载入方法。 fastNLP将模型的训练过程封装在了 :class:`~fastnlp.trainer` 类中。 根据不同的任务调整trainer中的参数即可。通常,一个trainer实例需要有:指定的训练数据集,模型,优化器,loss函数,评测指标,以及指定训练的epoch数,batch size等参数。 .. code-block:: python #实例化模型 model = CNNBiLSTMCRF(word_embed, char_embed, hidden_size=200, num_layers=1, tag_vocab=data.vocabs[Const.TARGET], encoding_type=encoding_type) #定义优化器 optimizer = Adam(model.parameters(), lr=0.005) #定义评估指标 Metrics=SpanFPreRecMetric(tag_vocab=data.vocabs[Const.TARGET], encoding_type=encoding_type) #实例化trainer trainer = Trainer(train_data=data.datasets['train'], model=model, optimizer=optimizer, dev_data=data.datasets['test'], batch_size=10, metrics=Metrics,callbacks=callbacks, n_epochs=100) #开始训练 trainer.train() 训练中会保存最优的参数配置。 训练的结果如下: .. code-block:: python Evaluation on DataSet test: SpanFPreRecMetric: f=0.727661, pre=0.732293, rec=0.723088 Evaluation at Epoch 1/100. Step:1405/140500. SpanFPreRecMetric: f=0.727661, pre=0.732293, rec=0.723088 Evaluation on DataSet test: SpanFPreRecMetric: f=0.784307, pre=0.779371, rec=0.789306 Evaluation at Epoch 2/100. Step:2810/140500. SpanFPreRecMetric: f=0.784307, pre=0.779371, rec=0.789306 Evaluation on DataSet test: SpanFPreRecMetric: f=0.810068, pre=0.811003, rec=0.809136 Evaluation at Epoch 3/100. Step:4215/140500. SpanFPreRecMetric: f=0.810068, pre=0.811003, rec=0.809136 Evaluation on DataSet test: SpanFPreRecMetric: f=0.829592, pre=0.84153, rec=0.817989 Evaluation at Epoch 4/100. Step:5620/140500. SpanFPreRecMetric: f=0.829592, pre=0.84153, rec=0.817989 Evaluation on DataSet test: SpanFPreRecMetric: f=0.828789, pre=0.837096, rec=0.820644 Evaluation at Epoch 5/100. Step:7025/140500. SpanFPreRecMetric: f=0.828789, pre=0.837096, rec=0.820644