实现了nlp-beginner的几个任务,一方面自己练练手,另一方面供刚入门的朋友参考。才学疏浅,难免有不少问题,有任何问题可以发issue或者邮箱联系,万分感谢~
数据集地址:Classify the sentiment of sentences from the Rotten Tomatoes dataset
-
用
sklearn
实现,n-gram
特征提取直接用sklearn
内置的CountVectorizer
。 -
用
numpy
实现:- 自定义
n-gram
特征抽取类,用scipy
的csr_matrix
来保存doc-ngram
稀疏矩阵; numpy
实现用于二分类的Logistic Regression
及用于多分类的Softmax Regression
;- 实现三种梯度更新方式:
BGD
、SGD
以及MBGD
;
方法 参数 准确度 LR (sklearn) C=0.8; penalty='l1' 0.587 SoftmaxRegression (numpy) C=0.8; penalty='l1' 0.548 - 自定义
数据集地址:Classify the sentiment of sentences from the Rotten Tomatoes dataset
-
老老实实一步步写分词、构建词典、数据向量化、加载词向量等;
-
用
pytorch
写RNN
,GRU
,LSTM
以及TextCNN
,其中自己编写的RNN
,GRU
,LSTM
模型已经测试与pytorch
内部nn.xxx
一致。 -
用
torchtext
简化数据的处理操作;方法 参数 准确度 RNN epoch=5; hidden_size = 256; num_layers = 1; bidirectional = True; random embedding 0.629 RNN epoch=5; hidden_size = 256; num_layers = 1; bidirectional = True; glove_200 embedding 0.633 CNN epoch=5; num_filters = 200; kernel_sizes = [2, 3, 4]; random embedding 0.654 CNN epoch=5; num_filters = 200; kernel_sizes = [2, 3, 4]; glove_200 embedding 0.660
说明:该实验glove
词向量对结果提升不大,第四个实验效果较为显著;
数据集地址:SNLI
-
实现
ESIM
模型,如上图左边所示,模型主要分三层,由下至上:- 第一层用
BiLSTM
来对句子的每个词向量进行重新编码,使其具备全局性; - 第二层先用
Attention
来提取前提与假设之间的关系,然后重构,以前提为例:
# x1为前提,x2为假设,new_embed1是假设x1经过BiLSTM后的值,weight2是x2的每个词对x1的归一化相关程度,即attention值。 # 1. 对假设x2进行加权求和,该值提取出了x2中与x1相关的部分; x1_align = torch.matmul(weight2, x2) # 2. 将四部分连接起来,用相减以及相乘来实现前提与假设的“交互推断”,文中说可以使得局部信息(如矛盾关系)更加明显; x1_combined = torch.cat([new_embed1, x1_align, new_embed1 - x1_align, new_embed1 * x1_align],dim=-1)
- 第三层是将重构后的前提和假设再放到一个
BiLSTM
中,文中说为了控制模型复杂度,在传入前先经过一个单层FFN
并且ReLU
一下。 - 第四层是输出层,先
pooling
一下,文中前提和假设都用了max-pooling
以及average-pooling
两种形式,再对两者连接后MLP输出。
- 第一层用
-
注意用
torchtext
读取json
文件的方式,及依赖解析数据的读取方式。其实torchtext
内部有dataset.nli
模块实现了nli
数据读取方式,但是在代码中我还是用原版的FIELD
来实现,便于理解其内部的处理流程。
model test accuracy | paper test accuracy |
---|---|
0.86 | 0.88 |
数据集地址:CONLL 2003
采用CNN+BiLSTM+CRF
结构,复现论文End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF
- 数据采用
BIOES
结构,用bio2bioes.py
进行转换。 - 关于预处理,将数字都变为0;
- 设置预训练
embedding
的时候需注意模糊匹配(大小写); - 设置
vocab
的时候使要用到train
以及dev
+test
中出现在embedding
中的词; - 关于初始化,论文里有详细的设置,注意的是
LSTM
里面的forget gate
的bias
初始为1,因为开始的时候记忆准确度不高。 - 关于
dropout
,LSTM
的输入和输出的时候都加dropout
;字符embedding
进入CNN
前也要dropout
。 - 关于优化器,论文是采用了
SGD
,每个epoch都对学习率进行调整,注意这里不能用pytorch
的SGD
中的weight decay
,因为它是对权重的衰减(L2正则),而我们要的是对学习率进行衰减。
embedding | entity-level F1 | paper result |
---|---|---|
random (uniform) | 83.18 | 80.76 |
glove 100 | 90.7 | 91.21 |
注意点:使用torchtext
进行文本处理,需注意要由于torchtext
只能处理tsv/csv/json
格式的文本,这里需要自己
从文本读取的句子,也要自定义Dataset
,make Example
时的两种表现形式:
list
形式,此时构建FIELD
的时候FIELD
内部的tokenizer
不会起作用;str
形式,word
空格隔开,此时构建FIELD
的时候必须传入tokenizer=lambda x:x.split()
(针对该任务)来覆盖内部的tokenizer
, 否则会用内部的来分词,得到的word
可能不一样了,也就和label
不对应了。
用CharRNN
来写诗,评价指标为困惑度,是交叉熵损失取exp
。
- 采用单向
LSTM
,输入的最后一个为[EOS]
,对应的target
为输入右移一位; - 控制诗的长度为
MAX_LEN
,以一行为单位进行切分,即将超长的诗切分为若干短诗; - 训练200个
epoch
后,困惑度为400左右。
Input the first word or press Ctrl-C to exit: 鸟
鸟渠霭乌秋,游王居信知。鹏未弟休不,深沙由意。寥五将不,两迹悄臣。生微心日,水复师尘。来称簸更,影乏魍无。