@@ -10,14 +10,50 @@ fastNLP 由 :mod:`~fastNLP.core` 、 :mod:`~fastNLP.io` 、:mod:`~fastNLP.module | |||
fastNLP 中最常用的组件可以直接从 fastNLP 包中 import ,他们的文档如下: | |||
""" | |||
__all__ = ["Instance", "FieldArray", "Batch", "Vocabulary", "DataSet", "Const", | |||
"Trainer", "Tester", "Callback", | |||
"Padder", "AutoPadder", "EngChar2DPadder", | |||
"AccuracyMetric", "BMESF1PreRecMetric", "SpanFPreRecMetric", "SQuADMetric", | |||
"Optimizer", "SGD", "Adam", | |||
"Sampler", "SequentialSampler", "BucketSampler", "RandomSampler", | |||
"LossFunc", "CrossEntropyLoss", "L1Loss", "BCELoss", "NLLLoss", "LossInForward", | |||
"cache_results"] | |||
__all__ = [ | |||
"Instance", | |||
"FieldArray", | |||
"Batch", | |||
"Vocabulary", | |||
"DataSet", | |||
"Const", | |||
"Trainer", | |||
"Tester", | |||
"Callback", | |||
"GradientClipCallback", | |||
"EarlyStopCallback", | |||
"TensorboardCallback", | |||
"LRScheduler", | |||
"ControlC", | |||
"Padder", | |||
"AutoPadder", | |||
"EngChar2DPadder", | |||
"AccuracyMetric", | |||
"BMESF1PreRecMetric", | |||
"SpanFPreRecMetric", | |||
"SQuADMetric", | |||
"Optimizer", | |||
"SGD", | |||
"Adam", | |||
"Sampler", | |||
"SequentialSampler", | |||
"BucketSampler", | |||
"RandomSampler", | |||
"LossFunc", | |||
"CrossEntropyLoss", | |||
"L1Loss", "BCELoss", | |||
"NLLLoss", | |||
"LossInForward", | |||
"cache_results" | |||
] | |||
from .core import * | |||
from . import models | |||
from . import modules | |||
@@ -10,10 +10,11 @@ core 模块里实现了 fastNLP 的核心框架,常用的组件都可以从 fa | |||
对于常用的功能,你只需要在 :doc:`fastNLP` 中查看即可。如果想了解各个子模块的分工,您可以阅读以下文档: | |||
TODO 向导 | |||
""" | |||
from .batch import Batch | |||
from .callback import Callback | |||
from .callback import Callback, GradientClipCallback, EarlyStopCallback, TensorboardCallback, LRScheduler, ControlC | |||
from .const import Const | |||
from .dataset import DataSet | |||
from .field import FieldArray, Padder, AutoPadder, EngChar2DPadder | |||
@@ -1,7 +1,62 @@ | |||
""" | |||
callback模块实现了 fastNLP 中的Callback类,用于增强 :class:`~fastNLP.Trainer` 类, | |||
r""" | |||
callback模块实现了 fastNLP 中的许多 callback 类,用于增强 :class:`~fastNLP.Trainer` 类, | |||
我们将 :meth:`~fastNLP.Train.train` 这个函数内部分为以下的阶段,在对应阶段会触发相应的调用:: | |||
callback.on_train_begin() # 开始进行训练 | |||
for i in range(1, n_epochs+1): | |||
callback.on_epoch_begin() # 开始新的epoch | |||
for batch_x, batch_y in Batch: | |||
callback.on_batch_begin(batch_x, batch_y, indices) # batch_x是设置为input的field,batch_y是设置为target的field | |||
获取模型输出 | |||
callback.on_loss_begin() | |||
计算loss | |||
callback.on_backward_begin() # 可以进行一些检查,比如loss是否为None | |||
反向梯度回传 | |||
callback.on_backward_end() # 进行梯度截断等 | |||
进行参数更新 | |||
callback.on_step_end() | |||
callback.on_batch_end() | |||
# 根据设置进行evaluation,比如这是本epoch最后一个batch或者达到一定step | |||
if do evaluation: | |||
callback.on_valid_begin() | |||
进行dev data上的验证 | |||
callback.on_valid_end() # 可以进行在其它数据集上进行验证 | |||
callback.on_epoch_end() # epoch结束调用 | |||
callback.on_train_end() # 训练结束 | |||
callback.on_exception() # 这是一个特殊的步骤,在训练过程中遭遇exception会跳转到这里 | |||
关于Trainer的详细文档,请参见 :doc:`trainer 模块<fastNLP.core.trainer>` | |||
如下面的例子所示,我们可以使用内置的 callback 类,或者继承 :class:`~fastNLP.core.callback.Callback` | |||
定义自己的 callback 类:: | |||
from fastNLP import Callback, EarlyStopCallback, Trainer, CrossEntropyLoss, AccuracyMetric | |||
from fastNLP.models import CNNText | |||
start_time = time.time() | |||
class MyCallback(Callback): | |||
def on_epoch_end(self): | |||
print('{:d}ms\n\n'.format(round((time.time()-start_time)*1000))) | |||
model = CNNText((len(vocab),50), num_classes=5, padding=2, dropout=0.1) | |||
trainer = Trainer(model=model, train_data=train_data, dev_data=dev_data, loss=CrossEntropyLoss(), | |||
metrics=AccuracyMetric(), callbacks=[MyCallback(),EarlyStopCallback(10)]) | |||
trainer.train() | |||
""" | |||
__all__ = [ | |||
"Callback", | |||
"GradientClipCallback", | |||
"EarlyStopCallback", | |||
"TensorboardCallback", | |||
"LRScheduler", | |||
"ControlC", | |||
"CallbackException", | |||
"EarlyStopError" | |||
] | |||
import os | |||
import torch | |||
from ..io.model_io import ModelSaver, ModelLoader | |||
@@ -19,7 +74,7 @@ class Callback(object): | |||
Callback是fastNLP中被设计用于增强 :class:`~fastNLP.Trainer` 的类。 | |||
如果Callback被传递给了 Trainer , 则 Trainer 会在对应的阶段调用Callback的函数, | |||
具体调用时机可以通过 :doc:`trainer 模块<fastNLP.core.trainer>` 查看。 | |||
这是Callback的基类,所有的callback必须继承自这个类(参见 :doc:`callback 模块 <fastNLP.core.callback>` ) | |||
这是Callback的基类,所有的callback必须继承自这个类 | |||
""" | |||
@@ -236,7 +291,7 @@ class CallbackManager(Callback): | |||
for env_name, env_val in env.items(): | |||
for callback in self.callbacks: | |||
print(callback, env_name, env_val ) | |||
print(callback, env_name, env_val) | |||
setattr(callback, '_' + env_name, env_val) # Callback.trainer | |||
@_transfer | |||
@@ -294,12 +349,15 @@ class CallbackManager(Callback): | |||
class GradientClipCallback(Callback): | |||
""" | |||
别名::class:`fastNLP.GradientClipCallback` :class:`fastNLP.core.callback.GradientClipCallback` | |||
每次backward前,将parameter的gradient clip到某个范围。 | |||
:param None,torch.Tensor,List[torch.Tensor] parameters: 一般通过model.parameters()获得。如果为None则默认对Trainer | |||
的model中所有参数进行clip | |||
:param float clip_value: 将gradient 限制到[-clip_value, clip_value]。clip_value应该为正数 | |||
:param str clip_type: 支持'norm', 'value'两种:: | |||
:param str clip_type: 支持'norm', 'value' | |||
两种:: | |||
1 'norm', 将gradient的norm rescale到[-clip_value, clip_value] | |||
@@ -331,8 +389,11 @@ class GradientClipCallback(Callback): | |||
class EarlyStopCallback(Callback): | |||
""" | |||
别名::class:`fastNLP.EarlyStopCallback` :class:`fastNLP.core.callback.EarlyStopCallback` | |||
多少个epoch没有变好就停止训练,相关类 :class:`EarlyStopError` | |||
:param int patience: 多少个epoch没有变好就停止训练 | |||
:param int patience: epoch的数量 | |||
""" | |||
def __init__(self, patience): | |||
@@ -358,11 +419,10 @@ class EarlyStopCallback(Callback): | |||
class LRScheduler(Callback): | |||
"""对PyTorch LR Scheduler的包装以使得其可以被Trainer所使用 | |||
Example:: | |||
""" | |||
别名::class:`fastNLP.LRScheduler` :class:`fastNLP.core.callback.LRScheduler` | |||
from fastNLP import LRScheduler | |||
对PyTorch LR Scheduler的包装以使得其可以被Trainer所使用 | |||
:param torch.optim.lr_scheduler._LRScheduler lr_scheduler: PyTorch的lr_scheduler | |||
""" | |||
@@ -382,6 +442,7 @@ class LRScheduler(Callback): | |||
class ControlC(Callback): | |||
""" | |||
别名::class:`fastNLP.ControlC` :class:`fastNLP.core.callback.ControlC` | |||
:param bool quit_all: 若为True,则检测到control+C 直接退出程序;否则只退出Trainer | |||
""" | |||
@@ -418,6 +479,8 @@ class SmoothValue(object): | |||
class LRFinder(Callback): | |||
""" | |||
别名::class:`fastNLP.LRFinder` :class:`fastNLP.core.callback.LRFinder` | |||
用第一个 epoch 找最佳的学习率,从第二个epoch开始应用它 | |||
:param float start_lr: 学习率下界 | |||
@@ -442,7 +505,7 @@ class LRFinder(Callback): | |||
def lr_gen(self): | |||
scale = (self.end_lr - self.start_lr) / self.batch_per_epoch | |||
return (self.start_lr + scale * (step + 1) for step in range(self.batch_per_epoch)) | |||
@property | |||
def num_it(self): | |||
return self.batch_per_epoch | |||
@@ -487,10 +550,17 @@ class LRFinder(Callback): | |||
class TensorboardCallback(Callback): | |||
""" | |||
别名::class:`fastNLP.TensorboardCallback` :class:`fastNLP.core.callback.TensorboardCallback` | |||
接受以下一个或多个字符串作为参数: | |||
- "model" | |||
- "loss" | |||
- "metric" | |||
.. warning:: | |||
fastNLP 已停止对此功能的维护,请等待 fastNLP 兼容 PyTorch1.1 的下一个版本。 | |||
或者使用和 fastNLP 高度配合的 fitlog(参见 :doc:`/user/with_fitlog` )。 | |||
""" | |||
def __init__(self, *options): | |||
@@ -1,4 +1,4 @@ | |||
""" | |||
r""" | |||
Trainer在fastNLP中用于组织单任务的训练过程,可以避免用户在不同训练任务中重复撰以下步骤的代码 | |||
(1) epoch循环; | |||
@@ -93,7 +93,10 @@ Trainer在fastNLP中用于组织单任务的训练过程,可以避免用户在 | |||
尽管fastNLP使用了映射机制来使得loss的计算变得比较灵活,但有些情况下loss必须在模型中进行计算,比如使用了CRF的模型。 | |||
fastNLP中提供了 :class:`~fastNLP.LossInForward` 这个loss。 | |||
这个loss的原理是直接在forward()的返回结果中找到loss_key(默认寻找'loss')指定的那个tensor,并使用它作为loss。 | |||
如果Trainer初始化没有提供loss则默认使用 :class:`~fastNLP.LossInForward` 。TODO 补充一个例子 详细例子可以参照 | |||
如果Trainer初始化没有提供loss则默认使用 :class:`~fastNLP.LossInForward` 。 | |||
.. todo:: | |||
补充一个例子 详细例子可以参照 | |||
1.3 Metric | |||
:mod:`Metric<fastNLP.core.metrics>` 使用了与上述Loss一样的策略,即使用名称进行匹配。 | |||
@@ -102,7 +105,10 @@ Trainer在fastNLP中用于组织单任务的训练过程,可以避免用户在 | |||
在进行验证时,可能用到的计算与forward()中不太一致,没有办法直接从forward()的结果中得到预测值,这时模型可以提供一个predict()方法, | |||
如果提供的模型具有predict方法,则在模型验证时将调用predict()方法获取预测结果, | |||
传入到predict()的参数也是从DataSet中被设置为input的field中选择出来的; | |||
与forward()一样,返回值需要为一个dict。 TODO 补充一个例子 具体例子可以参考 | |||
与forward()一样,返回值需要为一个dict。 | |||
.. todo:: | |||
补充一个例子 具体例子可以参考 | |||
2 Trainer的代码检查 | |||
由于在fastNLP中采取了映射的机制,所以难免可能存在对应出错的情况。Trainer提供一种映射检查机制,可以通过check_code_level来进行控制 | |||
@@ -267,37 +273,26 @@ Example2.3 | |||
虽然Trainer本身已经集成了一些功能,但仍然不足以囊括训练过程中可能需要到的功能,比如负采样,learning rate decay, Early Stop等。 | |||
为了解决这个问题fastNLP引入了callback的机制,:class:`~fastNLP.Callback` 是一种在Trainer训练过程中特定阶段会运行的函数集合, | |||
所有的 :class:`~fastNLP.Callback` 都具有on_*(比如on_train_start, on_backward_begin)等函数。 | |||
如果 Callback 实现了该函数,则Trainer运行至对应阶段,会进行调用。 | |||
我们将Train.train()这个函数内部分为以下的阶段,在对应阶段会触发相应的调用。 | |||
Example:: | |||
如果 Callback 实现了该函数,则Trainer运行至对应阶段,会进行调用,例如:: | |||
from fastNLP import Callback, EarlyStopCallback, Trainer, CrossEntropyLoss, AccuracyMetric | |||
from fastNLP.models import CNNText | |||
callback.on_train_begin() # 开始进行训练 | |||
for i in range(1, n_epochs+1): | |||
callback.on_epoch_begin() # 开始新的epoch | |||
for batch_x, batch_y in Batch: | |||
callback.on_batch_begin(batch_x, batch_y, indices) # batch_x是设置为input的field,batch_y是设置为target的field | |||
获取模型输出 | |||
callback.on_loss_begin() | |||
计算loss | |||
callback.on_backward_begin() # 可以进行一些检查,比如loss是否为None | |||
反向梯度回传 | |||
callback.on_backward_end() # 进行梯度截断等 | |||
进行参数更新 | |||
callback.on_step_end() | |||
callback.on_batch_end() | |||
# 根据设置进行evaluation,比如这是本epoch最后一个batch或者达到一定step | |||
if do evaluation: | |||
callback.on_valid_begin() | |||
进行dev data上的验证 | |||
callback.on_valid_end() # 可以进行在其它数据集上进行验证 | |||
callback.on_epoch_end() # epoch结束调用 | |||
callback.on_train_end() # 训练结束 | |||
callback.on_exception() # 这是一个特殊的步骤,在训练过程中遭遇exception会跳转到这里 | |||
fastNLP已经自带了很多callback函数供使用,可以参考 :class:`~fastNLP.Callback` 。 | |||
TODO callback的例子 一些关于callback的例子,请参考 | |||
start_time = time.time() | |||
class MyCallback(Callback): | |||
def on_epoch_end(self): | |||
print('{:d}ms\n\n'.format(round((time.time()-start_time)*1000))) | |||
model = CNNText((len(vocab),50), num_classes=5, padding=2, dropout=0.1) | |||
trainer = Trainer(model=model, train_data=train_data, dev_data=dev_data, loss=CrossEntropyLoss(), | |||
metrics=AccuracyMetric(), callbacks=[MyCallback(),EarlyStopCallback(10)]) | |||
trainer.train() | |||
这里,我们通过继承 :class:`~fastNLP.Callback` 类定义了自己的 callback 的,并和内置的 :class:`~fastNLP.EarlyStopCallback` | |||
一起传给了 :class:`~fastNLP.Trainer` ,增强了 :class:`~fastNLP.Trainer` 的功能 | |||
fastNLP已经自带了很多callback函数供使用,可以参考 :doc:`fastNLP.core.callback` 。 | |||
""" | |||