优化算法进阶;word2vec;词嵌入进阶

目录
优化算法进阶
An ill-conditioned Problem
Maximum Learning Rate
Supp: Preconditioning
Solution to ill-condition
Momentum Algorithm
Exponential Moving Average
Supp
由指数加权移动平均理解动量法
Pytorch Class
AdaGrad
Algorithm
Feature
Pytorch Class
RMSProp
Algorithm
Pytorch Class
AdaDelta
Algorithm
Implement
Pytorch Class
Adam
Algorithm
Implement
Pytorch Class
word2vec
二次采样
Skip-Gram 模型的前向计算
负采样近似
损失函数
词嵌入进阶
GloVe 全局向量的词嵌入
GloVe 模型
载入预训练的 GloVe 向量
求类比词
优化算法进阶
在每次迭代中,梯度下降根据自变量当前位置,沿着当前位置的梯度更新自变量。然而,如果自变量的迭代方向仅仅取决于自变量当前位置,这可能会带来一些问题。对于noisy gradient,我们需要谨慎的选取学习率和batch size, 来控制梯度方差和收敛的结果。

gt=∂w1∣Bt∣∑i∈Btf(xi,wt−1)=1∣Bt∣∑i∈Btgi,t−1. \mathbf{g}t = \partial{\mathbf{w}} \frac{1}{|\mathcal{B}t|} \sum{i \in \mathcal{B}t} f(\mathbf{x}{i}, \mathbf{w}{t-1}) = \frac{1}{|\mathcal{B}t|} \sum{i \in \mathcal{B}t} \mathbf{g}{i, t-1}.
An ill-conditioned Problem
Condition Number of Hessian Matrix:
condH=λmaxλmin cond
{H} = \frac{\lambda_{max}}{\lambda_{min}}
cond
=20→ill-conditioned

一般来说condition number比较大时即认定该问题为ill-conditioner problem.可参考神经网络优化中的病态问题

Maximum Learning Rate
For f(x) f(x)f(x), according to convex optimizaiton conclusions, we need step size η≤1L \eta \leq \frac{1}{L}η≤


且不满足 η≤1L \eta \leq \frac{1}{L}η≤
L
1

时,函数将在区间谷壁对碰折线递减迭代,但依旧能够保证最终收敛到最小点,而当某一维坐标上学习率不满足在该坐标上η≤2L \eta \leq \frac{2}{L}η≤
L
2

时,函数将不能递减迭代,也不能收敛到该维度上的最小点处。

Supp: Preconditioning
在二阶优化中,我们使用Hessian matrix的逆矩阵(或者pseudo inverse)来左乘梯度向量 i.e.Δx=H−1g i.e. \Delta_{x} = H^{-1}\mathbf{g}i.e.Δ
x

=H
−1
g,这样的做法称为precondition,相当于将 H HH 映射为一个单位矩阵,拥有分布均匀的Spectrum,也即我们去优化的等价标函数的Hessian matrix为良好的identity matrix,同一个学习率在各个坐标维度上递减迭代减少量接近,就不会出现在某一维度上学习率过高而另一维度上则学习率过低的情况。

Solution to ill-condition
Preconditioning gradient vector: applied in Adam, RMSProp, AdaGrad, Adelta, KFC, Natural gradient and other secord-order optimization algorithms.
Averaging history gradient: like momentum, which allows larger learning rates to accelerate convergence; applied in Adam, RMSProp, SGD momentum.
Momentum Algorithm
动量法的提出是为了解决梯度下降的上述问题。设时间步 t tt 的自变量为 xt \boldsymbol{x}_tx
t

,学习率为 ηt \eta_tη
t


在时间步 t=0 t=0t=0,动量法创建速度变量 m0 \boldsymbol{m}_0m
0

,并将其元素初始化成 0。在时间步 t>0 t>0t>0,动量法对每次迭代的步骤做如下修改:
Another version:

mtxt←βmt−1+(1−β)gt,←xt−1−αtmt, \begin{aligned}\boldsymbol{m}t &\leftarrow \beta \boldsymbol{m}{t-1} + (1-\beta) \boldsymbol{g}_t, \\boldsymbol{x}t &\leftarrow \boldsymbol{x}{t-1} - \alpha_t \boldsymbol{m}_t,\end{aligned}
m

其中,动量超参数 β \betaβ满足 0≤β<1 0 \leq \beta < 10≤β<1。当 β=0 \beta=0β=0 时,动量法等价于小批量随机梯度下降。

在解释动量法的数学原理前,让我们先从实验中观察梯度下降在使用动量法后的迭代轨迹。

由实验观察可得,在学习率满足以上收敛条件时,优化仍旧收敛,并且没有之前在某一维度上陡增陡减的情况,反而是迭代得更为平缓;在学习率超出以上收敛条件规定范围时候,优化依旧收敛,即momentum对历史的梯度会有一个加权的平均,平均值就是mt \boldsymbol{m}_{t}m
t

,经过加权之后更新参数时使用的并不是某点处的直接梯度方向,而是以某种更平缓更接近最优点的方向进行参数更新,所以momentum可以允许使用更大的学习率从而更快迭代寻找到最优点。

Exponential Moving Average
为了从数学上理解动量法,让我们先解释一下指数加权移动平均(exponential moving average)。给定超参数 0≤β<1 0 \leq \beta < 10≤β<1,当前时间步 t tt 的变量 yt y_ty −1)≈0.3679,

所以当 β→1 \beta \rightarrow 1β→1时,β1/(1−β)=exp(−1) \beta^{1/(1-\beta)}=\exp(-1)β
1/(1−β)
=exp(−1),如 0.9520≈exp(−1) 0.95^{20} \approx \exp(-1)0.95
20
≈exp(−1)。如果把 exp(−1) \exp(-1)exp(−1) 当作一个比较小的数,我们可以在近似中忽略所有含 β1/(1−β) \beta^{1/(1-\beta)}β
1/(1−β)
和比 β1/(1−β) \beta^{1/(1-\beta)}β
1/(1−β)
更高阶的系数的项。例如,当 β=0.95 \beta=0.95β=0.95 时,

yt≈0.05∑19i=00.95ixt−i. y_t \approx 0.05 \sum_{i=0}^{19} 0.95^i x_{t-i
.

因此,在实际中,我们常常将 yt y_ty
t

看作是对最近 1/(1−β) 1/(1-\beta)1/(1−β) 个时间步的 xt x_tx
t

值的加权平均。例如,当 γ=0.95 \gamma = 0.95γ=0.95 时,yt y_ty
t

可以被看作对最近20个时间步的 xt x_tx
t

值的加权平均;当 β=0.9 \beta = 0.9β=0.9 时,yt y_ty
t

可以看作是对最近10个时间步的 xt x_tx
t

值的加权平均。而且,离当前时间步 t tt 越近的 xt x_tx
t

值获得的权重越大(越接近1)。

由指数加权移动平均理解动量法
现在,我们对动量法的速度变量做变形:

mt←βmt−1+(1−β)(ηt1−βgt). \boldsymbol{m}t \leftarrow \beta \boldsymbol{m}{t-1} + (1 - \beta) \left(\frac{\eta_t}{1 - \beta} \boldsymbol{g}_t\right).

由指数加权移动平均的形式可得,速度变量 vt \boldsymbol{v}tv
t

实际上对序列 {ηt−igt−i/(1−β):i=0,…,1/(1−β)−1} {\eta
{t-i}\boldsymbol{g}_{t-i} /(1-\beta):i=0,\ldots,1/(1-\beta)-1}{η
t−i

g
t−i

/(1−β):i=0,…,1/(1−β)−1} 做了指数加权移动平均。换句话说,相比于小批量随机梯度下降,动量法在每个时间步的自变量更新量近似于将前者对应的最近 1/(1−β) 1/(1-\beta)1/(1−β) 个时间步的更新量做了指数加权移动平均后再除以 1−β 1-\beta1−β。所以,在动量法中,自变量在各个方向上的移动幅度不仅取决当前梯度,还取决于过去的各个梯度在各个方向上是否一致。在本节之前示例的优化问题中,所有梯度在水平方向上为正(向右),而在竖直方向上时正(向上)时负(向下)。这样,我们就可以使用较大的学习率,从而使自变量向最优解更快移动。

Pytorch Class
在Pytorch中,torch.optim.SGD已实现了Momentum。

d2l.train_pytorch_ch7(torch.optim.SGD, {‘lr’: 0.004, ‘momentum’: 0.9},
features, labels)
1
2
当不传入momentum参数时该参数默认为零,即使用SGD。

AdaGrad
AdaGrad算法根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题 。

Algorithm
AdaGrad算法会使用一个小批量随机梯度gt \boldsymbol{g}_tg
t
其中⊙ \odot⊙是按元素相乘。接着,我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下:

xt←xt−1−ηst+ϵ√⊙gt, \boldsymbol{x}t \leftarrow \boldsymbol{x}{t-1} - \frac{\eta}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t,
其中η \etaη是学习率,ϵ \epsilonϵ是为了维持数值稳定性而添加的常数,如10−6 10^{-6}10
−6
。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。

例如当梯度较大(小)时,gt \boldsymbol{g}{t}g
t

就很大(小),从而st \boldsymbol{s}
{t}s
t

很大(小),所以学习率由η \etaη调整为ηst+ϵ√ \frac{\eta}{\sqrt{s_{t}+\epsilon}}

,对应学习率就很小(大)。

Feature
需要强调的是,小批量随机梯度按元素平方的累加变量st \boldsymbol{s}_ts
t

出现在学习率的分母项中。因此,如果目标函数有关自变量中某个元素的偏导数一直都较大,那么该元素的学习率将下降较快;反之,如果目标函数有关自变量中某个元素的偏导数一直都较小,那么该元素的学习率将下降较慢。然而,由于st \boldsymbol{s}_ts
t

一直在累加按元素平方的梯度,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。

Pytorch Class
通过名称为“adagrad”的Trainer实例,我们便可使用Pytorch提供的AdaGrad算法来训练模型。

d2l.train_pytorch_ch7(torch.optim.Adagrad, {‘lr’: 0.1}, features, labels)
1
RMSProp
当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。为了解决这一问题,RMSProp算法对AdaGrad算法做了修改。该算法源自Coursera上的一门课程,即“机器学习的神经网络”。

Algorithm
在“动量法”(momentum)一节里介绍过指数加权移动平均。不同于AdaGrad算法里状态变量st \boldsymbol{s}_ts
t

是截至时间步t tt所有小批量随机梯度gt \boldsymbol{g}_tg
t

按元素平方和,RMSProp算法将这些梯度按元素平方做指数加权移动平均。具体来说,给定超参数0≤γ0 0 \leq \gamma 00≤γ0计算

vt←βvt−1+(1−β)gt⊙gt. \boldsymbol{v}t \leftarrow \beta \boldsymbol{v}{t-1} + (1 - \beta) \boldsymbol{g}_t \odot \boldsymbol{g}_t.
v
以上α \alphaα和β \betaβ均为超参数。

其中η \etaη是学习率,ϵ \epsilonϵ是为了维持数值稳定性而添加的常数,如10−6 10^{-6}10
−6
。因为RMSProp算法的状态变量st \boldsymbol{s}_ts
t

是对平方项gt⊙gt \boldsymbol{g}_t \odot \boldsymbol{g}_tg
t

⊙g
t

的指数加权移动平均,所以可以看作是最近1/(1−β) 1/(1-\beta)1/(1−β)个时间步的小批量随机梯度平方项的加权平均。如此一来,自变量每个元素的学习率在迭代过程中就不再一直降低(或不变)。

Pytorch Class
通过名称为“rmsprop”的Trainer实例,我们便可使用Gluon提供的RMSProp算法来训练模型。注意,超参数γ \gammaγ通过gamma1指定。

d2l.train_pytorch_ch7(torch.optim.RMSprop, {‘lr’: 0.01, ‘alpha’: 0.9},
features, labels)
1
2
可以看到,如不考虑ϵ \epsilonϵ的影响,AdaDelta算法与RMSProp算法的不同之处在于使用Δxt−1−−−−−√ \sqrt{\Delta\boldsymbol{x}_{t-1}}
Δx
t−1


来替代超参数η \etaη。

Implement
AdaDelta算法需要对每个自变量维护两个状态变量,即st \boldsymbol{s}_ts
t

和Δxt \Delta\boldsymbol{x}_tΔx
t

。我们按AdaDelta算法中的公式实现该算法。

Pytorch Class
通过名称为“adadelta”的Trainer实例,我们便可使用pytorch提供的AdaDelta算法。它的超参数可以通过rho来指定。

d2l.train_pytorch_ch7(torch.optim.Adadelta, {‘rho’: 0.9}, features, labels)
1
Adam
Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均 。

Algorithm
Adam算法使用了动量变量mt \boldsymbol{m}_tm
t

和RMSProp算法中小批量随机梯度按元素平方的指数加权移动平均变量vt \boldsymbol{v}_tv
t

,并在时间步0将它们中每个元素初始化为0。给定超参数0≤β1<1 0 \leq \beta_1 < 10≤β
1

<1(算法作者建议设为0.9),时间步t tt的动量变量mt \boldsymbol{m}_tm
t

即小批量随机梯度gt \boldsymbol{g}_tg
t

的指数加权移动平均:

mt←β1mt−1+(1−β1)gt. \boldsymbol{m}t \leftarrow \beta_1 \boldsymbol{m}{t-1} + (1 - \beta_1) \boldsymbol{g}_t.

。需要注意的是,当t tt较小时,过去各时间步小批量随机梯度权值之和会较小。例如,当β1=0.9 \beta_1 = 0.9β
1

=0.9时,m1=0.1g1 \boldsymbol{m}_1 = 0.1\boldsymbol{g}_1m
1
。为了消除这样的影响,对于任意时间步t tt,我们可以将mt \boldsymbol{m}_tm
t

再除以1−βt1 1 - \beta_1^t1−β
1
t

,从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。在Adam算法中,我们对变量mt \boldsymbol{m}_tm
t

和vt \boldsymbol{v}_tv
t
Implement
我们按照Adam算法中的公式实现该算法。其中时间步t tt通过hyperparams参数传入adam函数。

Pytorch Class
d2l.train_pytorch_ch7(torch.optim.Adam, {‘lr’: 0.01}, features, labels)
1
word2vec
二次采样
文本数据中一般会出现一些高频词,如英文中的“the”“a”和“in”。通常来说,在一个背景窗口中,一个词(如“chip”)和较低频词(如“microprocessor”)同时出现比和较高频词(如“the”)同时出现对训练词嵌入模型更有益。因此,训练词嵌入模型时可以对词进行二次采样。 具体来说,数据集中每个被索引词 wi w_iw
i

将有一定概率被丢弃,该丢弃概率为

P(wi)=max(1−tf(wi)−−−−√,0) P(w_i)=\max(1-\sqrt{\frac{t}{f(w_i)}},0)
P(w
i

)>t 时,我们才有可能在二次采样中丢弃词 wi w_iw
i

,并且越高频的词被丢弃的概率越大。

Skip-Gram 模型的前向计算
def skip_gram(center, contexts_and_negatives, embed_v, embed_u):
‘’’
@params:
center: 中心词下标,形状为 (n, 1) 的整数张量
contexts_and_negatives: 背景词和噪音词下标,形状为 (n, m) 的整数张量
embed_v: 中心词的 embedding 层
embed_u: 背景词的 embedding 层
@return:
pred: 中心词与背景词(或噪音词)的内积,之后可用于计算概率 p(w_o|w_c)
‘’’
v = embed_v(center) # shape of (n, 1, d)
u = embed_u(contexts_and_negatives) # shape of (n, m, d)
pred = torch.bmm(v, u.permute(0, 2, 1)) # bmm((n, 1, d), (n, d, m)) => shape of (n, 1, m)
ret 近似
由于 softmax 运算考虑了背景词可能是词典 V \mathcal{V}V 中的任一词,对于含几十万或上百万词的较大词典,就可能导致计算的开销过大。我们将以 skip-gram 模型为例,介绍负采样 (negative sampling) 的实现来尝试解决这个问题。

负采样方法用以下公式来近似条件概率 P(wo∣wc)=exp(u⊤ovc)∑i∈Vexp(u⊤ivc) P(w_o\mid w_c)=\frac{\exp(\boldsymbol{u}_o^\top \boldsymbol{v}c)}{\sum{i\in\mathcal{V}}\exp(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}P(w
o

词嵌入进阶
在“Word2Vec的实现”一节中,我们在小规模数据集上训练了一个 Word2Vec 词嵌入模型,并通过词向量的余弦相似度搜索近义词。虽然 Word2Vec 已经能够成功地将离散的单词转换为连续的词向量,并能一定程度上地保存词与词之间的近似关系,但 Word2Vec 模型仍不是完美的,它还可以被进一步地改进:

子词嵌入(subword embedding):FastText 以固定大小的 n-gram 形式将单词更细致地表示为了子词的集合,而 BPE (byte pair encoding) 算法则能根据语料库的统计信息,自动且动态地生成高频子词的集合;
GloVe 全局向量的词嵌入: 通过等价转换 Word2Vec 模型的条件概率公式,我们可以得到一个全局的损失函数表达,并在此基础上进一步优化模型。
实际中,我们常常在大规模的语料上训练这些词嵌入模型,并将预训练得到的词向量应用到下游的自然语言处理任务中。本节就将以 GloVe 模型为例,演示如何用预训练好的词向量来求近义词和类比词。

GloVe 全局向量的词嵌入
GloVe 模型
先简单回顾以下 Word2Vec 的损失函数(以 Skip-Gram 模型为例,不考虑负采样近似):

−∑Tt=1∑−m≤j≤m,j≠0logP(w(t+j)∣w(t)) -\sum_{t=1}^T\sum_{-m\le j\le m,j\ne 0} \log P(w^{(t+j)}\mid w^{(t)})

线性相关的隐含假设;
用平方损失函数替代了交叉熵损失函数。
综上,我们获得了 GloVe 模型的损失函数表达式:
∑i∈V∑j∈Vh(xij)(u⊤jvi+bi+cj−logxij)2 \sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} h(x_{ij}) (\boldsymbol{u}^\top_j\boldsymbol{v}i+b_i+c_j-\log x{ij})^2
i∈V

由于这些非零 xij x_{ij}x
ij

是预先基于整个数据集计算得到的,包含了数据集的全局统计信息,因此 GloVe 模型的命名取“全局向量”(Global Vectors)之意。

载入预训练的 GloVe 向量
GloVe 官方 提供了多种规格的预训练词向量,语料库分别采用了维基百科、CommonCrawl和推特等,语料库中词语总数也涵盖了从60亿到8,400亿的不同规模,同时还提供了多种词向量维度供下游模型使用。

torchtext.vocab 中已经支持了 GloVe, FastText, CharNGram 等常用的预训练词向量,我们可以通过声明 torchtext.vocab.GloVe 类的实例来加载预训练好的 GloVe 词向量。

求类比词
除了求近义词以外,我们还可以使用预训练词向量求词与词之间的类比关系,例如“man”之于“woman”相当于“son”之于“daughter”。求类比词问题可以定义为:对于类比关系中的4个词“a aa 之于 b bb 相当于 c cc 之于 d dd”,给定前3个词 a,b,c a,b,ca,b,c 求 d dd。求类比词的思路是,搜索与 vec©+vec(b)−vec(a) \text{vec}©+\text{vec}(b)−\text{vec}(a)vec©+vec(b)−vec(a) 的结果向量最相似的词向量,其中 vec(w) \text{vec}(w)vec(w) 为 w ww 的词向量。

发布了8 篇原创文章 · 获赞 0 · 访问量 244

猜你喜欢

转载自blog.csdn.net/loveheart123/article/details/104506447