diff --git a/fastNLP/__init__.py b/fastNLP/__init__.py index 54d96959..9873be72 100644 --- a/fastNLP/__init__.py +++ b/fastNLP/__init__.py @@ -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 diff --git a/fastNLP/core/__init__.py b/fastNLP/core/__init__.py index ed1bd0c9..52e716f6 100644 --- a/fastNLP/core/__init__.py +++ b/fastNLP/core/__init__.py @@ -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 diff --git a/fastNLP/core/callback.py b/fastNLP/core/callback.py index 0a2d052f..abba2790 100644 --- a/fastNLP/core/callback.py +++ b/fastNLP/core/callback.py @@ -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 模块` + +如下面的例子所示,我们可以使用内置的 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 模块` 查看。 - 这是Callback的基类,所有的callback必须继承自这个类(参见 :doc:`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): diff --git a/fastNLP/core/dataset.py b/fastNLP/core/dataset.py index aa3d2d82..d527bf76 100644 --- a/fastNLP/core/dataset.py +++ b/fastNLP/core/dataset.py @@ -798,7 +798,10 @@ class DataSet(object): @classmethod def read_csv(cls, csv_path, headers=None, sep=",", dropna=True): """ - 从csv_path路径下以csv的格式读取数据. + .. warning:: + 此方法会在下个版本移除,请使用 :class:`fastNLP.io.CSVLoader` + + 从csv_path路径下以csv的格式读取数据。 :param str csv_path: 从哪里读取csv文件 :param list[str] headers: 如果为None,则使用csv文件的第一行作为header; 如果传入list(str), 则元素的个数必须 diff --git a/fastNLP/core/trainer.py b/fastNLP/core/trainer.py index ed76ee8e..2ad92f6b 100644 --- a/fastNLP/core/trainer.py +++ b/fastNLP/core/trainer.py @@ -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` 使用了与上述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` 。 """ @@ -445,6 +440,7 @@ class Trainer(object): _check_code(dataset=train_data, model=model, losser=losser, metrics=metrics, dev_data=dev_data, metric_key=metric_key, check_level=check_code_level, batch_size=min(batch_size, DEFAULT_CHECK_BATCH_SIZE)) + # _check_code 是 fastNLP 帮助你检查代码是否正确的方法 。如果你在错误栈中看到这行注释,请认真检查你的代码 self.train_data = train_data self.dev_data = dev_data # If None, No validation. diff --git a/fastNLP/io/dataset_loader.py b/fastNLP/io/dataset_loader.py index 1fe92e23..5df48d71 100644 --- a/fastNLP/io/dataset_loader.py +++ b/fastNLP/io/dataset_loader.py @@ -11,7 +11,16 @@ Example:: # ... do stuff """ - +__all__ = [ + 'DataSetLoader', + 'CSVLoader', + 'JsonLoader', + 'ConllLoader', + 'SNLILoader', + 'SSTLoader', + 'PeopleDailyCorpusLoader', + 'Conll2003Loader', +] from nltk.tree import Tree from ..core.dataset import DataSet