赞
踩
可以使用 Weights&Biases 一种模型可视化库,来对模型训练进行可视化
只需要为模型的args属性中,给字典里的'wandb_project'
设置一个属性名称就好
model = ClassificationModel('roberta', 'roberta-base', args={'wandb_project': 'project-name'})
Early stopping 是一种防止模型过拟合的技术。简单来说,就是周期性的评估一个模型在测试集上的性能,当模型不在测试集上有性能提升就停止训练。
可以通过模型的参数设置来调整相应的early stopping条件
更多详细配置请参考配置选项表:
(early_stopping_consider_epochs,
early_stopping_delta,
early_stopping_metric,
early_stopping_metric_minimize,
early_stopping_patience)
要使用early stopping就必须设置use_early_stopping
为True
以下设置的含义是:模型训练会在如下条件下停止:
每1000次做一次评估,模型连续5次在测试集上的mcc评估成绩没有比之前最好的mcc成绩提升0.01.
from simpletransformers.classification import ClassificationModel, ClassificationArgs
model_args = ClassificationArgs()
model_args.use_early_stopping = True
model_args.early_stopping_delta = 0.01
model_args.early_stopping_metric = "mcc" #马修斯相关系数,二分类的一种评价指标,取值在[-1,1]之间,值越大分类越精确
model_args.early_stopping_metric_minimize = False
model_args.early_stopping_patience = 5
model_args.evaluate_during_training_steps = 1000
model = ClassficationModel("bert", "bert-base-cased", args=model_args)
Simple Transformers根据所选的特定模型,都会有个默认的评估指标,用于计算模型在数据集上的性能。
然而有时候,需要根据自己的实际用例来调整评估指标。
因此,eval_model()
和train_model()
方法接受关键字参数来设置评估函数,评估函数必须接受2种输入(True label, Prediction),跟sklearn的格式一样
from simpletransformers.classification import ClassificationModel
import sklearn
model = ClassficationModel("bert", "bert-base-cased")
model.train_model(train_df, acc=sklearn.metrics.accuracy_score)
model.eval_model(eval_df, acc=sklearn.metrics.accuracy_score)
小提示:可以将自己设定的评估函数和early stopping 进行结合。通过将自己的评估函数的名字设置为early_stopping_metric
Simple Vieweer是一个网页app,根据Streamlit框架搭建,可以迅速用于训练好的模型。
使用命令simple-viewer
调用
当Simple Viewer开始运行,它会在当前的文件夹以及子文件夹中搜索Simple Transfomers 模型。所有检测到的模型都可以在Choose Model
下拉模块中找到。或者,通过指定Simple Transformers 任务、模型种类以及模型名称来加载模型。
模型名称可以是本地模型的地址,或是Hugging Face model中对应的模型名称
以下四种任务·是可以支持可视化的:
Classification
Multi-Label Classification
Named Entity Recognition
Question Answering
小贴士:模型训练中涉及到两种参数:1.learned parameters(就比如模型的权重 model weights)2.超参数hyperparameters(学习率,batch size…)
选择一组好的超参数值在创建好的模型的过程中扮演重要的角色。Simple Transformers 有优秀的 W&B Sweeps
属性,来自动进行超参数优化。
sweep可以通过python的字典(sweep_config)进行配置,字典中包含3个keys
必须是在W&B里面有的metric
sweep_config
的metric
key指向另一个Python字典,包含了name
,goal
和target(可选)
'minimize'
或是 'maximize'
默认 minimizesweep_config
的parameters
key指向另一个Python字典,其中包含了所有要调参的超参数以及可能的值。
W&B提供了许多方法来为每个参数指定可能的值。详情在W&B doc 里面
可能的值也是用字典的形式来表示的。有两种方法:
样例:
sweep_config = {
"method": "bayes", # grid, random
"metric": {"name": "train_loss", "goal": "minimize"},
"parameters": {
"num_train_epochs": {"values": [2, 3, 5]},
"learning_rate": {"min": 5e-5, "max": 4e-4},
},
}
sweep_id = wandb.sweep(sweep_config, project="Simple Sweep")
1.加载数据
# Preparing train data
train_data = [
["Aragorn was the heir of Isildur", "true"],
["Frodo was the heir of Isildur", "false"],
]
train_df = pd.DataFrame(train_data)
train_df.columns = ["text", "labels"]
# Preparing eval data
eval_data = [
["Theoden was the king of Rohan", "true"],
["Merry was the king of Rohan", "false"],
]
eval_df = pd.DataFrame(eval_data)
eval_df.columns = ["text", "labels"]
2.设置模型参数
小提示:根据经验,当运行sweep进行超参数值搜索时,最好将reprocess_input_data
, overwrite_output_dir
, and no_save
设置为 True
model_args = ClassificationArgs()
model_args.reprocess_input_data = True
model_args.overwrite_output_dir = True
model_args.evaluate_during_training = True
model_args.manual_seed = 4
model_args.use_multiprocessing = True
model_args.train_batch_size = 16
model_args.eval_batch_size = 8
model_args.labels_list = ["true", "false"]
model_args.wandb_project = "Simple Sweep"
设置一个训练函数train(),W&B会调用这个函数来进行相应的sweep训练。这个函数必须执行3个关键任务
1.初始化wandb
2.初始化一个Simple Transformers模型,并将sweep_config=wandb.config
传入
3.运行Simple Transformer模型
def train(): # Initialize a new wandb run wandb.init() # Create a TransformerModel model = ClassificationModel( "roberta", "roberta-base", use_cuda=True, args=model_args, sweep_config=wandb.config, # 前面设置的超参数值 ) # Train the model model.train_model(train_df, eval_df=eval_df) # Evaluate the model model.eval_model(eval_df) # Sync wandb sync:同步 wandb.join()
wandb.agent(sweep_id, train)
import logging import pandas as pd import sklearn import wandb from simpletransformers.classification import ( ClassificationArgs, ClassificationModel, ) # 超参数搜索策略设置 sweep_config = { "method": "bayes", # grid, random "metric": {"name": "train_loss", "goal": "minimize"}, "parameters": { "num_train_epochs": {"values": [2, 3, 5]}, "learning_rate": {"min": 5e-5, "max": 4e-4}, }, } sweep_id = wandb.sweep(sweep_config, project="Simple Sweep") logging.basicConfig(level=logging.INFO) transformers_logger = logging.getLogger("transformers") transformers_logger.setLevel(logging.WARNING) # Preparing train data train_data = [ ["Aragorn was the heir of Isildur", "true"], ["Frodo was the heir of Isildur", "false"], ] train_df = pd.DataFrame(train_data) train_df.columns = ["text", "labels"] # Preparing eval data eval_data = [ ["Theoden was the king of Rohan", "true"], ["Merry was the king of Rohan", "false"], ] eval_df = pd.DataFrame(eval_data) eval_df.columns = ["text", "labels"] model_args = ClassificationArgs() model_args.reprocess_input_data = True model_args.overwrite_output_dir = True model_args.evaluate_during_training = True model_args.manual_seed = 4 model_args.use_multiprocessing = True model_args.train_batch_size = 16 model_args.eval_batch_size = 8 model_args.labels_list = ["true", "false"] model_args.wandb_project = "Simple Sweep" def train(): # Initialize a new wandb run wandb.init() # Create a TransformerModel model = ClassificationModel( "roberta", "roberta-base", use_cuda=True, args=model_args, sweep_config=wandb.config, ) # Train the model model.train_model(train_df, eval_df=eval_df) # Evaluate the model model.eval_model(eval_df) # Sync wandb wandb.join() wandb.agent(sweep_id, train)
为了将你的sweep结果可视化,在W&B 上打开项目。更多细节在这文档
详细的超参数优化知道,请看这个文件
较少用(不太轻易改模型参数)
Simple Transformer支持自定义的参数组,这些参数组可用来给模型中不同的layers设置不同的学习率,冻结layers,只训练最后一层等等
custom_parameter_groups
提供最精细的配置选项。它是一个python字典列表,每个字典包含了一个params
键和其他可选的键,这些键对应着优化器可接受的关键字参数(例如:lr,weight_decay权重衰减)
params键的值时个列表,其中包含了命名了的参数(e.g. [“classifier.weight”, “bert.encoder.layer.10.output.dense.weight”])
model_args = ClassificationArgs()
model_args.custom_parameter_groups = [
{
"params": ["classifier.weight", "bert.encoder.layer.10.output.dense.weight"],
"lr": 1e-2,
}
]
小提示:所有的simple transformer模型都有一个get_named_parameters()
方法,会返回一个列表,包含了模型中所有参数名
Custom layer parameters
可以更方便的给给定的layer或一些列layer设置优化器选项。
他是一个列表,每个元素是字典,
model_args = ClassificationArgs()
model_args.custom_layer_parameters = [
{
"layer": 10, #明确第几个layer
"lr": 1e-3,
},
{
"layer": 0,
"lr": 1e-5,
},
]
要注意的是custom_parameter_groups
的优先级高于custom_layer_parameters
,可能会出现有些属性参数在两边都设置的情况,这时以前者为先
train_custom_parameters_only
选项用于让模型只训练指定的模型参数。如果train_custom_parameters_only
设置为True。那么模型只会训练custom_parameter_groups
和custom_layer_parameters
里指定的参数。
from simpletransformers.classification import ClassificationModel, ClassificationArgs import pandas as pd import logging logging.basicConfig(level=logging.INFO) transformers_logger = logging.getLogger("transformers") transformers_logger.setLevel(logging.WARNING) # Preparing train data train_data = [ ["Aragorn was the heir of Isildur", 1], ["Frodo was the heir of Isildur", 0], ] train_df = pd.DataFrame(train_data) train_df.columns = ["text", "labels"] # Preparing eval data eval_data = [ ["Theoden was the king of Rohan", 1], ["Merry was the king of Rohan", 0], ] eval_df = pd.DataFrame(eval_data) eval_df.columns = ["text", "labels"] # Train only the classifier layers model_args = ClassificationArgs() model_args.train_custom_parameters_only = True # 这里设置为True,就只训练更新下面指定的参数 model_args.custom_parameter_groups = [ { "params": ["classifier.weight"], "lr": 1e-3, }, { "params": ["classifier.bias"], "lr": 1e-3, "weight_decay": 0.0, }, ] # Create a ClassificationModel model = ClassificationModel( "bert", "bert-base-cased", args=model_args ) # Train the model model.train_model(train_df)
大多数Simple Transformer模型会用from_trained() 方法来从hugging face下载预训练模型。你可以传入关键字实参到这个方法中,来指定下载特定的模型
如果你在防火墙后面,你需要设置代理
model = ClassficationModel(
"bert",
"bert-base-cased",
proxies={"http": "foo.bar:3128", "http://hostname": "foo.bar:4012"}
)
每个模型的检查点都耗费相同的磁盘空间。当训练transformer模型在很多epoch时,我们不希望每一轮都进行存档。假设我们希望每三轮保存一次。
过程分两步:
1.关闭自动保存 将属性save_model_every_epoch = False
2.save_steps
要设置为N(每N轮保存一次)
from simpletransformers.classification import ClassificationModel, ClassificationArgs
import math
SAVE_EVERY_N_EPOCHS = 3 #这里设置
model_args = ClassificationArgs()
steps_per_epoch = math.floor(len(train_df) / SAVE_EVERY_N_EPOCHS)
if(len(train_df) % SAVE_EVERY_N_EPOCHS > 0):
steps_per_epoch +=1
model_args["save_steps"] = steps_per_epoch * SAVE_EVERY_N_EPOCHS
model_args["save_model_every_epoch"] = False
model = ClassficationModel("bert", "bert-base-cased", args=model_args)
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。