README.md 11.8 KB
Newer Older
1 2
# PaddleHub 阅读理解

S
Steffy-zxf 已提交
3
本示例将展示如何使用PaddleHub Fine-tune API以及BERT预训练模型完成阅读理解任务。
4

S
Steffy-zxf 已提交
5
## 如何开始Fine-tune
6

S
Steffy-zxf 已提交
7
在完成安装PaddlePaddle与PaddleHub后,通过执行脚本`sh run_finetune.sh`即可开始使用BERT对SQuAD数据集进行Fine-tune。
8 9 10 11 12 13

其中脚本参数说明如下:

```bash
# 模型相关
--batch_size: 批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数
S
Steffy-zxf 已提交
14
--learning_rate: Fine-tune的最大学习率
15 16
--weight_decay: 控制正则项力度的参数,用于防止过拟合,默认为0.01
--warmup_proportion: 学习率warmup策略的比例,如果0.1,则学习率会在前10%训练step的过程中从0慢慢增长到learning_rate, 而后再缓慢衰减,默认为0
S
Steffy-zxf 已提交
17
--num_epoch: Fine-tune迭代的轮数
18 19 20 21 22 23 24 25 26
--max_seq_len: BERT模型使用的最大序列长度,最大不能超过512, 若出现显存不足,请适当调低这一参数
--use_data_parallel: 是否使用并行计算,默认False。打开该功能依赖nccl库。

# 任务相关
--checkpoint_dir: 模型保存路径,PaddleHub会自动保存验证集上表现最好的模型
```

## 代码步骤

S
Steffy-zxf 已提交
27
使用PaddleHub Fine-tune API进行Fine-tune可以分为4个步骤
28 29 30 31 32 33 34 35 36

### Step1: 加载预训练模型

```python
module = hub.Module(name="bert_uncased_L-12_H-768_A-12")
inputs, outputs, program = module.context(trainable=True, max_seq_len=384)
```
其中最大序列长度`max_seq_len`是可以调整的参数,建议值384,根据任务文本长度不同可以调整该值,但最大不超过512。

S
Steffy-zxf 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
PaddleHub还提供BERT等模型可供选择, 模型对应的加载示例如下:

   模型名                           | PaddleHub Module
---------------------------------- | :------:
ERNIE, Chinese                     | `hub.Module(name='ernie')`
ERNIE tiny, Chinese                | `hub.Module(name='ernie_tiny')`
ERNIE 2.0 Base, English            | `hub.Module(name='ernie_v2_eng_base')`
ERNIE 2.0 Large, English           | `hub.Module(name='ernie_v2_eng_large')`
BERT-Base, Uncased                 | `hub.Module(name='bert_uncased_L-12_H-768_A-12')`
BERT-Large, Uncased                | `hub.Module(name='bert_uncased_L-24_H-1024_A-16')`
BERT-Base, Cased                   | `hub.Module(name='bert_cased_L-12_H-768_A-12')`
BERT-Large, Cased                  | `hub.Module(name='bert_cased_L-24_H-1024_A-16')`
BERT-Base, Multilingual Cased      | `hub.Module(nane='bert_multi_cased_L-12_H-768_A-12')`
BERT-Base, Chinese                 | `hub.Module(name='bert_chinese_L-12_H-768_A-12')`
BERT-wwm, Chinese                  | `hub.Module(name='bert_wwm_chinese_L-12_H-768_A-12')`
BERT-wwm-ext, Chinese              | `hub.Module(name='bert_wwm_ext_chinese_L-12_H-768_A-12')`
RoBERTa-wwm-ext, Chinese           | `hub.Module(name='roberta_wwm_ext_chinese_L-12_H-768_A-12')`
RoBERTa-wwm-ext-large, Chinese     | `hub.Module(name='roberta_wwm_ext_chinese_L-24_H-1024_A-16')`

更多模型请参考[PaddleHub官网](https://www.paddlepaddle.org.cn/hub?filter=hot&value=1)

如果想尝试BERT模型,只需要更换Module中的`name`参数即可.
```python
# 更换name参数即可无缝切换BERT中文模型, 代码示例如下
module = hub.Module(name="bert_chinese_L-12_H-768_A-12")
```

S
Steffy-zxf 已提交
64
### Step2: 准备数据集并使用ReadingComprehensionReader读取数据
65 66 67 68 69 70
```python
dataset = hub.dataset.SQUAD(
    version_2_with_negative=False)
reader = hub.reader.ReadingComprehensionReader(
    dataset=dataset,
    vocab_path=module.get_vocab_path(),
S
Steffy-zxf 已提交
71
    max_seq_length=384)
72 73
```

K
kinghuin 已提交
74
其中数据集的准备代码可以参考 [squad.py](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.2/paddlehub/dataset/squad.py)
75

S
Steffy-zxf 已提交
76
`hub.dataset.SQUAD(version_2_with_negative=False)` 会自动从网络下载数据集SQuAD v1.1并解压到用户目录下`$HOME/.paddlehub/dataset`目录;如果想选择数据集SQuAD v2.0,则只需version_2_with_negative=True
77 78 79 80 81 82 83 84 85

`module.get_vocab_path()` 会返回预训练模型对应的词表

`max_seq_len` 需要与Step1中context接口传入的序列长度保持一致

ReadingComprehensionReader中的`data_generator`会自动按照模型对应词表对数据进行切词,以迭代器的方式返回BERT所需要的Tensor格式,包括`input_ids``position_ids``segment_id`与序列对应的mask `input_mask`.

**NOTE**: Reader返回tensor的顺序是固定的,默认按照input_ids, position_ids, segment_id, input_mask这一顺序返回。

S
Steffy-zxf 已提交
86 87 88 89 90 91 92 93 94 95 96
PaddleHub还提供了其他的阅读理解数据集,具体信息如下表:

数据集         |  API                                                                | 推荐预训练模型                           |
------------- | ------------------------------------------------------------------- |--------------------------------------- |
SQuAD v1.1    |  hub.dataset.SQUAD(version_2_with_negative=False)                   | bert_uncased_L-12_H-768_A-12           |
SQuAD v2.0    |  hub.dataset.SQUAD(version_2_with_negative=True)                    | bert_uncased_L-12_H-768_A-12           |
DRCD          |  hub.dataset.DRCD()                                                 |roberta_wwm_ext_chinese_L-24_H-1024_A-16|
CMRC 2018     |  hub.dataset.CMRC2018()                                             |roberta_wwm_ext_chinese_L-24_H-1024_A-16|

更多数据集信息参考[Dataset](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-API:-Dataset)

S
Steffy-zxf 已提交
97 98 99
#### 自定义数据集

如果想加载自定义数据集完成迁移学习,详细参见[自定义数据集](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E9%80%82%E9%85%8D%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E5%AE%8C%E6%88%90FineTune)
S
Steffy-zxf 已提交
100

101 102 103 104 105 106
### Step3:选择优化策略和运行配置

```python
strategy = hub.AdamWeightDecayStrategy(
    learning_rate=5e-5,
    weight_decay=0.01,
S
Steffy-zxf 已提交
107
    warmup_proportion=0.1
108 109 110 111 112 113
)

config = hub.RunConfig(use_cuda=True, num_epoch=2, batch_size=12, strategy=strategy)
```

#### 优化策略
S
Steffy-zxf 已提交
114
针对ERNIE/BERT类Transformer模型,PaddleHub封装了适合这一任务的迁移学习优化策略`AdamWeightDecayStrategy`
115

S
Steffy-zxf 已提交
116
`learning_rate`: Fine-tune过程中的最大学习率;
S
Steffy-zxf 已提交
117

118
`weight_decay`: 模型的正则项参数,默认0.01,如果模型有过拟合倾向,可适当调高这一参数;
S
Steffy-zxf 已提交
119

120
`warmup_proportion`: 如果warmup_proportion>0, 例如0.1, 则学习率会在前10%的steps中线性增长至最高值learning_rate;
S
Steffy-zxf 已提交
121

S
Steffy-zxf 已提交
122 123 124
`lr_scheduler`: 有两种策略可选(1)`linear_decay`策略学习率会在最高点后以线性方式衰减; (2)`noam_decay`策略学习率会在最高点以多项式形式衰减;

PaddleHub提供了许多优化策略,如`AdamWeightDecayStrategy``ULMFiTStrategy``DefaultFinetuneStrategy`等,详细信息参见[策略](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-API:-Strategy)
125 126

#### 运行配置
S
Steffy-zxf 已提交
127
`RunConfig` 主要控制Fine-tune的训练,包含以下可控制的参数:
128 129 130 131 132 133

* `log_interval`: 进度日志打印间隔,默认每10个step打印一次
* `eval_interval`: 模型评估的间隔,默认每100个step评估一次验证集
* `save_ckpt_interval`: 模型保存间隔,请根据任务大小配置,默认只保存验证集效果最好的模型和训练结束的模型
* `use_cuda`: 是否使用GPU训练,默认为False
* `checkpoint_dir`: 模型checkpoint保存路径, 若用户没有指定,程序会自动生成
S
Steffy-zxf 已提交
134
* `num_epoch`: Fine-tune的轮数
135 136
* `batch_size`: 训练的批大小,如果使用GPU,请根据实际情况调整batch_size
* `enable_memory_optim`: 是否使用内存优化, 默认为True
S
Steffy-zxf 已提交
137
* `strategy`: Fine-tune优化策略
138

S
Steffy-zxf 已提交
139
### Step4: 构建网络并创建阅读理解迁移任务进行Fine-tune
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
```python
seq_output = outputs["sequence_output"]

# feed_list的Tensor顺序不可以调整
feed_list = [
    inputs["input_ids"].name,
    inputs["position_ids"].name,
    inputs["segment_ids"].name,
    inputs["input_mask"].name,
]

reading_comprehension_task = hub.ReadingComprehensionTask(
    data_reader=reader,
    feature=seq_output,
    feed_list=feed_list,
S
Steffy-zxf 已提交
155 156
    config=config,
    sub_task="squad")
157 158 159 160

reading_comprehension_task.finetune_and_eval()
```
**NOTE:**
S
Steffy-zxf 已提交
161 162 163 164
1. `outputs["sequence_output"]`返回了ERNIE/BERT模型输入单词的对应输出,可以用于单词的特征表达。
2. `feed_list`中的inputs参数指名了BERT中的输入tensor的顺序,与ReadingComprehensionReader返回的结果一致。
3. `sub_task`指明阅读理解数据集名称,可选{squad, squad2.0, cmrc2018, drcd}, 用于适配各个数据集的模型训练过程中的评估方法
4.  `hub.ReadingComprehensionTask`通过输入特征、段落背景、问题和答案,可以生成适用于阅读理解迁移任务ReadingComprehensionTask
165

S
Steffy-zxf 已提交
166 167 168 169 170

#### 自定义迁移任务

如果想改变迁移任务组网,详细参见[自定义迁移任务](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub:-%E8%87%AA%E5%AE%9A%E4%B9%89Task)

171 172
## 可视化

S
Steffy-zxf 已提交
173
Fine-tune API训练过程中会自动对关键训练指标进行打点,启动程序后执行下面命令
174 175 176 177 178 179 180
```bash
$ tensorboard --logdir $CKPT_DIR/visualization --host ${HOST_IP} --port ${PORT_NUM}
```
其中${HOST_IP}为本机IP地址,${PORT_NUM}为可用端口号,如本机IP地址为192.168.0.1,端口号8040,用浏览器打开192.168.0.1:8040,即可看到训练过程中指标的变化情况

## 模型预测

S
Steffy-zxf 已提交
181
通过Fine-tune完成模型训练后,在对应的ckpt目录下,会自动保存验证集上效果最好的模型。
182 183 184 185
配置脚本参数

```bash
CKPT_DIR=".ckpt_rc/"
S
Steffy-zxf 已提交
186
python predict.py --checkpoint_dir $CKPT_DIR --max_seq_len 384 --batch_size=1
187
```
S
Steffy-zxf 已提交
188
其中CKPT_DIR为Fine-tune API保存最佳模型的路径, max_seq_len是ERNIE/BERT模型的最大序列长度,*请与训练时配置的参数保持一致*
189

S
Steffy-zxf 已提交
190
参数配置正确后,请执行脚本`sh run_predict.sh`,预测时程序会自动调用官方评价脚本即可看到SQuAD数据集的最终效果。
191 192 193 194
如需了解更多预测步骤,请参考`predict.py`

**NOTE:**
运行预测脚本时,建议用单卡预测。
S
Steffy-zxf 已提交
195

S
Steffy-zxf 已提交
196 197 198 199 200 201 202 203 204 205 206 207 208 209
我们在AI Studio上提供了IPython NoteBook形式的demo,您可以直接在平台上在线体验,链接如下:

|预训练模型|任务类型|数据集|AIStudio链接|备注|
|-|-|-|-|-|
|ResNet|图像分类|猫狗数据集DogCat|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216772)||
|ERNIE|文本分类|中文情感分类数据集ChnSentiCorp|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216764)||
|ERNIE|文本分类|中文新闻分类数据集THUNEWS|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216649)|本教程讲述了如何将自定义数据集加载,并利用Fine-tune API完成文本分类迁移学习。|
|ERNIE|序列标注|中文序列标注数据集MSRA_NER|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216787)||
|ERNIE|序列标注|中文快递单数据集Express|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216683)|本教程讲述了如何将自定义数据集加载,并利用Fine-tune API完成序列标注迁移学习。|
|ERNIE Tiny|文本分类|中文情感分类数据集ChnSentiCorp|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/215599)||
|Senta|文本分类|中文情感分类数据集ChnSentiCorp|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216851)|本教程讲述了任何利用Senta和Fine-tune API完成情感分类迁移学习。|
|Senta|情感分析预测|N/A|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216735)||
|LAC|词法分析|N/A|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/215641)||
|Ultra-Light-Fast-Generic-Face-Detector-1MB|人脸检测|N/A|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/216749)||
S
Steffy-zxf 已提交
210 211 212 213

## 超参优化AutoDL Finetuner

PaddleHub还提供了超参优化(Hyperparameter Tuning)功能, 自动搜索最优模型超参得到更好的模型效果。详细信息参见[AutoDL Finetuner超参优化功能教程](../../tutorial/autofinetune.md)[使用样例](../autofinetune)