Skip to content

Commit 8dec821

Browse files
committed
修改了最新的文档
1 parent 927d386 commit 8dec821

20 files changed

+195
-75
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Build Status](https://travis-ci.org/fastnlp/fastNLP.svg?branch=master)](https://travis-ci.org/fastnlp/fastNLP)
44
[![codecov](https://codecov.io/gh/fastnlp/fastNLP/branch/master/graph/badge.svg)](https://codecov.io/gh/fastnlp/fastNLP)
5-
[![PyPI version](https://badge.fury.io/py/fastNLP.svg)](https://badge.fury.io/py/fastNLP)
5+
[![Pypi](https://img.shields.io/pypi/v/fastNLP.svg)](https://pypi.org/project/fastNLP)
66
![Hex.pm](https://img.shields.io/hexpm/l/plug.svg)
77
[![Documentation Status](https://readthedocs.org/projects/fastnlp/badge/?version=latest)](http://fastnlp.readthedocs.io/?badge=latest)
88

@@ -32,12 +32,14 @@ fastNLP 依赖如下包:
3232
pip install fastNLP
3333
```
3434

35+
3536
## 参考资源
3637

3738
- [文档](https://fastnlp.readthedocs.io/zh/latest/)
3839
- [源码](https://github.com/fastnlp/fastNLP)
3940

4041

42+
4143
## 内置组件
4244

4345
大部分用于的 NLP 任务神经网络都可以看做由编码(encoder)、聚合(aggregator)、解码(decoder)三种模块组成。
@@ -108,5 +110,6 @@ fastNLP的大致工作流程如上图所示,而项目结构如下:
108110
</table>
109111

110112

113+
<hr>
111114

112115
*In memory of @FengZiYjun. May his soul rest in peace. We will miss you very very much!*

docs/source/figures/fitlogChart.png

265 KB
Loading

docs/source/figures/fitlogTable.png

165 KB
Loading

docs/source/figures/workflow.png

328 KB
Loading

docs/source/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fastNLP 在 :mod:`~fastNLP.models` 模块中内置了如 :class:`~fastNLP.models
5555
安装指南 <user/installation>
5656
快速入门 <user/quickstart>
5757
详细指南 <user/tutorial_one>
58+
科研指南 <user/with_fitlog>
5859

5960
API 文档
6061
-------------

docs/source/user/with_fitlog.rst

+118-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,121 @@
22
科研向导
33
=================
44

5-
本文介绍使用 fastNLP 和 fitlog 进行科学研究的方法
5+
本文介绍结合使用 fastNLP 和 fitlog 进行科研的方法。
6+
7+
首先,我们需要安装 `fitlog <https://fitlog.readthedocs.io/>`_ 。你需要确认你的电脑中没有其它名为 `fitlog` 的命令。
8+
9+
我们从命令行中进入到一个文件夹,现在我们要在文件夹中创建我们的 fastNLP 项目。你可以在命令行输入 `fitlog init test1` ,
10+
然后你会看到如下提示::
11+
12+
Initialized empty Git repository in /Users/fdujyn/workspaces/test1/.git/
13+
Auto commit by fitlog
14+
Initialized empty Git repository in /Users/fdujyn/workspaces/test1/.git/
15+
Fitlog project test1 is initialized.
16+
17+
这表明你已经创建成功了项目文件夹,并且在项目文件夹中已经初始化了 Git。如果你不想初始化 Git,
18+
可以参考文档 `命令行工具 <https://fitlog.readthedocs.io/zh/latest/user/command_line.html>`_
19+
20+
现在我们进入你创建的项目文件夹 test1 中,可以看到有一个名为 logs 的文件夹,后面我们将会在里面存放你的实验记录。
21+
同时也有一个名为 main.py 的文件,这是我们推荐你使用的训练入口文件。文件的内容如下::
22+
23+
import fitlog
24+
25+
fitlog.commit(__file__) # auto commit your codes
26+
fitlog.add_hyper_in_file (__file__) # record your hyperparameters
27+
28+
"""
29+
Your training code here, you may use these functions to log your result:
30+
fitlog.add_hyper()
31+
fitlog.add_loss()
32+
fitlog.add_metric()
33+
fitlog.add_best_metric()
34+
......
35+
"""
36+
37+
fitlog.finish() # finish the logging
38+
39+
我们推荐你保留除注释外的四行代码,它们有助于你的实验,
40+
他们的具体用处参见文档 `用户 API <https://fitlog.readthedocs.io/zh/latest/fitlog.html>`_
41+
42+
我们假定你要进行前两个教程中的实验,并已经把数据复制到了项目根目录下的 tutorial_sample_dataset.csv 文件中。
43+
现在我们编写如下的训练代码,使用 :class:`~fastNLP.core.callback.FitlogCallback` 进行实验记录保存::
44+
45+
import fitlog
46+
from fastNLP import Vocabulary, Trainer, CrossEntropyLoss, AccuracyMetric
47+
from fastNLP.io import CSVLoader
48+
from fastNLP.models import CNNText
49+
from fastNLP.core.callback import FitlogCallback
50+
51+
fitlog.commit(__file__) # auto commit your codes
52+
fitlog.add_hyper_in_file (__file__) # record your hyperparameters
53+
54+
############hyper
55+
word_embed = 50
56+
dropout = 0.1
57+
############hyper
58+
59+
loader = CSVLoader(headers=('raw_sentence', 'label'), sep='\t')
60+
dataset = loader.load("tutorial_sample_dataset.csv")
61+
62+
dataset.apply(lambda x: x['raw_sentence'].lower(), new_field_name='sentence')
63+
dataset.apply(lambda x: x['sentence'].split(), new_field_name='words', is_input=True)
64+
dataset.apply(lambda x: int(x['label']), new_field_name='target', is_target=True)
65+
vocab = Vocabulary(min_freq=2).from_dataset(dataset, field_name='words')
66+
vocab.index_dataset(dataset, field_name='words',new_field_name='words')
67+
68+
model = CNNText((len(vocab),word_embed), num_classes=5, padding=2, dropout=dropout)
69+
70+
train_dev_data, test_data = dataset.split(0.1)
71+
train_data, dev_data = train_dev_data.split(0.1)
72+
73+
trainer = Trainer(model=model, train_data=train_data, dev_data=dev_data,
74+
loss=CrossEntropyLoss(), metrics=AccuracyMetric(),
75+
callbacks=[FitlogCallback(test_data)])
76+
trainer.train()
77+
78+
fitlog.finish() # finish the logging
79+
80+
用命令行在项目目录下执行 `python main.py` 之后,输出结果如下::
81+
82+
Auto commit by fitlog
83+
input fields after batch(if batch size is 2):
84+
words: (1)type:torch.Tensor (2)dtype:torch.int64, (3)shape:torch.Size([2, 11])
85+
target fields after batch(if batch size is 2):
86+
target: (1)type:torch.Tensor (2)dtype:torch.int64, (3)shape:torch.Size([2])
87+
88+
training epochs started 2019-05-23-21-11-51
89+
Evaluation at Epoch 1/10. Step:2/20. AccuracyMetric: acc=0.285714
90+
91+
Evaluation at Epoch 2/10. Step:4/20. AccuracyMetric: acc=0.285714
92+
93+
Evaluation at Epoch 3/10. Step:6/20. AccuracyMetric: acc=0.285714
94+
95+
Evaluation at Epoch 4/10. Step:8/20. AccuracyMetric: acc=0.428571
96+
97+
Evaluation at Epoch 5/10. Step:10/20. AccuracyMetric: acc=0.571429
98+
99+
Evaluation at Epoch 6/10. Step:12/20. AccuracyMetric: acc=0.571429
100+
101+
Evaluation at Epoch 7/10. Step:14/20. AccuracyMetric: acc=0.285714
102+
103+
Evaluation at Epoch 8/10. Step:16/20. AccuracyMetric: acc=0.142857
104+
105+
Evaluation at Epoch 9/10. Step:18/20. AccuracyMetric: acc=0.285714
106+
107+
Evaluation at Epoch 10/10. Step:20/20. AccuracyMetric: acc=0.571429
108+
109+
110+
In Epoch:5/Step:10, got best dev performance:AccuracyMetric: acc=0.571429
111+
Reloaded the best model.
112+
113+
现在,我们在项目目录下输入 `fitlog log logs` ,命令行会启动一个网页,默认 url 为 ``0.0.0.0:5000`` 。
114+
我们在浏览器中打开网页,可以看到如下的统计表格:
115+
116+
.. image:: ../figures/fitlogTable.png
117+
118+
如果我们点击action中的最后一个键钮,可以看到详细的 loss 图:
119+
120+
.. image:: ../figures/fitlogChart.png
121+
122+
更多的教程还在编写中,敬请期待~

fastNLP/core/batch.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,8 @@ class Batch(object):
3030
"""
3131
别名::class:`fastNLP.Batch` :class:`fastNLP.core.batch.Batch`
3232
33-
Batch 用于从 `DataSet` 中按一定的顺序, 依次按 ``batch_size`` 的大小将数据取出.
34-
组成 `x` 和 `y`
35-
36-
37-
Example::
33+
Batch 用于从 `DataSet` 中按一定的顺序, 依次按 ``batch_size`` 的大小将数据取出,
34+
组成 `x` 和 `y`::
3835
3936
batch = Batch(data_set, batch_size=16, sampler=SequentialSampler())
4037
num_batch = len(batch)

fastNLP/core/callback.py

+27-22
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def on_epoch_end(self):
5454
"GradientClipCallback",
5555
"EarlyStopCallback",
5656
"TensorboardCallback",
57+
"FitlogCallback",
5758
"LRScheduler",
5859
"ControlC",
5960

@@ -65,6 +66,7 @@ def on_epoch_end(self):
6566

6667
import torch
6768
from copy import deepcopy
69+
6870
try:
6971
from tensorboardX import SummaryWriter
7072

@@ -81,6 +83,7 @@ def on_epoch_end(self):
8183
except:
8284
pass
8385

86+
8487
class Callback(object):
8588
"""
8689
别名::class:`fastNLP.Callback` :class:`fastNLP.core.callback.Callback`
@@ -367,16 +370,17 @@ class GradientClipCallback(Callback):
367370
368371
每次backward前,将parameter的gradient clip到某个范围。
369372
370-
:param None,torch.Tensor,List[torch.Tensor] parameters: 一般通过model.parameters()获得。如果为None则默认对Trainer
371-
的model中所有参数进行clip
373+
:param None,torch.Tensor,List[torch.Tensor] parameters: 一般通过model.parameters()获得。
374+
如果为None则默认对Trainer的model中所有参数进行clip
372375
:param float clip_value: 将gradient 限制到[-clip_value, clip_value]。clip_value应该为正数
373376
:param str clip_type: 支持'norm', 'value'
374377
两种::
375378
376379
1 'norm', 将gradient的norm rescale到[-clip_value, clip_value]
377380
378-
2 'value', 将gradient限制在[-clip_value, clip_value], 小于-clip_value的gradient被赋值为-clip_value;
379-
大于clip_value的gradient被赋值为clip_value.
381+
2 'value', 将gradient限制在[-clip_value, clip_value],
382+
小于-clip_value的gradient被赋值为-clip_value;
383+
大于clip_value的gradient被赋值为clip_value.
380384
381385
"""
382386

@@ -431,14 +435,13 @@ def on_exception(self, exception):
431435
else:
432436
raise exception # 抛出陌生Error
433437

438+
434439
class FitlogCallback(Callback):
435440
"""
436-
别名: :class:`fastNLP.FitlogCallback` :class:`fastNLP.core.callback.FitlogCallback`
437-
438441
该callback将loss和progress自动写入到fitlog中; 如果Trainer有dev的数据,将自动把dev的结果写入到log中; 同时还支持传入
439-
一个(或多个)test数据集进行测试(只有在trainer具有dev时才能使用),每次在dev上evaluate之后会在这些数据集上验证一下。
440-
并将验证结果写入到fitlog中。这些数据集的结果是根据dev上最好的结果报道的,即如果dev在第3个epoch取得了最佳,则
441-
fitlog中记录的关于这些数据集的结果就是来自第三个epoch的结果。
442+
一个(或多个)test数据集进行测试(只有在trainer具有dev时才能使用),每次在dev上evaluate之后会在这些数据集上验证一下。
443+
并将验证结果写入到fitlog中。这些数据集的结果是根据dev上最好的结果报道的,即如果dev在第3个epoch取得了最佳,则
444+
fitlog中记录的关于这些数据集的结果就是来自第三个epoch的结果。
442445
443446
:param DataSet,dict(DataSet) data: 传入DataSet对象,会使用多个Trainer中的metric对数据进行验证。如果需要传入多个
444447
DataSet请通过dict的方式传入,dict的key将作为对应dataset的name传递给fitlog。若tester不为None时,data需要通过
@@ -447,7 +450,9 @@ class FitlogCallback(Callback):
447450
:param int verbose: 是否在终端打印内容,0不打印
448451
:param bool log_exception: fitlog是否记录发生的exception信息
449452
"""
450-
453+
# 还没有被导出到 fastNLP 层
454+
# 别名: :class:`fastNLP.FitlogCallback` :class:`fastNLP.core.callback.FitlogCallback`
455+
451456
def __init__(self, data=None, tester=None, verbose=0, log_exception=False):
452457
super().__init__()
453458
self.datasets = {}
@@ -460,7 +465,7 @@ def __init__(self, data=None, tester=None, verbose=0, log_exception=False):
460465
assert 'test' not in data, "Cannot use `test` as DataSet key, when tester is passed."
461466
setattr(tester, 'verbose', 0)
462467
self.testers['test'] = tester
463-
468+
464469
if isinstance(data, dict):
465470
for key, value in data.items():
466471
assert isinstance(value, DataSet), f"Only DataSet object is allowed, not {type(value)}."
@@ -470,46 +475,46 @@ def __init__(self, data=None, tester=None, verbose=0, log_exception=False):
470475
self.datasets['test'] = data
471476
else:
472477
raise TypeError("data receives dict[DataSet] or DataSet object.")
473-
478+
474479
self.verbose = verbose
475-
480+
476481
def on_train_begin(self):
477-
if (len(self.datasets)>0 or len(self.testers)>0 ) and self.trainer.dev_data is None:
482+
if (len(self.datasets) > 0 or len(self.testers) > 0) and self.trainer.dev_data is None:
478483
raise RuntimeError("Trainer has no dev data, you cannot pass extra data to do evaluation.")
479-
480-
if len(self.datasets)>0:
484+
485+
if len(self.datasets) > 0:
481486
for key, data in self.datasets.items():
482487
tester = Tester(data=data, model=self.model, batch_size=self.batch_size, metrics=self.trainer.metrics,
483488
verbose=0)
484489
self.testers[key] = tester
485490
fitlog.add_progress(total_steps=self.n_steps)
486-
491+
487492
def on_backward_begin(self, loss):
488493
fitlog.add_loss(loss.item(), name='loss', step=self.step, epoch=self.epoch)
489-
494+
490495
def on_valid_end(self, eval_result, metric_key, optimizer, better_result):
491496
if better_result:
492497
eval_result = deepcopy(eval_result)
493498
eval_result['step'] = self.step
494499
eval_result['epoch'] = self.epoch
495500
fitlog.add_best_metric(eval_result)
496501
fitlog.add_metric(eval_result, step=self.step, epoch=self.epoch)
497-
if len(self.testers)>0:
502+
if len(self.testers) > 0:
498503
for key, tester in self.testers.items():
499504
try:
500505
eval_result = tester.test()
501-
if self.verbose!=0:
506+
if self.verbose != 0:
502507
self.pbar.write("Evaluation on DataSet {}:".format(key))
503508
self.pbar.write(tester._format_eval_results(eval_result))
504509
fitlog.add_metric(eval_result, name=key, step=self.step, epoch=self.epoch)
505510
if better_result:
506511
fitlog.add_best_metric(eval_result, name=key)
507512
except Exception:
508513
self.pbar.write("Exception happens when evaluate on DataSet named `{}`.".format(key))
509-
514+
510515
def on_train_end(self):
511516
fitlog.finish()
512-
517+
513518
def on_exception(self, exception):
514519
fitlog.finish(status=1)
515520
if self._log_exception:

fastNLP/core/dataset.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,7 @@ def set_target(self, *field_names, flag=True):
571571

572572
def set_input(self, *field_names, flag=True):
573573
"""
574-
将field_names的field设置为input
575-
576-
Example::
574+
将field_names的field设置为input::
577575
578576
dataset.set_input('words', 'seq_len') # 将words和seq_len这两个field的input属性设置为True
579577
dataset.set_input('words', flag=False) # 将words这个field的input属性设置为False
@@ -605,9 +603,7 @@ def set_ignore_type(self, *field_names, flag=True):
605603

606604
def set_padder(self, field_name, padder):
607605
"""
608-
为field_name设置padder
609-
610-
Example::
606+
为field_name设置padder::
611607
612608
from fastNLP import EngChar2DPadder
613609
padder = EngChar2DPadder()

fastNLP/core/field.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,7 @@ class EngChar2DPadder(Padder):
448448
但这个Padder只能处理index为int的情况。
449449
450450
padded过后的batch内容,形状为(batch_size, max_sentence_length, max_word_length). max_sentence_length为这个batch中最大句
451-
子长度;max_word_length为这个batch中最长的word的长度
452-
453-
Example::
451+
子长度;max_word_length为这个batch中最长的word的长度::
454452
455453
from fastNLP import DataSet
456454
from fastNLP import EngChar2DPadder

fastNLP/core/instance.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ class Instance(object):
1313
别名::class:`fastNLP.Instance` :class:`fastNLP.core.instance.Instance`
1414
1515
Instance是fastNLP中对应一个sample的类。每个sample在fastNLP中是一个Instance对象。
16-
Instance一般与 :class:`~fastNLP.DataSet` 一起使用, Instance的初始化如下面的Example所示
17-
18-
Example::
16+
Instance一般与 :class:`~fastNLP.DataSet` 一起使用, Instance的初始化如下面的Example所示::
1917
2018
>>>from fastNLP import Instance
2119
>>>ins = Instance(field_1=[1, 1, 1], field_2=[2, 2, 2])

fastNLP/core/losses.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,10 @@ class LossFunc(LossBase):
190190
找到相对应的参数名为value的参数,并传入func中作为参数名为key的参数
191191
:param kwargs: 除了参数映射表以外可以用key word args的方式设置参数映射关系
192192
193-
Example::
193+
使用方法::
194194
195-
>>> func = torch.nn.CrossEntropyLoss()
196-
>>> loss_func = LossFunc(func, input="pred", target="label")
195+
func = torch.nn.CrossEntropyLoss()
196+
loss_func = LossFunc(func, input="pred", target="label")
197197
# 这表示构建了一个损失函数类,由func计算损失函数,其中将从模型返回值或者DataSet的target=True的field
198198
# 当中找到一个参数名为`pred`的参数传入func一个参数名为`input`的参数;找到一个参数名为`label`的参数
199199
# 传入func作为一个名为`target`的参数
@@ -227,7 +227,7 @@ class CrossEntropyLoss(LossBase):
227227
228228
Example::
229229
230-
>>> loss = CrossEntropyLoss(pred='pred', target='label', padding_idx=0)
230+
loss = CrossEntropyLoss(pred='pred', target='label', padding_idx=0)
231231
232232
"""
233233

0 commit comments

Comments
 (0)