🔥 如题,本文将要介绍三种模型:
- Convolutional Neural Network (CNN)
- Recurrent Neural Network (RNN)
- Hierarchical Attention Network (HAN)
介绍
文本分类是自然语言处理和监督学习领域一个非常热门的子任务,很多新手的学习也都是从文本分来开始的。那么文本分类是啥?🙈
类似于判定一则新闻是否是垃圾新闻,通常此类数据只需两个字段,比如:review,label等。我们需要做的就是根据带标签的文本数据,训练出一个判别器,用于识别其类型的正负。常见的文本分类任务有:
- 文本情感分类(喜怒哀乐)
- 垃圾邮件判别
- 用户话语标签(某米音响中的:放歌,闭嘴,关灯等话语)
- 新闻类别分类(历史,娱乐,政治等)
当然应用领域肯定不止这些,分类属于一个非常基础且重要的功能,学好不易,且学且努力。
安利一波文本分类代码:
- Text-Classification
- brightmart-text-classification
- cnn-text-classification-tf
- ...... (👩💻 自己上gayhub上找)
说明
一个健全的文本分类任务是需要准备以下素材的:
-
训练语料 :没有这个都是*淡
-
WordEmbedding:可以使用预训练好的词向量,也可以自己训练词向量
预训练好的词向量:
-
标签:这个一般是和训练语料放在一起的,由标签种类的数量可以将文本分类认为二分类和多分类任务
-
模型:用来训练语料生成最终的判别器
好了,该介绍的废话都说完了,接下来就开始介绍其中多种模型了。有研究背景的同学,一定要看论文,一定要看论文,一定要看论文,地址在最底下自己找,本文中的图也大多数来自于原论文。
CNN
首先我假设各位大佬们都了解CNN的基本原理,那如何将CNN应用在文本上呢?在此我通过TextCNN来讲解,参考了 What Does a TextCNN Learn? 论文来给大家讲解,希望大家能够吸收消化20%就已经很不错了。
首先来看看其整体架构图:
左边是由两个 static vectors和 non-static vectors组成,两者的区别在于词向量能否学习(微调)。这个特性能够让网络拥有一定的基础文字关系 的 记忆和学习能力。
词向量一般基于大量的语料库学习而来,里面包含语法和语义的相关信息,这些信息可以使用相似度来进行描述,通过统计方法得来。而这些仅仅只是通过一定的统计方法得来的特征,到底能不能经得起验证(loss函数的验证)就不得而知了,所以此处的学习能力是非常重要的。
中间就是卷积核学习而来的结果,接下来做max pooling操作,选出一个channel最大的值最终拼接到一起。然后再来个全连接。简单的代码如下所示:
sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')
embedded_sequences = embedding_layer(sequence_input)
l_cov1= Conv1D(128, 5, activation='relu')(embedded_sequences)
l_pool1 = MaxPooling1D(5)(l_cov1)
l_cov2 = Conv1D(128, 5, activation='relu')(l_pool1)
l_pool2 = MaxPooling1D(5)(l_cov2)
l_cov3 = Conv1D(128, 5, activation='relu')(l_pool2)
l_pool3 = MaxPooling1D(35)(l_cov3) # global max pooling
l_flat = Flatten()(l_pool3)
l_dense = Dense(128, activation='relu')(l_flat)
preds = Dense(len(macronum), activation='softmax')(l_dense)
最后生成的模型的架构图如下所示:
为啥CNN能够在文本序列中学习到序列特征呢?后面我也会出相关的博文阐述。
RNN
使用RNN及其扩展模型来处理文本序列模型才是大家认为的常见操作,也被实践证明是处理效果最好的方法。在此RNN的基本概念我就不说了,不熟悉的也可以看Colah‘s blog,另外对LSTM不熟悉的孩童们,可以看看我的这篇博文,里面有详细说明其中的概念。
RNN在处理序列数据方面能力那是杠杠的,因为本身架构就是为序列而生的。序列数据领域包含:文本,时序,视频,DNA数据等等。
接下来我的模型架构如下:
-
Embedding可以直接使用预训练模型,种类在上文
-
LSTM Encoder使用LSTM对word进行简单编码
-
Full Connected Network对输出结构进行全连接操作,输出最终分类
由上图所见,这是一个很标准的Sequence to Sequence模型,可以分为以下几点理解:
-
Encoder
词向量序列喂给LSTM之后,会生成一个隐藏层向量,也就是Encoder/LSTM的输出。上面Encoder中只是包含比较简单的一层LSTM,也可以添加稍微复杂点的Attention机制,也可以添加层级基于Attention的Sequence2Sequence结构,结构可以很复杂,一般处理下过也是很好的。不过咱们还得一步一步来。
Encoder的输出被称作为
Context Vector,这个就是Encoder对输入这句话的理解,然后Decoder对这句话进行翻译,解码。 -
Decoder
一般结构与Encoder一致,即使有差别也差别不大。
你怎么编码,我就怎么解码,不然两者的脑回路不一样,理解的结果也就不一样。
-
全连接层
这个就是对解码后的信息点进行加权处理,最终得到分类结果。
Keras代码如下所示:
sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')
embedded_sequences = embedding_layer(sequence_input)
l_lstm = Bidirectional(LSTM(100))(embedded_sequences)
preds = Dense(len(macronum), activation='softmax')(l_lstm)
model = Model(sequence_input, preds)
model.compile(loss='categorical_crossentropy',optimizer='rmsprop', metrics=['acc'])
最终的架构图如下所示:
HAN
全称:Hierarchical Attention Network,详细了解请看这篇论文。
这个小节,我将要给大家介绍层级LSTM网络。模型结构如下所示:
上面我已经讲了两种模型图,如果这个还不懂,可以再回过头过去看看,之后再回来看这个应该就明白了。
keras 伪代码如下所示:
embedding_layer=Embedding(len(word_index)+1,EMBEDDING_DIM,weights=[embedding_matrix],
input_length=MAX_SENT_LENGTH,trainable=True)
sentence_input = Input(shape=(MAX_SENT_LENGTH,), dtype='int32')
embedded_sequences = embedding_layer(sentence_input)
l_lstm = Bidirectional(LSTM(100))(embedded_sequences)
sentEncoder = Model(sentence_input, l_lstm)
review_input = Input(shape=(MAX_SENTS,MAX_SENT_LENGTH), dtype='int32')
review_encoder = TimeDistributed(sentEncoder)(review_input)
l_lstm_sent = Bidirectional(LSTM(100))(review_encoder)
preds = Dense(len(macronum), activation='softmax')(l_lstm_sent)
model = Model(review_input, preds)
上述代码模型结构如下:
参考文章及论文:
其中大部分论文地址,我都放在文章中,在此就不重复一一罗列了。