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.jsonnetcheckpoint/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、我们在做不同任务的时候需要指定不同的衡量指标,比如分类任务有accf1:那么在编写自定义模型的时候要添加一下:

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版本的一些使用技巧相关推荐

  1. 【tools】Latex菜鸟快速入门教程(基于overleaf平台:Learn LaTeX in 30 minutes)

    [tools]Latex菜鸟快速入门教程(基于overleaf平台) 注册登录overleaf LaTeX入门教程 1.First start 2.序言Preamble 3.添加标题.作者和日期 4. ...

  2. Activiti最全入门教程(基于Eclipse插件开发)

    工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进 ...

  3. sql数据库教程百度云_SQL菜鸟入门教程(基于SQLITE数据库)(D1)

    从事IT工作的都知道,SQL 是用于访问和处理数据库的标准的计算机语言.对于非计算机专业人员而言,职场中如果有了这个技能,很容易脱颖而出,但是非计算机专业人员而言,SQL似乎又深不可测.其实并非如此, ...

  4. matlab教程——基于6.x版本,MATLAB教程:基于6.x版本

    第一章  基础准备及入门 1. 1  MATLAB的安装和内容选择 1. 2  Desktop操作桌面的启动 1. 2. 1  MATLAB的启动 1. 2. 2  Desktop操作桌面简介 1.  ...

  5. sql数据库教程百度云_SQL菜鸟入门教程(基于SQLITE数据库)(D4)

    今天开始我们介绍select查询命令.select最基本的用法就是" select * from 表名 ",意思就是把该表所有内容全部显示出来.我们结合花名册这个表说明一下具体操作 ...

  6. cad旋转命令_CAD制图初学入门教程:CAD软件中旋转命令的使用技巧

    在CAD软件中,旋转是最基础的编辑命令,基本操作也没有什么难度,但相对比移动就复杂一些,而且有更多的技巧,对于很多CAD制图初学入门者来说,这个命令也是需要掌握的,下面就给大家介绍一下CAD制图入门学 ...

  7. CAD制图初学入门教程:CAD软件中旋转命令的使用技巧

    在浩辰CAD软件中,旋转是最基础的编辑命令,基本操作也没有什么难度,但相对比移动就复杂一些,而且有更多的技巧,对于很多CAD制图初学入门者来说,这个命令也是需要掌握的,下面就给大家介绍一下CAD制图入 ...

  8. c# 定位内存快速增长_CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)...

    Linux Pwn入门教程系列分享已到尾声,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  9. 前端 IndexDB 操作入门教程

    前端 IndexDB 操作入门教程 idb-js 基于indexdb本地数据库的封装 文档地址 安装: npm install idb-js --save 使用: 第一步: 引入Idb import ...

  10. walking机器人入门教程-视觉转激光建图-cartographer算法建图

    系列文章目录 walking机器人入门教程-目录 walking机器人入门教程-硬件清单 walking机器人入门教程-软件清单 walking机器人入门教程-测试底盘 walking机器人入门教程- ...

最新文章

  1. YYCache 源码分析(一)
  2. JAVA之JVM分代垃圾回收策略(一)
  3. 英语影视台词---六、Saving Private Ryan Quotes
  4. LVS入门篇(二)之LVS基础
  5. C# 使用int.TryParse,Convert.ToInt32,(int)将浮点类型转换整数时的区别
  6. 5.一文搞懂MySQL的数据类型
  7. 国网“泛在电力物联网”的战略与逻辑
  8. WIFI 网络操作--------------------笔记
  9. S3TC IAP15F2K61S2点亮一个发光二极管keil和stc-isp软件操作
  10. stringbuilder_String,StringBuilder,StringBuffer三者的区别?
  11. libevhtp介绍与demo构建
  12. Flutter之SemanticsBinding和WidgetsBindingObserver简析
  13. vue中:key 和react 中key={} 的作用,以及ref的特性?
  14. 提示框几秒消失比较好_移动设计提示框介绍-《产品日常笔记》
  15. Mujoco-一阶单摆建模与控制
  16. Android车牌识别SDK
  17. Opencv图像识别从零到精通(34)---SIFI
  18. 使用codeigniter_使用CodeIgniter解开MVC
  19. Motion Planning中的问题与挑战
  20. RabbitMq消息队列进一步认识

热门文章

  1. Golang 实现文件内容差异比较
  2. 嵌入式软件c语言笔试题
  3. 隐式函数声明警告---调用malloc函数但不包含头文件
  4. 操作 神通数据库_神通数据库安装及操作笔记
  5. 《社会调查数据管理——基于Stata 14管理CGSS数据》一3.4 Stata的一些术语及使用通则...
  6. idea打包时控制台中文乱码
  7. ETL工具——Taskctl Web应用篇
  8. pyspark 空值填充
  9. 安卓熄屏录像_最屌免费安卓Android屏幕录像软件 (免ROOT)
  10. 二元一次方程用计算机怎么解,二元一次方程的解法