本文基于AllenNLP英文tutorial翻译,其中不少错误,仅作为个人学习记录
有一篇帖子总结了一下学习处理NLP问题中间的坑。NLP数据预处理要比CV的麻烦很多。
- 去除停用词,建立词典,加载各种预训练词向量,Sentence -> Word ID -> Word Embedding的过程(Tobias Lee:文本预处理方法小记),其中不仅需要学习pytorch,可能还要学习spacy,NLTK,numpy,pandas,tensorboardX等常用python包。
- 用到RNN时,还要经过pad,pack,pad的过程,像这样的很多函数在使用时需要有数学基础加上简单的实践,感觉对一个新人来说,高维数据的流动有点抽象,不容易理解。
- 数据集的读取,tensorboardX的使用。。。。各种东西要学习。在运行别人的代码后打印出信息,不仅看着上档次,而且可以看到很多实用的信息。。。
AllenNLP是在pytorch基础上的封装,它的目标是处理NLP任务,可以减少很多额外的学习。
- 分词,帮你用spacy,NLTK,或者简单的按空格分词处理。
- 数据集的读取,它内置了很多数据集的读取,你可以在通过学习它的读取方式,在它的基础上对自己需要的数据集进行读取。 、
- 在Sentence -> Word ID -> Word Embedding的过程中,Glove,ELMo,BERT等常用的都可以直接使用,需要word,char粒度的都可以。
- log打印输出,在内置的输出项之外,你可以很方便地加入想要输出的信息。模型的各个组件中的参数都可以存在一个json/jsonnet文件中,修改参数进行实验很方便。
2. A Walk Through AllenNLP
第一部分 训练和评估模型
训练一个模型
目标:使用AllenNLP训练一个简单的词性标注器,模型源代码,包括了一个词嵌入层和LSTM。
数据集使用Brown Corpus在实现的时候我会看一下是否需要下载,我们会训练一个基于4000随机抽取句子的模型(sentences.small.train),使用不同的1000个随机抽取句子作为验证集(sentences.small.dev)。
标记实验源码
在这里需要注意的是代码中训练部分。
"trainer": {
"optimizer": "adam",
"num_epochs": 40,
"patience": 10,
"cuda_device": -1
}
- 优化器为adam
- 迭代次数为40次(教程中使用mac,用时大概40min,等下可以测一下win环境),
- patience(忍耐?)用于控制早期停止,如果我们的验证矩阵在这些迭代中不能提高,训练就挂起,
- cuda_device为GPU参数设置,如果使用GPU,就把cuda_device改为0
好了我们现在可以来试一下这个训练器。如果使用pycharm,可以在terminal中输入下面命令行
allennlp train tutorials/getting_started/walk_through_allennlp/simple_tagger.json --serialization-dir /tmp/tutorials/getting_started
我下午调了半天才通,其实还是因为命令行不熟……
不要盯着console看,虽然运行很爽。
注意看这行命令,其中serialization-dir参数指定将保存模型的词汇表和检查点权重的目录。
2019-03-07 18:01:18,951 - INFO - allennlp.training.trainer - Epoch 5/5
2019-03-07 18:01:18,953 - INFO - allennlp.training.trainer - Peak CPU memory usage MB: 0.0
2019-03-07 18:01:18,991 - INFO - allennlp.training.trainer - Training
accuracy: 0.8524, accuracy3: 0.9407, loss: 0.6855 ||: 100%|##########################################################################################################################| 125/125 [00:45<00:00, 2.22it/s]
2019-03-07 18:02:04,654 - INFO - allennlp.training.trainer - Validating
accuracy: 0.8300, accuracy3: 0.9268, loss: 0.7355 ||: 100%|############################################################################################################################| 31/31 [00:02<00:00, 12.91it/s]
2019-03-07 18:02:07,300 - INFO - allennlp.training.tensorboard_writer - Training | Validation
2019-03-07 18:02:07,300 - INFO - allennlp.training.tensorboard_writer - cpu_memory_MB | 0.000 | N/A
2019-03-07 18:02:07,301 - INFO - allennlp.training.tensorboard_writer - accuracy | 0.852 | 0.830
2019-03-07 18:02:07,302 - INFO - allennlp.training.tensorboard_writer - loss | 0.686 | 0.736
2019-03-07 18:02:07,302 - INFO - allennlp.training.tensorboard_writer - accuracy3 | 0.941 | 0.927
2019-03-07 18:02:07,324 - INFO - allennlp.training.checkpointer - Best validation performance so far. Copying weights to '/tmp/tutorials/getting_started/best.th'.
2019-03-07 18:02:07,339 - INFO - allennlp.training.trainer - Epoch duration: 00:00:48
在这里,accuracy 衡量我们的模型预测“正确”词性标签最常可能的频率,而accuracy3 衡量正确标签是最可能的三个标签之一的频率。
loss是交叉熵,是用于训练模型的目标。你想确保它在培训期间大多减少。
为了GKD,我就设置了5次迭代。
评价模型
训练完毕之后,就需要对模型进行评价了,这里使用的是随机1000个句子的测试集。
allennlp evaluate /tmp/tutorials/getting_started/model.tar.gz https://allennlp.s3.amazonaws.com/datasets/getting-started/sentences.small.test
2019-03-07 18:04:32,031 - INFO - allennlp.commands.evaluate - accuracy: 0.8252221324717286
2019-03-07 18:04:32,031 - INFO - allennlp.commands.evaluate - accuracy3: 0.9229604200323102
2019-03-07 18:04:32,031 - INFO - allennlp.commands.evaluate - loss: 0.7843235787004232
对比一下训练和测试的结果。差了0.0x个点,还好……
进行预测
最后,自然是要预测一个。predict命令采用归档模型和输入的JSON行文件,并使用模型进行预测。
这里,标记模型的“预测变量”需要一个包含句子的JSON blob:
cat <<EOF >> inputs.txt
{"sentence": "I am reading a tutorial."}
{"sentence": "Natural language processing is easy."}
EOF
教程中是这么做的,使用linux写入inputs文件,我直接生成了,然后使用以下语句进行预测。注意,inputs.txt建议使用绝对地址。
allennlp predict /tmp/tutorials/getting_started/model.tar.gz ****\inputs.txt
结果如下
"words": ["Natural", "language", "processing", "is", "easy", "."], "tags": ["jj", "nn", "np", "bez", "jj", "."]}
"words": ["we", "have", "a", "date", "tomorrow", "afternoon", ".", "When", "would", "be", "convenient", "for", "you", "."], "tags": ["ppss", "hv", "at", "nn", "vb", "nn", "in", "wrb", "md", "be", "jj", "in", "ppo", "."]}
网友评论