精华内容
下载资源
问答
  • 支持向量机SVM、支持向量回归SVR详细推导

    万次阅读 多人点赞 2019-06-30 09:31:52
    文章详细介绍了支持向量机SVM及其拓展,支持向量回归SVR.并从线性分类和非线性分类的角度出发,详细推导了硬间隔、软间隔和核函数的支持向量机。

    目录


    一、SVM简介

    简介:SVM的英文全称是Support Vector Machines,中文叫支持向量机。支持向量机是我们用于分类的一种算法。支持向量也可以用于回归,此时叫支持向量回归(Support Vector Regression,简称SVR)。

    发展历史:1963年,ATE-T Bell实验室研究小组在Vanpik的领导下,首次提出了支持向量机(SVM)理论方法。但在当时,SVM在数学上不能明晰地表示,人们对模式识别问题的研究很不完善,因此SVM的研究没有得到进一步的发展与重视。 1971年,Kimeldorf提出了使用线性不等约束重新构造SV的核空间,使一部分线性不可分的问题得到了解决。20世纪90年代,一个比较完善的理论体系——统计学习理论(Statistical Learning Theory,SLT)形成了,此时一些新兴的机器学习方法(如神经网络等)的研究遇到了一些重大的困难,比如欠学习与过学习问题、如何确定网络结构的问题、局部极小点问题等,这两方面的因素使得SVM迅速发展和完善,并在很多问题的解决中表现出许多特有优势,而且能够推广应用到函数拟合等其他机器学习问题中,从此迅速发展了起来,目前已经成功地在许多领域里得到了成功应用。

    思想:SVM的主要思想可以概括为如下两点:
    (1)它是针对线性可分的情况进行分析的。对于线性不可分的情况,通过使用非线性映射算法将低维输入空间线性不可分的样本转化为高维特征空间,使其线性可分,从而使得在高维特征空间中采用线性算法对样本的非线性特征进行线性分析成为可能。
    (2)它基于结构风险最小化理论,在特征空间中构建最优分类面,使得学习器能够得到全局最优化,并且使整个样本空间的期望风险以某个概率满足一定上界。
      从上面的两点基本思想来看,SVM没有使用传统的推导过程,简化了通常的分类和回归等问题;少数的支持向量确定了SVM 的最终决策函数,计算的复杂性取决于支持向量,而不是整个样本空间,这就可以避免“维数灾难”。少数支持向量决定了最终结果,这不但可以帮助我们抓住关键样本,而且注定了该方法不但算法简单,而且具有较好的“鲁棒”性。

    数学基础:拉格朗日乘子法、对偶问题、KKT条件

    应用:人脸检测、验证和识别,说话人/语音识别,文字/手写体识别 ,图像处理等等

    二、推导过程

    SVM有三宝:间隔、对偶、核技巧。
    遇到的问题大致可以分为线性可分和线性不可分的情况,因此,我将分开介绍:

    1.线性可分

    1.1 硬间隔

    1. 基本模型

    训练样本集 D = { ( x 1 , y 1 ) , ( x 1 , y 1 ) , … … , ( x m , y m ) } , y i = 1 或 y i = − 1 D=\{(x_{1},y_{1}),(x_{1},y_{1}),……,(x_{m},y_{m})\},y_{i}=1或y_{i}=-1 D={(x1,y1),(x1,y1),(xm,ym)},yi=1yi=1,分类学习的思想:找一个划分超平面,将不同类别的样本分开。

    在这里插入图片描述
    划分的超平面很多,我们去找哪一个?直观上看,我们应该找位于两类训练样本“正中间”的超平面。

    在样本空间中,划分超平面可通过如下线性方程来描述: w T x + b = 0 {\color{Red} w^{T}x+b=0} wTx+b=0
    w = ( w 1 ; w 2 ; … ; w d ) w=(w_{1};w_{2};…;w_{d}) w=(w1;w2;;wd)为法向量,决定了超平面的方向;b为位移项,决定了超平面与原点之间的距离。
    显然,划分超平面可被法向量w和位移b确定,下面我们将其记为(w,b)。 样本空间中任意点x到超平面(w,b)的距离可写为 r = ∣ w T x + b ∣ ∥ w ∥ {\color{Red} r=\frac{\left | w^{T}x+b \right |}{\left \| w \right \|}} r=wwTx+b
    假设超平面(w,b)能将训练样本正确分类,即对 ( x i , y i ) ∈ D (x_{i},y_{i} )\in D (xi,yi)D,若 y i = + 1 y_{i}=+1 yi=+1,则 w T x i + b &gt; 0 w^{T}x_{i}+b&gt;0 wTxi+b>0.否则: w T x i + b &lt; 0 w^{T}x_{i}+b&lt;0 wTxi+b<0,令
    在这里插入图片描述
    对应如下:
    在这里插入图片描述
    问题只与投影方向有关,一旦方向定了,通过缩放w和b,总能使上式成立。所以,求超平面的问题转化为求w和b的问题。

    如下图所示,距离超平面最近的这几个训练样本点使上式的等号成立,它们被称为“支持向量”(support vector),两个异类支持向量机到超平面的距离之和为 : r = ∣ w T x + b ∣ ∥ w ∥ {\color{Red} r=\frac{\left | w^{T}x+b \right |}{\left \| w \right \|}} r=wwTx+b
    在这里插入图片描述
    上图中,两条虚线之间的距离为: γ = 2 ∥ w ∥ \gamma =\frac{2}{\left \| w \right \|} γ=w2,将其称之为间隔。欲找到具有“最大间隔”(maximum margin)的划分超平面,也就是找到参数w和b,使得γ最大,即:
    在这里插入图片描述
    上面的约束等价于如下约束:
    在这里插入图片描述
    即支持向量机(Support Vector Machine,简称SVM)的基本型。

    2. 模型求解

    上式中,其中w和b是模型参数。注意到上式本身是一个凸二次规划问题,能直接用现成的优化计算包求解,但我们可以有更高效的办法,可以求出闭式解。
    对式使用拉格朗日乘子法可得到其“对偶问题”(dual problem):
    在这里插入图片描述
    其中 α = ( α 1 ; α 2 ; … ; α m ) \alpha =(\alpha _{1};\alpha _{2};…;\alpha _{m}) α=(α1;α2;;αm),令 L ( w , b , α ) L(w,b,\alpha) L(w,b,α)对w和b的偏导数等于零得:
    在这里插入图片描述
    将第一个式代入L,即可将 L ( w , b , α ) L(w,b,α) L(w,b,α)中的w和b消去,再考虑第二个式的约束,就得到对偶问题:
    在这里插入图片描述
    解出α后,求出w和b即可得到模型:
    在这里插入图片描述
    从对偶问题解出的 α i α_i αi是拉格朗日乘子,它恰对应着训练样本 ( x i , y i ) (x_i,y_i) (xi,yi)。注意到支持向量机最优化问题中有不等式约束,因此上述过程需满足KKT条件,即要求:
    在这里插入图片描述
    最后一个条件,对任意训练样本 ( x i , y i ) (x_i,y_i) (xi,yi),总有 α i = 0 \alpha _{i}=0 αi=0 y i f ( x i ) = 1 y_{i}f(x_{i})=1 yif(xi)=1.
    则有以下两种情况:
    (1) 若 α i = 0 α_i=0 αi=0,则该样本将不会在求和中出现,不会对f(x)有任何影响;
    (2) 若 α i &gt; 0 α_i&gt;0 αi>0,则必有 y i f ( x i ) = 1 y_i f(x_i )=1 yif(xi)=1,位于最大间隔边界上,是一个支持向量。
    在这里插入图片描述
    这显示出支持向量机的一个重要性质:训练完成后,大部分的训练样本都不需保留,最终模型仅与支持向量有关.

    如何求解 α i α_i αi:二次规划问题,通过SMO算法求解。
    基本思路:每次选择两个变量α_i和α_j,并固定其他参数。这样,在参数初始化后,SMO不断执行如下两个步骤直至收敛:
    (1) 选取一对需更新的变量 α i α_i αi α j α_j αj
    (2) 固定 α i α_i αi α j α_j αj以外的参数,求解式获得更新后的 α i α_i αi α j α_j αj.

    分析:KKT条件违背的程度越大,则变量更新后可能导致的且标函数值减幅越大。
    第一个变量:SMO先选取违背KKT条件程度最大的变量。
    第二个变量:应选择一个使且标函数值减小最快的变量,使选取的两变量所对应样本之间的间隔最大。

    为什么更新两个,而非一个?原因是,若仅选择一个,则其可有其他变量导出。因此更新两个。
    在这里插入图片描述
    SMO算法之所以高效,是由于在固定其他参数后,仅优化两个参数的过程能做到非常高效
    之前的优化问题:
    在这里插入图片描述
    仅考虑 α i α_i αi α j α_j αj时,式中的约束可重写为:
    在这里插入图片描述
    其中c是使 ∑ i = 0 m α i y i = 0 ∑_{i=0}^mα_i y_i=0 i=0mαiyi=0成立的常数。用 α i y i + α j y j = c α_i y_i+α_j y_j=c αiyi+αjyj=c消去上式中的变量 α j α_j αj,则得到一个关于 α i α_i αi的单变量二次规划问题,仅有的约束是 α i ≥ 0 α_i≥0 αi0
    不难发现,这样的二次规划问题具有闭式解,于是不必调用数值优化算法即可高效地计算出更新后的 α i α_i αi α j α_j αj.

    确定偏移项b
    対任意支持向量 ( x i , y k ) (x_i,y_k) (xi,yk) 都有 y s f ( x s ) = 1 y_s f(x_s )=1 ysf(xs)=1,即
    在这里插入图片描述
    其中 S = { i ∣ α i &gt; 0 , i = 1 , 2 , … , m } S=\{i|α_{i}&gt;0,i=1,2,…,m\} S={iαi>0,i=1,2,,m} 为所有支持向量的下标集,但现实任务中常采用一种更鲁棒的做法:使用所有支持向量求解的平均值
    在这里插入图片描述

    1.2 软间隔

    在现实任务中往往很难确定合适的核函数使得训练样本在特征空间中线性可分。
    缓解该问题的一个办法是允许支持向量机在一-些样本上出错.为此,要引入“软间隔”的概念,如图所示:
    在这里插入图片描述
    在最大化间隔的同时,不满足约束的样本应尽可能少.于是,优化目标可写为:
    在这里插入图片描述
    即,在间隔上加一个损失,允许错分,但是损失应该尽量小。

    (1)0/1损失函数
    在这里插入图片描述
    显然,当C为无穷大时,迫使所有样本均满足约束,于是等价于经典支持向量机方法;
    当C取有限值时,允许一些样本不满足约束。
    然而, l 0 / 1 l_{0/1} l0/1非凸、非连续,不易直接求解。人们通常用其他一些函数来代替 l 0 / 1 l_{0/1} l0/1,称为“替代损失”(surrogate loss),通常是凸的连续函数且是 l 0 / 1 l_{0/1} l0/1的上界。

    (2)hinge损失函数
    若采用hinge损失,则代价函数变成:
    在这里插入图片描述
    引入“松弛变量”(slack variables) ξ i ≥ 0 ξ_i≥0 ξi0,可将重写为:
    在这里插入图片描述
    这就是常用的“软间隔支持向量机”。
    (3)其他损失函数

    在这里插入图片描述
    损失函数:
    在这里插入图片描述
    标准:>0时,尽可能小,<0时,尽可能大。从而保证分类的准确性。

    2.线性不可分(核函数)

    我们假设训练样本是线性可分的,超平面能将训练样本正确分类。然而在现实任务中,原始样本空间内也许并不存在一个能正确划分两类样本的超平面。例如图中的“异或”问题就不是线性可分的.
    在这里插入图片描述
    对这样的问题,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分。

    例如在图中,若将原始的二维空间映射到一个合适的三维空间,就能找到一个合适的划分超平面。
    在这里插入图片描述
    如何映射?有没有通用的办法?

    幸运的是,如果原始空间是有限维,即属性数有限,那么一定存在一个高维特征空间使样本可分。 令∅(x)表示将x映射后的特征向量,于是,在特征空间中划分超平面所对应的模型可表示为:
    在这里插入图片描述
    其中w和b是模型参数。
    问题转化为:
    在这里插入图片描述
    其对偶问题是:
    在这里插入图片描述
    求解式涉及到计算 ϕ ( x i ) T ϕ ( x j ) ϕ(x_i )^T ϕ(x_j ) ϕ(xi)Tϕ(xj),这是样本 x i x_i xi x j x_j xj映射到特征空间之后的内积。
    由于特征空间维数可能很高,甚至可能是无穷维,因此直接计算 ϕ ( x i ) T ϕ ( x j ) ϕ(x_i )^T ϕ(x_j ) ϕ(xi)Tϕ(xj)通常是困难的。
    为了避开这个障碍,可以设想这样一个函数:
    在这里插入图片描述
    x i x_i xi x j x_j xj在特征空间的内积等于它们在原始样本空间中通过函数κ(∙,∙ )计算的结果。

    有了这样的函数,我们就不必直接去计算高维甚至无穷维特征空间中的内积。

    于是式可重写为:
    在这里插入图片描述
    于是,求解后即可得到:
    在这里插入图片描述
    这里的函数κ(∙,∙ )就是“核函数”(kernel function)。上式显示出模型最优解可通过训练样本的核函数展开,这一展式亦称“支持向量展式”(support vector expansion)。

    问题:显然,若已知合适映射ϕ(∙)的具体形式,则可写出核函数κ(∙,∙ ),但在现实任务中我们通常不知道ϕ(∙)是什么形式。

    合适的核函数是否一定存在呢?什么样的函数能做核函数呢?
    答案是肯定的。

    定理(核函数) 令χ为输入空间,κ(∙,∙ )是定义在 χ × χ χ×χ χ×χ上的对称函数,则κ是核函数当且仅当对于任意数据 D = { x 1 , x 2 , … , x m } D=\{x_{1},x_{2},…,x_{m}\} D={x1,x2,,xm},“核矩阵”(kernel matrix)K总是半正定的:
    在这里插入图片描述
    定理表明,只要一个对称函数所对应的核矩阵半正定,它就能作为核函数使用。

    在不知道特征映射的形式时,我们并不知道什么样的核函数是合适的,“核函数选择”成为支持向量机的最大变数。

    通常,可选择如下核函数,选择性能最优者作为某一问题的核函数:
    在这里插入图片描述
    注意:当d=1时,高斯核也成为径向基核函数(RBF)核。

    此外,还可通过函数组合得到,例如:
    (1) 若κ_1和κ_2为核函数,则对于任意正数 γ 1 、 γ 2 γ_1、γ_2 γ1γ2,其线性组合也是核函数:
    γ 1 κ 1 + γ 2 κ 2 γ_1 κ_1+γ_2 κ_2 γ1κ1+γ2κ2

    (2) 若κ_1和κ_2为核函数,则核函数的直积也是核函数;
    κ 1 ⊗ κ 2 ( x , z ) = κ 1 ( x , z ) κ 2 ( x , z ) κ_1 ⊗κ_2 (x,z)=κ_1 ( x,z)κ_2 (x,z) κ1κ2(x,z)=κ1(x,z)κ2(x,z)

    (3) 若κ_1为核函数,则对于任意函数g(x),也是核函数;
    κ ( x , z ) = g ( x ) κ 1 ( x , z ) g ( z ) κ(x,z)=g(x)κ_1 (x,z)g (z) κ(x,z)=g(x)κ1(x,z)g(z)

    3.SVR支持向量回归

    给定训练样本 D = { ( x 1 , y 1 ) , ( x 1 , y 1 ) , … … , ( x m , y m ) } , y i ∈ R D=\{(x_{1},y_{1}),(x_{1},y_{1}),……,(x_{m},y_{m})\},y_{i}∈R D={(x1,y1),(x1,y1),(xm,ym)},yiR,希望学得一个回归模型,使得 f ( x ) f(x) f(x) y y y尽可能接近, w w w b b b是待确定的模型参数。
    在这里插入图片描述
    假设我们能容忍 f ( x ) f(x) f(x) y y y之间最多有 ϵ ϵ ϵ的偏差,即仅当 f ( x ) f(x) f(x) y y y之间的差别绝对值大于 ϵ ϵ ϵ时才计算损失.

    于是,SVR问题可形式化为:
    在这里插入图片描述
    其中C为正则化常数, l ϵ l_ϵ lϵ是图中所示的ϵ -不敏感损失(ϵ -insensitive loss)函数:
    在这里插入图片描述
    引入松弛变量 ξ i ξ_i ξi ( ξ i ) (ξ_i ) (ξi),可将式重写为:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190630091142826.png
    在这里插入图片描述
    引入拉格朗日乘子 μ i μ_i μi
    在这里插入图片描述
    再令 L ( w , b , α , α ^ , ξ , ξ ^ , μ , μ ^ ) L(w,b,\alpha ,\hat{\alpha },\xi ,\hat{\xi },\mu ,\hat{\mu }) L(w,b,α,α^,ξ,ξ^,μ,μ^) w w w b b b ξ i ξ_i ξi ξ i ^ \hat{ξ_i } ξi^ 的偏导为零可得:
    在这里插入图片描述
    上述过程中需满足KKT条件,即要求:
    在这里插入图片描述
    SVR的解形如
    在这里插入图片描述
    能使式中的 ( α i ^ − α i ) ≠ 0 (\hat{\alpha_i}-α_i )\neq 0 (αi^αi)̸=0的样本即为SVR的支持向量,它付必落在ϵ-同隔带之外.显然, SVR的支持向量仅是训练样本的一部分,即其解仍具有稀疏性.

    0 &lt; α i &lt; C 0&lt;α_i&lt;C 0<αi<C,则必有 ξ i = 0 ξ_i=0 ξi=0
    在这里插入图片描述
    实践中常采用一中更鲁棒的办法:迭取多个满足条件 0 &lt; α i &lt; C 0&lt;α_i&lt;C 0<αi<C的样本求解b后取平均値。

    若考虑特征映射形式,则:
    在这里插入图片描述
    则SVR可表示为:
    在这里插入图片描述
    其中 K ( x i T x ) = ∅ ( x i ) T ∅ ( x j ) K(x_i^T x)=∅(x_i )^T∅(x_j ) K(xiTx)=(xi)T(xj)为核函数。

    展开全文
  • python利用支持向量机SVM进行时间序列预测, 包括数据和python代码 python利用支持向量机SVM进行时间序列预测, 包括数据和python代码
  • 矩阵、向量求导法则

    2018-09-12 14:28:52
    该文档总结了矩阵对矩阵、矩阵对向量向量对矩阵、向量向量、元素对矩阵、元素对向量的求导法则,非常有用!
  • 1. 向量、矩阵对元素求导 2 1.1 行向量对元素求导 2 1.2 列向量对元素求导 2 1.3 矩阵对元素求导 2 2. 元素对向量、矩阵求导 3 2.1 元素对行向量求导 3 2.2 元素对列向量求导 3 2.3 元素对矩阵求导 3 3. 向量向量...
  • 支持向量机matlab代码

    2018-08-15 15:20:15
    支持向量机svm代码 matlab代码 用于分类的 比传统bp神经网络好
  • 支持向量机导论中文版PDF(李国正 王猛 曾华君译) 带书签 支持向量机符号说明,学习方法,线性回归,核函数等
  • 向量空间模型的Java代码
  • 用粒子群算法优化支持向量机的matlab程序,用于对股价、经济的预测作用,优化后预测精确
  • 基于matlab的svm预测 代码
  • 支持向量机(SVM)是深度学习的基础。本视频课程主要讲解机器学习之支持向量机的主要知识点。本课程包括:间隔与支持向量,对偶问题,核函数,软间隔与正则化,支持向量回归,核方法等知识点。
  • 该资源主要参考我的博客:word2vec词向量训练及中文文本相似度计算 http://blog.csdn.net/eastmount/article/details/50637476 其中包括C语言的Word2vec源代码(从官网下载),自定义爬取的三大百科(百度百科、互动...
  • 向量算法

    千次阅读 2019-06-05 22:31:07
    https://www.cnblogs.com/the-wolf-sky/articles/10192363.html...基于神经网络的表示一般称为词向量、词嵌入(word embdding)或分布式表示。 神经网络的词向量和其他分布式类似,都基于分布式表达方式,核心依然是上...

    https://www.cnblogs.com/the-wolf-sky/articles/10192363.html

    https://blog.csdn.net/weixin_37947156/article/details/83146141

    基于神经网络的表示一般称为词向量、词嵌入(word embdding)或分布式表示。

    神经网络的词向量和其他分布式类似,都基于分布式表达方式,核心依然是上下文的表示以及上下文与目标词之间的关系映射。主要通过神经网络对上下文,以及上下文和目标词之间的关系进行建模,之所以神经网络可以进行建模,主要是由于神经网络的空间非常大,所以这种方法可以表达复杂的上下文关系。

    1. 词向量
      nlp中最常见的第一步是创建一个词表库并把每个词顺序编号,one-hot表达就是一种。这种方法把每个词顺序编号,但每个词就变成一个很长的向量,向量的维度就是词表的大小,只有对应位置上的数字为1,其他都为0。这种方式的弊病是很显然的,就是无法捕捉到词与词之间的相似度,也称为“语义鸿沟“。one-hot的基本假设是词与词之间的语义和语法关系是相互独立的,仅仅靠两个向量是无法看出两个词之间的关系的。其次,维度爆炸问题也是one-hot表达方法的很大的一个问题,随着词典的规模的增大,句子构成的词袋模型的维度变得越来越大,矩阵也变得越稀疏。所以此时构建上下文与目标词之间的关系,最为理想的方式是使用语言模型。

    分布式表示的基本细想是通过训练将每个词映射成k维实数向量(k一般为模型中的超参数),然后通过词之间的距离来判断它们之间的语义相似度。而word2vec使用的就是这种分布式表示的词向量表示方式。

    1. 词向量模型
      词向量模型是基于假设:衡量词之间的相似性,在于其相邻词汇是否相识,这是基于语言学的“距离相似性“原理。词汇和它的上下文构成一个象,当从语料库当中学习到相识或相近的象时,他们在语义上总是相识的。
      而典型的就是word2vec了,它可以分为CBOW(continuous bag-of-words 连续的词袋模型)和skip-gram两种。word2vec通过训练,可以把对文本内容的处理简化为k维向量空间中的向量运算,而向量空间上的相似度可以用来表示文本语义上的相似度,因此word2vec输出的词向量是一个基础性的工作,比如聚类、同义词、词性分析等。还有一个word2vec被广泛使用的原因是其向量的加法组合和高效性。

    2.1 NNLM模型
    关于该模型的介绍可以参考:https://blog.csdn.net/lilong117194/article/details/82018008
    这里需要注意的是整个网络分为两部分:

    第一部分是利用词特征矩阵C获得词的分布式表示(即词嵌入)。
    第二部分是将表示context的n个词的词嵌入拼接起来,通过一个隐藏层和一个输出层,最后通过softmax输出当前的p(wt|context)(当前上下文语义的概率分布,最大化要预测的那个词的概率,就可以训练此模型)。
    第一部分词嵌入的获取如下图所示:
    在这里插入图片描述
    这里可以看到最初的输如其实是词的one-hot表示,而这里的中间的w矩阵就是c矩阵。

    其中第i行对应的是one-hot表示中第i项为1的词向量的词嵌入。词向量与矩阵相乘后就可以得到自己的词嵌入了。由于C是神经网络的参数,所以词的词嵌入会随着模型的训练不断得到优化。

    在网络的第二部分中,表示context的n个词嵌入通过隐藏层进行语义组合,最后经过输出层使用softmax输出预测的词向量,因为本模型是基于n-gram模型,所以只要最大化正确预测当前词即可。最后不但训练了一个用神经网络表示的语言模型,而且还获得了词语的词嵌入(存在矩阵C中)

    从第二部分的输入到输出层有一个直连边,一般情况下该直连边的权重矩阵可以设为0,在最后的实验中,Bengio 发现直连边虽然不能提升模型效果,但是可以少一半的迭代次数。同时他也猜想如果没有直连边,可能可以生成更好的词向量。

    nnlm模型的其他细节可以参考上面的连接。

    2.2 C&W模型
    首先要明确:nnlm模型的目标是构建一个语言概率模型,而C&W模型则是以生成词向量为目的模型。
    在nnlm中最废时间的是隐藏层到输出层的权重计算。由于C&W模型没有采用语言模型的方式求解词语上下文的条件概率,而是直接对n元短语打分,这是一种更快速获取词向量的方式。
    而其简单来讲就是:如果n元短语在语料库中出现过,那么模型会给该短语打高分;如果是未出现在语料库中的短语则会得到较低的评分。
    优化的目标函数是:∑(w,c)∈D∑w′∈Vmax(0,1−score(w,c)+score(w′,c))∑(w,c)∈D∑w′∈Vmax(0,1−score(w,c)+score(w′,c))
    其中(w,c)(w,c)为 语料库中抽取的n元短语,为保证上下文词数的一致性,n为奇数。
    其中ww是目标词,c是目标词的上下文语境
    其中w′w′是从词典中随机抽取的一个词语。

    C&W模型采用的是成对的词语方式对目标函数进行优化。这里(w,c)表示正样本,(w’,c)表示负样本,负样本是将正样本序列中的中间词替换为其他词得到的。一般而言,如果用一个随机的词语替代正确文本序列的中间词,得到的新的文本序列基本上都是不符合语法习惯的错误序列,这种构造负样本的方法是合理的。同时由于负样本仅仅修改了正样本的一个词得到的,故其基本的语境没有改变,因此不会对分类效果造成太大的影响。

    与nnlm模型的目标词所在输出层不同,C&W模型的输入层就包含了目标词,其输出层也变为了一个节点,该节点输出值的大小就代表n元短语的打分高低。相应的,C&W模型的最后一层运算次数是|h|,远低于nnlm的|v|x|h|次。

    C&W模型设计了2个网络来完成词性标注 (POS)、短语识别(CHUNK)、命名实体识别(NER) 和语义角色标注 (SRL)这些nlp任务。其中一个模型叫window approach,另一个叫sentence approach。其中词嵌入的预训练用的是window approach,只是把输出层的神经原个数改成了1个,window approach网络结构见下图
    在这里插入图片描述
    其中,窗口大小为n,中心的那个词为中心词,上下文各(n-1)/2个词。作者利用该模型以无监督的方法预训练词嵌入来提高在具体工作上的效果,最后的输出层只有一个神经元,表示该中心词与上下文语义关联程度的得分。得分高则说明该中心词在当前位置是符合上下文语义的,得分低则说明该中心词在当前位置不符合上下文语义。

    2.3 CBOW模型
    上面说多的nnlm模型以训练语言模型为目标,同时得到了词表示。而word2vec包含了CBOW和Skip-gram两个得到词向量为目标的模型。
    这里要注意的地方是:CBOW和Skip-gram模型当中,目标词wtwt是一个词串联的词,也即是该词是在一句话的中间某个词,并拥有上下文。而nnlm的wtwt是最后一个词,并作为要预测的词。

    在这里插入图片描述
    由图可知,该模型使用一段文本的的中间词作为目标词,同时cbow模型去掉了隐藏层,大大提高了预运算速度,也因此其输入层就是语义上下文的表示。此外cbow模型,使用上下文各词的词向量的平均值替代nnlm模型各个拼接的词向量。

    整体流程:
    首先明确输入是周围词的词向量,而输出则是当前词的词向量,也就是通过上下文来预测当前的词。
    CBOW包含了输入层、投影层、以及输出层(没有隐藏层)。其运算流程如下:

    随机生成一个所有单词的词向量矩阵,每一个行对应一个单词的向量
    对于某一个单词(中心词),从矩阵中提取其周边单词的词向量
    求周边单词的的词向量的均值向量
    在该均值向量上使用logistic regression 进行训练,softmax作为激活函数
    期望回归得到的概率向量可以与真实的概率向量(即中心词的one-hot编码向量)相匹配
    在这里插入图片描述
    2.4 Skip-gram模型
    Skip-gram模型的结构如下:
    在这里插入图片描述

    由图可知, Skip-gram模型同样没有隐藏层,但与CBOW模型的输入上下文词的平均向量不同, Skip-gram模型是从目标词w的上下文中选择一个词,将其词向量组成上下文的表示。
    Skip-gram模型的目标函数:
    max(∑(w,c)∈D∑wj∈clogP(w|wj))max(∑(w,c)∈D∑wj∈clogP(w|wj))
    2.5 CBOW和Skip-gram模型的对比
    其中CBOW是周围的词预测中间的词,最大化对w(t)的预测。Skip-gram是中间的词预测周围的词,最大化对w(t-2),w(t-1),w(t+1),w(t+2)的预测之和。由于没有隐藏层,所以2个网络都是线性模型。正因为如此,模型的训练时间比较短,只花了一天就训练了16亿单词的语料。且获得的词嵌入质量很好,还具有“king”-“man”+“women”=“queen”的语义规律。

    论文中使用了两种训练方法,一种是哈夫曼树结构的Hierarchical Softmax,另一种是Negative Sampling,它们的使用都是为了缩短训练时间。由于这两个技术这是加快训练的技术,不是网络结构。
    不过正是这2个技术的运用缩短了训练时间(另外一个缩短时间的原因是删掉隐藏层),使其更快地生成了质量好的词嵌入,值得重视。
    在这里插入图片描述

    网络对比:
    对比上面介绍的模型我们发现,后面的模型都是以NNLM为基础进行修改的。其中主要修改有3个部分:输入层,隐藏层,输出层。其中输入层是存储词嵌入的层,隐藏层是做语义重组的层,输出层是根据目标构造输出语义的层。
    以NNLM作为对比对象。后面几个模型的修改情况如下:

    C&W:修改了输入和输出层
    CBOW :去除了隐藏层,输出层优化
    skip-gram:去除了隐藏层,修改了输入层,输出层优化
    根据上面的对比,总结一下:

    对与每个模型来说,输入是上下文,输出是预测,这些模型的核心是用上下文做预测。
    C&W只是为了具体任务来做词嵌入的预训练,所以它把要预测的和上下文放在一起,以得分的形式进行判断,最大化正例和反例的得分差。
    CBOW没有隐藏层,直接叠加构造语义输出,或许正是如此所以训练的词嵌入具有线性语义特征。其当前的预测是作为上下文语义的词嵌入的线性叠加。

    Skip-gram以一个单词作为上下文,多次预测周围的词。它的成功是否表明预测是可逆的,即A可预测B,则B可预测A,而其根本原因是A与B具有相似语义。而这种相似的产生是因为模型没有隐藏层,只有线性变换?

    在这里插入图片描述

    3.ELMo–动态词向量
    ELMo官网:https://allennlp.org/elmo

    艾伦研究所开发,并于6月初在NAACL 2018年发布ELMo(深度语境化的单词表示)。

    ELMO(Embeddings from Language Models) ,被称为时下最好的通用词和句子嵌入方法,来自于语言模型的词向量表示,也是利用了深度上下文单词表征,该模型的优势:
    (1)能够处理单词用法中的复杂特性(比如句法和语义)
    (2)这些用法在不同的语言上下文中如何变化(比如为词的多义性建模)

    ELMo与word2vec最大的不同:
    Contextual: The representation for each word depends on the entire context in which it is used. 
    (即词向量不是一成不变的,而是根据上下文而随时变化,这与word2vec或者glove具有很大的区别)

    举个例子:针对某一词多义的词汇w=“苹果”
    文本序列1=“我 买了 六斤 苹果。”
    文本序列2=“我 买了一个 苹果 7。”
    上面两个文本序列中都出现了“苹果”这个词汇,但是在不同的句子中,它们我的含义显示是不同的,一个属于水果领域,一个属于电子产品呢领域,如果针对“苹果”这个词汇同时训练两个词向量来分别刻画不同领域的信息呢?答案就是使用ELMo。

    ELMo是双向语言模型biLM的多层表示的组合,基于大量文本,ELMo模型是从深层的双向语言模型(deep bidirectional language model)中的内部状态(internal state)学习而来的,而这些词向量很容易加入到QA、文本对齐、文本分类等模型中,后面会展示一下ELMo词向量在各个任务上的表现。
    在这里插入图片描述

    它首先在大文本语料库上预训练了一个深度双向语言模型(biLM),然后把根据它的内部状态学到的函数作为词向量。实验表明,这些学到的词表征可以轻易地加入到现有的模型中,并在回答问题、文本蕴含、情感分析等 6 个不同的有难度的 NLP 问题中大幅提高最佳表现。实验表明显露出预训练模型的深度内部状态这一做法非常重要,这使得后续的模型可以混合不同种类的半监督信号。

    3.1 ELMo的安装与使用
    AllenNLP是一个相对成熟的基于深度学习的NLP工具包,它构建于 PyTorch之上,该工具包中集成了ELMo方法。
    可以直接使用pip安装:

    pip install allennlp

    适用于python3.6以上的版本

    或者,也可以直接clone源码到本地[https://github.com/allenai/allennlp]
    在这里插入图片描述
    使用ELMo获得词向量替换Glove的词向量作为多项特定NLP模型的输入,在ELMo的论文实验中表明具有一定的效果提升:
    在这里插入图片描述

    BERT的诞生过程:
    BERT的工作方式跟ELMo是类似的,但是ELMo存在一个问题,它的语言模型使用的是LSTM,而不是google在2017最新推出的Transformer(来自论文《Attention is all you need》)。LSTM这类序列模型最主要的问题有两个,一是它单方向的,即使是BiLSTM双向模型,也只是在loss处做一个简单的相加,也就是说它是按顺序做推理的,没办法考虑另一个方向的数据;二是它是序列模型,要等前一步计算结束才可以计算下一步,并行计算的能力很差。
    所以在ELMo之后,一个新模型GPT(来自论文《Improving Language Understanding by Generative Pre-Training》)推出了,它用Transformer来编码。但是它的推理方式跟ELMo相似,用前面的词去预测下一个词,所以它是单方向,损失掉了下文的信息。
    然后BERT诞生了,它采用了Transformer进行编码,预测词的时候双向综合的考虑上下文特征。这里作者做了一个改进,原来没办法综合利用双向的特征是因为目标是用前面的词逐个的预测下一个词,如果你能看到另一个方向,那就等于偷看了答案。BERT的作者说受到了完形填空的启发,遮盖住文章中15%的词,用剩下85%的词预测这15%的词,那就可以放心的利用双向上下文的特征了。
    在这里插入图片描述

    Transformer:
    Transformer是论文《Attention is all you need》中的模型,它把attention机制从配角搬上了主角的位置,没有采用CNN或者RNN的结构,完全使用attention进行编码。Transformer应该会取代CNN和RNN成为NLP主流的编码方式,CNN提取的是局部特征,但是对于文本数据,忽略了长距离的依赖,CNN在文本中的编码能力弱于RNN,而RNN是序列模型,并行能力差,计算缓慢,而且只能考虑一个方向上的信息。Transformer可以综合的考虑两个方向的信息,而且有非常好的并行性质,简单介绍一下Transformer的结构。

    https://jalammar.github.io/illustrated-transformer/ 这一篇博客上有非常详细的介绍,详细了解Transformer可以看一下这一个博客。
    在这里插入图片描述

    整个Transformer的结构如上图所示,它分为两个部分,一边是encoder,另一边是decoder,一个encoder或decoder看作一个block,encoder和decoder又有多个block串行相连,图中是2个,原文中使用了6个。
    先看encoder,单独看一个block,输入一行句子,先经过一个Self-Attention,Self-Attention首先是对每个Token的embedding通过3个不同的矩阵映射成3个向量,Query(Q)、Key(K)和Value(V)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    每个pos的位置用一个d维的向量表示,这个向量的偶数位置用sin,奇数位置用cos计算,得到-1到1之间的值,之所以用三角函数是利用了三角函数和差变换可以线性变换的特性,因为BERT中没有采用这种计算方式,所以不作详细的介绍。
    然后经过一个Feed Forward的神经网络再经过Add&Normalize完成一个encoder,传向下一个encoder。Decoder的结构和运算机制与encoder基本一致,不同的是encoder顶层的K、V向量会传到Decoder的每个Block的Encoder-Decoder Attention部件中。最后经过一个线性的变换和Softmax分类器得到最后的结果。

    BERT的实现方式:
    Mask Language Model
    受到完形填空的启发,它不同于传统的语言模型,它是盖住整篇文章15%的词,然后用其他的词预测这15%的词。被盖住的词用[mask]这样的一个标记代替,但是由于下游任务中没有[mask]这个符号,为了削弱这个符号的影响,15%被盖住的词中:

    80%的词就用[mask]符号盖住
    10%的词保留原来真实的词
    10%的词用随机的一个词替代
    编码方式:
    采用Transformer为编码方式,实验结果最好的结构是BERT:L=24,H=1024,A=16。L=24也就是Transformer中提到的Block数,H=1024是隐藏层的维度,也就是Token经过矩阵映射之后K、Q、V向量的维度,A=16是Attention的头数,叠加了16层相互独立的Self-Attention。非常的google,money is all you need,如此复杂的结构,一般人是玩不了的,所幸的是google开源了pre-train的参数,只要用pre-train的参数对下游任务进行fine-tuning就可以使用google的BERT。
    BERT的Transformer结构与Attention is all you need中有一个不同是对于位置信息的编码,论文中的Transformer是采用cos和sin函数计算,而BERT用了更为简单粗暴的方法,每一个位置赋予一个向量,例如句子的截断长度固定为50,那么0-49这50个位置各赋予一个向量,将这个向量加到self-attention的embedding上。

    获取句间的关系:
    目前为止只获得了Token级别的特征,但是对于一些句间关系的推理,对话系统、问答系统需要捕捉一些句子的特征。BERT采用给定2个句子,判断它们是否是连续的句子的方式捕捉句子级别的特征:
    在这里插入图片描述
    具体的实现方式是两个连续的句子,开始和结束打上符号,两句之中打上分隔符,然后中一个二分类,反例的生成采用类似于word2vec的负采样。
    在这里插入图片描述
    这是整体的编码方式,Token Embedding是Transformer的embedding,加上segment embedding A和B,捕捉句子级别的特征,区分第一句和第二句,如果只有一个句子的情况就只有embedding A,加上每个位置赋予的Position embedding得到最终的embedding。

    BERT的实验结果:
    在这里插入图片描述

    在这里插入图片描述
    在 NLP 具体任务中应用的效果来看:效果最差的是 CBOW;其次是 Skip-gram(GloVe 跟 Skip-gram 差不多);效果最好的是 FastText。其中,FastText 能很好地处理 OOV(Out of Vocabulary)问题,最小粒度介于word和character之间 问题,并能很好地对词的变形进行建模,对词变形非常丰富的德语、西班牙语等语言都非常有效;

    从效率(训练时间)上来看:CBOW 的效率是最高的,其次是 GloVe;之后是 Skip-gram;而最低的是 FastText。

    https://blog.csdn.net/sinat_26917383/article/details/83041424

    展开全文
  • 基于支持向量机的图像分类.MATLAB
  • 一文纵览向量检索

    千次阅读 2020-09-28 15:07:22
    摘要:本文针对向量检索要解决的问题,梳理了主流向量检索相关的技术,分析了向量检索目前的一个趋势。 什么是向量检索 首先我们了解下什么是向量,所谓向量就是由n个数字(二值向量由n个比特组成)组成的数组,...
    摘要:本文针对向量检索要解决的问题,梳理了主流向量检索相关的技术,分析了向量检索目前的一个趋势。

    什么是向量检索

    首先我们了解下什么是向量,所谓向量就是由n个数字(二值向量由n个比特组成)组成的数组,我们称之为n维向量。而向量检索就是在一个给定向量数据集中,按照某种度量方式,检索出与查询向量相近的K个向量(K-Nearest Neighbor,KNN),但由于KNN计算量过大,我们通常只关注近似近邻(Approximate Nearest Neighbor,ANN)问题。

    向量度量

    常见的向量度量有四种:欧式距离、余弦、内积、海明距离

    不同的度量方式对应不同的场景,通常欧式距离用于图片检索,余弦用于人脸识别,内积多用于推荐,海明距离由于向量比较小,通常用于大规模视频检索场景。

    有了度量以后,我们通常会用召回率(也通常叫精度)来评估向量检索的效果,对于给定的向量q,其在数据集上的K近邻为N,通过检索召回的K个近邻集合为M,则

    召回越接近100%代表索引效果越好。

    向量检索解决的问题

    向量检索从本质上讲,其思维框架和传统的检索方法没有什么区别,后面在讲解向量检索的索引结构部时,体会能更深刻一些。

    1. 减少候选向量集

    和传统的文本检索类似,向量检索也需要某种索引结构来避免在全量的数据上做匹配,传统文本检索是通过倒排索引来过滤掉无关文档,而向量检索是通过对向量建立索引结构来绕过不相关的向量,本文重点讨论相关的向量索引结构。

    2. 降低单个向量计算的复杂度

    传统文本检索在排序时通常会采用漏斗模型,上层计算比较轻量,越往下计算越精细,但随着过滤的进行,需要计算的文档数也逐级下降,对高维向量而言,单个向量的计算量还是比较重,通常会对向量进行量化,对向量做近似计算,最后在一个很小的数据集上做原始向量的排序。

    下面我们围绕这两个问题来展开向量检索的相关讨论。

    向量检索索引结构

    为向量建立高效的索引结构是向量检索面对的头号问题,在开始展开前我们看一个Benchmark项目,这个项目在多个公开的向量数据集对比了相关索引结构的召回性能指标,使我们能够快速对各种索引结构的性能表现有个直观的认识。

    暴力计算

    暴力计算是最简单但复杂度最高的一种方式,在计算召回的时候,暴力计算的结果是作为答案的基准数据,在人脸识别的场景中经常要求100%的召回率,这种情况下一般直接暴力计算。

    基于树的方法

    基于树的方法有很多种,比较典型的有KDTree、BallTree、VPTree,类比传统的二叉树,树结构无非是在建树的时候是决定往左还是往右扩展,不同的向量树索引在于按照什么标准去决策,KDTree(如下图所示)会选取向量中某个方差最大的维度取中值作为判定标准,也就是以超平面去划分空间,而BallTree则以球面去划分空间,VPTree会先选取一个制高点,然后计算每个点和制高点的距离,取距离中值作为判定标准。通常这些方法在检索的时候都会利用三角形不等式来去除不必要的探索。

    基于树的方法还有很多其他类型,但万变不离其宗,无非就是按照某个判定标准,对向量空间进行划分,但不管怎么划分,由于需要回溯的,都决定了基于树的方法在性能上要稍逊一筹。

    哈希方法

    哈希对大家再熟悉不过,向量也可以采用哈希来加速查找,我们这里说的哈希指的是局部敏感哈希(Locality Sensitive Hashing,LSH),不同于传统哈希尽量不产生碰撞,局部敏感哈希依赖碰撞来查找近邻。

    满足如下两个条件的哈希函数称为(d1,d2,p1,p2)-sensitive:

    1. 如果d(x,y) <= d1,则h(x) = h(y)的概率至少为p1;

    2. 如果d(x,y) >= d2,则h(x) = h(y)的概率至少为p2;

    上面的表达式用人话来说就是:高维空间的两点若距离很近,那么设计一种哈希函数对这两点进行哈希值计算,使得他们哈希值有很大的概率是一样的,若两点之间的距离较远,他们哈希值相同的概率会很小。不同距离度量的哈希函数不同,不是所有距离度量(如内积)都能找到对应局部敏感哈希

    基于倒排方法

    传统倒排索引是根据文档包含某个词,然后将当前文档放入改词的倒排索引中来建立索引结构,那向量是如何建立起倒排索引呢?通过聚类把整个向量空间划分为K个区域,每个区域用一个中心点C代替,这样每个向量和所有中心点对比,将自身归入到距离自己最近的中心点对应的倒排,整个索引结构就建立起来了

    另一种基于倒排的索引是BOW,原理大体相同,例如一张图片会抽取出几百个局部特征,先对所有的特征聚类,形成中心点,这些中心点作为倒排的基础,建立索引时,把图片的每个局部特征归类到其最近的中心点,建立倒排,检索时会根据命中的次数来过滤结果。

    基于图的方法

    前面介绍的索引结构都可以归类为基于空间划分的方法,每个向量只会属于某个划分好的一个区域,这些方法最大的的问题是为了提高召回需要考察很大一块区域的向量,导致计算量激增,那有没有更好的方法来解决这个问题呢?基于图的方法就可以比较好的实现这一目标,图方法最朴素的想法是邻居的邻居也可能是邻居,这样把最近邻的查找转化为图的遍历,由于其连通性,可以针对性的考察部分向量而不是按区域来考察,因此可以大幅降低向量的考察范围。

    最近几年图方法是向量检索研究的一个热点,出现了如KGraph、NSG、HNSW、NGT等一批图索引方法,但实际上这些图方法的主要区别在构建过程,不同图方法采用不同的手段来提升图的质量,但图检索的步骤基本是一致的:a.选好入口点;b.遍历图;c.收敛。在不断实践中我们观察到一些特性来评判图索引质量,指引我们在图方法改进的方向:

    1. 邻居点接近K近邻

    2. 邻居点数量尽可能少,即减少出度

    3. 尽可能保证图的连通性,增加入度

    下面我们以HNSW为例介绍一下图方法的原理,之所以选取HNSW在于该方法易于理解,比较容易实现流式索引构建和更新,属于传统方法在向量上的完美体现。

    HNSW背后其实是跳表在图上的应用,跳表作为一种简单高效的索引结构在Redis、LevelDB等系统中获得广泛应用,如下图所示:

    第一层上有全量的数据,在上层根据随机投币决定,越往上投到的概率越小,投到高层的节点往下都有一条记录,作为检索的高速公路快速前进。

    HNSW的原理也类似,不同于传统跳表在每层用链表来串联节点,HNSW在每层都是一个NSW(Navigable Small World Graph),通过图数据结构组织,上层节点也是通过投币决定在哪一层,并且它们在下层图中都有记录,上层图可以看做下层图的一个缩影,检索时,从上到下,不断指引检索过程逐步靠近想要探寻的向量空间。另外在构图过程中HNSW通过边的裁剪来保证图的连通性,这里顺便提一下,纵观多篇图方法的论文,都从自己的视角表述了边裁剪方法, 但不管各种方法对裁边描述的有多酷炫,其方法本质都是一模一样的,只是视角不一样而已。

    向量量化

    前面把主流的向量检索的索引技术基本都概述了一遍,经过索引结构对考察的向量做了裁剪以后,对高维向量而言,单个的计算量还是很大,有没有方法来减少计算量呢?量化正是基于这个目的技术,所谓量化是指把一个很大的值空间量化到一个较小的值范围,举个简单的例子,全世界有60多亿人口,也就是地球人的表征有60多亿种,我们可以把人量化为男人和女人两种类型,这样就把一个60多亿的空间量化成只有两个值的范围。

    常用的量化一般包括PQ(及其优化OPQ、LOPQ)和二值两种。

    PQ原理如图,PQ中的P是乘积的意思,那怎么就冒出个乘积呢?在下图中一个128维的向量空间在经过PQ处理后,向量空间切分成了4段,每段内由256个中心点来量化表达,因此原始的128维空间现在可以用每段里的中心点组合,也即256 * 256 * 256 * 256种组合来表达,这就是所谓的乘积。

    对于二值向量,由于现代CPU都提供了专门的指令,计算海明距离非常快速,在海量的向量检索中通常会直接生成二值向量,生成二值向量方法常见的有ITQ(Iterative Quantization)、DeepHash等方法。

    其他技术

    聚类

    向量聚类主要指的是K-means系列方法,如经典的K-means、K-means++、K-means#、One pass K-means、YinYang k-means等,在实践中我们也使用过分层的方法来获得海量中心点。

    内积转换

    前面在哈希章节我们已经看到对内积是没有办法找到对应的局部敏感哈希函数,内积也不满足三角形不等式,因此导致很多索引结构无法直接使用内积作为度量,大多数做法是先对向量做归一化再检索,但归一化会转换向量空间分布。研究人员通过一个数学观察发现了一个方法,通过一定规则变换,可以使得内积和欧式能够实现负相关,如下图所示:

    对向量转换后,可直接用欧式距离度量方式检索。

    向量检索发展趋势

    本文开头我们提到向量检索的思维框架和传统检索没有什么区别,到目前为止传统方法应用到向量检索的红利也基本吃完。这两年的一个发展趋势是各种方法的组合,通过吸收各种方法的长处,来获得更好的性能、承载更大规模的向量。

    量化图

    从Benchmark上我们可以清晰的看到,处在优势地位的方法基本被图方法霸屏,同时我们知道量化可以降低单个向量的计算量,因此很自然的一种想法是让两者强强联手,在图遍历过程中使用量化计算来加速,这种方法对于在高维度方法上优势明显,加速比能达到三倍以上。

    图+倒排

    图的性能虽然卓越,但缺点也非常明显,为了保证检索效果,图上边的保存消耗大量的存储

    尤其在向量本身很小的二值向量上,这是不能承受之重,另外图的邻居本身具有随机性,对硬件处理向量也非常不利。倒排方式则恰恰相反,索引结构基本不消耗太多空间,但缺点是空间划分方法容易导致召回率不高,但我们从暴力计算的观察获得一些启发,暴力计算从空间划分角度有两种视角:可以将暴力计算看做成把所有向量聚类为一个;也可以将暴力计算看做聚类为N(N为向量数据集的大小)个中心,每个中心点是向量本身。这两种方法都能100%召回,但他们一个是因为中心点下面的向量太多,另一个因为聚类的中心点太多,而导致计算量不可接受,那我们是否可以找到一个平衡点?适当的中心点数目使得召回和性能取得一个比较好的平衡?图+倒排方式应运而生,用海量中心点去分割向量空间,图方法来组织海量中心点。

    华为云向量检索实践

    向量检索的应用出现了空前的繁荣,华为云搜索服务(Cloud Search Service,CSS)目前已经对外开放向量检索的能力,我们针对高性能和海量数据两种典型的场景都提供了解决方案。

    实现上我们主要基于图方法,在裁边优化,连通性增强,指令加速,多线程处理等方面做了大量增强。对比测试中,我们召回率远高于Faiss,在高维度数据上差距更为明显,在同样召回下,我们性能在SIFT,GIST等公开数据集上是Faiss 2.3倍以上。对比测试采用的是相同的机器,相同的算法。

    总结:

    本文针对向量检索要解决的问题,梳理了主流向量检索相关的技术,分析了向量检索目前的一个趋势。在向量检索的发展历程中,还有很多相关的方法没有囊括进来,但万变不离其宗,这些方法要么还是传统方法的扩展或者应用三角不等式的优化或者应用层次方法等等。期盼本文能帮助梳理向量检索的脉络。

    参考文献:

    1.  J. L. Bentley. Multidimensional binary search trees used for associative searching. Communications of the ACM, 18:509–517,1975

    2.  P. N. Yianilos. Data structures and algorithms for nearest neighbor search in general metric spaces. In Proc. of the 4th annual ACM-SIAM Symposium on Discrete Algorithms, pages 311–321, 1993

    3.  Liu, T.; Moore, A. & Gray, A. (2006). New Algorithms for Efficient High-Dimensional Nonparametric ClassificationJournal of Machine Learning Research. 7: 1135–1158.

    4.  P. Indyk and R. Motwani. Approximate nearest neighbors: Towards removing the curse of dimensionality. In STOC, pages 604–613, Dallas, TX, 1998.

    5.  W. Dong, C. Moses, and K. Li. Efficient k-nearest neighbor graph construction for generic similarity measures. In Proceedings of the 20th international conference on World wide web, pages 577–586. ACM, 2011.

    6.  Y. A. Malkov and D. A. Yashunin. Efficient and robust approximate nearest neighbor search using hierarchical navigable small world graphs. CoRR,abs/1603.09320, 2016.

    7.  https://arxiv.org/abs/1707.00143

    8.  https://yongyuan.name/blog/vector-ann-search.html

    9.  A. Shrivastava and P. Li. An improved scheme for asymmetric lsh. Technical report, arXiv:1410.5410, 2014.

    10. H. Jegou, M. Douze, and C. Schmid. Product quantization for nearest neighbor search. IEEE transactions on pattern analysis and machine intelligence, 33(1):117{128, 2011.

    11.https://arxiv.org/abs/1810.07355

     

    注:本文部分索引结构示例图源自https://yongyuan.name/blog/vector-ann-search.html

     

    点击关注,第一时间了解华为云新鲜技术~

    展开全文
  • 段落向量与句子向量表达

    万次阅读 热门讨论 2017-05-20 17:08:27
    这是Tomas Mikolov的一篇关于段落向量和句子向量的论文。本文是我翻译加自我理解的结果,如需要更详细的介绍,请看英文文献。摘要许多机器翻译的算法都需要使用固定长度的词向量特征。在到达文本层面时,我我们最...

    这是Tomas Mikolov的一篇关于段落向量和句子向量的论文。本文是我翻译加自我理解的结果,如需要更详细的介绍,请看英文文献。

    摘要

    许多机器翻译的算法都需要使用固定长度的词向量特征。在到达文本层面时,我我们最常用的一个固定长度的特征时词袋模型。尽管他们很流行,但是词袋模型有两大缺点:1、失去了词序特征;2、忽略了语义特征,例如,powerful与strong和Paris距离都是非常远的。在本文中,我们提出了一个段落向量,它是一个无监督算法,从变长的文本(句子、段落、文章)中学习到固定长度的词向量特征。我们的算法使用一个密集向量来表示每个文本,而这个是通过预测词出现在文本来训练的。它的结构给了我们可以克服词袋模型缺点的可能。实验结果显示,段落向量优于词袋模型,也同样优于其他文本向量表示。最终我们在几个文本分类和情感分析任务中取得了最优值。

    1 引言

    文本分类和聚类在许多应用中扮演重要作用,例如文本检索、网页搜索和垃圾邮件过滤。而这些应用的核心都是像逻辑斯蒂回归或者K-means聚类这样的机器学习算法。这些算法通常需要使用一个定长的向量来表示输入文本。由于词袋模型和n-graims模型的简单、有效和经常去的不错的准确度,因此他们是最常用文本定长向量表达方式。

    但是,词袋模型有许多缺点。词序特征会丢失,因此不同的句子,如果使用相同的单词,可能得到的是相同的向量表达。即使是n-gram模型,它也只是在较短的上下文中考虑词序,这就受到了稀疏数据和高维的约束。词袋模型和n-gram模型对于词义都是不敏感的,它们更多的会考虑词与词之间的距离。就像摘要中说的那样,powerful与strong和Paris距离都是非常远的,事实上,我们知道,powerful与strong更近。

    本文中,我们提出了段落向量,一种无监督框架来学习为每篇文本分配向量。文本可以是变长的,无论是句子还是篇章。之所以叫做段落向量是为了强调这个方法可以应用到变长文本中,无论是句子、段落还是更大的篇章单元。

    在我们的模型中,向量表达是由在段落中预测有用的词来训练的。更确切来讲,我们通过几个从段落中获取的词向量来连接成段落向量,并且对在给出的上下文中预测接下来的词。词向量和段落向量都是基于SGD和BP算法的。不同的是,词向量是共享的,而段落向量是段落间相互独立的。在预测时,段落向量通过固定的词向量来进行预测,并且训练一个新的段落向量直到收敛。

    我们的技术主要受到了最近使用神经网络学习词向量表示的工作的激励。在他们的前期工作中,每一个词都会由一个向量表示,而这个向量来源于上下文中其他词向量的拼接或者平均。例如,在2006年的Bengio的神经网络语言模型中,它使用前几个词向量的拼接来构建神经网络的输入,并且尝试去预测接下来的词。其结果就是,当模型训练完成后,词向量被映射到了一个向量空间,在这个向量空间中,具有相似语义的词会有相似的向量表示。

    接着这些成功的技术,研究者们又试图把模型扩展以从词层面到达短语级或者句子级层面。例如,一个简单的方法就是使用文本的所有词向量加权平均。一个更复杂的方法是使用矩阵操作,根据句子的短语结构分析树给出的顺序组合词向量。这两种方法都有缺陷,第一种方法和词袋模型一样丢失了词序特征,第二种方法则只能在句子层面上做,因为它依赖于短语句法分析。

    段落向量能够组合序列化变长输入的表达。不像之前的方法,它具有普适性而且可以应用于各种长度的文本:句子、段落和篇章。他不需要对特定任务进行词权重的调整,它也不需要依赖于句法分析树。在接下来的部分中,我们将会展现一些在基准数据集上的实验,这些实验充分展示了段落向量的优势。例如,在情感分析中,我们取得了最优的结果,比之前复杂的方法还要减少16%的错误率。在文本分类任务中,我们方法明显打败了词袋模型,取得了大约30%的性能提升。

    2算法

    我们从之前学习词向量的方法开始讲起。这些方法都对我们的段落向量方法有促进作用。

    2.1 词向量表示学习方法

    这一部分,我们介绍词向量的相关概念。一个著名的词向量学习框架如图1所示,其任务就是通过给出的上下文中的词可以预测当前词的向量。
    这里写图片描述
    在这个框架中,每个词都会被映射成一个独一无二的词向量,通过一个一维矩阵W(译者注:onehot编码),这一列表示着这个词在词典中的位置。通过求和或者求平均的方法来获得矩阵,这个矩阵被用来预测下一个词的词向量的特征。

    更正式的,给定一串单词w1,w2,w3,…wT,词向量模型的目标就是使得平均似然估计最大:

    预测任务通常是使用一个多类分类器,例如Softmax函数。这里,我们使用:
    这里写图片描述
    每一个yi都是一个非归一化的似然概率,对应的是每一个输出的词i,其中y的计算如下:
    这里写图片描述
    这里,U,b是softmax的参数。h是由W中抽取出的词向量的平均值或者求和构成。
    这里写图片描述
    实际应用中,层次化的Softmax(Morin&Bengio,2005;Mnih &Hinton,2008;Mikolov et all,2013c)比普通Softmax更适合快速训练。在我们的工作中,层次化的Softmax是一个二叉哈夫曼树。短编码被分配给了频率高的词。这时一个很好的加速训练的小技巧因为这样一般的词都可以得到快速训练。其代码和(Mikolov et all,2013c)用的是一样的。

    基于词向量的神经网络模型大多使用SGD方法训练,其梯度通过BP算法获得。这种模型在神经语言模型中非常常见。一个关于词向量的训练算法的具体实现在这里可以找到:code.google.com/p/word2vec/( Mikolov et all,2013a)

    当训练收敛后,拥有类似语义的单词会被映射到向量空间里相似的位置上。还是“powerful”和“strong”,他们离的更近。而且词向量间的不同,也表示着不同的意思。这就意味着距离差距也有语义差距。King-man=Queen-woman。大概就是这意思,这个可以被用来学习一个线性矩阵来翻译不同语言间的单词和短语。

    这些特性使得词向量对于一些自然语言处理的任务特别适合,例如语言模型(Bengio et al 2006;Mikolov et all 2012),自然语言理解(Collobert & Weston 2008;Zhila et all,2013),统计机器翻译(Mikolov et all 2013b;Zou et al.,2013),图像理解(Frome et al,2013)和相关性抽取(Socher et al,2013a)。

    2.2 段落向量

    我们的学习段落向量的方法是受到了学习词向量的启发。这个启发就是,我们使用词向量来预测句子中下一个单词。所以,尽管这些词向量初始化时是随机的,但是他们最终还是捕获了语义信息作为预测结果的副产品。我们将使用同样的这种方法应用到我们的段落向量中。段落向量也被用来在段落里给出上下文预测下一个词。

    在我们的段落向量框架中(图2),每一个段落也被映射成一个独立的向量,使用一个矩阵D来表示。而每个单词也被映射为一个独立的向量,使用矩阵W来表示。段落向量和词向量都被平均或者求和在一个上下文中用来预测下一个词。在实验中,我们使用平均的方法来组合这些向量。
    这里写图片描述
    更重要的,模型中唯一改变的只有式1中的h,从只是D表示变成了D和W共同表示。

    段落块可以被看成是另一个词,这个词里记载着当前上下文所缺失的信息,或者说是段落的主题。正因为这个原因,我们经常叫这个模型为分布式记忆模型——段落向量(PV-DM)

    上下文信息是按照固定长度在段落上根据滑动窗口不断采样,段落向量会被该段落产生的所有上下文窗口所共同拥有,但是不跨越段落,也就是说,不同段落的段落向量是不同的。但是不同段落的词向量是相同的。

    段落向量和词向量使用随机梯度下降方法训练,这个梯度使用的是BP算法获得。每一步的随机梯度下降,都是从一个随机段落里采样获得固定长度的上下文,通过图2种的网络计算梯度误差并且使用该梯度更新模型中的参数。

    在预测的时候,需要一个实现一个预测的步骤来进行计算一个新段落的段落向量,这也是通过梯度下降获得。在这步骤中,模型的剩余参数,包括词向量W和Softmax的权重都是固定的。

    假设这里有N个段落在语料库中,有M个词在词典里,我们想去学习段落向量。因此每段都被映射到p维里,每个词被映射到q维里,这样,模型总共拥有N*p+M*q参数,包括softmax的参数。即使当N非常大时,这些参数也有可能非常大,但是整个训练过程也是稀疏的并且高效的。

    经过训练后,段落向量就可以被用来作为段落的特征。例如可以替代词袋特征等。我们可以把这个特征直接用到机器学习算法中,例如逻辑斯蒂回归、支持向量机或者K-means聚类。

    总的来说,这个算法有2个主要步骤:1)使用无监督方法训练词向量W(译者注:和Word2vec一样);2)推测阶段获取段落向量D。第三步骤是使用D在一个标准分类器上进行标签预测,例如逻辑斯蒂分类或者支持向量机。

    段落向量的优势:段落向量的一个最主要的优势在于它不需要标注的语料。

    段落向量也克服了一些词袋模型的缺点。首先它隐含了词向量模型的最重要的特点,词的语义。也就是说,相似的语义的词会有相似的位置(译者注:意思是,相似的语义的段落也有相似的位置)。第二个优势就是它考虑了词序,就像在较短的上下文中n-gram模型所做的那样。这是非常重要的,因为n-gram模型提供了大量的段落信息,包括词序。我们的模型就有可能优于n-gram模型,因为n-gram模型可能创建出一个高维的但却稀疏的矩阵。

    2.3无词序的段落向量:分布的词袋模型

    以上的方法都是考虑了在一个文本窗口中使用词向量和段落向量的链接来预测下一个单词。另一个方法是在输入中忽略上下文单词,但是在输出中强制模型对段落中随机采样的单词进行预测。事实上,SGD的每一次迭代中,我们都会从一个文本窗口中采样,然后从这个文本窗口中随机采样一个单词并且构建一个基于段落向量的分类任务。这项技术见图三。我们叫做这种方法为PV-DBOW,与PV-DM相对应。

    除了概念上简单外,这个模型也存储更少的数据。我们只需要存储Softmax权重,而之前的模型需要存储Softmax权重和词向量。这个模型更像是词向量模型中的Skip-gram模型。
    这里写图片描述
    在我们的试验中,每个段落向量由2部分组成:一个是通过标准段落向量(PV-DM)另一个是(PV-DBOW)。PV-DM通常可以取得很好的成绩在很多任务上,但是如果和PV-DBOW搭配的话,能对多个系统都取得更连续的好的成绩,因此我们强烈推荐。

    3实验

    我们做了实验来更好的理解段落向量的表现。为此,我们在两个文本理解问题上做了基准的段落向量:情感分析和信息检索。

    对于情感分析任务,我们使用了2个数据集斯坦福情感分析树库数据集(Socher ,2013b)和IMDB数据集(Mass ,2011)。在这两个数据集中的文本长度是非常不同的,Socher每个例子都是一个单独的句子,而Mass的数据集中的例子都是好几个句子连在一起的。

    我们也使用了我们的方法在信息检索的任务上,这个任务是当给出一个查询时,判断一个文档是否应当被检索到。

    3.1 斯坦福情感树库数据集上的情感分析

    数据集:这个数据集首先被(Pang & Lee ,2005)提出来,并且被(Socher et all. 2013c)扩展作为情感分析的基准系统。它包含了11855个从烂番茄上的影视评论的句子。

    这个数据集包涵一下集合:8544个训练集,2210个测试集,1101个验证集。
    每一个句子都有一个标签,这个标签从0-1分别表示最消极到最积极。这些标签都是Amazon Mechanical Turk上由人工标记得到的。

    这个数据集附带有每个句子的具体标签以及子句法结构树,前面两个做了很多工作(译者注:此处省略),最终这个数据集可以在http://nlp.Stanford.edu/sentiment/获取。

    任务和基准线:在(Socher et all.2013)文章中,任务被分成了2个基准系统,一个细准系统使用5分类,一个基准系统分为2分类。而且既可以对整个句子进行标注也可以对所有的短语进行标注。这里使用的是对整个句子标注。

    (Socher et al. 2013b)使用和好几种方法在这个数据及上,并且发现递归神经张量网络要比词袋模型好很多。这可以被认为是影评经常非常短并且结构在判断是否是积极还是消极上具有重要作用,就像在很小的数据集上给出单词后。

    实验草案:
    我们按照(Socher et al. 2013b)的方法实现了一下。为了保证我们能够充分使用已提供的数据集,在我们的模型中,我们把每个短语都看成是一个独立的句子,因此我们是在所有的短语中训练的。

    在学习完短语和句子的向量表达后,我们使用这些来学习一个影评打分的预测器。

    在测试的时候,我们固定每个词的向量表达并且学习这个句子的向量表达,使用的是梯度下降方法。一旦句子向量表达学习完成后,我们就使用它用一个逻辑斯蒂回归来预测影评打分。

    在我们的实验中,我们使用验证集交叉验证了窗口的大小,最优的窗口大小为8.因此向量表达的分类器有两个向量组成,一个是PV-DBOW,另一个是PV-DM。在这两个中,所有的词和段落向量都是400维的。我们为了预测第8个词,我们使用的是7个词向量和一个段落向量。而特殊符号(。?!)等,我们也视作是一个普通的字符。如果这个句子小于9个词,我们使用NULL来填充。

    结果:
    我们把不同方法的错误率都放在了表1种。首先应当注意的就是传统的词袋模型(贝叶斯、SVM、二元贝叶斯)的表现非常差。这是因为词袋模型没有考虑到句子的组成,例如词序。因此有很多复杂的语言现象不能够被识别,例如讽刺。这个结果也显示递归神经网络模型这种更先进的方法,使用的句法分析而考虑了句子组成,因此表现的更好。
    这里写图片描述
    但是我们的方法由于以上所有基准系统,包括递归神经网络。而且我们也不需要句法分析。在粗颗粒度上我们降低了2.4%的错误率,相比较最好的基准系统提升了16%。

    3.2 真正的段落向量:在IMDB数据集上的情感分析

    之前都是一个句子,下面是多个句子,即使是(Socher,2013b)使用的RNTN,也是需要依靠句法分析的。我们段落是没有句法分析的,但是我们仍然可以做,因为我们不需要句法分析。(译者注:这个实验可以见http://blog.csdn.net/lenbow/article/details/52120230,但是效果没有论文的报告上的好)实验表明,我们的方法优于其他方法。

    数据集:这里同样的选取100000条来自IMDB的影评,这个工作在(Maas 2011)里讲过了。主要是25000个已标注的训练实例、25000个已标注的测试集实例和50000个未标注的实例。总共有2种标签:积极和消极。这些标签在训练集和测试集里是平均分布的。数据集可以从http://ai.Stanford.edu/amaas/data/sentiment/index.html获得。

    实验草案;
    我们使用了75000个训练样例(25000标注的50000未标注的)。然后获取已标注的实例的段落向量并把它们放到一个含有一层一藏层50个单元的神经网络并且使用一个逻辑斯蒂分类器来学习预测分类器。

    在测试时,给出一个实力句子,我们固定好其他的网络并且使用梯度下降方法学习测试样例中的段落向量。一旦向量学习完毕后,我们通过给神经网络输入这些向量来预测这些评论的情感。

    我们段落向量模型的超参数使用的和之前的那个任务一样,只是窗口大小变成了10个词。其他都没变。

    结果:实验结果如表2所示。从表中我们可以看出,词袋模型在长句中的表现很非常好,但是很难有很大的提升知道使用了词向量。最显著的改进是在2012年的(Dahl et al. 2012)的工作中,他们在词袋模型中使用了一种限制型波兹曼机。组合了这两个模型也只改进了1.5%的错误率。

    另一个重要改进工作来源于(Wang & Manning,2012).在他们尝试的方法中,NBSVM的2元特征取得了最好成绩并且提升了2%的错误率。
    这里写图片描述
    在本文中,我们提到的方法显著的低于10%的错误率,达到了7.42%,比最好的还低了1.3%,如果算相对改进的话,则改进了15%。

    3.3使用段落向量进行信息抽取

    我们开始把注意力转移到了另一个任务上,在这个任务上,我们使用定长的段落向量表达。其主要任务就是给出最热门的1000000查询,然后每个查询选取前10个结果。然后每次使用3个段落,这三个段落中,有2个是来自同一查询,另一个是随机选取的。目的是能预测出哪两个段落来自同一查询。判断的方法为段落向量化并测量之间的距离,距离近的为来自同一个查询。(译者注:这里我们不详细举例,这是Google的特权)
    这里写图片描述

    4 相关工作

    这里主要介绍了从向量表达到神经网络语言模型,以及从词袋模型到词向量表达,并且到达短语向量表达和段落向量表达的整个过程。具体可见原文。

    5 结论

    我们描述了一种无监督学习算法来从变长的文本(句子、段落)中学习到向量表达,我们称为段落向量。这些向量表达是根据上下文来预测段落中采样获得的单词。

    我们在几个文本分类任务上都做了实验,例如在斯坦福树库和IMDB数据集上的情感分析任务。在这些任务中,这种方法都是最优的。这些好的表现也表明了段落向量可以对段落的语义有表征能力。事实上,段落向量确实可以克服很多词袋模型的缺点。

    尽管现在的工作都是聚焦于文本表达,但我们的方法是可以被应用于序列化数据的表达。在无文本领域,句法分析是没有提供的,我们认为段落向量是可以取代词袋模型和n-gram模型的。

    展开全文
  • 本文介绍了向量的定义、向量的模、负向量、单位向量、零向量以及向量加减法的三种实现方法。
  • 最小二乘支持向量机(LSSVM)详解

    万次阅读 2019-02-14 20:51:57
    最小二乘支持向量机(LSSVM)详解 第四十六次写博客,本人数学基础不是太好,如果有幸能得到读者指正,感激不尽,希望能借此机会向大家学习。在《》一文中曾对支持向量机(SVM)以及支持向量回归(SVR)进行了...
  • 矩阵特征值和特征向量求解

    千次阅读 2018-05-11 13:42:27
    下面以Matlab为例进行讲解求取矩阵特征值和特征向量求解。(Python和C/C++的相应代码在博客的最后给出)当一个计算机专业的人放下手头的工作,转而写博客时。说明他的CSDN账号积分所剩无几了。。。。。。基于Matlab...
  • 支持向量机故障诊断及控制技术 matalb 代码
  • matlab支持向量机分类实例(十分详细)附数据
  • 这是Tomas Mikolov的一篇关于段落向量和句子向量的论文。本文是我翻译加自我理解的结果,如需要更详细的介绍,请看英文文献。 摘要 许多机器翻译的算法都需要使用固定长度的词向量特征。在到达文本层面时,我我们最...
  • 本文介绍一种计算句向量和文章向量的方法及参考代码,自然语言处理的第一步即是要进行文本的向量化,包括获得词向量,句向量或者文章向量,以便输入各种机器学习模型或者深度学习模型。 词向量 可以笼统的认为词向量...
  • 遗传算法优化支持向量机算法,从而更好的提高识别率和预测率
  • ChineseEmbedding Chinese Embedding ...中文自然语言处理向量合集,包括字向量,拼音向量,词向量,词性向量,依存关系向量.共5种类型的向量. 项目地址:https://github.com/liuhuanyong 项目简介 目前不同于on...
  • 如何训练一个词向量

    千次阅读 2019-09-26 16:14:02
    现在在NLP领域,词向量是一切自然语言处理的基础,有了词向量我们就可以进行数据分析,文本聚类分类的一系列操作了。接下来我们就开始学习如何训练词向量,之前我们有介绍关于 word2vec 的博文 word2vec算法理解和...
  • n维向量

    千次阅读 2019-09-10 19:43:18
    向量的定义 由n个数a1, a2, …, an组成的一个有序数组 称为一个n维向量. a=(a1a2...an)a=\begin{pmatrix} a_{1}\\ a_{2}\\ ...\\ a_{n} \end{pmatrix}a=⎝⎜⎜⎛​a1​a2​...an​​⎠⎟⎟⎞​ 若干个同维数的...
  • 估计某个点的法向量,可以类似于点云的曲面法向量估计,将该点附近K近邻的点近似在一个局部平面上,之后就通过最小二乘法拟合该平面方程.本代码是基于PCL库,往库中添加新的法向量估计。
  • 3d数学之向量详解

    千次阅读 2019-06-01 21:00:57
    游戏中一般以二维向量跟三维向量居多,例如一个由A点指向B点的向量,可以表示为AB⃗\vec{AB}AB,由于向量是有方向的,因此向量AB⃗\vec{AB}AB与向量BA⃗\vec{BA}BA并不等价 二维向量的表示为V=(...
  • 向量检索的搜索引擎实现

    千次阅读 2019-07-16 01:13:17
    融合对比是指用第一步得到的词向量、第二步得到的类目向量、第三步得到的doc向量加权求和得到的向量,定义为doc4,与上面定义的doc2,即第二步融合之后的向量的对比。 4. 参考 Deep Learning在O2O搜索相关性中的...
  • 向量基础知识

    千次阅读 2018-07-05 18:36:02
     向量的加法满足平行四边形法则和三角形法则.  AB+BC=AC. a+b=(x+x′,y+y′). a+0=0+a=a.AB+BC=AC. a+b=(x+x′,y+y′). a+0=0+a=a.  AB+BC=AC.  a+b=(x+x',y+y').  a+0=0+a=a.    向量加法的运算律: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 688,272
精华内容 275,308
关键字:

向量