普通视图

发现新文章,点击刷新页面。
昨天以前Sanzo's Blog

线性代数

作者 Sanzo
2021年6月13日 17:09

线性代数笔记。

基础知识

行列式

二阶行列式

$\begin{vmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{vmatrix} = a_{11}a_{22} - a_{12}a_{21}$

三阶行列式

$ \begin{vmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{vmatrix} = a_{11}a_{22}a_{33} + a_{12}a_{23}a_{31} + a_{13}a_{21}a_{32} -a_{13}a_{22}a_{31} - a_{23}a_{32}a_{11} - a_{33}a_{12}a_{21}$

image-20210111133613519

对于更高阶的行列式,一般将行列式转为三角形,这样只用计算对角线的乘积即可。

余子式

$n$阶行列式,把第$a_{ij}$所在的行列删除,留下的$n-1$阶行列式称为余子式,记为$M_{ij}$。

image-20210111133933964

代数余子式

代数余子式的$A_{ij} = -1^{i+j}M_{ij}$。

伴随矩阵

代数余子式的转置称为伴随矩阵,只有方阵才有伴随矩阵,记为$A^*$。

伴随矩阵的性质:

$AA^* = A^*A = |A|E$

$A^{-1} = \frac{1}{|A|}A^*(存在A^{-1})$

$(A^*)^{-1}=(A^{-1})^*=\frac{1}{|A|}A$

$|A^*|=|A|^{n-1}$

$(kA)^*=k^{n-1}A^*$

矩阵的逆

$A^{-1} = \frac{1}{|A|}A^*(存在A^{-1})$

$A^{-1} = \frac{1}{|A|}A^{*}=\frac{1}{ad-bc}\begin{bmatrix}d &-b\ -c & a\end{bmatrix}$

例:

$\begin{bmatrix}1&-1\\1&1 \end{bmatrix}^{-1} = \frac{1}{2}\begin{bmatrix}1&1\\-1&1 \end{bmatrix}$

线性代数的本质

b站视频链接

什么是向量

向量对于不同的学科有不一样的定义。

物理中的向量有长度方向决定,长度和方向不变可以随意移动,它们表示的是同一个向量。

计算机中的向量更多的是对数据的抽象,可以根据面积和价格定义一个房子$\begin{bmatrix}100m^2\\700000¥\end{bmatrix}$。

数学中的向量可以是任意东西,只要保证两个向量的相加$\vec v + \vec w$以及数字和向量相乘$2\vec v$是有意义的即可。

线性代数中的向量可以理解为一个空间中的箭头,这个箭头起点落在原点。如果空间中有许多的向量,可以点表示一个向量,即向量头的坐标。

向量的基本运算

向量的加法:可以理解为在坐标中两个向量的移动。

$\begin{bmatrix} 1 \\ 2 \end{bmatrix} + \begin{bmatrix} 3 \\ -1 \end{bmatrix} = \begin{bmatrix} 4 \\ 1 \end{bmatrix}$

image-20200919202730552

数字和向量相乘:可以理解为向量的缩放。

$2\begin{bmatrix} 3 \\ 1 \end{bmatrix}=\begin{bmatrix} 6 \\ 2 \end{bmatrix}$

image-20200919202902807

线性组合、张成空间、基

线性组合

两个数乘向量称为两个向量的线性组合$a\vec v+ b\vec w$。

两个不共线的向量通过不同的线性组合可以得到二维平面中的所有向量。

两个共线的向量通过线程组合只能得到一个直线的所有向量。

如果两个向量都是零向量那么它只能在原点。

张成空间

所有可以表示给定向量线性组合的向量的集合称为给定向量的张成空间(span)。

一般来说两个向量张成空间可以是直线、平面。

三个向量张成空间可以是平面、空间。

如果多个向量,并且可以移除其中一个而不减小张成空间,那么它们是线性相关的,也可以说一个向量可以表示为其他向量的线性组合$\vec u = a \vec v + b\vec w$。

如果所有的向量都给张成的空间增加了新的维度,它们就成为线性无关的$\vec u \neq a \vec v + b\vec w$。

向量空间的一组及是张成该空间的一个线性无关向量集。

矩阵与线性变换

严格意义上来说,线性变换是将向量作为输入和输出的一类函数。

变化可以多种多样,线性变化将变化限制在一个特殊类型的变换上,可以简单的理解为网格线保持平行且等距分布。

线性变化满足一下两个性质:

  • 线性变化前后直线依旧是直线不能弯曲。
  • 原点必须保持固定。

image-20200919212207688

可以使用基向量来描述线性变化

通过记录两个基向量$\hat{i}$,$\hat{j}$的变换,就可以得到其他变化后的向量。

已知向量$\vec v = \begin{bmatrix}-1\\2\end{bmatrix}$

变换之前的$\hat i$和$\hat j$:

$$\hat{i} = \begin{bmatrix}1 \\ 0 \end{bmatrix} \\ \hat{j} = \begin{bmatrix}0 \\ 1 \end{bmatrix} \\\vec{v} = -1\hat{i} + 2 \hat{j} = \begin{bmatrix}-1 \\ 2 \end{bmatrix}$$
变换之后的$\hat i$和$\hat j$:
$$\begin{aligned}\hat{i} = \begin{bmatrix}1 \\ -2 \end{bmatrix} \\ \hat{j} = \begin{bmatrix}3 \\ 0 \end{bmatrix} \\\vec{v} = -1\hat{i} + 2 \hat{j} &= \begin{bmatrix}5 \\ 2 \end{bmatrix} \\ &= -1\begin{bmatrix}1 \\ -2 \end{bmatrix} + 2 \begin{bmatrix}3 \\ 0 \end{bmatrix} \\ &= \begin{bmatrix}1 & 3 \\ -2 & 0 \end{bmatrix} \begin{bmatrix}-1 \\ 2 \end{bmatrix} \\ &= \begin{bmatrix}5 \\ 2 \end{bmatrix} \\\end{aligned}$$
我们可以将变换后的$\hat i$和$\hat j$写成矩阵的形式:$\begin{bmatrix}1 & 3 \\ -2 & 0 \end{bmatrix} \begin{bmatrix}-1 \\ 2 \end{bmatrix}$,通过矩阵的乘法得到变化后的向量。

image-20200919214800453

image-20200919214828033

image-20200919214904438

image-20200919214934222

如果变化后的$\hat{i}$和$\hat{j}$是线性相关的,变化后向量的张量就是一维空间:

image-20200919215136876

矩阵乘法与线性变换复合的联系

线性变化的复合

如何描述先旋转再剪切的操作呢?

一个通俗的方法是首先左乘旋转矩阵然后左乘剪切矩阵

image-20200919221913292

两个矩阵的乘积需要从右向左读,类似函数的复合。

image-20200919221959763

这样两个矩阵的乘积就对应了一个复合的线性变换,最终得到对应变换后的$\hat{i}$和$\hat{j}$。

image-20200919222849490

image-20200919222936127

这一过程具有普适性:

image-20200919223010638

矩阵乘法的顺序

image-20200919223307428

image-20200919223234205

image-20200919223255780

如何证明矩阵乘法的结合性?

$(AB)C = A(BC)$

根据线性变化我们可以得出,矩阵的乘法都是以CBA的顺序变换得到,所以他们本质上相同,通过变化的形式解释比代数计算更加容易理解。

image-20200919223807543

三维空间的线性变化

三维的空间变化和二维的类似。

image-20200919231921745

同样跟踪基向量的变换,能很好的解释变换后的向量,同样两个矩阵相乘也是。

image-20200919233624101

行列式

行列式的本质

行列式的本质是计算线性变化对空间的缩放比例,具体一点就是,测量一个给定区域面积增大或减小的比例。

单位面积的变换代表任意区域的面积变换比例。

image-20200920130814473

image-20200920130933473

image-20200920130915512

行列式的值表示缩放比例。

image-20200920131118018

image-20200920131210961

行列式为什么有负值呢?

三维空间的行列式类似,它的单位是一个单位1的立方体。

三位空间的线性变换,可以使用右手定则判断三维空间的定向。如果变换前后都可以通过右手定则得到,那么他的行列式就是正值,否则为负值。

image-20200920132802227

image-20200920132900515

行列式的计算

二阶行列式

image-20200920133432426

三阶行列式

image-20200920133410970

二阶行列式中a、d,表示横向和纵向的拉伸,b、c表示对角线的拉伸和压缩的情况。

image-20200920133555705

逆矩阵、列空间、秩、零空间

线性方程组

image-20200920141506454

从几何的角度来思考,矩阵A表示一个线性变换,我们需要找到一个$\vec x$使得它在变换后和$\vec v$重合。

逆矩阵

矩阵的逆运算,记为$\vec A = \begin{bmatrix}3&1 \\0&2\end{bmatrix}^{-1}$,对于线程方程$A \vec x = \vec v $来说,找到$A^{-1}$就得到解$\vec x = A^{-1} \vec v$。

$A^{-1}A=\begin{bmatrix}1&0 \\ 0&1 \end{bmatrix}$,什么都不做称为恒等变换。

线性方程组的解

对于方程组$A\vec x = \vec v$,线性变换A存在两种情况:

$det(A) \neq0$:这时空间的维数并没有改变,有且只有一个向量经过线性变换后和$\vec v$重合。

$det(A) =0$:空间被压缩到更低的维度,这时不存在逆变换,因为不能将一个直线解压缩为一个平面,这样就会映射多个向量。但是即使不存在逆变换,解可能仍然存在,因为目标$\vec v$刚好落在压缩后的空间上。

秩代表变换后空间的维度。

如果线性变化后将空间压缩成一条直线,那么称这个变化的秩为1;

如果线性变化后向量落在二维平面,那么称这个变化的秩为2。

列空间

所有可能的输出向量$A\vec v$构成的集合,称为列空间,即所有列向量张成的空间。

零空间(Null space)

所有的线性变化中,零向量一定包含在列空间中,因为线性变换原点保持不动。对于非满秩的情况来说,会有一系列的向量在变换后仍为零向量。

二维空间压缩为一条直线,一条线上的向量都会落到原点。

三维空间压缩为二维平面,一条线上的向量都会落到原点。

三维空间压缩为一条直线,整个平面上的向量都会落到原点。

当$A\vec x = \vec v$中的$\vec v$是一个零向量,即$A\vec x = \begin{bmatrix}0 \\0\end{bmatrix}$时,零空间就是它所有可能的解。

非方阵、不同维度空间之间的线性变换

不同维度的变换也是存在的。

一个$3\times2$的矩阵:$\begin{bmatrix}2&0\-1&1\-2&1 \end{bmatrix}$它的集合意义是将一个二维空间映射到三维空间上,矩阵有两列表明输入空间有两个基向量,有三行表示每个向量在变换后用三个独立的坐标描述。

image-20200921204842378

一个$2\times 3$的矩阵:$\begin{bmatrix}3&1&4\1&5&9 \end{bmatrix}$则表示将一个三维空间映射到二维空间上。

image-20200921204804360

一个$1\times 2$的矩阵:$\begin{bmatrix}1&2 \end{bmatrix}$表示一个二维空间映射到一维空间。

image-20200921205137915

点积与对偶性

点积

对于两个维度相同的向量,他们的点积计算为:$\begin{bmatrix}1\\2\end{bmatrix}\cdot\begin{bmatrix} 3\\4\end{bmatrix}=1\cdot3+2\cdot4=11$。

点积的几何解释是将一个向量向一个向量投影,然后两个长度相乘,如果为负数则表示反向。

image-20200921213129723

为什么点积和坐标相乘联系起来了?这和对偶性有关。

对偶性

对偶性的思想是:每当看到一个多维空间到数轴上的线性变换时,他都与空间中的唯一一个向量对应,也就是说使用线性变换和与这个向量点乘等价。这个向量也叫做线性变换的对偶向量

当二维空间向一维空间映射时,如果在二维空间中等距分布的点在变换后还是等距分布的,那么这种变换就是线性的。

假设有一个线性变换A$\begin{bmatrix}1&-2\end{bmatrix}$和一个向量$\vec v=\begin{bmatrix}4\\3\end{bmatrix}$。

变换后的位置为$\begin{bmatrix}1&-2\end{bmatrix}\begin{bmatrix}4\\3\end{bmatrix}=4\cdot1+3\cdot-2=-2$,这个变换是一个二维空间向一维空间的变化,所以变换后的结果为一个坐标值。

我们可以看到线性变换的计算过程和向量的点积相同$\begin{bmatrix}1\\-2\end{bmatrix}\cdot\begin{bmatrix}4\\3\end{bmatrix}=4\cdot1+3\cdot-2=-2$,所以向量和一个线性变化有着微妙的联系。

假设有一个倾斜的数轴,上面有一个单位向量$\vec v$,对于任意一个向量它在数轴上的投影都是一个数字,这表示了一个二维向量到一位空间的一种线性变换,那么如何得到这个线性变化呢?

image-20200921215610833

由之前的内容来说,我们可以观察基向量$\vec i$和$\vec j$的变化,从而得到对应的线性变化。

image-20200921215905156

因为$\vec i$、$\vec j$、$\vec u$都是单位向量,根据对称性可以得到$\vec i$和$\vec j$在$\vec u$上的投影长度刚好是$\vec u$的坐标。

image-20200921220129867

image-20200921220208217

这样空间中的所有向量都可以通过线性变化$\begin{bmatrix}u_x&u_y \end{bmatrix}$得到,而这个计算过程刚好和单位向量的点积相同。

image-20200921220552315

也就是为什么向量投影到直线的长度,刚好等于它与直线上单位向量的点积,对于非单位向量也是类似,只是将其扩大到对应倍数。

叉积

对于两个向量所围成的面积来说,可以使用行列式计算,将两个向量看作是变换后的基向量,这样通过行列式就可以得到变换后面积缩放的比例,因为基向量的单位为1,所以就得到了对应的面积。

考虑到正向,这个面积的值存在负值,这是参照基向量$\vec i$和$\vec j$的相对位置来说的。

image-20200922102602172

image-20200922102722945

真正的叉积是通过两个三维向量$\vec v$和$\vec w$,生成一个新的三维向量$\vec u$,这个向量垂直于向量$\vec v$和$\vec w$所在的平面,长度等于它们围成的面积。

叉积的反向可以通过右手定则判断:

image-20200922103452143

叉积的计算方法:

image-20200922103702614

image-20200922103629488

线性代数看叉积

参考二维向量的叉积计算:

image-20200922122052167

三维的可以写成类似的形式,但是他并是真正的叉积,不过和真正的叉积已经很接近了。

image-20200922122142162

我可以构造一个函数,它可以把一个三维空间映射到一维空间上。

image-20200922122515739

右侧行列式是线性的,所以我们可以找到一个线性变换代替这个函数。

image-20200922122703239

根据对偶性的思想,从多维空间到一维空间的线性变换,等于与对应向量的点积,这个特殊的向量$\vec p$就是我们要找的向量。

image-20200922122835340

从数值计算上:

image-20200922123007736

image-20200922123018405

向量$\vec p$的计算结果刚好和叉积计算的结果相同。

从几何意义:

image-20200922122835340

当向量$\vec p$和向量$\begin{bmatrix}x\y\z \end{bmatrix}$点乘时,得到一个$\begin{bmatrix}x\y\z \end{bmatrix}$与$\vec v$与$\vec w$确定的平行六面体的有向体积,什么样的向量满足这个性质呢?

点积的几何解释是,其他向量在$\vec p$上的投影的长度乘以$\vec p$的长度。

对于平行六面体的体积来说,它等于$\vec v$和$\vec w$所确定的面积乘以$\begin{bmatrix}x\y\z \end{bmatrix}$在垂线上的投影。

那么$\vec p$要想满足这一要求,那么它就刚好符合,长度等于$\vec v,\vec w$所围成的面积,且刚好垂直这个平面。

image-20200922123829003

image-20200922123858594

基变换

标准坐标系的基向量为$\vec {i}: \begin{bmatrix}1\\0 \end{bmatrix}$和$\vec {j}: \begin{bmatrix}0\\1 \end{bmatrix}$,假如詹妮弗有另一个坐标系:她的基向量为$\vec i \begin{bmatrix}2\\1 \end{bmatrix}$和$\vec j \begin{bmatrix}-1\\1 \end{bmatrix}$。

对于同一个点$\begin{bmatrix}3\\2 \end{bmatrix}$来说他们所表示的形式不同,在詹妮弗的坐标系中表示为$\begin{bmatrix}\frac{5}{3}\\\frac{1}{3} \end{bmatrix}$。

从标准坐标到詹尼佛的坐标系,我能可以得到一个线性变换$A:\begin{bmatrix}2&-1\\1&1 \end{bmatrix}$。

如果想知道詹妮弗的坐标系中点$\begin{bmatrix}3\\2 \end{bmatrix}$在标准坐标系的位置,可以通过$\begin{bmatrix}2&-1\\1&1 \end{bmatrix}\begin{bmatrix}3\\2 \end{bmatrix}$得到。

如果想知道标准坐标系中点$\begin{bmatrix}3\\2 \end{bmatrix}$在詹妮弗坐标系的位置,可以通过$\begin{bmatrix}2&-1\\1&1 \end{bmatrix}^{-1}\begin{bmatrix}3\\2 \end{bmatrix}$得到。

具体的例子,90°旋转。

在标准坐标系可以跟踪基向量的变化来体现:

image-20200922133429853

在詹妮弗的坐标系中如何表示旋转呢?首先将向量转换为标准坐标系的表示,然后左旋,最后再转换为詹妮弗的表示。

image-20200922133607455

所以我们可以得到对于詹妮弗坐标系的左旋线性变化的表示:

image-20200922133725994

所以表达式$A^{-1}MA$表示一种数学上的转移作用,$M$表示一种线性变换,$A$和$A^{-1}$表示坐标系的转换。

特征向量与特征值

对于一些线性变化来说,存在一些向量在变换前后留在了张成的空间里,只是拉伸或收缩了一定比例,这些向量称为特征向量,拉伸收缩的比例称为特征值。

GIF 2020-11-21 17-46-40

image-20200922152146060

一个三维空间的旋转,如果能找到特征值为1的特征向量,那么它就是旋转轴,因为旋转并不进行缩放,且旋转轴在线性变换中保持不变。

image-20200922152945686

特征向量的求解

特征向量的概念,等号左侧表示矩阵向量的乘积,等号右侧表示向量数乘,可以将右侧重写为某个向量的乘积,$\vec I$为单位向量。

image-20200922152931670

image-20200922153357401

求解等式,就是使左侧的行列式det为0,$\lambda$就是特征值。

image-20200922153527410

image-20201121180605568

求解$\lambda$对应的特征向量时,即求解满足$(A-\lambda I)\vec{X}=0$的所有向量$\vec{X}$。

image-20201121181300520

对应原始矩阵上所有落在$\begin{bmatrix} -1 \ 1 \end{bmatrix}$的向量被拉伸了2倍。

image-20201121181819854

二维线性变换不一定存在特征向量,例如左旋90°,每个想都都发生了旋转,离开了张成空间。如果强行计算,会得到两个虚根:

image-20200922154353867

剪切变换的特征向量分布在x轴:

image-20200922154541171

只有一个特征值,但是特征向量不一定只在一条直线上:

image-20200922154704668

特征基

一组基向量构成的集合被称为一组特征基

如果特征向量是基向量,它对应的矩阵是一个对角矩阵,矩阵的对角元是它们所属的特征值。

image-20201121182906650

对角矩阵在求幂次时更方便求解,对应的幂次就是对角元的幂次。

image-20201121183110982

而对于非对角矩阵的幂次求解就非常麻烦。

image-20201121183319365

实际遇到对角矩阵的概率很低,但是我们可以通过基坐标变换来得到对角矩阵,前提有足够多的特征向量且可以张成整个空间,例如剪切变化就不行,应为它只有一个特征向量,无法进行坐标变换。

image-20201121184627004

image-20200922155515737

image-20201121202207724

求解特征值:

$\begin{bmatrix}-\lambda&1\1&1-\lambda \end{bmatrix}\vec{X}=0$

$$\begin{bmatrix}-\lambda&1\\1&1-\lambda \end{bmatrix}\vec{X}=0 \\\lambda=\frac{1+\sqrt{5}}{2},\frac{1-\sqrt{5}}{2} \\将\lambda带入求导特征向量为:\vec{v_1}=\begin{bmatrix}2\\1+\sqrt{5}\end{bmatrix},\vec{v_2}=\begin{bmatrix}2\\1-\sqrt{5}\end{bmatrix}\\所以特征基为:P = \begin{bmatrix}2&2\\1+\sqrt{5}&1-\sqrt{5}\end{bmatrix}\\P^{-1}=\frac{1}{4\sqrt{5}}\begin{bmatrix}\sqrt{5}-1&2\\\sqrt{5}+1&-2\end{bmatrix}\\构造对角矩阵:M=P^{-1}AP=\frac{1}{2}\begin{bmatrix}7+3\sqrt{5}&0\\0&7-3\sqrt{5}\end{bmatrix}\\A=PMP^{-1}\\A^{n}=PMP^{-1}PMP^{-1}...PMP^{-1}=PM^{n}P^{-1}$$

抽象向量空间

线性的严格定义是:可加性和成比例性。

image-20200922163048868

和函数的求导类似,求导具有可加性和成比例性。

image-20200922163207612

image-20200922163213512

对于多项式的求导,我们也可以看成是矩阵的形式,将x的不同次幂看成基函数,这和多维空间的基向量类似。

image-20200922163437035

因为求导的可加性和成比例行,我们可以分别对每个基向量求导,从而得到左侧的矩阵。

image-20200922163605065

数学中有很多类似向量的事物,只要处理的对象具有数乘和相加的概念,都可以运行向量的基本性质。

对于发明向量的数学家来说,他不用考虑其他所有类似的向量,他只需要给出向量数乘和加法必须遵守的规则即定理,那么所有满足这些定理的对象,就可以使用向量所拥有的性质。

image-20200922164358498

image-20200922164421196

ubuntu配置

作者 Sanzo
2021年10月8日 09:52

ubuntu常用设置.

vim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sudo apt install vim

# 添加配置文件
vim ~/.vimrc

"set paste
"set nopaste
set expandtab
set softtabstop=2
set autoindent
set tabstop=2
set shiftwidth=2
set nu
syntax on
set mouse=a "支持鼠标滑轮
set mouse=v "支持鼠标选中复制
"set viminfo='1000,<500

用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建用户sanzo,指定home目录和登陆的shell
useradd -d /home/sanzo -s /bin/bash -m sanzo

# 设置登录密码
passwd sanzo

# 添加sudo组
usermod -a -G sudo sanzo

# 删除用户
sudo userdel -r test

# append ssh key to remote host
cat .ssh/id_ras.pub | ssh user@hostname "cat >> ~/.ssh/authorized_keys"

代理

配置v2ray

v2ray-core/releases

1
2
3
4
5
6
mkdir v2ray && cd v2ray
wget https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh
sudo bash install-release.sh --local ./v2ray-linux-64.zip

# local user run
nohup ./v2ray run config.json > v2ray.log 2>&1 &

v2ray config.json配置

image-20211008182055367

proxychains

1
2
3
4
5
6
sudo apt install proxychains

# 修改配置文件
sudo vim /etc/proxychains.conf
# 最后一行改为对应自己的端口
socks5 127.0.0.1 10800

apt代理

1
2
3
sudo vim /etc/apt/apt.conf.d/proxy.conf
Acquire::http::Proxy "socks5h://127.0.0.1:10800";
Acquire::https::Proxy "socks5h://127.0.0.1:10800";

bash代理

1
2
3
4
5
6
7
8
vim ~/.bashrc
# vim ~/.zshrc

export ALL_PROXY="socks5://127.0.0.1:10800"
export all_proxy="socks5://127.0.0.1:10800"
export http_proxy="http://127.0.0.1:10801"
export https_proxy="https://127.0.0.1:10801"
# export https_proxy="http://127.0.0.1:10801" # for conda http error

在setting中设置了http,apt和bash应该可以不用再设置了,以防万一可以加上。

git

1
2
3
4
5
6
7
8
9
10
11
sudo apt install git

# 环境配置
git config --global user.email "arrangeman@163.com"
git config --global user.name "Sanzo00"

# 生成公钥和私钥
ssh-keygen -t rsa -C "your_email@example.com"

# 将公钥放到github中
cat ~/.ssh/id_rsa.pub

代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# http and https
git config --global http.proxy http://127.0.0.1:10801
git config --global https.proxy https://127.0.0.1:10801
# socks5
git config --global http.proxy socks5://127.0.0.1:10800
git config --global https.proxy socks5://127.0.0.1:10800

# unset
git config --global --unset http.proxy
git config --global --unset https.proxy


# ssh
sudo apt install connect-proxy
vim ~/.ssh/config
# socks5
Host github.com
User git
ProxyCommand connect -S 127.0.0.1:10800 %h %p
# http || https
Host github.com
User git
ProxyCommand connect -H 127.0.0.1:10801 %h %p

zsh

https://sanzo.top/Linux/zsh/

1
2
3
4
5
6
7
8
# 安装zsh
sudo apt install zsh

# 安装ohmyzsh
sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# 切换shell为zsh
chsh -s /bin/zsh

插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 自动补全
git clone https://github.com/zsh-users/zsh-autosuggestions.git $ZSH_CUSTOM/plugins/zsh-autosuggestions

# 高亮
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting

# 修改配置文件
vim ~/.zshrc
plugins=(
git
zsh-autosuggestions
zsh-syntax-highlighting
)

# 重置zsh环境
source ~/.zshrc

鼠标

修改滑轮速度

IMWheel

1
2
3
4
5
6
7
8
9
10
sudo apt install imwheel
sudo vim ~/.imwheelrc

".*"
None, Up, Button4, 5 # 速度
None, Down, Button5, 5 # 速度
Control_L, Up, Control_L|Button4
Control_L, Down, Control_L|Button5
Shift_L, Up, Shift_L|Button4
Shift_L, Down, Shift_L|Button5

开机自启

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sudo ~/.config/systemd/user
vim ~/.config/systemd/user/imwheel.service

[Unit]
Description=IMWheel
Wants=display-manager.service
After=display-manager.service

[Service]
Type=simple
Environment=XAUTHORITY=%h/.Xauthority
ExecStart=/usr/bin/imwheel -d
ExecStop=/usr/bin/pkill imwheel
RemainAfterExit=yes

[Install]
WantedBy=graphical-session.target

systemctl --user daemon-reload
systemctl --user enable --now imwheel.service
journalctl --user --unit imwheel.service

网速监控

1
2
3
4
5
6
7
8
sudo add-apt-repository ppa:fossfreedom/indicator-sysmonitor -y
sudo apt update
sudo apt-get install indicator-sysmonitor

# 运行
indicator-sysmonitor

cpu: ({cpu} {cputemp}) gpu: ({nvgputemp}) mem: ({mem}) net: {net} {totalnet}

image-20211008210121275

image-20211008205948437

截图

我在windows上用的snipaste,不过linux还没出,有两个方案可以代替:

1、系统默认的截图工具

  • PrtSc – 获取整个屏幕的截图并保存到 Pictures 目录。
  • Shift + PrtSc – 获取屏幕的某个区域截图并保存到 Pictures 目录。
  • Alt + PrtSc –获取当前窗口的截图并保存到 Pictures 目录。
  • Ctrl + PrtSc – 获取整个屏幕的截图并存放到剪贴板。
  • Shift + Ctrl + PrtSc – 获取屏幕的某个区域截图并存放到剪贴板。
  • Ctrl + Alt + PrtSc – 获取当前窗口的 截图并存放到剪贴板。

2、flameshot

1
2
3
4
5
# install
apt install flameshot

# start
flameshot gui

显卡

显卡算力

cuda对应的最低驱动版本

Ubuntu20.04安装NVIDIA显卡驱动+cuda+cudnn配置深度学习环境

驱动安装

1
2
# 查看显卡型号
lspci | grep -i nvidia

image-20211008193000787

下载驱动

image-20211008193044041

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo apt install -y lightdm gcc make
sudo passwd root

# 切换桌面,选择lightdm
sudo dpkg-reconfigure gdm3

# 关闭lightdm桌面
systemctl stop lightdm

sudo chmod a+x NVIDIA-Linux-x86_64-450.80.02.run
sudo ./NVIDIA-Linux-x86_64-450.80.02.run -no-x-check -no-nouveau-check -no-opengl-files --no-kernel-module
# -no-x-check:安装时关闭X服务
# -no-nouveau-check: 安装时禁用nouveau
# -no-opengl-files:只安装驱动文件,不安装OpenGL文件
# 后面出来的提示,选择默认选项
1
2
# 测试是否成功
nvidia-smi

image-20211008204151165

如果出现/dev/xxx: clean的问题,进不了桌面,可能是因为驱动不匹配的问题。可以删除/etc/X11/xorg.conf

如果出现An NVIDIA kernel module 'nvidia-drm' appears to already be loaded in your kernel. This may be because it is in use (for example, by an X server, a CUDA program, or the NVIDIA Persistence Daemon), but this may also happen if your kernel was configured without support for module unloading.

1
2
3
4
5
6
7
8
# https://unix.stackexchange.com/questions/440840/how-to-unload-kernel-module-nvidia-drm

sudo systemctl isolate multi-user.target
modprobe -r nvidia-drm

# reinstall you nvidia driver
# then
sudo systemctl start graphical.target

安装cuda

下载cuda,这里我选择的是cuda 11.2。

image-20211008204125042

1
2
wget https://developer.download.nvidia.com/compute/cuda/11.2.0/local_installers/cuda_11.2.0_460.27.04_linux.run
sudo sh cuda_11.2.0_460.27.04_linux.run

回车取消勾选Driver,因为前面已经装过驱动,然后install,也可以在Options中自定义安装位置。

image-20211008204241869

在.bashrc文件中配置环境变量

1
2
export PATH=/usr/local/cuda-11.2/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda-11.2/lib64:${LD_LIBRARY_PATH}
1
2
3
4
source ~/.bashrc

# 测试cuda
nvcc -V

image-20211008204439775

安装cudnn

下载cudnn

1
2
3
4
# 将文件复制到cuda对应的文件夹下
sudo cp cuda/include/cudnn.h /usr/local/cuda/include/
sudo cp cuda/include/cudnn_version.h /usr/local/cuda/include/ # for cudnn v8+
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/

测试

~/NVIDIA_CUDA-11.2_Samples下编译代码,然后运行cuda提供的例子。

image-20211008204814707

image-20211008204917470

踩坑

  1. apt 更新软件包之后,导致显卡驱动失效,这是因为内核版本发生了变化,将内核回退到上一个版本即可。

    https://www.jianshu.com/p/5ac8aa703075

显示器

适用于多个显示器。

我这里有两块屏幕HDMI-1HDMI-1-0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看当前显示器信息
xrandr

# 设置HDMI-1为主屏幕
xrandr --output HDMI-1 --primary

# 只显示一个屏幕,关闭HDMI-1-0屏幕
xrandr --output HDMI-1 --auto --output HDMI-1-0 --off

# 复制屏幕
xrandr --output HDMI-1-0 --same-as HDMI-1 --auto

# 设置HDMI-1-0为左扩展屏
xrandr --output HDMI-1-0 --left-of HDMI-1 --auto

# 设置HDMI-1-0右扩展屏
xrandr --output HDMI-1-0 --right-of HDMI-1 --auto

开机自启

还没找到合适的开机自启命令,不过可以在系统设置中调。

VSCode

vscode

server端网络不好,“Downloading VS Code Server”

进入~/.vscode-server/bin/查看vscode server的commit id,然后手动下载上传到服务器。

下载链接:https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable

解压之后重命名为commit id,然后放到~/.vscode-server/bin/

其他

typora

python环境

python环境配置

作者 Sanzo
2021年6月25日 11:37

python相关环境配置:Miniconda,PyTroch,Jupyter, venv。

Miniconda

Miniconda是一个轻量级的Conda包管理器

安装包

所有安装包:repo.anaconda.com/miniconda

Linux: python3.8 Miniconda3 Linux 64-bit

python3.7 Miniconda3 Linux 32-bit

1
2
# 以前的版本没有ssh问题
wget https://repo.anaconda.com/miniconda/Miniconda3-4.7.12.1-Linux-x86_64.sh

配置

初始化终端:

1
~/miniconda3/bin/conda init

如果失败可以手动添加bin目录。

1
echo "export PATH=\$PATH:/home/pi/miniconda3/bin" >> .bashrc

使用

新建环境

1
2
3
4
5
# 新建名称为test的环境
conda create --name test python=3.8 -y

# arm只能创建python=3.4的环境
conda create -n test python=3.4 -y

查看所有的环境

1
conda env list

使用环境

1
2
3
4
5
6
7
8
9
10
# 激活环境
conda activate test
source activate test # arm

# 退出当前环境
conda deactivate
source deactivate # arm

# 删除环境
conda remove -n test1 --all

rpi

armv7l: miniconda3-latest-linux-armv7l.sh

Berryconda3-2.0.0-Linux-armv7l.sh

arm版本的miniconda最高只能安装python3.4,如果需要安装更高版本的python,需要第三方conda,这里使用的是 berryconda,目前最高支持到python3.6

1
2
3
conda config --add channels rpi

conda create --name test python=3.6 -y

venv

python自带的虚拟环境模块

1
2
3
4
5
6
7
8
# 新建
python -m venv /path/venv_name

# 激活
source /path/venv_name/bin/activate

# 退出
deactivate

https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tgz

Pytorch

old version lib torch: https://github.com/pytorch/pytorch/issues/40961

Pytorch,选择对应cuda版本。

1
2
3
4
5
torch.version # PyTorch version
torch.cuda.is_available()
torch.version.cuda # Corresponding CUDA version
torch.backends.cudnn.version() # Corresponding cuDNN version
torch.cuda.get_device_name(0) # GPU type

build

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# install pytorch and dependences
git clone --depth 1 --recurse-submodule https://github.com/pytorch/pytorch.git
conda create -y --name pytorch-build python=3.8
conda activate pytorch-build
conda install -y astunparse numpy ninja pyyaml mkl mkl-include setuptools cmake cffi typing_extensions future six requests dataclasses pkg-config libuv

# arm64
mkdir pytorch-build-arm64
cd pytorch-build-arm64
cmake -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_OSX_ARCHITECTURES=arm64 DCMAKE_OSX_DEPLOYMENT_TARGET=12.10 -DUSE_MKLDNN=OFF -DUSE_QNNPACK=OFF -DUSE_PYTORCH_QNNPACK=OFF -DBUILD_TEST=OFF -DUSE_NNPACK=OFF -DCMAKE_BUILD_TYPE:STRING=Release -DPYTHON_EXECUTABLE:PATH=`which python3` -DCMAKE_INSTALL_PREFIX:PATH=../pytorch-install-arm64 ../pytorch
cmake --build . --target install
cd ..

# x86_64
mkdir pytorch-build-x86_64
cd pytorch-build-x86_64
cmake -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=12.10 -DUSE_MKLDNN=OFF -DUSE_QNNPACK=OFF -DUSE_PYTORCH_QNNPACK=OFF -DBUILD_TEST=OFF -DUSE_NNPACK=OFF -DCMAKE_BUILD_TYPE:STRING=Release -DPYTHON_EXECUTABLE:PATH=`which python3` -DCMAKE_INSTALL_PREFIX:PATH=../pytorch-install-x86_64 ../pytorch
cmake --build . --target install
cd ..

test

1
2
3
4
5
6
7
8
9
10
11
12
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)

set(Torch_DIR /Users/sanzo/Software/pytorch-install-arm64)
set(CMAKE_PREFIX_PATH "/Users/sanzo/Software/pytorch-install-arm64/share/cmake/Torch")
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <torch/torch.h>
#include <iostream>

int main() {
std::cout << "PyTorch version: "
<< TORCH_VERSION_MAJOR << "."
<< TORCH_VERSION_MINOR << "."
<< TORCH_VERSION_PATCH << std::endl;
torch::Tensor tensor = torch::rand({2, 3});
std::cout << tensor << std::endl;
}

/*
0.0598 0.7058 0.0322
0.2230 0.4112 0.9342
[ CPUFloatType{2,3} ]
*/

references

old version lib torch: https://github.com/pytorch/pytorch/issues/40961

https://dev-discuss.pytorch.org/t/universal-binaries-for-libtorch-mac/229

https://github.com/pytorch/pytorch/issues/63558

jupyter notebook

ipykernel

通过ipykernel管理jupyter notebook的内核。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 激活环境
activate env_name

# 安装ipykernel
pip install ipykernel

# 添加kernel
python -m ipykernel install --name env_name

# 删除内核
jupyter kernelspec remove kernelname

# 查看所有内核
jupyter kernelspec list

远程访问

生成密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 通过ipython生成密码
ipython

In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password:
Verify password:
Out[3]: 'xxxxxxxxxxxxxxxxxxxxxx'

# 生成配置文件,并添加如下配置
jupyter notebook --generate-config

c.NotebookApp.ip='0.0.0.0'
c.NotebookApp.password = u'xxxxxxxxxxxxxxxxxxxxxx'
c.NotebookApp.open_browser = False
c.NotebookApp.port =8888

然后就可以通过https://ip:8888远程访问jupyter notebook

Linux常用命令

作者 Sanzo
2021年6月17日 15:54

Linux common commands.


用户管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建用户sanzo,指定home目录和登陆的shell
useradd -d /home/sanzo -s /bin/bash -m sanzo

# 设置登录密码
passwd sanzo

# 添加sudo组
usermod -a -G sudo sanzo

# 删除用户
sudo userdel -r test

# append ssh key to remote host
cat .ssh/id_ras.pub | ssh user@hostname "cat >> ~/.ssh/authorized_keys"

# check group
getent group groupname

# delete group of username
sudo deluser username groupname

进程管理

后台执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看后台任务
jobs

# 前台执行任务
fg %np's

# 继续在后台执行挂起的任务
bg %n

# 挂起任务
ctrl+z

# 杀掉后台任务
kill %n

# 从当前shell移除
disown -h %1

# 后台执行
nohup ./xx.exe > log 2>&1 &

查找/终止进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看占用端口的PID
lsof -i:port
netstat -tunpl | grep port

# 查找指定名称的进程
ps -ef | grep xxx

# 获取指定名称进程的pid
ps -ef | grep free | grep -v grep | awk '{print $2}'

# 查看指定进程的开始和执行的时间
ps -eo pid,lstart,etime | grep pid

# 终止进程
ps -ef | grep free | grep -v grep | awk '{print $2}' | xargs kill

# 终止所有指定名称的进程
killall xxx

终止指定名称的进程:kill.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# check input args
if [ $# -ne 1 ]; then
echo "Usage: ./$0 xxx"
exit 1
fi

echo "kill all $1*"

ps -ef | grep $1 | grep -v grep | grep -v kill.sh

pids=$(ps -ef | grep $1 | grep -v grep | grep -v kill.sh | awk '{print $2}')
#echo "pids:"
#echo $pids


if test -z $pids; then
echo "$1 is alread killed!"
else
for pid in $pids
do
echo "kill $pid"
kill -9 $pid
done
fi

常用命令

wc

1
2
3
4
5
# 查看文件的行数
wc -l data.txt

# 查看./xx目录下.h文件的行数
find ./xx -name "*.h" | xargs wc -l

date

1
2
3
4
5
6
# 日期
date

# 格式化显示
date +%Y-%m-%d
date +%H:%m

cal

1
2
3
4
5
6
7
8
# 显示本月的日历
$ cal

# 显示2020年的日历
$ cal 2020

# 显示2020年5月的日历
$ cal 5 2020

ssh

1
2
# 将远端服务器10.1.1.1的8888端口映射到本地的8888端口
ssh -L8888:localhost:8888 root@10.1.1.1

head/tail

1
2
3
4
5
6
7
8
9
# 前1000行
head -n 1000 input.txt > output.txt

# 后1000行
tail -n 1000 input.txt > output.txt


# 第6-10行
head -n 10 input.txt | tail -n 5

grep

1
2
# 查找当前目录下所有包含'void main()'的文件
grep -rn "void main()" ./

gzip

1
2
# 解压到DIR目录
gzip xxx.gz -d DIR

tar

1
2
# 解压到DIR目录
tar -xzvf xx.tar.gz -C DIR

RAG介绍

作者 Sanzo
2024年2月28日 08:06

RAG是什么?目前的研究现状如何?

RAG介绍

什么是LLM?

大语言模型(Large Language Model,LLM)是基于海量数据集进行预训练的超大规模的深度学习模型。OpenAI发布的ChatGPT使人们意识到,具有足够的训练数据巨大的参数的神经网络模型可以捕获人类语言的大部分语法和语义。得益于与LLM出色的语言理解能力,LLM被广泛的应用于各种下游任务,例如文案写作,知识问答,文本分类,代码生成,文本生成等。虽然LLM在很多领域具有出色的表现,但是它面临诸如幻觉过时的知识缺乏可解释性等挑战。

图1:RAG执行流程 (from RAGCache paper)

RAG的执行流程

检索增强生成(Retrieval Augmented Generation,RAG)包含检索和生成两部分。如图1所示,在处理用户请求之前,RAG系统首先对外部数据(文档,语音,视频等非结构化数据)进行预处理(生成向量等),并存储到知识数据库中以供后续检索使用。当接收到用户的请求时,RAG系统首先从知识数据库中检索与问题相关的知识,然后将检索得到的知识和用户的问题一起输入到LLM,生成最终的答案。通过外挂知识库的方法,RAG一定程度缓解了LLM的幻觉,时效性差,和不可解释等问题。

目前的RAG形态主要分为VectorRAG和GraphRAG两种。

VectorRAG

图2: VectorRAG

VectorRAG使用向量来组织外部的知识。如图2所示,VectorRAG首先将文档划分为多个文本块(chunk)。每个文本块通过嵌入模型得到对应的向量表示,然后存储到向量数据库中。对于用的的请求,VectorRAG对用户的问题生成嵌入向量。然后,从向量数据库检索与问题嵌入向量相似的向量并返回对应的文本块。

VectorRAG的优点是:(1)检索速度快。(2)丰富的上下文语义信息。

VectorRAG的缺点是:(1)由于信息分散导致的检索不完整性。(2)由于语义导致的不准确性。

举个具体的例子,例如我们基于《乔布斯自传》来回答用户的问题。与用户问题相关的文本块可能有30个,而且它们分散的存储在书中的不同位置。此时,如果只取top K个片段很难得到这种分散,细粒度的完整信息。而且这种方法容易一楼相互关联的文本块,从而导致检索信息的不完整。

另外,基于嵌入的语义搜索存在不准确的问题,例如“保温杯”和“保温大棚”,这两个关键词在语义空间上存在很大的相似性,然而在真实的场景中,我们并不希望这种通用语义下的相关性出现,进而作为错误的上下文而引入”幻觉“。

GraphRAG

==重新整理==

GraphRAG是一种使用知识图谱(Knowledge Graph,KG)来组织外部数据的RAG。与向量RAG相比,GraphRAG具有更加细粒度的知识形式,而且,通过在图上查询目标实体的多跳邻居,可以查询相互关联的信息,即使他们不在同一个文本块内部。

图3: GraphRAG

GraphRAG的执行过程可以简单概括为以下三步:

  • 从问题中提取实体
  • 从知识图谱中检索得到子图
  • 根据子图构造上下文

图4: Graph + VectorRAG (siwei.io/graph-rag)

图3是Graph和Vector联合RAG的流程图。首先对外部的文档构建索引(向量索引和KG索引),用户后续的数据检索。当用户提交一个问题的查询时,首先通过嵌入模型对用户的问题生成向量表示,然后分别从向量数据库中检索语义相关的文本块;从知识图谱数据库中检索相关的实体,然后遍历得到实体相关的查询子图。最后将向量检索得到的文本块和知识图谱检索得到的查询子图,联合问题一起输入到LLM生成问题的回答。

GraphRAG可以看作是对已有方法的额外扩展。通过将知识图谱引入到RAG中,GraphRAG可以利用现有或者新建的知识图谱,提取细粒度,领域特定且相互关联的知识。

研究现状

==想个分类==

OP-RAG [arixv’24]

paper

这篇论文讨论了RAG在Long-context LLM下是否还是有必要存在的问题?

结论是:Long-context LLM可能会导致对相关信息的关注减少,从而可能降低问答任务中的答案质量。因此RAG还是有必要存在的,通过使用RAG可以有效的输入文本的长度,同时可以获取更高的准确率。

在上下文限制的LLM中,使用RAG可以有效的减少输入大模型的文本长度,然后模型回答的准确率就取决于检索的性能。最近出现了很多Long-context的LLM模型,例如GPT-4o,Claudi-3.5,Llama3.1,Phi-3,Mistral-Large2具有128K的上下文长度,Gemini-1.5-pro甚至达到了1M的上下文窗口大小。因此这里有个问题:在Long-context LLM下,是否还有必要使用RAG?

RAG在不同上下文长度下的表现

作者通过实验,对比了RAG在不同上下问长度下的性能。实验结果表明:随着上下文的增加,RAG性能先上升后下降。这是因为更多的上下文可能有更大的机会覆盖相关的块。然而,随着上下文长度进一步增加,答案质量会下降,因为更多不相关的块被用作干扰。

另外本文提出了一种保留检索文档原始顺序的方法,order-preserve RAG (OP-RAG),通过实验发现可以有效的提高准确率。(没有提供insight和分析)。

Evaluation

RGB [AAAI’24]

paper code

RGB是针对QA场景下的RAG benchmark工作,主要贡献如下:

  1. 构建了一个中英文的RAG benchmark。
  2. 从以下四个方面对RAG进行了评估,分析总结了LLM和RAG的局限性和缺点。
    • Noise Robustness,表示LLM可以从噪声文档中提取有用的信息。其中噪声文档,是语文题相关但是不包含答案相关的信息。
    • Negative Rejection,表示如果检索的文档不包含与答案相关的信息,LLM应该拒绝回答。
    • information Integration,表示LMM是否可以回答需要整合多个文档信息的复杂问题。
    • Counterfactual Robustness,表示当LLM通过prompt警告检索的信息可能包含事实错误的信息时,LLM可以识别文档中的事实错误。

数据集构造

  1. QA instances generation,收集最新的新闻文章,然后使用ChatGPT对每个文章生成 (events, questions, and answers)。通过人工检查答案的正确性,并过滤掉一些无法从搜索引擎检索得到的数据。

  2. Retrieve using search engine,对于每个问题,使用Google的API获取10个相关的网页,然后提取出相关的文档快。每个文档快包含300个token,使用dense retrieval model(m3e-baseall-mpnet-base-v2) 选择top-30的文本块。这些文本被分为positive documents and negative documents。

  3. Testbeds construction for each ability

    • noise robustness,根据比例采样不同数量的negative documents。

    • negative rejection,只从negative documents中采样外部文档。

    • information integration,对问题进行expanding或者rewriting,使得问题的答案包含多个文档的信息。

      例如:”Who won the MVP of Super Bowl 2023?” can be rewrite as “Who won the MVPs of Super Bowl 2022 and 2023?”

    • counterfactual robustness,利用LLM内部的知识生成问题的答案,然后检索出相关的文档,手动修改文档中的信息。

RGB的数据构造过程

评估的metrics

  1. Accuracy ,用来评估noise robustness and information integration。生成的回答是否和标准答案一样。
  2. Rejection rate,评估negative rejection。当只提供negative documents,LLM应该输出”I can not answer the question because of the insufficient information in documents.”。
  3. Error detection rate,评估counterfactual robustness。当提供的文档包含错误的事实,LLM应该输出”There are factual errors in the provided documents.“。
  4. Error correction rate,评估LLM在识别出检索文档的事实错误后,是否可以回答出正确的答案。

实验结果

  1. RAG的性能随着噪声比例上升严重下降。存在以下问题:
    • Long-distance information
    • Evidence uncertainty
    • Concept confusion.
  2. RAG很容易受到噪音信息的干扰,Negative Rejection很低。
  3. RAG在information integration上表现不佳,存在以下问提:
    • Merging Error,成功识别了两个问题,但是在合并答案出错。
    • Ignoring Error,没有正确识别两个问题,只回答了一个答案。
    • Misalignment Error,两个问题的答案混淆。
  4. RAG基本没有识别事实错误的能力,因为这个RAG的基本假设冲突(模型缺乏信息,从外部检索相关信息),现有的LLM缺乏对错误信息的识别能力,严重依赖检索的信息。

参考文献

  1. Retrieval-Augmented Generation for Large Language Models: A Survey

  2. Graph_RAG_LlamaIndex_Workshop.ipynb

    • KG gets Fine-grained Segmentation of info. with the nature of interconnection/global-context-retained, it helps when retriving spread yet important knowledge pieces.

    • Hallucination due to w/ relationship in literal/common sense, but should not be connected in domain Knowledge

  3. Custom Index combining KG Index and VectorStore Index

    • Not all cases are advantageous, many other questions do not contain small-grained pieces of knowledges in chunks. In these cases, the extra Knowledge Graph retriever may not that helpful.

吴恩达机器学习笔记

作者 Sanzo
2022年3月27日 13:02

机器学习劝退指南…

吴恩达机器学习-B站视频

课后作业及答案:https://github.com/Sanzona/ML-homework

ppt和笔记下载链接: 阿里云盘

监督学习

监督学习是已经知道数据的label,例如预测房价问题,给出了房子的面积和价格。

  • 回归问题是预测连续值的输出,例如预测房价。

    image-20200922232432315

  • 分类问题是预测离散值输出,例如判断肿瘤是良性还是恶性。

    image-20200922232452094

无监督学习

无监督学习是不知道数据具体的含义,比如给定一些数据但不知道它们具体的信息,对于分类问题无监督学习可以得到多个不同的聚类,从而实现预测的功能。

image-20200922232542888

线性回归

image-20200925221455511

线性回归是拟合一条线,将训练数据尽可能分布到线上。另外还有多变量的线性回归称为多元线性回归。

代价函数

cost function,一般使用最小均方差来评估参数的好坏。

image-20200925222847271

image-20200925225215790

image-20200925230206340

image-20200925230227443

梯度下降

梯度下降,首先为每个参数赋一个初值,通过代价函数的梯度,然后不断地调整参数,最终得到一个局部最优解。初值的不同可能会得到两个不同的结果,即梯度下降不一定得到全局最优解。

image-20200926193450504

梯度下降在具体的执行时,每一次更新需要同时更新所有的参数。

image-20200926193952535

梯度下降公式中有两个部分,学习率和偏导数。

偏导数,用来计算当前参数对应代价函数的斜率,导数为正则$\theta$减小,导数为负则$\theta$增大,通过这样的方式可以使整体向$\theta=0$收敛。

image-20200926195243593

$\alpha$用来描述学习率,即每次参数更新的步长。$\alpha$的大小不好确定,如果太小则需要很多步才能收敛,如果太大最后可能不会收敛甚至可能发散。

image-20200926195756443

当$\theta$处于局部最优解时,$\theta$的值将不再更新,因为偏导为0。

image-20200926195859632

这也说明了如果学习率$\alpha$不改变,参数也可能收敛,假设偏导$> 0$,因为偏导一直在向在减小,所以每次的步长也会慢慢减小,所以$\alpha$不需要额外的减小。

image-20200926200328203

单元梯度下降

梯度下降每次更新的都需要进行偏导计算,这个偏导对应线性回归的代价函数。

image-20200926202751517

对代价函数求导的结果为:

image-20200926202845222

梯度下降的过程容易出现局部最优解:

image-20200926193450504

但是线性回归的代价函数,往往是一个凸函数。它总能收敛到全局最优。

image-20200926203154017

梯度下降过程的动图展示:

多元梯度下降

通常问题都会涉及到多个变量,例如房屋价格预测就包括,面积、房间个数、楼层、价格等

image-20200927122907240

因此代价函数就不再只包含一个变量,为了统一可以对常量引入变量$x_0=1$。

image-20200927122848759

虽然参数的个数增多,但是对每个参数求偏导时和单个参数类似。

image-20200927123117176

特征缩放

多个变量的度量不同,数字之间相差的大小也不同,如果可以将所有的特征变量缩放到大致相同范围,这样会减少梯度算法的迭代。

特征缩放不一定非要落到[-1,1]之间,只要数据足够接近就可以。

$X_i = \frac{X_i-\mu}{\sigma}$,$\mu$表示平均值,$\sigma$表示标准差。

image-20200927122159371

image-20200927122356465

image-20200927122645246

缩放后的还原

经过线性回归得到的参数$\theta’$,对应着缩放后的数据,如何得到缩放前的参数$\theta$?

$$\begin{aligned}不缩放,回归方程为y&=\theta_0+x_1\theta_1+x_2\theta_2+\cdots+x_n\theta_n\\缩放,回归方程为y'&=\theta_0'+x_1'\theta_1'+x_2'\theta_2'+\cdots+x_n'\theta_n'\\\because y'&=\frac{y'-\mu_y}{\sigma_y},x_i'=\frac{x_i-\mu_i}{\sigma_i}\\\therefore \frac{y-\mu_y}{\sigma_y}&=\theta_0'+x_1'\theta_1'+x_2'\theta_2'+\cdots+x_n'\theta_n'\\&=\theta_0'+\frac{x_1-\mu_1}{\sigma_1}\theta_1'+\frac{x_2-\mu_2}{\sigma_2}\theta_2'+\cdots+\frac{x_n-\mu_n}{\sigma_n}\theta_n'\\\therefore y&=[(\theta_0' - \sum_{i=1}^{n}\frac{\mu_i\theta_i'}{\sigma_i})\sigma_y+\mu_y]+x_1\frac{\theta_1'\sigma_y}{\sigma_1}+x_2\frac{\theta_2'\sigma_y}{\sigma_2}+\cdots +x_n\frac{\theta_n'\sigma_y}{\sigma_n}\\&\therefore \left\{ \begin{matrix}(\theta_0' - \sum_{i=1}^{n}\frac{\mu_i\theta_i'}{\sigma_i})\sigma_y+\mu_y &(i=0)\\\frac{\theta_i'\sigma_y}{\sigma_i} &(i\ne 0)\\\end{matrix} \right.\end{aligned}$$

学习率

学习率$\alpha$的大小会影响梯度算法的执行,太大可能会导致算法不收敛,太小会增加迭代的次数。

可以画出每次迭代的$J(\theta)$的变化,来判断当前算法执行的情况,然后选择合适的学习率。(调参开始…)

image-20200927124215044

image-20200927124314735

Batch梯度下降:每一步梯度下降,都需要遍历整个训练集样本。

矩阵和向量

一些数学计算转化为矩阵的形式,可以简化代码书写、提高效率、代码更容易理解。

image-20200926215031531

image-20200926223409425

矩阵乘法不满足交换律:

image-20200926225453052

矩阵乘法满足结合律

image-20200926225542850

单位矩阵

image-20200926225634974

矩阵的逆

  • 首先是方阵
  • 不是所有的矩阵都有逆

image-20200926225331312

转置矩阵

image-20200926225407464

正则方程

偏导等于0对应线性方程的最小值:

image-20200927173714299

利用线性代数的方法直接求解$\theta$。

image-20200927173747699

$\theta$的推导可以根据等式$X\theta=y$得到,$X^TX$的目的是将矩阵转化为方阵,因为求矩阵的逆的前提是方阵。

矩阵可能存在 不可逆的情况,这时可是删除一些不必要的特征,或使用正则化。

梯度下降和正则方程的优缺点:

image-20200927174320125

逻辑回归

Logistic Regression

逻辑回归用于解决分类的问题,如果使用线性回归可能会造成很大的误差;假如样本的标签值为0、1,线性回归输出值是连续的存在>1和小于0的情况,不符合实际。

如果对于一个均匀的数据,使用线性回归,选取0.5作为分界线,可能会得到一个比较准确的模型,但是如果数据不太均匀就会存在很大的误差。

image-20201002134249446

image-20201002134545596

激活函数

sigmoid.py

image-20201002142636471

激活函数的y值分布在[0,1]内,对于分类问题,我们可以使用激活函数的值来表示满足特征的概率。

image-20201002144146860

决策界限

决策边界是假设函数的一个属性,取决于函数的参数,而不是数据集。

假设以x=0,y=0.5作为判断的界限,当$\theta^Tx >=0.5$,预测$y=1$;$\theta^Tx <0.5$,预测$y=0$。

image-20201002151014707

image-20201002151544351

[代码示例](https://github.com/Sanzona/ML-homework/blob/main/ex2-logistic regression/ex2-regularized logistic regression.ipynb)

image-20201002151951691

代码示例

代价函数

对于函数$f(x)=\frac{1}{1+e^{-x}}$,如果使用类似线性回归的代价函数$\Sigma(h(x)-y)^2$,将得到一个非凸函数,这样就不能使用梯度下降的方法求解全局最优解。

image-20201002155109200

逻辑回归一般使用对数函数作为代价函数:

首先对于分类函数来说,他的输出值范围为[0,1],得到的对数图像如下:

image-20201002155225235

当评估模型参数对y=1(恶性肿瘤)进行预测的好坏时,如果实际为恶性,预测值也为1(恶性),此时的代价为0;如果实际为恶性,预测为0(良性),此时的代价为$+\infty$,这时代价函数就很好的评估了参数$\theta$的表现。

image-20201002160155129

同样对于y=0(良性肿瘤)的代价函数为:

image-20201002160126721

y的取值只有0、1,可以将上面两个函数合成一个,评估当前参数的$J(\theta)$为:

image-20201002193349426

梯度下降

在确定代价函数之后的任务是,如何最小化代价函数,因为代价函数是凸的,所以可以使用梯度下降求解。

image-20201002193549679

image-20201002193728758

虽然求偏导之后,$\theta$更新的形式和线性回归类似,但是他们本质不同,因为$h_\theta(x)$完全不一样。

具体的偏导推导过程

image-20201002193927240

多元分类

image-20201002200132671

对每个特征单独训练,在做预测的时候,取三个分类器结果最大的。

image-20201002200303264

过拟合

存在多个特征,但是数据很少,或者模型函数不合理,都会出现过拟合的现象。过拟合可能对样本数能够很好的解释,但是无法正确的预测新数据。

image-20201002211447558

image-20201002211511303

正则化

解决过拟合的方法:

image-20201002211815208

正则化处理过拟合问题:

在代价函数中加入正则项,通过lambda的来平衡拟合程度和参数的大小,$\theta$约大越容易出现过拟合的现象。

image-20201009160444537

如果lambda过大,导致$\theta \approx 0$,那么最终只剩下下$\theta_0$,图像将变成一个直线。

image-20201009160357606

image-20201028164800636

模型评估

训练、测试集

将数据集分为训练集和测试集,训练集得到参数$\theta$,然后使用测试集的数据对参数$\theta$进行评估,即计算误差。

image-20201017130647268

线性回归问题的评估:

image-20201017130713921

逻辑回归问题的评估:

image-20201017130740110

训练、验证、测试集

首先用训练集得到一个最优的参数$\theta$,然后用测试集进行评估误差。通过这样的方式可以在众多模型中选择一个理想的模型。

但是这样做并不能评估模型的泛化能力,通过测试集评估选择的模型,可能刚好适合测试集的数据,并不能说明它对其他数据的预测能力,这时就引入了验证集。

image-20201017131449719

将数据集分为:训练集、验证集、测试集。

image-20201017131519699

对于每个集合都可以计算相应的误差。

image-20201017131609332

这样在选择模型的时候,可以先使用测试集得到每个模型的$\theta$,然后使用验证集评估得到误差最小的模型,最后使用测试集评估他的泛化能力。

image-20201017131812807

偏差、方差

当多项式次数增大时,训练集的误差慢慢减小,因为多项式次数越高,图像拟合的就越准确。但是验证集不同,它的趋势是先减少后增大,这分别对应着欠拟合和过拟合。

image-20201017131855857

那么我们可以根据误差的不同表现来区分偏差和方差。

高偏差:训练误差和验证误差都很大。

高方差:训练误差小,验证误差大。

image-20201017132221852

正则化

通过引入$\lambda$来平衡多形式的权重。

当$\lambda$太大,参数$\theta \approx0$,模型近似直线,即欠拟合。当$\lambda$太小,就会出现过拟合。

image-20201017140626985

image-20201017140936964

学习曲线

随着数据量的增加,$J_{train}(\theta)$的误差慢慢增大,因为数据越少,模型越容易拟合;$J_{cv}(\theta)$慢慢减少,因为数据越多,模型越精准,所以误差减小。

image-20201017142111611

高偏差的模型的学习曲线:

因为参数很少,数据很多,所以随着数据的增多高偏差的模型的$J_{train}(\theta)$和$J_{cv}(\theta)$很接近。这时选择增加数据就不是很好的选择了,可以尝试增加数据的特征。

image-20201017142532611

高方差的模型的学习曲线:

高方差的特点是训练误差和验证误差之间有很大的差距,这时可以选择增加数据,随着图像右移可以看出训练误差和验证误差会慢慢接近。

image-20201017142556080

如何抉择

image-20201017143417016

image-20201017143728141

查准率、召回率

例如对癌症的预测,相对于样本数据真实得癌症的人非常少,大概只有0.5%的概率,这样的问题称为偏斜类,一个类中的样本数比另一个类多得多。

对于偏斜类的问题,如何评估模型的精准度呢?可能一个只输出y=1的函数都比你的模型准确。

这里引入了查准率和召回率,对于稀有的样本有:

image-20201019123538038

通常如果阈值设置的比较高,那么对应的查准率高、召回率低;相反如果阈值设置的低,那么查准率低、召回率高。

image-20201019123701192

F1 score

如何比较权衡不同的算法呢?

这里使用的$F_1 score$,即调和平均数(倒数的平均数)来衡量。

$F_1 score$会比较照顾数值小的一方,如果PR都为0,$F_1 score=0$;如果PR都为1,$F_1 score=1$

image-20201019123950436

image-20201019124139908

神经网络

大多数的机器学习所涉及到的特征非常多,对于非线性分类问题,往往需要构造多项式来表示数据之间的关系,多项式的组成方式千变万化,这对计算带来一定困扰。

image-20201015221136066

大脑中的神经元结构:

image-20201015221446454

机器学习中的神经网络一般包括三部分,输入层,隐藏层,输出层。

image-20201015221559627

数据从输入层开始,通过激活函数前向传播到第一隐藏层,经过多个隐藏层,最后到达输出层,神经网络表示复杂的逻辑关系,主要是对隐藏层的构造。

image-20201015221627962

逻辑运算

image-20201015221807035

如上为一个XNOR的分类问题,$xnor=(x_1 & x_2) or (\bar{x_1} & \bar{x_2})$,我们可以搭建出每种逻辑运算的神经网络,最终整合得到XNOR的神经网络模型。

AND运算

image-20201015221951588

OR运算

image-20201015222018533

NOT运算

image-20201015222132014

XNOR运算

$xnor=(x_1 & x_2) or (\bar{x_1} & \bar{x_2})$

image-20201015222208813

多元分类

通过构建神经网络,每种输出就对应一个分类器。

image-20201015222645344

image-20201015222753618

代价函数

image-20201029103442247

K表示输出层的单元数目,L为神经网络的层数。

image-20201029103800511

前向传播

image-20201016153630528

反向传播

image-20201016153534741

image-20201016153516048

image-20201016153457879

image-20201016153704540

随机初始化

在对神经网络进行训练时,theta的取值要随机取值,如果都赋值为0,就会使得每一层的输出值、误差相同,从而存在大量冗余。

image-20201109212012819

梯度检测

在实现反向传播算法时,如何确保梯度计算正确呢?

在数学上可以使用拉格朗日中值定理来近似的表示曲线上某一点的导数,梯度检测正是使用的这种思想。

image-20201106223535108

梯度检测的使用,可以对每个参数单独进行验证。

image-20201106223800987

image-20201106223848817

image-20201109210603659

假设通过中值定理得到的梯度为approx_grad,经过反向传播得到的梯度为grad,如果满足以下等式,则说明反向传播得到的梯度精度还行。

$$diff = \frac{||approx\_grad-grad||}{||approx\_grad+grad|||} < 10e^{-9}$$

梯度计算正确的情况下,当算法进行学习的时候要关闭梯度检测,因为它非常耗时。

image-20201106223929987

支持向量机

逻辑回归模型的图像是一个曲线或复杂的曲线,SVM使用简单函数来近似这个曲线。

image-20201019172254573

代价函数

支持向量机在逻辑回归的基础上简化了代价函数,逻辑回归使用正则项来权衡$\theta$的大小,以此解决过拟合的问题。SVM也是类似,它是在代价函数上添加系数C,效果等价。

image-20201019172318776

最大边界

SVM又叫做最大边界分类问题,观察代价函数可以得到:

image-20201019172946034

最小化代价函数,就是让左侧代价函数的和尽可能等于0,即对应$\theta^Tx$,另外还有右侧的$\theta^2$的和最小,即向量的模尽可能小。

image-20201019174929240

分类问题的界限有多种可能,SVM对于如下二分类的问题,往往会得到黑色的那条分界线,这条线恰好对应着最大的边界,因此也叫做最大边界分类问题。

image-20201019174955408

代价函数中的C决定了边界的划分,如果C很大对应逻辑回归的$\lambda$很小,模型过拟合,这样就会的到紫色的分界线,通过C的取值,我们可以决定边界的划分。

image-20201019175227034

证明

向量的内积,等价于投影长度的乘积。

image-20201019175359969

因此$\theta^Tx$可以写为$p||\theta||$。

image-20201019175637627

对于左侧的$\theta$,每个x向量在$\theta$上的投影距离很小,要满足条件那么$||\theta||$就要增大,这样最小化代价函数的值就不是最优的,可能发生过拟合,所以SVM会得到类似右侧的边界,这样$||\theta||$尽可能小些,因为投影距离都比左侧的要大,这也是最大边界的原因。

核函数

对于一个非线性决策边界问题,我们可能使用高阶的函数进行拟合,但是是否存在比当前特征刚好的表达形式呢?

image-20201019200045497

我们可以将每种特征表示为$f_i$,使用高斯核函数来做相似度分析。

随机选择三个点作为标记,通过核函数可以得到x对应的新特征。

image-20201019200231780

使用高斯函数的特点:如果相似度很高,即对应的欧几里得距离$\approx 0$对应$f_i=1$,相反如果相似度低对应$f_i\approx 0$。

image-20201019200525243

假设我们已经训练好参数$\theta$,那么就可以通过$\theta^Tf \ge 0$来进行预测,即对应红色的决策边界。

image-20201019200718526

可以直接将训练集中的$x^{(i)}$作为核函数中的$l^{(i)}$。

image-20201117170117585

这样对于训练中的数据$x^{(i)}$,都可以得到对应的$f^{(i)}$。

image-20201117170327476

SVM在使用核函数的时候,对应代价函数就可以替换为:

image-20201019201016956

和SVM中的参数C一样,核函数的$\sigma^2$决定了拟合的程度。

image-20201019201757549

image-20201019200547974

k均值

对于没有标签的数据来说,首先根据划分聚类的个数,随机设置聚类中心的位置,然后遍历所有的数据,把每个数据分配到离它最近的坐标,对于同一个簇的数据计算它们坐标的中心位置,并设置为新的聚类中心,以此不断的迭代。

image-20201020174043879

image-20201020174734697

k均值的目标函数是所有点到它所属聚类中心的距离和。

image-20201020174835196

随机初始化,当聚类数量很少时,如果初始化的位置不够好,会得到一个局部最优解,解决方案是多次随机初始化,从而得到一个全局最优解。

image-20201020194148820

image-20201020194208879

聚类数量的选择,得到聚类数量和代价的图像,根据肘部原则选取(一般不用);或者根据k均值聚类的目的来做判断,比如做衣服尺寸的聚类分析,根据市场需求,3个聚类or5个聚类更适合市场营销等等。

image-20201020195028492

image-20201020195102677

主成分分析(PCA)

image-20201120230001261

主成分分析(PCA)是一种数据压缩的算法,他将数据压缩到k维度,并使得所有数据投影到新维度的距离最小。

image-20201021093606393

PCA不是线性回归,一个是投影距离,一个是点与直线上点的距离。

image-20201021093750890

PCA执行过程,首先对数据进行均值归一化,然后计算协方差,最后得到一个k维的矩阵。

首先对数据进行均值归一化,然后确定要压缩的目标维度,即对应向量的个数,PCA的目标是使得所有数据距离新维度的距离最小。

image-20201120232141453

image-20201120232417568

image-20201021095651432

image-20201021095815835

如何确定维度K?

image-20201021100643103

image-20201021100650094

如何得到压缩直线的近似坐标?

image-20201021100903151

异常检测

高斯分布

可以使用高斯分布来进行异常检测。

image-20201021134842347

image-20201021134859966

计算m个数据集在每一个维度上的$\mu$和$\sigma^2$,然后根据$p(x)$得到一个概率$\epsilon$,根据概率的大小来定义是否为异常行为。

image-20201021160740256

image-20201021160747899

image-20201021160805733

多变量高斯分布

异常检测算法,往往是把$\mu$附近的数据认为是高频率出现的,表现在图像上类似一个圆形。在一些情况下数据并不是规则分布,单变量的高斯分布不能体现拟合椭圆形状。

image-20201021164402680

多变量高斯分布引入了协方差矩阵,通过修改矩阵的值来改变高斯分布的情况。

$\Sigma$可以理解为每个特征的缩放比例,这样就可以拟合更多的数据分布。

image-20201021164622303

image-20201021164636889

image-20201021164653817

image-20201021164707257

image-20201021164803037

传统的高斯分布实际上是多变量高斯分布的特殊形式,对应矩阵在非对角线上的数为0。

image-20201021164928186

传统的模型需要手动构造异常特征的组合,多变量可以自动的捕捉。不过多变量的计算复杂度高一些。

image-20201021165004871

推荐系统

内容推荐算法

例如一个电影推荐系统,一共有n个用户,m个电影,每部电影都有一定的特征,例如爱情片的比例、动作片的比例。n个用户对看过的电影进行评分,推荐系统做的给用户推荐新电影,预测用户对新电影的评分?

image-20201021200557627

可以使用线性回归的方法进行训练,得到用户对于特征的参数$\theta$,之后就可以根据$\theta^TX$对电影进行打分。

image-20201021201023606

优化目标函数为:

image-20201021201101616

image-20201021201152542

协同过滤

collaborative filtering,用于特征学习,自己学习得到数据的特征值。

我们无法得到每部电影中不同特征的比例,例如电影中爱情和动作的比例?除非人工审核每一部电影,但是太耗时。

这里有一个思路,首先用户根据自己的喜好对特征打分,通过计算可以大致确定已经打过分的电影它的特征值,根据已经确定的特征值,又可以计算出每个用户对这部电影的评分。

image-20201021201340270

先有鸡还是先有蛋…

根据特征向量$X$可以通过线性回归得到用户的$\theta$向量,通过用户提供的$\theta$向量可以估计每部电影的特征数值。这就有点像鸡和蛋的问题。

我们可以随机选取$\theta$向量计算得到特征数值,然后再通过线性回归去更新$\theta$,这样不停的迭代直到最后的收敛。

image-20201021202054835

我们也可以将两种函数合并为一个目标函数:

image-20201021202948381

image-20201021203015763

低秩矩阵分解

可以把n个用户对m部电影的评分结果表示为$m\times n$的矩阵。

image-20201021203534096

这个矩阵可以表示为$X\theta^T$。

image-20201021203614025

通过特征值之间的偏差,我们可以找到类型相近的电影。

image-20201021203650048

均值规范化

之前无论是参数$\theta$还是特征$X$,都基于每个用户都对多个电影进行的评分,每部电影也被多个用户评分。对于新用户,他可能还没有对任何一部电影进行评分,一种思路就是把所有用户对每部电影的评分的均值作为新用户的初始评分。

image-20201021204015593

随机梯度下降

Stochastic gradient descent

随机梯度下降算法对每个数据分开处理,对一个数据更新所有的参数。

梯度下降算法是在每次更新参数的时候,需要计算所有数据。

对比下来SGD的速度要快一些,不过收敛性可能没GD好。

image-20201021225514894

image-20201021225802565

如何判断SGD的收敛?

首先定义cost函数,然后每隔1000次迭代画出cost的图像,根据均值来判断。

如果噪声太多图像上下震荡,可以选择更多的迭代次数。

如果随着迭代次数cost增加,那么选择更小的$\alpha$。

image-20201021230250625

image-20201021230648977

SGD一般不能得到全局最优,他会一直在最优值附近徘徊。

学习率的大小一般保持不变,一个思路是可以动态的改变学习率$\alpha$的大小来提高准确度,比如随着迭代次数的增加慢慢减小$\alpha$的值。

image-20201021230901609

Mini-Batch

Mini-Batch gradient descent

将数据分为多份,对每一份执行GD,相当于GD和SGD的综合。

b可以取[10,100]。

image-20201021230101676

Map-reduce

Map-reduce and data parallelism。

Map-reduce利用了线性回归求和运算的特性,将GD对整个数据的求和处理,分摊到多个服务器上执行,最后各个服务器把结果汇总到一起进行合并。

image-20201021231524731

image-20201021231829330

逻辑回归也可以这样搞。

image-20201021231921203

OCR

pipeline

image-20201022150326345

image-20201022150336290

image-20201022150639975

image-20201022150659195

滑动窗口

GIF 2020-10-22 15-05-26

获取数据

下载字体,然后将它们放到一个随机北京图片上。

image-20201022150833190

对图像进行人工扭曲

image-20201022150910402

对语音文本加入不同的背景干扰。

image-20201022150949080

首先确保算法已经有很低的偏差,整体的模型ok,然后在考虑加数据,否则只是徒劳。

然后考虑加数据的人工和时间成本。

image-20201022151143779

上限分析

对多个模块进行分析,让其中一个模块达到100%的准确率,然后判断它能提高整个系统多少准确率。

image-20201022151317349

image-20201022151401539

课后作业

作业地址:https://github.com/Sanzona/ML-homework

❌
❌