Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add text classification models #24

Merged
merged 33 commits into from
May 17, 2017
Merged

Conversation

JiayiFeng
Copy link
Collaborator

fix #14

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost finished, and you can begin to write the doc.

if isinstance(event, paddle.event.EndPass):
result = trainer.test(reader=test_reader, feeding=feeding)
print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)
with gzip.open("cnn_params.tar.gz", 'w') as f:
Copy link
Collaborator

@lcy-seso lcy-seso May 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better that models are saved according to the pass number, otherwise, new models will overwrite the old model, as a result, it is impossible to do the model selection.

infer_data_num = 100
for item in paddle.dataset.imdb.test(word_dict):
infer_data.append([item[0]])
infer_label_data.append(item[1])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning is more unambiguous if rename infer_label_data to infer_data_label.


infer_data = []
infer_label_data = []
infer_data_num = 100
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constraint on the number of test data can be removed.


emb = paddle.layer.embedding(input=data, size=emb_dim)
seq_pool = paddle.layer.pooling(
input=emb, pooling_type=paddle.pooling.Max())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is max pooling better than average pooling or sum?
p.s. the old configuration file may not always be a good network configuration.

input=hd1,
size=32,
act=paddle.activation.Tanh(),
param_attr=paddle.attr.Param(initial_std=0.01))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does initializing the parameter matrix according to layer size work better?

if isinstance(event, paddle.event.EndPass):
result = trainer.test(reader=test_reader, feeding=feeding)
print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)
with gzip.open("dnn_params.tar.gz", 'w') as f:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to save the model according to the pass number.


[_, output] = fc_net(dict_dim, class_dim=class_dim)
parameters = paddle.parameters.Parameters.from_tar(
gzip.open("dnn_params.tar.gz"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to save the model according to the pass number.

infer_data_num = 100
for item in paddle.dataset.imdb.test(word_dict):
infer_data.append([item[0]])
infer_label_data.append(item[1])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning is more unambiguous if rename infer_label_data to infer_data_label.

@lcy-seso
Copy link
Collaborator

lcy-seso commented May 4, 2017

The configuration is almost finished, and I think you can begin to working on the doc.

Besides, please also be careful to verify the learning performance. We should not provide an example that works poorly to the users.

Thanks for the work.

@lcy-seso lcy-seso self-requested a review May 4, 2017 08:33
@lcy-seso lcy-seso self-assigned this May 4, 2017
Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Help with testing a configuration with more than one evaluators.

output = paddle.layer.fc(
input=[conv_3, conv_4], size=class_dim, act=paddle.activation.Softmax())

cost = paddle.layer.classification_cost(input=output, label=lbl)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you help with adding more than one evaluators to this configuration, for example, besides an evaluator to calculate the error rate, if it possible to add a precision-recall evaluator? I hope to test a configuration with more than one evaluators. Thanks for your work.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, added auc evaluator

Copy link
Contributor

@luotao1 luotao1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

文档需要再优化下。对dnn模型和cnn模型的区别(包括实际应用中该如何选择,它们效果上有什么差别,模型物理意义上有什么差别等),在文章的开头简单的说几句,给小白用户一个直观的感受。

如果两个模型没什么本质区别和效果区别,也需要给用户一个说明。

@@ -0,0 +1,2 @@
*.pptx
*.pdf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么需要忽略掉pptx和pdf?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pptx和pdf是我自己目录下作图中产生的一些临时文件,所以忽略

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

准备将临时文件都放入专门的temp目录

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自己的临时文件请不要上传到版本库里。.gitignore可以删去。


## DNN模型

#### DNN的模型结构入下图所示:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第7行是##
第9行应该是###,下同。而且“DNN的模型结构如下图所示”也不适合作为标题,下同。


需要注意的是,该模型的输入数据为整数序列,而不是原始的英文单词序列。事实上,为了处理方便我们一般会事先将单词根据词频顺序进行id化,即将单词用整数替代。这一步一般在DNN模型之外完成。

##CNN模型
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

71行和73行##后面要加空格,不然标题无法渲染出来。


#### 可以看到,模型主要分为如下几个部分:

- **embedding层**:IMDB的样本由原始的英文单词组成,为了方便模型的训练,必须通过embedding将英文单词转化为固定维度的向量。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

术语要统一,后面两层用的是中文,前面的embedding和max pooling也用中文。分别是词向量层和最大池化层。全文同。

文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的IMDB语料库训练二分类DNN和CNN模型,完成对语料的简单文本分类。

## 实验数据
本例子的实验在IMDB数据集上进行。IMDB数据集包含了来自IMDb(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。数据集被划分为train和test两部分,各2.5万条数据,正负样本的比例基本为1:1。样本直接以英文原文的形式表示。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. IMDB数据集包含了来自IMDb(这个b是小写么?)
  2. 数据集可以放链接。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b是小写,全称Internet Movie Database


- **embedding层**:IMDB的样本由原始的英文单词组成,为了方便模型的训练,必须通过embedding将英文单词转化为固定维度的向量。

- **max pooling**:max pooling在时间序列上进行,pooling过程消除了不同语料样本在单词数量多少上的差异,并提炼出词向量中每一下标位置上的最大值。经过pooling后,样本被转化为一条固定维度的向量。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

并提炼出词向量中每一下标位置上的最大值。这句中,“每一个下标位置”得解释一下,小白用户会懵。


- **embedding层**:与DNN中embedding的作用一样,将英文单词转化为固定维度的向量。如图2中所示,将embedding得到的词向量定义为行向量,再将语料中所有的单词产生的行向量拼接在一起组成矩阵。假设embedding_size=5,语料“The cat sat on the read mat”包含7个单词,那么得到的矩阵维度为7*5。

- **卷积层**: 文本分类中的卷积在时间序列上进行,即卷积核的宽度和embedding得到的矩阵一致,卷积验证矩阵的高度方向进行。假设卷积核的高度为h,矩阵的高度为N,卷积的step_size为1,则卷积后得到的feature map为一个高度为N+1-h的向量。可以同时使用多个不同高度的卷积核,得到多个feature map。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feature map也可以用中文词汇表示。

return cost, output
```

该CNN网络的输入数据类型和前面介绍过的DNN一致。`paddle.networks.sequence_conv_pool`为Paddle中已经封装好的带有pooling的文本序列卷积模块,该模块的`context_len`参数用于指定卷积核在同一时间覆盖的文本长度,也即图2中的卷积核的高度;`hidden_size`用于指定该类型的卷积核的数量。可以看到,上述代码定义的结构中使用了128个大小为3的卷积核和128个大小为4的卷积核,这些卷积的结果经过max pooling和结果并置后产生一个256维的向量,向量经过一个全连接层输出最终预测结果。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paddle-》PaddlePaddle,全文文字中的Paddle均需改成PaddlePaddle


- **max pooling**:max pooling在时间序列上进行,pooling过程消除了不同语料样本在单词数量多少上的差异,并提炼出词向量中每一下标位置上的最大值。经过pooling后,样本被转化为一条固定维度的向量。

- **全连接隐层**:经过max pooling后的向量被送入一个具有两个隐层的DNN模型,隐层之间为全连接结构。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

22行送入“DNN模型”(可以去掉,或者换个别的词),因为整个是一个DNN模型,这里又写着送入DNN模型,会让小白用户觉得是递归了?

return cost, output

```
该DNN模型默认对输入的语料进行二分类(`class_dim=2`),embedding的词向量维度默认为256(`emd_dim=256`),两个隐层均使用Tanh激活函数(`act=paddle.activation.Tanh()`)。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

67行第二个括号是英文括号,全文都是中文括号,建议统一。

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a new section on how to feed user's data for training.

```

该CNN网络的输入数据类型和前面介绍过的DNN一致。`paddle.networks.sequence_conv_pool`为Paddle中已经封装好的带有池化的文本序列卷积模块,该模块的`context_len`参数用于指定卷积核在同一时间覆盖的文本长度,也即图2中的卷积核的高度;`hidden_size`用于指定该类型的卷积核的数量。可以看到,上述代码定义的结构中使用了128个大小为3的卷积核和128个大小为4的卷积核,这些卷积的结果经过最大池化和结果并置后产生一个256维的向量,向量经过一个全连接层输出最终预测结果。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我有一个建议,PaddleBook 是目前官方唯一可以找到正式托管 V2 API 用法的“教程”,但是PaddleBook读数据直接 import paddle.dataset.×,隐层了读数据的过程。

普通用户如果需要替换自己的数据,还是会比较难以运行这些例子。我们可以简单地增加一节:使用用户数据训练。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的,将在接下来添加这一部分

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readme doc needs some modifications.

@@ -1 +1,187 @@
TBD
# 文本分类
文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的IMDB语料库训练二分类DNN和CNN模型,完成对语料的简单文本分类。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里稍微用一两句话介绍一下IMDB数据集是一个什么样的数据集。对不了解这个任务的用户更加友好一些。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于IMDB的介绍在后面“实验数据”一节中有。为了避免用户读到这里时迷惑,准备在这里把IMBD去掉,直接表示为“有标注的语料库”

# 文本分类
文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的IMDB语料库训练二分类DNN和CNN模型,完成对语料的简单文本分类。

DNN与CNN模型之间最大的区别在于,CNN模型中存在卷积结构,而DNN大多使用基本的全连接结构。这使得CNN模型可以对语料信息中相邻单词组成的短语进行分析。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",而CNN模型则可能直接感知到"not bad"这个关键词组。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第一句话的标书仔细地琢磨不完全精确,改成下面这样。

DNN与CNN模型之间最大的区别在于:CNN是一种序列模型,能够提取一个局部区域之内的特征,能够处理变长的序列输入。而DNN大多使用基本的全连接结构,不是一种序列模型,只能接受固定维度的特征向量作为输入。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",这句话再补充一些:

对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",并且在输入时“not”和“bad”之间的顺序关系已经丢失,网络已经不再有机会学习到序列之间蕴含的特征。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

DNN与CNN模型之间最大的区别在于,CNN模型中存在卷积结构,而DNN大多使用基本的全连接结构。这使得CNN模型可以对语料信息中相邻单词组成的短语进行分析。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",而CNN模型则可能直接感知到"not bad"这个关键词组。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。

## 实验数据
本例子的实验在IMDB数据集上进行([数据集下载](http://ai.stanford.edu/%7Eamaas/data/sentiment/aclImdb_v1.tar.gz))。IMDB数据集包含了来自IMDb(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。数据集被划分为train和test两部分,各2.5万条数据,正负样本的比例基本为1:1。样本直接以英文原文的形式表示。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第二句话中的 , IMDb-->IMDB。把“IMDB数据集包含了来自IMDb(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。” 这句话放在IMDB数据集第一次出现的位置。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

个人觉得“实验数据”这部分单独成节会比较合适。。。因此准备将上文中IMDB第一次出现的位置删去,让IMDB的概念到“实验数据”这一节里才第一次出现


**可以看到,模型主要分为如下几个部分:**

- **词向量层**:IMDB的样本由原始的英文单词组成,为了方便模型的训练,必须将英文单词转化为固定维度的向量。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“为了方便模型的训练,必须将英文单词转化为固定维度的向量” 这样解释词向量是粗暴地,会误导用户。词向量的出现并不是为了方便模型的训练。建议修改为更加好的向用户传达词向量价值的表述。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


- **词向量层**:IMDB的样本由原始的英文单词组成,为了方便模型的训练,必须将英文单词转化为固定维度的向量。

- **最大池化层**:最大池化在时间序列上进行,池化过程消除了不同语料样本在单词数量多少上的差异,并提炼出词向量中每一下标位置上的最大值。经过池化后,样本被转化为一条固定维度的向量。例如,假设最大池化前的矩阵为`[[2,3,5],[7,3,6],[1,4,0]]`,该矩阵每一列代表一个词向量,则最大池化的结果为:`[[5],[7],[4]]`。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

样本被转化为一条固定维度的向向量 --> 卷积层输出的向量的序列被转化为一条固定维度的向量。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

假设最大池化前的矩阵为 --> 假设最大池化之前向量的序列为:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done,此处“卷基层”应该是“词向量层”?

每一行为一条样本,样本包括了原始语料和标签,语料内部的单词空格分隔,语料和标签之间用`\t`分隔。对于这样的数据我们可以如下编写数据读取接口:

```python
def encode_word(word, word_dict):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在代码中为每一个参数添加注释。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

else:
return word_dict['<unk>']

def data_reader(file_name, word_dict):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请按照python 的docstring 为每一个参数添加注释。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return reader
```

其中`word_dict`为事先准备好的将单词映射为id的词表。该`data_reader`可以替换代码中原先的`Paddle.dataset.imdb.train`用以数据提供。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

word_dict是字典,用来讲原始的单词字符串转化为在字典中的序号。可以用data_reader替换原先代码中的Paddle.dataset.imdb.train接口用以提供自定义的训练数据。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


- **fc_net函数**:定义dnn网络结构,上文已经有说明。

- **train\_dnn\_model函数**:模型训练函数。定义优化方式、训练输出等内容,并组织训练流程。该函数运行完成前会将训练得到的模型数保存至硬盘上的`dnn_params.tar.gz`文件中。本函数接受一个整数类型的参数,表示训练pass的轮数。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码里已经按照pass_id 存储,这里也需要相应修改。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

[ 0.98853314 0.01146684] 0
```

每一行表示一条样本的预测结果。前两列表示该样本属于0、1这两个类别的预测概率,最后一列表示样本的实际label。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里加上一些说明, CNN 模型的训练运行 ×,预测运行×。和DNN是一样的。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done,感谢曹总的细致review

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some modifications on REAMDE.


- **全连接隐层**:经过最大池化后的向量被送入两个连续的隐层,隐层之间为全连接结构。


- **输出层**:输出层的神经元数量和样本的类别数一致,例如在二分类问题中,输出层会有2个神经元。通过Softmax激活函数,我们保证输出层各神经元的输出之和为1,因此第i个神经元的输出就可以认为是样本属于第i类的预测概率。
- **输出层**:输出层的神经元数量和样本的类别数一致,例如在二分类问题中,输出层会有2个神经元。通过Softmax激活函数,输出层神经元的输出结果归一化为一个概率分布,和为1,因此第i个神经元的输出就可以认为是样本属于第i类的预测概率。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

”输出层神经元的输出结果归一化为一个概率分布“ 这句话略有不通顺,略作修改如下:
输出结果是一个归一化的概率分布,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -1,10 +1,10 @@
# 文本分类
文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的IMDB语料库训练二分类DNN和CNN模型,完成对语料的简单文本分类。
文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的语料库训练二分类DNN和CNN模型,完成对语料的简单文本分类。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在本例子中,我们利用有标注的IMDB电影评论语料库,训练二分类的DNN和CNN模型,完成对电影评论感情色彩的分类。

  1. 完成对语料的简单文本分类。 --> 完成对输入文本的分类任务。
  2. 第4行的例子提到的”not bad是决定这个句子情感的关键“,还是在出现这个例子之前,提一下“情感色彩分类”,避免比较突兀。

“简单”通常意义不甚明确,尽量避免“滥用”

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


DNN与CNN模型之间最大的区别在于,CNN模型中存在卷积结构,而DNN大多使用基本的全连接结构。这使得CNN模型可以对语料信息中相邻单词组成的短语进行分析。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",而CNN模型则可能直接感知到"not bad"这个关键词组。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。
DNN与CNN模型之间最大的区别在于:CNN是一种序列模型,能够提取一个局部区域之内的特征,能够处理变长的序列输入。而DNN大多使用基本的全连接结构,不是一种序列模型,只能接受固定维度的特征向量作为输入。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能感知到句子中有一个"not"和一个"bad",并且在输入时“not”和“bad”之间的顺序关系已经丢失,网络已经不再有机会学习到序列之间蕴含的特征;而CNN模型则可能直接感知到"not bad"这个关键词组。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 并且在输入时“not”和“bad”之间的顺序关系已经丢失,网络已经 [这个已经重复,删去] 不再有机会学习到序列之间蕴含的特征;
  2. 而CNN模型则可能直接感知到"not bad"这个关键词组 --> CNN模型接受文本序列作为输入,保留了"not bad"之间的顺序信息。(尽量用更精确的词汇传达信息,如果只留下“CNN模型可以直接感知”这样的表述,“感知“是一个比较抽象的概念,不便于普通用户对应到技术细节上)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


## 实验数据
本例子的实验在IMDB数据集上进行([数据集下载](http://ai.stanford.edu/%7Eamaas/data/sentiment/aclImdb_v1.tar.gz))。IMDB数据集包含了来自IMDb(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。数据集被划分为train和test两部分,各2.5万条数据,正负样本的比例基本为1:1。样本直接以英文原文的形式表示。
本例子的实验在IMDB数据集上进行([数据集下载](http://ai.stanford.edu/%7Eamaas/data/sentiment/aclImdb_v1.tar.gz))。IMDB数据集包含了来自IMDB(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。数据集被划分为train和test两部分,各2.5万条数据,正负样本的比例基本为1:1。样本直接以英文原文的形式表示。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

数据集下载这里可以删去,放在第一次引入 IMDB 时加上。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -19,24 +19,35 @@ DNN与CNN模型之间最大的区别在于,CNN模型中存在卷积结构,

**可以看到,模型主要分为如下几个部分:**

- **词向量层**:IMDB的样本由原始的英文单词组成,为了方便模型的训练,必须将英文单词转化为固定维度的向量
- **词向量层**:IMDB的样本由原始的英文单词组成,为了更好地表示不同的词之间语义上的关系,首先将英文单词转化为固定维度的向量。训练完成后,词与词语义上的相似程度将可以用它们的词向量之间的距离来表示,语义上越相似,距离越近
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第一个句话之后加一句吧:关于词向量的解释请参考PaddleBook中的词向量一节。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -86,7 +97,7 @@ def fc_net(input_dim, class_dim=2, emb_dim=256):

**可以看到,模型主要分为如下几个部分:**

- **词向量层**:与DNN中词向量层的作用一样,将英文单词转化为固定维度的向量。如图2中所示,将得到的词向量定义为行向量,再将语料中所有的单词产生的行向量拼接在一起组成矩阵。假设词向量维度为5,语料“The cat sat on the read mat”包含7个单词,那么得到的矩阵维度为7*5。
- **词向量层**:与DNN中词向量层的作用一样,将英文单词转化为固定维度的向量,利用向量之间的距离来表示词之间的语义相关程度。如图2中所示,将得到的词向量定义为行向量,再将语料中所有的单词产生的行向量拼接在一起组成矩阵。假设词向量维度为5,语料“The cat sat on the read mat”包含7个单词,那么得到的矩阵维度为7*5。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第一个句话之后加一句吧:关于词向量的解释请参考PaddleBook中的词向量一节。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -120,33 +144,50 @@ def convolution_net(input_dim, class_dim=2, emb_dim=128, hid_dim=128):

cost = paddle.layer.classification_cost(input=output, label=lbl)

return cost, output

return cost, output, lbl
```

该CNN网络的输入数据类型和前面介绍过的DNN一致。`paddle.networks.sequence_conv_pool`为Paddle中已经封装好的带有池化的文本序列卷积模块,该模块的`context_len`参数用于指定卷积核在同一时间覆盖的文本长度,也即图2中的卷积核的高度;`hidden_size`用于指定该类型的卷积核的数量。可以看到,上述代码定义的结构中使用了128个大小为3的卷积核和128个大小为4的卷积核,这些卷积的结果经过最大池化和结果并置后产生一个256维的向量,向量经过一个全连接层输出最终预测结果。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

150行,Paddle --> PaddlePaddle

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


编写数据读取接口的关键在于实现一个Python生成器,生成器负责解析数据文件中的每一行内容,并组合成适当的数据形式传送给网络中的data layer。例如在本样例中,data layer需要的数据类型为`paddle.data_type.integer_value_sequence`,这本质上是一个Python list。因此我们的生成器需要完成的主要就是“从文件中读取数据”和“转换成适当形式的Python list”这两件事。
编写数据读取接口的关键在于实现一个Python生成器,生成器负责从原始输入文集中解析出一条训练样本,并组合成适当的数据形式传送给网络中的data layer。例如在本样例中,data layer需要的数据类型为`paddle.data_type.integer_value_sequence`,这本质上是一个Python list。因此我们的生成器需要完成的主要就是“从文件中读取数据”和“转换成适当形式的Python list”这两件事。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 生成器负责从原始输入文集中解析出一条训练样本 --> 生成器负责从原始输入文本中解析出一条训练样本,文集 --> 文本
  2. [去掉这]本质上是一个Python list
  3. 最后一句话口语的痕迹比较重,略作修改:生成器主要完成:1. 从文件中读取数据, 2. 转换成适当形式的Python list,这两件事情。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


```
PaddlePaddle is good 1
What a terrible weather 0
```
每一行为一条样本,样本包括了原始语料和标签,语料内部的单词空格分隔,语料和标签之间用`\t`分隔。对于这样的数据我们可以如下编写数据读取接口
每一行为一条样本,样本包括了原始语料和标签,语料内部单词以空格分隔,语料和标签之间用`\t`分隔。对于这样的数据,可以如下自定义的数据读取接口来为PaddlePaddle返回训练数据
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“对于这样的数据,可以如下自定义的数据读取接口来为PaddlePaddle返回训练数据” 不太通顺,缺动词。

对以上格式的数据,可以使用如下自定义的数据读取接口为PaddlePaddle返回训练数据。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该是写的时候手抖漏掉了……done

@@ -156,7 +197,7 @@ def data_reader(file_name, word_dict):
return reader
```

其中`word_dict`为事先准备好的将单词映射为id的词表。该`data_reader`可以替换代码中原先的`Paddle.dataset.imdb.train`用以数据提供
`word_dict`是字典,用来讲原始的单词字符串转化为在字典中的序号。可以用`data_reader`替换原先代码中的`Paddle.dataset.imdb.train`接口用以提供自定义的训练数据
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

讲 --> 将

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done。感谢曹总review!

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small modifications.

@@ -0,0 +1 @@
.DS_Store
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个文件暂时先删掉吧。ignore mac 的这个文件比较奇怪。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个文件还没删掉?

@@ -0,0 +1 @@
temp/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个在目前上传的脚本中,并没有用到 temp 文件夹吧?如果是这样,请先从版本库中删除。

Copy link
Collaborator

@lcy-seso lcy-seso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@luotao1 luotao1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还有一些小问题

@@ -0,0 +1 @@
.DS_Store
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个文件还没删掉?

# 文本分类
文本分类是机器学习中的一项常见任务,主要目的是根据一条文本的内容,判断该文本所属的类别。在本例子中,我们利用有标注的语料库训练二分类DNN和CNN模型,完成对输入文本的分类任务。

DNN与CNN模型之间最大的区别在于:CNN是一种序列模型,能够提取一个局部区域之内的特征,能够处理变长的序列输入。而DNN大多使用基本的全连接结构,不是一种序列模型,只能接受固定维度的特征向量作为输入。举例来说,情感分类是一项常见的文本分类任务,在情感分类中,我们希望训练一个模型来判断句子中表现出的情感是正向还是负向。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能知道句子中有一个"not"和一个"bad",并且在输入时“not”和“bad”之间的顺序关系已经丢失,网络不再有机会学习到序列之间蕴含的特征;而CNN模型接受文本序列作为输入,保留了"not bad"之间的顺序信息。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 对比区别时使用列表更为清晰
  2. 既然开头是DNN与CNN,所以先讲DNN,后讲CNN。顺序要统一。

建议修改如下:

DNN与CNN模型之间最大的区别在于:

  • DNN不属于序列模型,大多使用基本的全连接结构,只能接受固定维度的特征向量作为输入。
  • CNN属于序列模型,能够提取一个局部区域之内的特征,从而处理变长的序列输入。

举例来说,情感分类是一项常见的文本分类任务。在情感分类中,我们希望训练一个模型来判断句子中表现出的情感是正向还是负向。例如,"The apple is not bad",其中"not bad"是决定这个句子情感的关键。

  • 对于DNN模型来说,只能知道句子中有一个"not"和一个"bad",但两者之间的顺序关系在输入时已经丢失,网络不再有机会学习序列之间的顺序信息。
  • CNN模型接受文本序列作为输入,保留了"not bad"之间的顺序信息。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

DNN与CNN模型之间最大的区别在于:CNN是一种序列模型,能够提取一个局部区域之内的特征,能够处理变长的序列输入。而DNN大多使用基本的全连接结构,不是一种序列模型,只能接受固定维度的特征向量作为输入。举例来说,情感分类是一项常见的文本分类任务,在情感分类中,我们希望训练一个模型来判断句子中表现出的情感是正向还是负向。例如,"The apple is not bad",其中的"not bad"是决定这个句子情感的关键。对于DNN模型来说,只能知道句子中有一个"not"和一个"bad",并且在输入时“not”和“bad”之间的顺序关系已经丢失,网络不再有机会学习到序列之间蕴含的特征;而CNN模型接受文本序列作为输入,保留了"not bad"之间的顺序信息。因此,在大多数文本分类任务上,CNN模型的表现要好于DNN。

## 实验数据
本例子的实验在IMDB数据集上进行([数据集下载](http://ai.stanford.edu/%7Eamaas/data/sentiment/aclImdb_v1.tar.gz))。IMDB数据集包含了来自IMDB(互联网电影数据库)网站的5万条电影影评,并被标注为正面/负面两种评价。数据集被划分为train和test两部分,各2.5万条数据,正负样本的比例基本为1:1。样本直接以英文原文的形式表示。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本例子的实验在IMDB数据集上进行。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


<p align="center">
<img src="images/dnn_net.png" width = "90%" align="center"/><br/>
图1. DNN文本分类模型
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这张图能显示出边框,请重新上传全白底的图片
image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


**可以看到,模型主要分为如下几个部分:**

- **词向量层**:IMDB的样本由原始的英文单词组成,为了更好地表示不同的词之间语义上的关系,首先将英文单词转化为固定维度的向量。训练完成后,词与词语义上的相似程度将可以用它们的词向量之间的距离来表示,语义上越相似,距离越近。关于词向量的更多信息请参考PaddleBook中的[词向量](https://github.com/PaddlePaddle/book/tree/develop/04.word2vec)一节。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 不同的词-》不同词
  2. 将可以(去掉将)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


- **卷积层**: 文本分类中的卷积在时间序列上进行,即卷积核的宽度和词向量层产出的矩阵一致,卷积验证矩阵的高度方向进行。卷积后得到的结果被称为“特征图”(feature map)。假设卷积核的高度为h,矩阵的高度为N,卷积的步长为1,则得到的特征图为一个高度为N+1-h的向量。可以同时使用多个不同高度的卷积核,得到多个特征图。

- **最大池化层**: 对卷积得到的各个特征图分别进行最大池化操作。由于特征图本身已经是向量,因此这里的最大池化实际上就是简单地选出各个向量中的最大元素。各个最大元素又被并置在一起,组成新的向量,显然,该向量的维度等于特征图的数量,也就是卷积核的数量。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 并置-》拼接?
  2. DNN的最大池化举了例子,这里是否也可举个例子。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确实是“拼接”表达得更加精确,done

return cost, output, lbl
```

该CNN网络的输入数据类型和前面介绍过的DNN一致。`paddle.networks.sequence_conv_pool`为PaddlePaddle中已经封装好的带有池化的文本序列卷积模块,该模块的`context_len`参数用于指定卷积核在同一时间覆盖的文本长度,也即图2中的卷积核的高度;`hidden_size`用于指定该类型的卷积核的数量。可以看到,上述代码定义的结构中使用了128个大小为3的卷积核和128个大小为4的卷积核,这些卷积的结果经过最大池化和结果并置后产生一个256维的向量,向量经过一个全连接层输出最终预测结果。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 也即-》即
  2. 并置-》拼接?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

## 自定义数据
本样例中的代码通过`Paddle.dataset.imdb.train`接口使用了PaddlePaddle自带的样例数据,在第一次运行代码时,PaddlePaddle会自动下载并缓存所需的数据。如果希望使用自己的数据进行训练,需要自行编写数据读取接口。

编写数据读取接口的关键在于实现一个Python生成器,生成器负责从原始输入文本中解析出一条训练样本,并组合成适当的数据形式传送给网络中的data layer。例如在本样例中,data layer需要的数据类型为`paddle.data_type.integer_value_sequence`,本质上是一个Python list。因此我们的生成器需要完成:1. 从文件中读取数据, 2. 转换成适当形式的Python list,这两件事情。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

因此我们的生成器需要完成:从文件中读取数据,以及转换成适当形式的Python list,这两件事情。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


- **main函数**:主函数

要运行本样例,直接在`text_classification_dnn.py`所在路径下执行`python ./text_classification_dnn.py`即可,样例会自动依次执行数据集下载、数据读取、模型训练和保存、模型读取、新样本预测等步骤。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一般运行命令是python text_classification_dnn.py

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


每一行表示一条样本的预测结果。前两列表示该样本属于0、1这两个类别的预测概率,最后一列表示样本的实际label。

在运行CNN的模型的`text_classification_cnn.py`脚本中,网络模型定义在`convolution_net`函数中,模型训练函数名为`train_cnn_model`,预测函数名为`cnn_infer`。其他的用法和`text_classification_dnn.py`是一致的。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

去掉多余“的”字:

  1. 运行CNN模型
  2. 其他用法

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@luotao1
Copy link
Contributor

luotao1 commented May 17, 2017

LGTM。最后还有一个问题,图中:The cat sat on the read mat 。read应该是red, @livc 在book中修复过了 PaddlePaddle/book#313

@JiayiFeng
Copy link
Collaborator Author

read和red的问题已经修复

@luotao1 luotao1 merged commit 6f06bb6 into PaddlePaddle:develop May 17, 2017

## DNN模型

**DNN的模型结构入下图所示:**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“DNN的模型结构如下图所示:”,有个错别字

HongyuLi2018 pushed a commit that referenced this pull request Apr 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

example configuration for text classification.
4 participants