【AllenNLP入门教程】: 2、基于Allennlp2.4版本的一些使用技巧
1.依赖
python == 3.8.0allennlp == 2.4.0pip install allennlp -i https://pypi.tuna.tsinghua.edu.cn/simple
2.使用lazy
注意
:在使用大数据进行训练的时候使用lazy模式是极其重要的,但是记得使用lazy模式之前需要进行数据的按照label的分布进行总体数据的shuffle,使得在训练的数据整体上是分布均匀的。这个可以使用sklearn实现,参考这里
这里需要知道默认的dataset_loader是:multiprocess_data_loader.py
而这个里面需要指定:"max_instances_in_memory": 80
, 才能使用lazy
在jsonnet中配置:
"data_loader": {"batch_size": 8,"max_instances_in_memory": 80,"cuda_device": 0,"shuffle": true
},
3.build vocab
跟lazy同样道理的是 vocab的构建:由于训练数据比较大的时候,在每一次训练时从头构建vocab(需要完整遍历一边所有的数据集)是比较耗时的,所以我们这里手动构建一个vocab,然后在每次修改模型,训练模型的时候直接load就行了。
1、在jsonnet中设置:
"datasets_for_vocab_creation": ["train","validation"],
2、提前使用build-vocab命令生成vocab.tar.gz
allennlp build-vocab scripts/my_text_classifier.jsonnet data/vocab.tar.gz --include-package my_text_classifier
我们的生成的位置在:data/vocab.tar.gz
这里也可以使用自己的脚本生成,然后仿照vocab.tar.gz
填入就行了,结构如下:
-- vocab.tar.gz
|___ labels.txt
|___ non_padded_namespaces.txt
|___ tokens.txt
3、只有生成之后才能在jsonnet中删除"datasets_for_vocab_creation": ["train","test"],
然后再添加:
"vocabulary":{"type": "from_files","directory": "data/vocab_model.tar.gz"},
这样之后的训练就会直接加载这个vocab了,不会浪费更多的时间。
3、预测
如何进行从 line 读取 test; 然后batch predict;然后存储指定格式的预测结果?
1、从line 读取 test(而不是从json中):
需要在自定义的predictor中重写这个方法:
@overridesdef load_line(self, line: str) -> JsonDict:"""If your inputs are not in JSON-lines format (e.g. you have a CSV)you can override this function to parse them correctly."""return {"sentence": line}
2. batch predict
需要在自定义的predictor中重写这个方法:
@overridesdef predict_batch_json(self, inputs: List[JsonDict]) -> List[JsonDict]:instances = self._batch_json_to_instances(inputs)outputs = self.predict_batch_instance(instances)outputs = [{"paperid": i["sentence"].split("\t")[0], "categories":j["label"]} for i, j in zip(inputs, outputs)]return outputs
3.把预测结果以指定格式存储
需要在自定义的predictor中重写这个方法:
@overridesdef dump_line(self, outputs: JsonDict) -> str:"""If you don't want your outputs in JSON-lines formatyou can override this function to output them differently."""if "paperid" in outputs:return str(outputs["paperid"]) + "," + str(outputs["categories"]) + "\n"else:# 这种情况是最后不在batch中的需要单独预测return str(self.line.split("\t")[0]) + "," + str(outputs["label"]) + "\n"
还需要再自定义模型中重写这个方法:
def make_output_human_readable(self, output_dict: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]:label = torch.argmax(output_dict["probs"], dim=1)label = [self.vocab.get_token_from_index(int(i), "labels") for i in label]output_dict["label"] = labelreturn output_dict
4、batch_预测的命令:
cpu
allennlp predict checkpoint/model.tar.gz data/paper_classification/test.csv --output-file data/paper_classification/predict_result.csv --include-package my_text_classifier --predictor sentence_classifier --batch-size 8 --silent
注意:只有在predictor中重写了predict_batch_json
方法,同时在预测命令中指定:--batch-size 8
,才能batch 预测。
gpu
nohup allennlp predict /home/featurize/data/checkpoint/model/model.tar.gz /home/featurize/data/test.csv
--output-file /home/featurize/data/predict_result.csv --include-package my_text_classifier
--predictor sentence_classifier --batch-size 16 --cuda-device 0 --silent &
注意:只有指定--cuda-device 0
才能在预测阶段使用gpu。
4、如何继续训练模型 ?
之前指定训练一个epoch,训练完成之后修改jsonnet,想接着训练更多的epoch。
分两种情况:
1、上次训练的checkpoint还在的情况下:
直接修改scripts/train.jsonnet
和checkpoint/config.jsonnet
中的num_epochs
,然后训练命令改为:
nohup allennlp train scripts/my_text_classifier_robert_gpu.jsonnet --serialization-dir /home/featurize/data/checkpoint/model --include-package my_text_classifier --recover &
注意:继续训练的命令是后面跟--recover
注意:因为这里是 recover ,所以千万不能跟 -f,要不然会把checkpoint 的内容删除掉
2、上次训练的checkpoint不存在了,只有model.tar.gz
的情况下:
1、修改tain.jsonnet
中的model,同时修改自己想要训练的num_epochs
:
"model": {"type": "from_archive","archive_file": "/home/featurize/data/model.tar.gz"},
2、继续训练:
nohup allennlp train scripts/robert_continue_train.jsonnet --serialization-dir /home/featurize/data/checkpoint_continue/ --include-package my_text_classifier &
注意:这个的前提是之前训练的moderl.tar.gz
中的config.json
中的 “model” 是自定义的而不是从archive中得到的,如果同样也是从archive中得到的,那么需要修改config.json中的“model”:
mkdir model
# 解压命令
tar -xvf model.tar.gz -C model/
cd model
vi config.jsonnet
# 修改完之后压缩命令
tar -zcvf model.tar.gz config.json meta.json vocabulary weights.th
5、如何定时存储 checkpoint
由于默认情况下的jsonnet
没有注册Checkpointer
,所以需要我们注册一个,然后把save_every_num_seconds
作为传参通过jsonnet
传进去。
1、重写一个 checkpointer,目的是可以在jsonnet中使用
from typing import Optional, Union
import osfrom allennlp.training.checkpointer import Checkpointer@Checkpointer.register("simple_checkpointer")
class SimpleCheckpointer(Checkpointer):def __init__(self,serialization_dir: Union[str, os.PathLike],save_every_num_seconds: Optional[float] = None):super().__init__(serialization_dir)self._save_every_num_seconds = save_every_num_secondsself._serialization_dir = str(serialization_dir)
2、在jsonnet中指定save_every_num_seconds
:
"trainer": {"checkpointer":{"type": "simple_checkpointer","serialization_dir":"checkpoint","save_every_num_seconds": 1200},}
6、如何写一个有效的dataset reader
这里要考虑两个因素:一个是训练阶段读取训练数据需要使用_read()
和text_to_instance()
,一个是预测阶段读取测试数据需要使用text_to_instance()
,所以text_to_instance()
的label默认要设置为None。
1、如何输入两个inputs?
def text_to_instance(self, title: str, abstract: str, label: str = None) -> Instance:tokens_title = self.tokenizer.tokenize(title)tokens_abstract = self.tokenizer.tokenize(abstract)if self.max_tokens:tokens_title = tokens_title[: self.max_tokens]tokens_abstract = tokens_abstract[: self.max_tokens]text_field_title = TextField(tokens_title, self.token_indexers)text_field_abstract = TextField(tokens_abstract, self.token_indexers)# 4、同时加入两个就是两个inputs text了fields = {"title": text_field_title, "abstract": text_field_abstract}# 3、如果含有label的话,就加入,说明是训练;没有的话不加入,说明是测试if label:fields["label"] = LabelField(label)return Instance(fields)def _read(self, file_path: str) -> Iterable[Instance]:with open(file_path, "r") as lines:for line in lines:line = line.strip().split("\t")# 1、这里判断输入的train(含有label)还是test(不含label)if len(line) == 4:paperid, title, abstract, categories = lineelse:paperid, title, abstract = linecategories = None# 2、这里判断是不是表头,如果是就略过if paperid == "paperid":continueyield self.text_to_instance(title, abstract, categories)
2、如何输入bert 方式
def text_to_instance(self, text_a: str, text_b: str, label: str = None) -> Instance:# 80% of the text_a length in the training set is less than 256, 512 - 256 = 256.tokens_a = self.tokenizer.tokenize(text_a)[:self.max_tokens//2]tokens_b = self.tokenizer.tokenize(text_b)[:self.max_tokens-len(tokens_a)]# 4、text_a+text_b 中间是sep 同时输入 berttokens = self.tokenizer.add_special_tokens(tokens_a[1:-1], tokens_b[1:-1])text_field = TextField(tokens, self.token_indexers)fields = {"text": text_field}# 3、如果含有label的话,就加入,说明是训练;没有的话不加入,说明是测试if label:fields["label"] = LabelField(label)return Instance(fields)def _read(self, file_path: str) -> Iterable[Instance]:with open(file_path, "r", encoding="utf-8") as lines:for line in lines:line = line.strip().split("\t")# 1、这里判断输入的train(含有label)还是test(不含label)if len(line) == 3:text_a, text_b, categories = lineelse:text_a, text_b, = linecategories = Noneif text_a == "text_a":continueyield self.text_to_instance(text_a, text_b, categories)
7、衡量标准
1、我们在做不同任务的时候需要指定不同的衡量指标,比如分类任务有acc
和f1
:那么在编写自定义模型的时候要添加一下:
from allennlp.training.metrics import CategoricalAccuracy, FBetaMeasure
...def __init__(self, vocab: Vocabulary, embedder: TextFieldEmbedder, encoder: Seq2VecEncoder):super().__init__(vocab)...self.accuracy = CategoricalAccuracy()self.accuracy_2 = FBetaMeasure(average="macro")
...def get_metrics(self, reset: bool = False) -> Dict[str, float]:return {"accuracy": self.accuracy.get_metric(reset),"f1": self.accuracy_2.get_metric(reset)["fscore"]}
2、在选择best model的时候,我们同样叶需要指定按照哪个指标来选择,默认是loss指标,如果想要其他指标需要在jsonnet
中指定:
"trainer": {"validation_metric": "+f1",...
}
8.data_loader使用bucket模式
"data_loader": {"batch_sampler": {"type": "bucket","batch_size": 16},"cuda_device": 0,"max_instances_in_memory": 1600},
9. patience
当连续两个epoch的accuracy没有提升,就early stop
"trainer": {"validation_metric": ["+accuracy","-loss"],"patience": 2,"optimizer": {"type": "huggingface_adamw","lr": 2.0e-5},"num_epochs": 5
}
10.tensorboard 查看训练参数变化
1、在jsonnet中设置callbacks
"trainer": {"validation_metric": ["+accuracy","-loss"],"patience": 2,"callbacks":["tensorboard"],"optimizer": {"type": "huggingface_adamw","lr": 1.0e-5},"num_epochs": 5}
2、环境安装tensorboard,然后启动服务,并指定logdir: checkpoint/log
pip install tensorboardtensorboard --logdir=checkpoint/log
【AllenNLP入门教程】: 2、基于Allennlp2.4版本的一些使用技巧相关推荐
- 【tools】Latex菜鸟快速入门教程(基于overleaf平台:Learn LaTeX in 30 minutes)
[tools]Latex菜鸟快速入门教程(基于overleaf平台) 注册登录overleaf LaTeX入门教程 1.First start 2.序言Preamble 3.添加标题.作者和日期 4. ...
- Activiti最全入门教程(基于Eclipse插件开发)
工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进 ...
- sql数据库教程百度云_SQL菜鸟入门教程(基于SQLITE数据库)(D1)
从事IT工作的都知道,SQL 是用于访问和处理数据库的标准的计算机语言.对于非计算机专业人员而言,职场中如果有了这个技能,很容易脱颖而出,但是非计算机专业人员而言,SQL似乎又深不可测.其实并非如此, ...
- matlab教程——基于6.x版本,MATLAB教程:基于6.x版本
第一章 基础准备及入门 1. 1 MATLAB的安装和内容选择 1. 2 Desktop操作桌面的启动 1. 2. 1 MATLAB的启动 1. 2. 2 Desktop操作桌面简介 1. ...
- sql数据库教程百度云_SQL菜鸟入门教程(基于SQLITE数据库)(D4)
今天开始我们介绍select查询命令.select最基本的用法就是" select * from 表名 ",意思就是把该表所有内容全部显示出来.我们结合花名册这个表说明一下具体操作 ...
- cad旋转命令_CAD制图初学入门教程:CAD软件中旋转命令的使用技巧
在CAD软件中,旋转是最基础的编辑命令,基本操作也没有什么难度,但相对比移动就复杂一些,而且有更多的技巧,对于很多CAD制图初学入门者来说,这个命令也是需要掌握的,下面就给大家介绍一下CAD制图入门学 ...
- CAD制图初学入门教程:CAD软件中旋转命令的使用技巧
在浩辰CAD软件中,旋转是最基础的编辑命令,基本操作也没有什么难度,但相对比移动就复杂一些,而且有更多的技巧,对于很多CAD制图初学入门者来说,这个命令也是需要掌握的,下面就给大家介绍一下CAD制图入 ...
- c# 定位内存快速增长_CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)...
Linux Pwn入门教程系列分享已到尾声,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- 前端 IndexDB 操作入门教程
前端 IndexDB 操作入门教程 idb-js 基于indexdb本地数据库的封装 文档地址 安装: npm install idb-js --save 使用: 第一步: 引入Idb import ...
- walking机器人入门教程-视觉转激光建图-cartographer算法建图
系列文章目录 walking机器人入门教程-目录 walking机器人入门教程-硬件清单 walking机器人入门教程-软件清单 walking机器人入门教程-测试底盘 walking机器人入门教程- ...
最新文章
- YYCache 源码分析(一)
- JAVA之JVM分代垃圾回收策略(一)
- 英语影视台词---六、Saving Private Ryan Quotes
- LVS入门篇(二)之LVS基础
- C# 使用int.TryParse,Convert.ToInt32,(int)将浮点类型转换整数时的区别
- 5.一文搞懂MySQL的数据类型
- 国网“泛在电力物联网”的战略与逻辑
- WIFI 网络操作--------------------笔记
- S3TC IAP15F2K61S2点亮一个发光二极管keil和stc-isp软件操作
- stringbuilder_String,StringBuilder,StringBuffer三者的区别?
- libevhtp介绍与demo构建
- Flutter之SemanticsBinding和WidgetsBindingObserver简析
- vue中:key 和react 中key={} 的作用,以及ref的特性?
- 提示框几秒消失比较好_移动设计提示框介绍-《产品日常笔记》
- Mujoco-一阶单摆建模与控制
- Android车牌识别SDK
- Opencv图像识别从零到精通(34)---SIFI
- 使用codeigniter_使用CodeIgniter解开MVC
- Motion Planning中的问题与挑战
- RabbitMq消息队列进一步认识
热门文章
- Golang 实现文件内容差异比较
- 嵌入式软件c语言笔试题
- 隐式函数声明警告---调用malloc函数但不包含头文件
- 操作 神通数据库_神通数据库安装及操作笔记
- 《社会调查数据管理——基于Stata 14管理CGSS数据》一3.4 Stata的一些术语及使用通则...
- idea打包时控制台中文乱码
- ETL工具——Taskctl Web应用篇
- pyspark 空值填充
- 安卓熄屏录像_最屌免费安卓Android屏幕录像软件 (免ROOT)
- 二元一次方程用计算机怎么解,二元一次方程的解法