README.md 12.4 KB
Newer Older
Z
Zeyu Chen 已提交
1 2 3 4
# 使用传统Recurrent Neural Networks完成中文文本分类任务

文本分类是NLP应用最广的任务之一,可以被应用到多个领域中,包括但不仅限于:情感分析、垃圾邮件识别、商品评价分类...

S
Steffy-zxf 已提交
5
情感分析是一个自然语言处理中老生常谈的任务。情感分析的目的是为了找出说话者/作者在某些话题上,或者针对一个文本两极的观点的态度。这个态度或许是他或她的个人判断或是评估,也许是他当时的情感状态(就是说,作者在做出这个言论时的情绪状态),或是作者有意向的情感交流(就是作者想要读者所体验的情绪)。其可以用于数据挖掘、Web 挖掘、文本挖掘和信息检索方面得到了广泛的研究。可通过 [AI开放平台-情感倾向分析](http://ai.baidu.com/tech/nlp_apply/sentiment_classify) 线上体验。
Z
Zeyu Chen 已提交
6

S
Steffy-zxf 已提交
7 8 9
<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/febb8a1478e34258953e56611ddc76cd20b412fec89845b0a4a2e6b9f8aae774" hspace='10'/> <br />
</p>
Z
Zeyu Chen 已提交
10 11 12

本项目开源了一系列模型用于进行文本建模,用户可通过参数配置灵活使用。效果上,我们基于开源情感倾向分类数据集ChnSentiCorp对多个模型进行评测。

S
Steffy-zxf 已提交
13 14 15 16 17 18 19 20 21 22 23
## paddlenlp.seq2vec

情感分析任务中关键技术是如何将文本表示成一个**携带语义的文本向量**。随着深度学习技术的快速发展,目前常用的文本表示技术有LSTM,GRU,RNN等方法。
PaddleNLP提供了一系列的文本表示技术,如`seq2vec`模块。

[`paddlenlp.seq2vec`](../../../paddlenlp/seq2vec) 模块作用为将输入的序列文本表征成一个语义向量。

<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/bbf00931c7534ab48a5e7dff5fbc2ba3ff8d459940434628ad21e9195da5d4c6" width = "500" height = "200"  hspace='10'/> <br />
</p>

Z
Zeyu Chen 已提交
24 25 26 27 28

## 模型简介



S
Steffy-zxf 已提交
29 30 31 32 33 34 35 36 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 64 65 66 67 68 69 70 71
本项目通过调用[seq2vec](../../../paddlenlp/seq2vec/)中内置的模型进行序列建模,完成句子的向量表示。包含最简单的词袋模型和一系列经典的RNN类模型。

`seq2vec`模块

* 功能是将序列Embedding Tensor(shape是(batch_size, num_token, emb_dim) )转化成文本语义表征Enocded Texts Tensor(shape 是(batch_sie,encoding_size))
* 提供了`BoWEncoder``CNNEncoder``GRUEncoder``LSTMEncoder``RNNEncoder`等模型
    - `BoWEncoder` 是将输入序列Embedding Tensor在num_token维度上叠加,得到文本语义表征Enocded Texts Tensor。
    - `CNNEncoder` 是将输入序列Embedding Tensor进行卷积操作,在对卷积结果进行max_pooling,得到文本语义表征Enocded Texts Tensor。
    - `GRUEncoder` 是对输入序列Embedding Tensor进行GRU运算,在运算结果上进行pooling或者取最后一个step的隐表示,得到文本语义表征Enocded Texts Tensor。
    - `LSTMEncoder` 是对输入序列Embedding Tensor进行LSTM运算,在运算结果上进行pooling或者取最后一个step的隐表示,得到文本语义表征Enocded Texts Tensor。
    - `RNNEncoder` 是对输入序列Embedding Tensor进行RNN运算,在运算结果上进行pooling或者取最后一个step的隐表示,得到文本语义表征Enocded Texts Tensor。


`seq2vec`提供了许多语义表征方法,那么这些方法在什么时候更加适合呢?

* `BoWEncoder`采用Bag of Word Embedding方法,其特点是简单。但其缺点是没有考虑文本的语境,所以对文本语义的表征不足以表意。

* `CNNEncoder`采用卷积操作,提取局部特征,其特点是可以共享权重。但其缺点同样只考虑了局部语义,上下文信息没有充分利用。

<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/2b2498edd83e49d3b017c4a14e1be68506349249b8a24cdaa214755fb51eadcd" width = "300" height = "150"  hspace='10'/> <br />
</p>

* `RNNEnocder`采用RNN方法,在计算下一个token语义信息时,利用上一个token语义信息作为其输入。但其缺点容易产生梯度消失和梯度爆炸。

<p align="center">
<img src="http://colah.github.io/posts/2015-09-NN-Types-FP/img/RNN-general.png" width = "50%" height = "30%"  hspace='10'/> <br />
</p>

* `LSTMEnocder`采用LSTM方法,LSTM是RNN的一种变种。为了学到长期依赖关系,LSTM 中引入了门控机制来控制信息的累计速度,
    包括有选择地加入新的信息,并有选择地遗忘之前累计的信息。

<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/a5af1d93c69f422d963e094397a2f6ce978c30a26ab6480ab70d688dd1929de0" width = "50%" height = "30%"  hspace='10'/> <br />
</p>

* `GRUEncoder`采用GRU方法,GRU也是RNN的一种变种。一个LSTM单元有四个输入 ,因而参数是RNN的四倍,带来的结果是训练速度慢。
    GRU对LSTM进行了简化,在不影响效果的前提下加快了训练速度。

<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/fc848bc2cb494b40ae42af892b756f5888770320a1fa42348cec10d3df64ee2f" width = "40%" height = "25%"  hspace='10'/> <br />
</p>

Z
Zeyu Chen 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

| 模型                                             | 模型介绍                                                     |
| ------------------------------------------------ | ------------------------------------------------------------ |
| BOW(Bag Of Words)                              | 非序列模型,将句子表示为其所包含词的向量的加和               |
| RNN (Recurrent Neural Network)                   | 序列模型,能够有效地处理序列信息                             |
| GRU(Gated Recurrent Unit)                      | 序列模型,能够较好地解决序列文本中长距离依赖的问题           |
| LSTM(Long Short Term Memory)                   | 序列模型,能够较好地解决序列文本中长距离依赖的问题           |
| Bi-LSTM(Bidirectional Long Short Term Memory)  | 序列模型,采用双向LSTM结构,更好地捕获句子中的语义特征       |
| Bi-GRU(Bidirectional Gated Recurrent Unit)     | 序列模型,采用双向GRU结构,更好地捕获句子中的语义特征        |
| Bi-RNN(Bidirectional Recurrent Neural Network) | 序列模型,采用双向RNN结构,更好地捕获句子中的语义特征        |
| Bi-LSTM Attention                                | 序列模型,在双向LSTM结构之上加入Attention机制,结合上下文更好地表征句子语义特征 |
| TextCNN                                          | 序列模型,使用多种卷积核大小,提取局部区域地特征             |


| 模型  | dev acc | test acc |
| ---- | ------- | -------- |
| BoW  |  0.8970 | 0.8908   |
| Bi-LSTM  | 0.9098  | 0.8983  |
| Bi-GRU  | 0.9014  | 0.8785  |
| Bi-RNN  | 0.8649  |  0.8504 |
| Bi-LSTM Attention |  0.8992 |  0.8856 |
| TextCNN  | 0.9102  | 0.9107 |


S
Steffy-zxf 已提交
96 97 98
<p align="center">
<img src="https://ai-studio-static-online.cdn.bcebos.com/ecf309c20e5347399c55f1e067821daa088842fa46ad49be90de4933753cd3cf" width = "600" height = "200"  hspace='10'/> <br />
</p>
Z
Zeyu Chen 已提交
99 100


S
Steffy-zxf 已提交
101
关于CNN、LSTM、GRU、RNN等更多信息参考:
Z
Zeyu Chen 已提交
102

S
Steffy-zxf 已提交
103 104 105 106 107
* https://canvas.stanford.edu/files/1090785/download
* https://colah.github.io/posts/2015-08-Understanding-LSTMs/
* https://arxiv.org/abs/1412.3555
* https://arxiv.org/pdf/1506.00019
* https://arxiv.org/abs/1404.2188
Z
Zeyu Chen 已提交
108 109


S
Steffy-zxf 已提交
110
## 快速开始
Z
Zeyu Chen 已提交
111

S
Steffy-zxf 已提交
112
### 环境依赖
Z
Zeyu Chen 已提交
113

S
Steffy-zxf 已提交
114 115 116 117
- python >= 3.6
- paddlepaddle >= 2.0.0-rc1

```
118
pip install paddlenlp>=2.0.0rc
S
Steffy-zxf 已提交
119
```
Z
Zeyu Chen 已提交
120 121 122 123 124 125

### 代码结构说明

以下是本项目主要代码结构及说明:

```text
126
rnn/
127
├── export_model.py # 动态图参数导出静态图参数脚本
Z
Zeyu Chen 已提交
128
├── predict.py # 模型预测
129 130
├── utils.py # 数据处理工具
├── train.py # 训练模型主程序入口,包括训练、评估
Z
Zeyu Chen 已提交
131 132 133 134 135 136 137 138
└── README.md # 文档说明
```

### 数据准备

#### 使用PaddleNLP内置数据集

```python
139 140 141
from paddlenlp.datasets import ChnSentiCorp

train_ds, dev_ds, test_ds = ChnSentiCorp.get_datasets(['train', 'dev', 'test'])
Z
Zeyu Chen 已提交
142 143 144 145 146 147 148
```

### 模型训练

在模型训练之前,需要先下载词汇表文件word_dict.txt,用于构造词-id映射关系。

```shell
149
wget https://paddlenlp.bj.bcebos.com/data/senta_word_dict.txt
Z
Zeyu Chen 已提交
150 151 152
```

我们以中文情感分类公开数据集ChnSentiCorp为示例数据集,可以运行下面的命令,在训练集(train.tsv)上进行模型训练,并在开发集(dev.tsv)验证
153 154 155

CPU 启动:

Z
Zeyu Chen 已提交
156
```shell
S
Steffy-zxf 已提交
157
python train.py --vocab_path='./senta_word_dict.txt' --use_gpu=False --network=bilstm --lr=5e-4 --batch_size=64 --epochs=10 --save_dir='./checkpoints'
158
```
Z
Zeyu Chen 已提交
159

160 161 162
GPU 启动:

```shell
S
Steffy-zxf 已提交
163
CUDA_VISIBLE_DEVICES=0 python train.py --vocab_path='./senta_word_dict.txt' --use_gpu=True --network=bilstm --lr=5e-4 --batch_size=64 --epochs=10 --save_dir='./checkpoints'
Z
Zeyu Chen 已提交
164 165 166 167
```

以上参数表示:

168 169
* `vocab_path`: 词汇表文件路径。
* `use_gpu`: 是否使用GPU进行训练, 默认为`False`
S
Steffy-zxf 已提交
170
* `network`: 模型网络名称,默认为`bilstm_attn`, 可更换为bilstm, bigru, birnn,bow,lstm,rnn,gru,bilstm_attn,textcnn等。
171
* `lr`: 学习率, 默认为5e-5。
172
* `batch_size`: 运行一个batch大小,默认为64。
173
* `epochs`: 训练轮次,默认为10。
174 175
* `save_dir`: 训练保存模型的文件路径。
* `init_from_ckpt`: 恢复模型训练的断点路径。
Z
Zeyu Chen 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189


程序运行时将会自动进行训练,评估,测试。同时训练过程中会自动保存模型在指定的`save_dir`中。
如:
```text
checkpoints/
├── 0.pdopt
├── 0.pdparams
├── 1.pdopt
├── 1.pdparams
├── ...
└── final.pdparams
```

190 191 192 193 194 195 196 197 198 199 200
**NOTE:**

* 如需恢复模型训练,则init_from_ckpt只需指定到文件名即可,不需要添加文件尾缀。如`--init_from_ckpt=checkpoints/0`即可,程序会自动加载模型参数`checkpoints/0.pdparams`,也会自动加载优化器状态`checkpoints/0.pdopt`
* 使用动态图训练结束之后,还可以将动态图参数导出成静态图参数,具体代码见export_model.py。静态图参数保存在`output_path`指定路径中。
  运行方式:

```shell
python export_model.py --vocab_path=./senta_word_dict.txt --network=bilstm --params_path=./checkpoints/final.pdparam --output_path=./static_graph_params
```

其中`params_path`是指动态图训练保存的参数路径,`output_path`是指静态图参数导出路径。
Z
Zeyu Chen 已提交
201 202 203 204

### 模型预测

启动预测:
205 206 207

CPU启动:

Z
Zeyu Chen 已提交
208
```shell
S
Steffy-zxf 已提交
209
python predict.py --vocab_path='./senta_word_dict.txt' --use_gpu=False --network=bilstm --params_path=checkpoints/final.pdparams
210 211 212
```

GPU启动:
Z
Zeyu Chen 已提交
213

214
```shell
S
Steffy-zxf 已提交
215
CUDA_VISIBLE_DEVICES=0 python predict.py --vocab_path='./senta_word_dict.txt' --use_gpu=True --network=bilstm --params_path='./checkpoints/final.pdparams'
Z
Zeyu Chen 已提交
216 217 218 219 220
```

将待预测数据分词完毕后,如以下示例:

```text
221 222 223
这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般
怀着十分激动的心情放映,可是看着看着发现,在放映完毕后,出现一集米老鼠的动画片
作为老的四星酒店,房间依然很整洁,相当不错。机场接机服务很好,可以在车上办理入住手续,节省时间。
Z
Zeyu Chen 已提交
224 225 226 227 228 229 230
```

处理成模型所需的`Tensor`,如可以直接调用`preprocess_prediction_data`函数既可处理完毕。之后传入`predict`函数即可输出预测结果。



```text
231 232 233
Data: 这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般      Lable: negative
Data: 怀着十分激动的心情放映,可是看着看着发现,在放映完毕后,出现一集米老鼠的动画片      Lable: negative
Data: 作为老的四星酒店,房间依然很整洁,相当不错。机场接机服务很好,可以在车上办理入住手续,节省时间。      Lable: positive
Z
Zeyu Chen 已提交
234
```
S
Steffy-zxf 已提交
235 236 237

## 线上体验教程

S
Steffy-zxf 已提交
238 239 240 241 242 243 244 245 246
- [使用seq2vec模块进行句子情感分类](https://aistudio.baidu.com/aistudio/projectdetail/1283423)

- [如何将预训练模型Fine-tune下游任务](https://aistudio.baidu.com/aistudio/projectdetail/1294333)

- [使用Bi-GRU+CRF完成快递单信息抽取](https://aistudio.baidu.com/aistudio/projectdetail/1317771)

- [使用预训练模型ERNIE优化快递单信息抽取](https://aistudio.baidu.com/aistudio/projectdetail/1329361)

- [使用Seq2Seq模型完成自动对联模型](https://aistudio.baidu.com/aistudio/projectdetail/1321118)
S
Steffy-zxf 已提交
247

S
Steffy-zxf 已提交
248
- [使用预训练模型ERNIE-GEN实现智能写诗](https://aistudio.baidu.com/aistudio/projectdetail/1339888)
S
Steffy-zxf 已提交
249

S
Steffy-zxf 已提交
250
- [使用TCN网络完成新冠疫情病例数预测](https://aistudio.baidu.com/aistudio/projectdetail/1290873)
S
Steffy-zxf 已提交
251

S
Steffy-zxf 已提交
252
更多教程参见[PaddleNLP on AI Studio](https://aistudio.baidu.com/aistudio/personalcenter/thirdview/574995)