深度学习基础知识之线性代数

575 阅读17分钟

线性代数

标量、向量、矩阵和张量

  • 标量(scalar):一个标量就是一个单独的数。我们用斜体表示标量。标量通常被赋予小写的变量名称。当我们介绍标量时,会明确它们是属于哪种类型的数。比如,在定义实数标量时,我们可能会说“令s\in{R}表示表示一条线的斜率”;在定义自然数标量时,我们可能会说“令n\in{N}表示元素的数目”。
  • 向量(vector):一个向量就是一列数。这些数时有序排列的。通过次序中的索引,我们可以确定每个单独的数。通常我们赋予向量粗体的小写的变量名称,比如x。向量中的元素可以通过带下标的斜体表示。向量x的第一个元素是x_1,第二个元素是x_2,等等。我们也会注明存储在向量中的元素是什么类型的。如果每个元素都属于R,并且该向量有n个元素,那么该向量属于实数集Rn次笛卡尔乘积构成的集合,记为R^n。需要明确表达向量中元素时,我们会将元素排列成一个方括号包围的纵列:

x = \begin{bmatrix}x_1\\x_2\\.\\.\\.\\x_n\end{bmatrix}

我们可以把向量看作空间上的点,每个元素时不同坐标轴上的坐标。
有时我们需要索引向量中的一些元素。在这种情况下,我们定义一个包含这些元素索引的集合,然后将该集合写在下标处。比如,指定x_1, x_3, x_6,我们定义集合S = \{1, 3, 6\},然后写作x_S。我们用符号-表示集合的补集中的索引。比如x_{-1}表示x中除x_1外的所有元素,x_{-S}表示x中除x_1,x_3,x_6外所有元素构成的向量。

  • 矩阵(matrix):矩阵是一个二维数据,其中的每一个元素被两个索引所确定。我们通常会赋予矩阵粗体的大写变量名称,比如A。如果一个实数矩阵高度为m,宽度为n,那么我们说A \in R^{m{\times}n}。我们在表示矩阵元素时,通常用其斜体名称,索引用逗号间隔。比如A_{1,1}表示A第一行第一列的元素,A_{m,n}表示A第m行第n列的元素。我们通常用“:”表示水平坐标,以表示垂直坐标i中的所有元素。比如,A_{i,:}表示A中垂直坐标i中的一横排元素。这也被成为A的第i行(row)。同样的,A_{:,j}表示A的第j列(column)。当我们需要表示矩阵中的元素时,我们将他们写在用方括号表示的数组中:

\begin{bmatrix}A_{1,1} & A_{1,2} \\ A_{2,1} & A_{2,2}\end{bmatrix}

  • 张量(tensor):在某些情况下,我们会讨论坐标超过两维的数组。一般地,一个数组中元素分布在若干维坐标的规则网格中,我们称之为张量。我们使用字体A来表示张量“A”。张量A中坐标为(i,j,k)的元素记作A_{i,j,k}

转置(transpose)是矩阵的重要操作之一。矩阵的转置是以对角线为轴的镜像,这条从左上角到右下角的对角线称之为主对角线(main diagonal)。我们将矩阵A的转置表示为A^T,定义如下:

(A^T)_{i,j} = A_{j,i}

向量可以看作只有一列的矩阵。对应地,向量的转置可以看作是只有一行的矩阵。有时,我们可以已下方式来定义一个向量,比如x = [x_1, x_2, x_3]^T

标量可以看作是只有一个元素的矩阵。因此,标量的转置等于它本身,a=a^T

只要矩阵的形状一样,我们可以把两个矩阵相加。比如C = A + B, 其中C_{i,j} = A_{i,j} + B_{i,j}

标量和矩阵相乘或者相加时,我们只需要将其与矩阵的每个元素相乘或相加,比如D = a {\cdot} B + c,其中D_{i,j} = a {\cdot} B_{i,j} + c

在深度学习中,我们也使用一些不常规的符号。我们允许矩阵和向量相加,产生另一个矩阵,C = A + b,其中C_{i,j} = A_{i,j} + b_j。这种隐式的复制向量b到很多位置的方式,被称为广播(broadcasting)。

矩阵和向量相乘

两个矩阵AB矩阵乘积(matrix product)是第三个矩阵C。为了使乘法定义良好,矩阵A的列数必须和矩阵B的行数一致。如果矩阵A的形状为m{\times}n,矩阵B的形状是n{\times}p,那么矩阵C的形状就是m{\times}p。我们可以通过将两个或多个矩阵并列放置以书写矩阵乘法,例如

C = AB

具体地,该乘法操作定义为

C_{i,j} = \sum_{k}{A_{i,k}}{B_{k,j}}

需要注意的是,两个矩阵的标准乘积不是指两个矩阵中对应元素的乘积。不过,那样的矩阵操作确实存在,被称为元素对应乘积(element-wise product)或Hadamard乘积(Hahdamard product),记作A{\odot}B

两个相同维数的向量xy点积(dot product)可看作矩阵乘积x^Ty。我们可以把矩阵乘积C=AB中计算C_{i,j}的步骤看作A的第i行和B的第j列之间的点积。

矩阵乘积运算符合分配律:

A(B+C) = AB + AC

矩阵乘积运算也符合结合律:

A(BC) = (AB)C

矩阵乘积运算不满足交换律。然而,两个向量的点积满足交换律:

x^Ty = y^Tx

矩阵乘积的转置有着简单的形式:

(AB)^T = B^TA^T

利用两个向量的点积是个标量,标量转置是自身的事实,可以证明向量点积交换律

x^Ty = (x^Ty)^T = y^Tx

现在我们已经了解了足够多的线性代数符号,可以表达下列线性方程组:

Ax=b

其中A \in R^{m{\times}n} 是一个已知矩阵, b \in R^m 是一个已知向量,x \in R^n是我们要求解的位置向量。向量x的每一个元素x_i都是未知的。矩阵A的每一行和b中对应的元素构成一个约束。我们可以把上式重写为:

A_{1,:}x = b_1 \\ A_{2,:}x = b_2 \\ {\cdot}{\cdot}{\cdot} \\ A_{m,:}x = b_m

或者更明确的写成:

A_{1,1}x_1 + A_{1,2}x_2 + {\cdot}{\cdot}{\cdot} + A_{1,n}x_n = b_1 \\ A_{2,1}x_1 + A_{2,2}x_2 + {\cdot}{\cdot}{\cdot} + A_{2,n}x_n = b_2 \\ {\cdot}{\cdot}{\cdot} \\A_{m,1}x_1 + A_{m,2}x_2 + {\cdot}{\cdot}{\cdot} + A_{m,n}x_n = b_m

单位矩阵和逆矩阵

线性代数提供了被称为矩阵逆(matrix inversion)的强大工具。对于大多数矩阵A,我们都能通过矩阵逆解析地求解式Ax=b

为了描述逆矩阵,我们首先定义单位矩阵(indentity matrix)地概念。任意矩阵与单位矩阵相乘,都不会改变。我们将保持n维向量不变的单位矩阵记作I_n。形式上,I_n \in R^{n{\times}n}

{\forall}x \in R^{n{\times}n}, I_nx = x

单位矩阵的结构, 比如I_3如下:

\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}

矩阵A矩阵逆(matrix inversion)记作A^{-1},其定义的矩阵满足如下条件:

A^{-1}A = I_n

我们现在通过以下步骤来求解Ax=b:

Ax = b \\ A^{-1}Ax=A^{-1}b \\ I_nx = A^{-1}b \\ x =A^{-1}b

这取决于我们能否找到一个逆矩阵A^{-1}

线性相关和生成子空间

如果逆矩阵A^{-1}存在,那么Ax=b肯定对于每一个向量b恰好存在一个解。但是对于方程组而言,对于向量b的某些值,有可能不存在解,或者存在无限多解。

为了分析方程有多少解,我们可以将A的列向量看作从原点(origin)(元素都是0的向量)出发的不同方向,确定有多少种方法到达向量b。在这个观点下,向量x中的每个元素表示我们应该沿着这些方向走多远,即x_i表示我们需要沿着第i个向量走多远:

Ax = \sum_{i}{x_iA_{:,i}}

一般而言,这种操作被称为线性组合(linear combination)。形式上,一组向量的线性组合,是指每个向量乘以对应标量系数之后的和,即:

\sum_{i}{c_i v^{(i)}}

一组向量的生成子空间(span)是原始向量线性组合后所能抵达的点的集合。

确定Ax=b是否有解相当于确定向量b是否在A列向量的生成子空间中。这个特殊的生成子空间被称为A列空间(column space)或者A值域(range)。

为了使得方程Ax=b对于任意向量b \in R^m都存在解,我们要求A的列空间构成整个R^m。如果R^m中的某个点不在A的列空间中,那么该点对应的b会使得该方程没有解。矩阵A的列空间是整个R^m的要求,那么意味着A至少有m列,即n{\geq}m。否则,A列空间的维数会小于m

不等式n{\geq}m仅是方程对每一点都有解的必要条件,因为有些列向量可能冗余。

正式地说,这种冗余被称为线性相关(linear dependence)。如果一组向量中地任意一个向量都不能表示成其他向量的线性组合,那么这组向量被称为线性无关(linear independent)。由此可知,如果一个矩阵的列空间涵盖整个R^m,那么该矩阵至少包含一组m个线性无关的向量。这就是式Ax=b对于每一个向量b的取值都有解的充分必要条件。需要注意的是,一个m维向量的集合不可能存在多于m个彼此线性不相关的列向量,但是对于一个有多于m个列向量的矩阵有可能拥有不止一个大小为m的线性无关向量集。

要想使矩阵可逆,我们还需要保证式Ax=b对于每一个b值至多一个解。对此,我们需要确保该矩阵至多有m个列向量。否则,该方程会有不止一个解。

综上所述,这意味着这个矩阵必须是一个方阵(square),即m=n,并且所有列向量都是线性无关的。一个列向量线性相关的方阵被称为奇异的(singular)。

如果矩阵A不是一个方阵或者是一个奇异的方阵,该方程仍然可能有解。但是我们不能用逆矩阵去求解。

目前为止,我们已经讨论了逆矩阵左乘。我们也可能定义逆矩阵右乘:

AA^{-1}=I

对于方阵而言,它的左逆和右逆是相等的。

范数

有时候我们需要衡量一下向量的大小。在机器学习中,我们经常使用被称为范数(norm)的函数衡量向量大小。形式上,L^p范数定义如下:

{\|x\|}_p = (\sum_{i} |x_i|^p)^{(\frac 1 p)}

其中p \in R, p \geq 1

范数(包括L^p范数)是将向量映射到非负值的函数。直观上来说,向量x的范数衡量从原点到点x的距离。更严格的来说,范数是满足以下性质的任意函数:

f(x) = 0 \Rightarrow x = 0 \\ f(x+y) \leq f(x) + f(y) \\ \forall \alpha \in R, f({\alpha}x) = |\alpha|f(x)

p=2时,L^2范数被称为欧几里得范数(Euclidean norm)。它表示从原点出发到向量x确定的点的欧几里得距离。L^2范数在机器学习中出现地十分频繁,经常简化为{\|x\|},略去了下标2。平方L^2范数也经常用来衡量向量的大小,可以简单的由点积x^Tx计算。

由于L^2范数在原点附近增长的十分缓慢,当机器学习问题中零和非零元素之间的差异非常重要时,通常会使用L^1范数:

{\|x\|}_1 = \sum_i |x_i|

另一个经常在机器学习中经常出现的范数是L^{\infty}范数,也被称为最大范数(max norm)。这个范数表示向量中具有最大增幅的元素的绝对值:

\|x\|_{\infty} = \underset{i} max |x_i|

有时候我们也可能衡量矩阵的大小。在深度学习中,最常见的做法是使用Frobenius范数(Frobenius norm),

{\|A\|}_F = \sqrt {\sum_{i,j} A_{i,j}^2}

其类似于向量的L^2范数。

两个向量的点积可以用范数来表示,

x^Ty = {\|x\|}_2\|y\|_2\cos\theta

其中\theta表示xy之间的夹角。

特殊类型的矩阵和向量

对角矩阵(diagonal matrix)只在主对角线含有非零元素,其他位置都是零。形式上,矩阵D是对角矩阵,当且仅当对于所有i{\neq}jD_{i,j}=0。单位矩阵就是一个对角矩阵。我们用diag(v)表示一个对角元素由向量v中元素给定的对角矩阵。计算乘法diag(v)x,我们只需要将x的每个元素x_i放大v_i倍。换而言之,diag(v)x = v {\odot} x。对于对角矩阵,其逆矩阵存在,当且仅当对角元素都是非零值,在这种情况下,diag(v)^{-1} = diag([1/v_1,...,1/v_n]^T)。在某些机器学习算法中,通过将一些矩阵限制为对角矩阵,可以得到一些计算代价较低的算法。

不是所有的对角矩阵都是方阵。长方形的矩阵也有可能是对角矩阵。非方阵的对角矩阵没有逆矩阵,但我们仍然可以高效地计算它们地乘法。

对称(symmetric)矩阵是转置和自己相等的矩阵:

A=A^T

当某些不依赖参数顺序的双参数函数生成元素时,对称矩阵经常出现。例如,如果A是一个距离度量矩阵,A_{i,j}表示点ij的距离,那么A_{i,j} = A_{j,i},因为距离函数是对称的。

单位向量(unit vector)是具有单位范数(unit norm)的向量:

{\|x\|}_2 = 1

如果x^Ty = 0,那么向量xy互相正交(orthogonal)。如果两个都有非零范数,那么这两个向量之间的夹角为90度。在R^n中,至少有n个范数非零向量正交。如果这些向量不仅正交,并且范数都是1,那么我们称之为标准正交(orthonormal)。

正交矩阵(orthogonal matrix)是指行向量和列向量是分别标准正交的方阵:

A^TA = AA^T = I

这意味着

A^{-1} = A^T

所以正交矩阵收到关注是因为求逆计算代价小。

特征分解

特征分解(eigendecomposition)是使用最广的矩阵分解之一,即我们将矩阵分解成一组特征向量和特征值。

方阵A特征向量(eigenvector)是指与A相乘后相当于对该向量进行缩放的非零向量v:

Av = {\lambda}v

标量\lambda被称为这个特征向量对应的特征值(eigenvalue)。(类似地,我们也可以定义左特征向量(left eigenvector) v^TA = {\lambda}v^T,但通常我们更关注右特征向量(right eigenvector))。

如果vA地特征向量,那么任意缩放后的向量sv(s \in R, s \neq 0)也是A的特征向量。此外,svv有相同的特征值。基于这个原因,我们通常只考虑单位特征向量。

假设矩阵An个线性无关的特征向量\{v^{(1)},...,v^{(n)}\},对应着特征值\{{\lambda}_1,...,{\lambda}_n\}。我们将特征向量连接成一个矩阵,使得每一列都是特征向量:

V = [v^{(1)},...,v^{(n)}]

类似地,我们可以将特征值连接成一个向量

{\lambda} = [{\lambda}_1,...,{\lambda}_n]^T

因此A特征分解(eigendecomposition)可以记作

A = Vdiag({\lambda})V^{-1}

每个实对称矩阵都可以分解成实特征向量和实特征值:

A = Q{\Lambda}Q^T

其中QA的特征向量组成的正交矩阵,\Lambda是对角矩阵。特征值\Lambda_{i,i}对应的特征向量是矩阵Q的第i列,记作Q_{:,i}。因为Q是正交矩阵,我们可以将A看作沿方向v^{(i)}延展\lambda_i的空间。

矩阵的特征分解给了我们很多矩阵的有用信息。矩阵是奇异的当且仅当含有零特征值。实对称矩阵的特征分解也可以用于优化二次方程f(x) = x^TAx,其中限制\|x\|_2=1。当x等于A的特征向量时,f将返回对应的特征值。在限制条件下,函数f的最大值是最大特征值,最小值是最小特征值。

所有特征值都是正数的矩阵被称为正定(positive definite);所有特征值都是非负数的矩阵被称为半正定(positive semidefinite)。同样的,所有特征值都是负数的矩阵被称为负定(negative definite);所有特征值都是非正数的矩阵被称为半负定(negative semidefinite)。半正定矩阵收到关注是因为它们保证\forall x, x^TAx \geq 0。此外,正定矩阵还保证x^TAx = 0 \Rightarrow x = 0

奇异值分解

奇异值分解(singular value decomposition, SVD)是将矩阵分解成奇异向量(singular vector)和奇异值(singular value)。每一个实数矩阵都有一个奇异值分解,但不一定有特征分解。奇异值分解的形式如下:

A = UDV^T

假设A是一个m{\times}n的矩阵,那么U是一个m{\times}m的正交矩阵,D是一个m{\times}n的对角矩阵,V是一个n{\times}n的正交矩阵。注意,矩阵D不一定是方阵。

对角矩阵D对角线上的元素被称为矩阵A奇异值(singular value)。矩阵U的列向量被称为左奇异向量(left singular vector),矩阵V的列向量被称为右特征向量(right singular vector)。

A的左奇异向量是AA^T的特征向量。A的右奇异向量是A^TA的特征向量。A的非零奇异值是A^TA特征值的平方根,也是AA^T特征值的平方根。

Moore-Penrose伪逆

矩阵A的伪逆定义为:

A^+ = \lim_{{\alpha}{\rightarrow}0}(A^TA+{\alpha}I)^{-1}A^T

计算伪逆的实际算法并没有基于这个定义,而是使用下面的公式:

A^+ = VD^+U^T

其中,矩阵UDV是矩阵A奇异值分解后得到的矩阵。对角矩阵D的伪逆D^+是其非零元素取倒数之后再转置得到的。

当矩阵A的列数多于行数时,使用伪逆求解线性方程是众多可能解法中的一种。特别地,x=A^+y是方程所有可行解中欧几里得范数\|x\|_2最小的一个。

当矩阵A的行数多余列数时,可能没有解。在这种情况下,通过伪逆得到的x使得Axy的欧几里得距离{\|Ax-y\|}_2最小。

迹运算

迹运算返回的是矩阵对角元素的和:

Tr(A) = \sum_{i}A_{i,i}

迹运算提供了另一种描述Frobenius范数的方式:

\|A\|_F = \sqrt{Tr(AA^T)}

用迹运算,我们可以使用很多有用的等式来处理表达式。例如,迹运算在转置运算下是不变的:

Tr(A) = Tr(A^T)

多个矩阵相乘得到的方阵的迹,和将这些矩阵中的最后一个挪到最前面之后相乘的迹相同。当然,我们需要考虑挪动后矩阵乘积依然定义良好:

Tr(ABC) = Tr(CAB) = Tr(BCA)

或者更一般地,

Tr(\prod_{i=1}^nF^{(i)}) = Tr(F^{(n)}\prod_{i=1}^{n-1}F^{(i)})

即使矩阵置换后矩阵乘积得到地矩阵形状变了,迹运算地结果仍然不变。例如,假设矩阵A \in R^{m{\times}n}B \in R^{n{\times}m},我们可以得到

Tr(AB) = Tr(BA)

尽管AB \in R^{m{\times}m}BA \in R^{n{\times}n}

标量在迹运算中仍然是它自己:

a = Tr(a)

行列式

行列式,记作det(A),是一个将方阵A映射到实数地函数。行列式等于矩阵特征值地乘积。

实例:主成分分析

主成分分析(principal components analysis, PCA)是一个简单地机器学习算法,可以由基础地线性代数知识推导。

假设在R^n空间中我们由m个点\{x^{(1)},...,x^{(m)}\},我们希望对这些点进行有损压缩。有损压缩表示我们可以使用更少地内存,但损失一些精度去存储这些点。我们希望损失的精度尽可能少。

一种编码这些点的方式是用低维表示。对于每个点x^{(i)} \in R^n,会有一个对应的编码向量c^{(i)} \in R^l。如果ln小,那么我们便使用了更少的内存来存储原来的数据。我们希望找到一个编码函数,根据输入返回编码,f(x)= c;我们也希望找到一个解码函数,给定编码重构输入,x{\approx}g(f(x))

PCA由我们的解码函数而定。具体的,为了简化解码器,我们使用矩阵乘法将编码映射回R^n,即g(c)=Dc,其中D{\in}R^{n{\times}l}是定义解码的矩阵。

为了使问题有唯一解,我们限制D中所有列向量都有单位范数。 为了使得解码问题简单,PCA限制D的列向量彼此正交(注意,除非l=n,否则严格意义上D不是一个正交矩阵)。

为了将这个基本想法变成我们能够实现的算法,首先我们需要明确如何根据每一个输入x得到一个最优编码c^*。一种方法是最小化原始输入向量x和重构向量g(c^*)之间的距离。在PCA算法中,我们使用L^2范数:

c^*=\underset{c}{argmin}{\|{x-g(c)}\|}_2

我们可以用平方L^2范数替代L^2范数,

c^*=\underset{c}{argmin}{\|{x-g(c)}\|}_2^2

该最小化函数可以简化为

(x-g(c))^T(x-g(c)) \\ =x^Tx-x^Tg(c)-g(c)^Tx+g(c)^Tg(c) \\ = x^Tx - 2x^Tg(c) + g(c)^Tg(c)

因为第一项x^Tx不依赖于c,所以我们可以忽略他,得到以下的优化目标:

c^* = \underset{c}{argmin} - 2x^Tg(c) + g(c)^Tg(c) \\ = \underset{c}{argmin}-2x^TDc+c^TD^TDc \\ = \underset{c}{argmin} - 2x^TDc + c^TI_lc \\ = \underset{c}{argmin} - 2x^TDc + c^Tc

我们可以用向量微积分解决这个问题

\nabla_c(-2x^TDc+c^Tc) = 0 \\ -2D^Tx + 2c = 0 \\ c = D^Tx

这使得算法很高效:最优编码x只需要一个矩阵-向量乘法操作。为了编码向量,我们使用编码函数:

f(x) = D^Tx

进一步使用矩阵乘法,我们也可以定义PCA重构操作:

r(x) = g(f(x)) = DD^Tx

接下来,我们需要挑选解码矩阵D。我们最小化所有维数和所有点上的误差矩阵的Frobenius范数:

D^* = \underset{D}{argmin}\sqrt{\sum_{i,j}{(x_j^{(i)} - r(x^{(i)})_j)^2}} \;{subject}\;{to}\;D^TD=I_l

为了推导用于寻求D^*的算法,我们首先考虑l=1的情况。在这种情况下,D是一个单一向量d。现在问题就简化为

D^* = \underset{d}{argmin}{\sum_{i}\|{(x^{(i)} - dd^Tx^{(i)})\|_2^2}} \;{subject}\;{to}\;\|d\|_2=1

由于d^Tx^{(i)}是标量,上式可以写成

D^* = \underset{d}{argmin}\sum_{i}\|{(x^{(i)} - x^{(i)T}dd\|_2^2} \;{subject}\;{to}\;\|d\|_2=1

将表示各点的向量堆叠成一个矩阵,记作X \in R^{m{\times}n}, 其中X_{i,:} = x^{(i)T},则可以重新表述为:

D^* = \underset{d}{argmin}{\|{X - Xdd^T\|_F^2}} \;{subject}\;{to}\;\|d\|_2=1

暂时不考虑约束,我们可以将Frobenius范数简化成下面的形式

\underset{d}{argmin}\|X-Xdd^T\|_F^2 \\ = \underset{d}{argmin}Tr((X-Xdd^T)^T(X-Xdd^T)) \\ = \underset{d}{argmin}Tr(X^TX-X^TXdd^T-dd^TX^TX + dd^TX^TXdd^T) \\ = \underset{d}{argmin}Tr(X^TX) - Tr(X^TXdd^T) - Tr(dd^TX^TX) + Tr(dd^TX^TXdd^T) \\ = \underset{d}{argmin} - Tr(X^TXdd^T) - Tr(dd^TX^TX) + Tr(dd^TX^TXdd^T) \\ = \underset{d}{argmin} - 2Tr(X^TXdd^T) + Tr(dd^TX^TXdd^T) \\ = \underset{d}{argmin} -2Tr(X^TXdd^T) + Tr(X^TXdd^Tdd^T)

在考虑约束条件:

\underset{d}{argmin} -2Tr(X^TXdd^T) + Tr(X^TXdd^Tdd^T)\;subject\;to\;d^Td=1 \\ = \underset{d}{argmin} -2Tr(X^TXdd^T) + Tr(x^TXdd^T)\;subject\;to\;d^Td=1 \\ =\underset{d}{argmin} -Tr(X^TXdd^T)\;subject\;to\;d^Td=1 \\ = \underset{d}{argmax} Tr(X^TXdd^T)\;subject\;to\;d^Td=1 \\ = \underset{d}{argmax} Tr(d^TX^TXd)\;subject\;to\;d^Td=1

这个优化问题可以通过特征分解来求解。具体来讲,最优的dX^TX最大特征值对应的特征向量。