继续学习基于深度学习的文本分类。资料链接
Word2Vec的使用和基础原理
使用 Word2Vec 学习词向量,其基本思想是对出现在上下文环境里的词进行预测。对于每一条输入文本,我们选取一个上下文窗口和一个中心词,并基于这个中心词去预测窗口里其他词出现的概率。
- 主要思路:通过单词和上下文彼此预测。对应两个算法:
Skip-grams (SG):给定input word来预测上下文
Continuous Bag of Words (CBOW):给定上下文来预测目标单词 - 另外提出两种更加高效的训练方法:
Hierarchical softmax
Negative sampling
1. Skip-grams原理和网络结构
过程:
- 选句子中间的一个词作为我们的输入词 input word。
- 两个参数:
定义一个叫做skip_window的参数,获取一个窗口,它代表着我们从当前input word的一侧(左边或右边)选取词的数量。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4,如 [‘The’, ‘dog’,‘barked’, ‘at’]。
定义另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word,当skip_window=2,num_skips=2时,我们将会得到两组 (input word, output word) 形式的训练数据,即 (‘dog’, ‘barked’),(‘dog’, ‘the’)。 - 神经网络基于这些训练数据将会输出一个概率分布。这个概率代表着当给定一个input word时,词典中的每个词作为它的output word的可能性。也就是说模型的输出概率代表着到我们词典中每个词有多大可能性跟input word同时出现。
举个例子:

模型将会从每对单词出现的次数中习得统计结果。
使用 one-hot 对input word和output word编码。输入被 one-hot 编码以后大多数维度上都是0,耗费大量计算资源。为了高效计算,它仅仅会选择矩阵中对应的向量中维度值为1的索引行。
2. Skip-grams训练
Word2Vec模型是一个超级大的神经网络,词典的大小决定了权重矩阵规模非常大。
解决方法:
- 将常见的单词组合(word pairs)或者词组作为单个“words”(phases)来处理;
一些单词组合(或者词组)的含义和拆开以后具有完全不同的意义。比如,名字。 - 对高频次单词进行抽样来减少训练样本的个数;
如上面图片中的常用词 the ,出现概率大,且不会提供额外的语义信息。
抽样:对于我们在训练原始文本中遇到的每一个单词,它们都有一定概率被我们从文本中删掉,而这个被删除的概率与单词的频率有关。
ωi 是一个单词,Z(ωi) 是 ωi 这个单词在所有语料中出现的频次,例如:如果单词“peanut”在10亿规模大小的语料中出现了1000次,那么 Z(peanut) = 1000/1000000000 = 1e - 6,P(ωi) 代表着保留某个单词的概率:

- 对优化目标采用“negative sampling”方法,这样每个训练样本的训练只会更新一小部分的模型权重,降低梯度下降过程中的计算量。
当我们用训练样本 ( input word: “fox”,output word: “quick”) 来训练我们的神经网络时,“ fox”和“quick”都是经过one-hot编码的。如果我们的词典大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。
随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重。
使用“一元模型分布(unigram distribution)”来选择“negative words”。每个单词被选作negative sample的概率跟它出现的频次有关,出现频次越高的单词越容易被选作negative words。每个单词被选为“negative words”的概率计算公式:

其中 f(ωi)代表着单词出现的频次,而公式中开3/4的根号完全是基于经验的。
3. Hierarchical Softmax
3.1 霍夫曼树
输入:权值为(w1,w2,…wn)的n个节点
输出:对应的霍夫曼树
- 将(w1,w2,…wn)看做是有n棵树的森林,每个树仅有一个节点;
- 在森林中选择根节点权值最小的两棵树进行合并,得到一个新的树,这两颗树分别作为新树的左右子树。新树的根节点权重为左右子树的根节点权重之和;
- 将之前的根节点权值最小的两棵树从森林删除,并把新树加入森林;
- 重复步骤 2 和 3 直到森林里只有一棵树为止。
3.2 Hierarchical Softmax 过程
Word2Vec 采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。
根据标签(label)和频率建立霍夫曼树(label出现的频率越高,Huffman树的路径越短),Huffman树中每一叶子结点代表一个label。

使用gensim训练word2vec
from gensim.models.word2vec import Word2Vec
model = Word2Vec(sentences, workers=num_workers, size=num_features)
TextCNN

TextRNN

使用TextCNN、TextRNN进行文本表示
- TextCNN
模型搭建:
self.filter_sizes = [2, 3, 4] # n-gram window
self.out_channel = 100
self.convs = nn.ModuleList([nn.Conv2d(1, self.out_channel, (filter_size, input_size), bias=True) for filter_size in self.filter_sizes])
前向传播:
pooled_outputs = []
for i in range(len(self.filter_sizes)):
filter_height = sent_len - self.filter_sizes[i] + 1
conv = self.convs[i](batch_embed)
hidden = F.relu(conv) # sen_num x out_channel x filter_height x 1
mp = nn.MaxPool2d((filter_height, 1)) # (filter_height, filter_width)
# sen_num x out_channel x 1 x 1 -> sen_num x out_channel
pooled = mp(hidden).reshape(sen_num, self.out_channel)
pooled_outputs.append(pooled)
- TextRNN
模型搭建:
input_size = config.word_dims
self.word_lstm = LSTM(
input_size=input_size,
hidden_size=config.word_hidden_size,
num_layers=config.word_num_layers,
batch_first=True,
bidirectional=True,
dropout_in=config.dropout_input,
dropout_out=config.dropout_hidden,
)
前向传播:
hiddens, _ = self.word_lstm(batch_embed, batch_masks) # sent_len x sen_num x hidden*2
hiddens.transpose_(1, 0) # sen_num x sent_len x hidden*2
if self.training:
hiddens = drop_sequence_sharedmask(hiddens, self.dropout_mlp)
使用HAN网络结构完成文本分类
基于层级注意力,在单词和句子级别分别编码并基于注意力获得文档的表示,然后经过Softmax进行分类。其中word encoder的作用是获得句子的表示,可以替换为上节提到的TextCNN和TextRNN,也可以替换为下节中的BERT。
练习
尝试通过Word2Vec训练词向量
尝试使用TextCNN、TextRNN完成文本表示
尝试使用HAN进行文本分类
探讨深度学习在文本分类的应用,深入解析Word2Vec的原理与Skip-grams算法,介绍Hierarchical Softmax和Negative Sampling优化技巧。

2069

被折叠的 条评论
为什么被折叠?



