优化算法进阶
Momentum:相对于小批量随机梯度下降,动量法需要对每一个自变量维护一个同它一样形状的速度变量,且超参数里多了动量超参数。
AdaGrad:同动量法一样,AdaGrad算法需要对每个自变量维护同它一样形状的状态变量。
RMSProp:相比于AdaGrad增加后期学习率
AdaDelta:没有学习率超参数
Adam:在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均
订正
mt和vt均使用EMA但是衰减参数不相同
word2vec
Skip-Gram 跳字模型:假设背景词由中心词生成
continuous bag-of-words 连续词袋模型:假设中心词由背景词生成
PTB 数据集
with open('/home/kesci/input/ptb_train1020/ptb.train.txt', 'r') as f:
lines = f.readlines() # 该数据集中句子以换行符为分割
raw_dataset = [st.split() for st in lines] # st是sentence的缩写,单词以空格为分割
print('# sentences: %d' % len(raw_dataset))
# 对于数据集的前3个句子,打印每个句子的词数和前5个词
# 句尾符为 '' ,生僻词全用 '' 表示,数字则被替换成了 'N'
for st in raw_dataset[:3]:
print('# tokens:', len(st), st[:5])
建立词语索引
counter = collections.Counter([tk for st in raw_dataset for tk in st]) # tk是token的缩写
counter = dict(filter(lambda x: x[1] >= 5, counter.items())) # 只保留在数据集中至少出现5次的词
idx_to_token = [tk for tk, _ in counter.items()]
token_to_idx = {tk: idx for idx, tk in enumerate(idx_to_token)}
dataset = [[token_to_idx[tk] for tk in st if tk in token_to_idx]
for st in raw_dataset] # raw_dataset中的单词在这一步被转换为对应的idx
num_tokens = sum([len(st) for st in dataset])
'# tokens: %d' % num_tokens
二次采样:丢掉对训练词嵌入模型的关键词
Skip-Gram 跳字模型:在跳字模型中,每个词被表示成两个 维向量,用来计算条件概率。
订正:
词嵌入模型首先需要在大规模语料库上进行训练,才能得到更有意义的词向量,其次在后续模型的训练过程中,可能还需要进行进一步的模型参数优化,所以在实现和使用上,都是比 one-hot 向量更复杂的
词嵌入进阶
GloVe 全局向量的词嵌入
import torch
import torchtext.vocab as vocab
print([key for key in vocab.pretrained_aliases.keys() if "glove" in key])
cache_dir = "/home/kesci/input/GloVe6B5429"
glove = vocab.GloVe(name='6B', dim=50, cache=cache_dir)
print("一共包含%d个词。" % len(glove.stoi))
print(glove.stoi['beautiful'], glove.itos[3366])
['glove.42B.300d', 'glove.840B.300d', 'glove.twitter.27B.25d', 'glove.twitter.27B.50d', 'glove.twitter.27B.100d', 'glove.twitter.27B.200d', 'glove.6B.50d', 'glove.6B.100d', 'glove.6B.200d', 'glove.6B.300d']
一共包含400000个词。
3366 beautiful
近义词:由于词向量空间中的余弦相似性可以衡量词语含义的相似性,我们可以通过寻找空间中的 k 近邻,来查询
类比词:除了求近义词以外,我们还可以使用预训练词向量求词与词之间的类比关系,c+b-a结果最相似的向量