最近开始练手pytorch,和张梅山老师讨论(基本是请教)了一下,给了我一个关系抽取方面的idea。基于本身对什么都感兴趣但是又不动手(眼高手低),所以干脆直接用这个开始练手把所有知道的model和一些技巧都练习一遍也是不错的选择。相当于正式开始真正动手做实验了吧。
动手之后发现还是有很多问题的,现在记录一下遇到的:
数据预处理与加载
第一步就是将数据处理为方便模型读取操作的格式了,包括文件读写、正则抽取、等。通过阅读源码这里主要用到了两个东西,第一个是torchtext,第二个是通过自定义DataLoader的collate_fn将特定格式的数据以想要的格式加载的pytorch原生的框架中。
- torchtext
torchtext主要是在之前做seq2seq中用到的,这里贴一下主要代码:
1 | def load_dataset(batch_size): |
这里其实可以直接使用torchtext给的TranslationDataset,但是为了自己拓展方便,找到了构建Iterator所需要的参数,通过自定义dataset实现的。
- DataLoader
通过dataloader加载数据的时候,为了自定义数据格式,需要自定义collate_fn传给dataloader,通过collate_fn接受dataset中getitem得到的数据,处理后给到dataloader,并在其内部调用_DataLoader中的—next方法中调用,源码如下:
1 | class _DataLoaderIter(object): |
而此处我自定的方法如下:
1 | def convert_instance_to_idx_seq(word_insts, word2idx): |
之后就可以通过正常的iter获取定义的格式的数据了。
加载预训练的词向量
Nlp项目中经常用到这个,这次也算是认真实践了一把。之前实现了都没认真分析过,对词向量的词袋如何对应等问题都不甚清楚。
步骤大概是:
- 获取目标数据的词表。
- 从预训练的词向量中加载目标词表中词语的向量值,构造自己的嵌入矩阵。
- 对未收录词语构造初始化向量。
代码如下所示
1 | full_vocab = set(w for sent in word_insts for w in sent) |
之后再把嵌入矩阵加载到embedding层就可以了:
1 | if config.pretrained_embed_path: |
视需要是否对嵌入层也进行优化