HotSummer

  • 首页
  • 分类
  • 归档
  • 标签

机器学习技法第二课——Dual Support Vector Machine

发表于 2016-05-31   |   分类于 ML

此文是学习林轩田老师的机器学习技法第二课——Dual Support Vector Machine——的课堂笔记,有关 SVM 公式推导。

给定原公式:
$$
\frac{1}{2}\min_{b, \mathbf{w}} \mathbf{w^T w} \\
s.t. \ y_n(\mathbf{w^T \mathbf{x_n}} + b) \ge 1
$$
(为简化求解,公式与前次笔记稍有不同,但等价)这节课做了一系列的变换,最终有什么效果呢?

参考

  • 机器学习技法
  • linear SVM
  • 拉格朗日乘数
  • 简易解说拉格朗日对偶(Lagrange duality)
  • 优化问题中的对偶性理论
  • 课件

拉格朗日乘数法

拉格朗日乘数法可以把限制条件和目标函数结合成一个整体。原公式整合成:
$$
L(b, \mathbf{w}, \alpha) = \frac{1}{2} \mathbf{w^T w} + \sum_{n=1}^{N}\alpha_n(1 - y_n(\mathbf{w^T \mathbf{xn}} + b))
$$
SVM 求解公式变为:
$$
\min
{b,\mathbf{w}} (\max_{all\ \alphan \ge 0}L(b, \mathbf{w}, \alpha)) = \min{b, \mathbf{w}}(\infty\ if\ violate;\ \mathbf{w^T w}\ if\ feasible)
$$

拉格朗日对偶问题

利用对偶问题,对上步的求解公式取下限:
$$
\min{b,\mathbf{w}} (\max{all\ \alphan \ge 0}L(b, \mathbf{w}, \alpha)) \ge \max{all\ \alpha’n \ge 0} (\min{b,\mathbf{w}} L(b, \mathbf{w}, \alpha’))
$$
至于为何成立我没有细究,只能说这符合直觉。因为,考虑 $L(b, \mathbf{w}, \alpha)$ 为一个波动的函数,视 $\max$ 为取波峰, $\min$ 取波谷,那么从波峰中最小的应该不小于波谷中最大的。

有证明表示,对拉格朗日对偶问题,如果满足 强对偶 的三个条件,原始函数为凸函数、原始问题可解、原始限制条件是线性的,就可以在上式中取等,而 SVM 刚好满足。 : P

关于 $\alpha$ 函数

接下来对求解公式做2步“简化”,使之成为仅关于 $\alpha$ 的函数。

去 $b$: 考虑在极值点,变量的梯度都应该为 $0$,所以 $b$ 的梯度
$$-\sum_{n=1}^N \alpha_n yn = 0$$
把该式置于条件中并化简,得到求解公式等价式:
$$
\max
{\alphan} \min\mathbf{w}(\frac{1}{2} \mathbf{w^T w} + \sum_{n=1}^{N}\alpha_n(1 - y_n \mathbf{w^T \mathbf{x_n}})) \\
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n y_n = 0
$$

去 $\mathbf{w}$: $\mathbf{w}$ 的梯度
$$\mathbf{w}i - \sum{n=1}^N \alpha_n yn x{n,i} = 0 \\
\Rightarrow \mathbf{w} = \sum_{n=1}^{N} \alpha_n y_n \mathbf{xn}$$
把该式置于条件中并经过化简,得到最终的求解公式:
$$
\max
{\alphan} (-\frac{1}{2}|\sum{n=1}^{N} \alpha_n y_n \mathbf{xn}|^2 + \sum{n=1}^{N}\alpha_n) \\
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n yn = 0,\ \mathbf{w} = \sum{n=1}^{N} \alpha_n y_n \mathbf{x_n}
$$
注意其中的 $\mathbf{x_n}$ 及其求和均为向量,原本的求最小因为消去 $b, \mathbf{w}$ 而除去。

KKT 条件

对凸优化问题,KKT 条件是一组解成为最优解的充分必要条件。(见“优化问题中的对偶性理论”)而 SVM 求解原式和对偶式(强对偶)都有最优解,所以最优解满足 KKT 条件。
这其中有 2 个条件可以用于从最最优 $\alpha$ 中解出最做优 $b, \mathbf{w}$
$$
\mathbf{w} = \sum_{n=1}^{N} \alpha_n y_n \mathbf{x_n} \\
\alpha_n(1 - y_n(\mathbf{w^T \mathbf{x_n}} + b)) = 0
$$

二次规划求解

与上一课一样,因为求解问题是一个二次规划问题,所以可以借助相关的工具。在此之前,需要做一些变换。

最大化变最小化  最优化工具往往求最小值。求解公式取相反数:
$$
\min_{\alphan} (\frac{1}{2}|\sum{n=1}^{N} \alpha_n y_n \mathbf{xn}|^2 - \sum{n=1}^{N}\alpha_n) \\
$$

隐藏 $\mathbf{w}$ 的限制条件  使公式完全变为关于 $\alpha$ 的函数,剩下的 $x, y$ 都是已知量
$$
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n y_n = 0
$$

展露二次项系数  求解公式中二次项系数不易发现,做拆分:
$$|\sum_{n=1}^{N} \alpha_n y_n \mathbf{xn}|^2 \\
=(\sum
{n=1}^{N} \alpha_n y_n \mathbf{xn})^\mathbf{T}(\sum{n=1}^{N} \alpha_n y_n \mathbf{xn})
=(\sum
{m=1}^{N} \alpha_m y_m \mathbf{xm^T})(\sum{n=1}^{N} \alpha_n y_n \mathbf{xn})\\
=\sum
{m=1}^{N} \sum_{n=1}^{N} y_m \mathbf{x_m^T} y_n \mathbf{x_n} \alpha_m \alpha_n
$$
注意该式原始是2个(由多个向量求和得到的)向量的内积,最后一步变换使用了向量的分配律。可见,二次项 $\alpha_m \alpha_n$ 的系数为 $y_m \mathbf{x_m^T} y_n \mathbf{x_n}$。

最后给出 完整公式:
$$
\min_{\alphan} (\frac{1}{2}\sum{m=1}^{N} \sum_{n=1}^{N} y_m \mathbf{x_m^T} y_n \mathbf{x_n} \alpha_m \alphan - \sum{n=1}^{N}\alpha_n) \\
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n yn = 0
$$
利用二次规划工具解决该问题,解出 $\alpha$ 后,再利用 KKT 公式的2个条件,解出 $\mathbf{w}, b$:
$$
\mathbf{w} = \sum
{n=1}^{N} \alpha_n y_n \mathbf{x_n} \\
b = y_n - \mathbf{w^T \mathbf{x_n}}\ ,\ s.t.\ \alpha_n \ne 0
$$

值得注意的是,二次项系数矩阵是 $N \times N$ 的大型矩阵,而且并非上节课的对角矩阵,需要专为 SVM 设计的二次规划求解工具。

SV 与后续

很明显,利用 $\alpha$ 求解 $\mathbf{w}, b$ 时,如果 $\alpha_i$ 为0,对求解没有影响。也就是说,对应 $\alpha_i = 0$ 的向量(数据点)对求解没有影响。联系上节课,即对应 $\alpha_i \gt 0$ 的向量为支持向量(SV)。

课程中对原始向量 $\mathbf{x}$ 做了向N维向量 $\mathbf{z}$ 的映射,$\mathbf{x}$ 替换成 $\mathbf{z}$ 后对推导没有影响。而这节课的变换似乎没有简化求解,至于为何目的,只有后续揭晓了。

机器学习技法第一课——Linear Support Vector Machine

发表于 2016-05-25   |   分类于 ML

此文是学习林轩田老师的机器学习技法第一课——Linear Support Vector Machine——的课堂笔记,有关 SVM 公式推导。

参考

  • 机器学习技法
  • 超平面
  • 课件

(单层)感知器

感知器 (Perceptron) 利用超平面
$$\mathbf{w} \cdot \mathbf{x} = b $$
进行二元分类。其中,$\mathbf{x} = (x_1, x_2, …, x_n)$,$\mathbf{w} = (w_1, w_2, …, w_n)$。

一个数据 $(\mathbf{x},y)$ 中,$\mathbf{x}$ 作为输入,一个特征向量,可代表一个实体,而输出 $y \in {-1, 1}$ 则标记该实体的类别。Perceptron 希望找到一个超平面,即确定参数 $\mathbf{w}, b$, 能对一组数据 ${(\mathbf{x_1}, y_1), (\mathbf{x_2}, y_2),…,(\mathbf{x_n}, y_n),}$ 进行分类,使得对每组 $(\mathbf{x}, y)$ 都有:当 $y > 0$ 时,$\mathbf{w} \cdot \mathbf{x} > b$, 否则,$\mathbf{w} \cdot \mathbf{x} < b$。

例子,考虑输入为二维向量,每个数据表现为一个点,而超平面视作一条直线,Perceptron 所做的是,对多个数据点,找到一条直线将有不同标记(-1或1)的点分开。

公式推导

SVM 在 Perceptron 上更进一步,不仅要求能够找到一个超平面,而且要求这个超平面能能够尽量容忍误差。就 Perceptron 一节所举例子,SVM 要求该直线尽可能远离数据点,使得如果数据点因为误差而偏移,该直线也可能正确分类。

这可以理解成要求向量到超平面的距离尽可能大。在 超平面 的 点与超平面距离与 SVM 一节中已经说明距离可以表示为
$$
d = \left| \frac{\mathbf{w \cdot x}}{\mathbf{|w|}} - \frac{b}{\mathbf{|w|}} \right| = \frac {1} {|\mathbf{w}|} |\mathbf{w \cdot x} - b|
$$
这时,目标可以转换成求使“最小的 d” “最大” 的 $\mathbf{w}, b$,“最小的d”指所有向量与某组 $\mathbf{w}, b$ 所确定的超平面的距离的最小值,“最大” 则指所有 $\mathbf{w}, b$ 组各自对应的 “最小的 d ” 中最大的。翻译成符号:
$$
\max_{b, \mathbf{w}} margin(b, \mathbf{w}) \\
subject\ to \ every\ y_n(\mathbf{w^T xn} - b) > 0 \\
margin(b, \mathbf{w}) = \min
{n=1,..,N} \frac {1}{|\mathbf{w}|} |\mathbf{w^T x_n} - b|
$$
其中,margin 可理解成距离,subject to 表示限制。即要求在可分类的情况下,求解出每组 $(b, \mathbf{w})$ 最小的距离,再选取其中最大的。注:$\min$ 内部,$n$ 作为变量,而 $\max$ 内部, $\mathbf{w}, b$ 作为变量。

课程中将其转换为二次规划(Quadratic programming)问题求解。

去绝对值,$|\mathbf{w^T x_n} - b|$ 转换成 $y_n(\mathbf{w^T x_n} - b)$。

令 $y_n(\mathbf{w^T x_n} - b)=1$(可以等于任一大于0常数),考虑到
$\mathbf{w}, b$ 作为求解变量可以乘以一个常数 k 进行放缩同时保持超平面不变,而 $|\mathbf{w}|$ 会抵消 k 带来的影响并保持 margin 不变,所以这步变换与原式等价。这使得
$$margin = \min_{n=1,..,N} \frac {1}{|\mathbf{w}|} $$
而且,这可以去除限制 $y_n(\mathbf{w^T xn} - b) > 0$,变换为:
$$
\max
{b, \mathbf{w}} \frac {1}{|\mathbf{w}|} \\
subject\ to \ [\min_{n=1,..,N} y_n(\mathbf{w^T x_n} - b)]=1
$$

令 $y_n(\mathbf{w^T x_n} - b) \ge 1$,要求对于所有的 $n$ 都成立(上步仅要求最小值处成立)。这是合乎情理的,因为对于被放缩的某组 $\mathbf{w}, b$,距离最小值为1,则该组所有值都应不小于1。好处是限制条件不必做最小化操作。课程中也给出证明,说明此步与原式等价,在此不赘述。

求最大值变为求最小值,去掉倒数与绝对值。最终变换成一个所谓简单的二次规划问题为
$$
\min_{b, \mathbf{w}} \mathbf{w^T w} \\
subject\ to \ y_n(\mathbf{w^T x_n} - b) \ge 1
$$

支持向量

所谓支持向量,即距离最佳超平面最近的向量。它们“支持”了最佳超平面,而丢失其他向量对最佳超平面没有影响。对最佳 $(\mathbf{w}, b)$ 支持向量满足:
$$y(\mathbf{w^T x} - b) = 1$$

更强容错能力

直觉上认为 SVM 有更强的容错能力。课程中比较了一般正则仳与 SVM:
| | minimize | constraint|
|:—–:|:—–:|:——-:|
regularization | $E{in}$ | $\mathbf{w^T w} \le C$
SVM | $\mathbf{w^T w}$ | $E
{in} = 0$ [and more]
可看出 SVM 实际上做了与正则化相似的工作,而正则化能提高模型的容错能力。

耶鲁博弈论-5个入门结论-笔记

发表于 2016-05-25   |   分类于 Math

链接:耶鲁大学公开课-博弈论

5个入门结论

  • Do not play a strictly dominated strategy.
  • Rational choose can lead to outcomes suck.
  • You can’t get what you want, till you know what you want.
  • Put yourself in others’ shoes and try to figure out what they’ll do.
  • Yale students are evil.

超平面

发表于 2016-05-23   |   分类于 Math

参考: 空间解析几何

在 n 维空间中,满足方程
$$a_1 x_1 + a_2 x_2 + … + a_n x_n = b $$
的向量 $(x_1, x_2,…,x_n)$ 构成的空间称为 超平面。 例如,立体空间中它表示平面,平面中它表示直线。表面上有 n 个自由维度,实际上当 $(n-1)$ 个维度值确定时,剩下的一个维度也确定了。

参数的取值范围与 Perceptron

单层感知器(Perceptron)利用超平面分类数据。输入训练数据为向量 $\mathbf{x} = (x_1, x_2,…, x_n)$, 其目标是训练出权重向量 $\mathbf{w} = (w_1, w_2,…, w_n)$ 与偏值 $b$, 使得所有满足 $\mathbf{w}\cdot \mathbf{x}\ge b$ 的数据同为一类,而满足 $\mathbf{w}\cdot \mathbf{x}< b$ 的数据同为另一类。形象地理解就是,给定 n 维空间的许多点,分为两种类型,要求找到一个超平面,将这两种类型的点分开。再形象点,在二维空间中,有许多红点和蓝点,Perceptron 需要划一条直线将红点蓝点分开。(当然,Perceptron 往往不能对数据完全正确分类,所以有后续的处理。这里只是理想情况)

值得注意的是,偏值 $b$ 容易被误认为无需训练,直接设为定值就行(比如零)。实际上,将权重向量的任何一个元素及偏值 $b$ 固定为常量,都会导致( $\mathbf{w}, b$ )所能表示的超平面减少,从而导致分类的能力下降。可以参考平面下直线的表达式: $ax+by=c$ ,如果固定 $c=0$, 该直线必定过原点,不能表示许多不过原点的直线。

点到超平面距离与 SVM

支持向量机(SVM)也是利用超平面分类向量的,它关注的是点与超平面的距离。

已知超平面的法向量 $\mathbf{w}=(w_1,w_2,…,w_n)$ 和数 $b$, 超平面表示为:

$$ \mathbf{w}\cdot\mathbf{x} + b=0 $$

$\mathbf{x}= (x_1, x_2,…, x_n)$ 表示超平面上的任意一点。设 $\mathbf{y}_0= (y_1, y_2,…, y_n)$ 为超平面上一点,则有 $\mathbf{w}\cdot\mathbf{y}_0 = -b$。可得点 $\mathbf{s}= (s_1, s_2,…, s_n)$ 与超平面的距离 $d$:

$$ d=\left| \frac{\mathbf{w}\cdot(\mathbf{s}_0 - \mathbf{y}_0)}{||\mathbf{w}||} \right|=\left| \frac{\mathbf{w}\cdot\mathbf{s}_0 + b}{||\mathbf{w}||} \right| $$

My Git Cheat Sheet

发表于 2016-05-22   |   分类于 Tools

gitignore

项目下 .gitignore 文件与项目下 .git/info/exclude 文件都可以使 git 在文件或目录未添加进记录前被忽略。前者应该被团队共享,而后者应该作为个人的配置。因为后者在 .git 目录下,其改变被 git 忽略,不会影响其他人。

  • .gitignore 模板
  • 使用 .git/info/exclude 作为个人配置,.gitignore 作为团队配置
  • 匹配目录加 “/“:“dir_name/”
  • 匹配前加上惊叹号 “!”,表示不忽略

常用命令

1
2
git config --global -l # 查看全局配置
git diff HEAD -- filename # 比较

撤销操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git reset HEAD    # 撤销上次 add 操作

# 提交级别
# 缓存重置
git reset --hard HEAD
# 工作区和缓存都重置
git reset --hard HEAD

# 文件级别
# 放弃工作区的更改
git checkout HEAD foo.py

# Unstage文件,撤销add
git reset HEAD foo.py

更详细的教程代码回滚:Reset、Checkout、Revert-的选择

diff 比较

1
2
3
git diff  # 比较工作区与缓存区
git diff --cached # 比较缓存区与仓库(HEAD)
git diff HEAD # 比较工作区与仓库(HEAD)

换行符差异

Unix/MacOS使用LF换行符,而Windows用CRLF。在Windows下,Git在检出时默认将LF转换为CRLF,在commit时自动将CRLF转换为LF,但可能造成混乱,例如直接从Unix拷贝到Windows的源文件是LF的,会被视为有变更。为避免这个问题,首先设置IDE换行符为LF,并关闭Git这个功能:

1
2
3
4
#提交检出均不转换换行符
git config --global core.autocrlf false
#拒绝提交包含混合换行符的文件
git config --global core.safecrlf true

生成ssh key

1
2
# ubuntu下打开shell,Windows下打开Git bash
ssh-keygen -t rsa

idea将已有项目添加到git

转载:IDEA 将已有项目添加到git,https://www.cnblogs.com/rongguang/p/5516300.html

首先,我们解决的情况是,已经有了一个正在开发的项目,现在我们要把他分享到git@osc上面去。

在git@OSC上创建仓库

先在Git@OSC上创建仓库,拿到Git@OSC仓库的HTTP连接http://git.oschina.net/***/***.git

把项目用git管理

如果我们的本地项目是非git项目,那我们要先把它变成git项目:在intellij中 VCS——Import into Version Control——Create Git Repository——选择你的本地项目。

执行git pull与push

1
2
3
4
5
6
7
8
# 给项目设置远程远程仓库 #  
git remote add origin http://git.oschina.net/***/***.git
# 把本地master指向origin/master
git branch --set-upstream-to=origin/master master
# 抓取远程仓库数据,并自动合并远程分支 #
git pull origin master
# 更新本地数据到Git@OSC #
git push origin master

矩阵相关

发表于 2016-05-21   |   分类于 Math

系列笔记

  • 行列式
  • 矩阵的秩
  • 线性方程组的解
  • 向量组
  • 矩阵特征值、正交化与对角化
  • 二次型
  • 向量空间
  • 空间解析几何

参考

  • Wikipedia 行列式

各种矩阵

单位矩阵 $\mathbf{I}$

数量矩阵 $k\mathbf{I}$

对角矩阵

三角矩阵

对称方阵

对称矩阵 —— $\mathbf{A^T}=\mathbf{A}$, 反对称矩阵 —— $\mathbf{A^T}=-\mathbf{A}$, 有 $a_{i,i}=0$

初等矩阵(Elementary M)

单位矩阵作一次初等变换得到的方阵。 左乘初等矩阵 相当于做行初等变换, 右乘初等矩阵 相当于做列初等变换

伴随矩阵 $\mathbf{A}^{ * }$

$n$ 阶方阵 $\mathbf{A}=(a{i,j}){n \times n}$ 的伴随矩阵为 $\mathbf{A}^{ } = (\mathbf{A}{j,i}){n\times n}$, 其中 $\mathbf{A}{j,i}$ 为 $\det \mathbf{A}$ 中元 $a{j,i}$ 的代数余子式。注意非 $\mathbf{A}_{i,j}$, 例如 $\mathbf{A}^{ }$ 的第一行二列的元素等于 $\mathbf{A}_{2,1}$。

对所有 n 阶方阵 $\mathbf{A}$,有 $\mathbf{A}\mathbf{A}^{ }=\mathbf{A}^{ }\mathbf{A}=(\det \mathbf{A}) \mathbf{I}$

  • $r(\mathbf{A}) = n$ 时, $r(\mathbf{A}^{ * })=n$
  • $r(\mathbf{A}) = n-1$ 时, $r(\mathbf{A}^{ * })=1$
  • $r(\mathbf{A}) < n-1$ 时, $r(\mathbf{A}^{ * })=0$
  • $\det \mathbf{A}^{ * } = (\det \mathbf{A})^{n-1}$
  • $(k\mathbf{A})^{ } = k^{n-1} \mathbf{A}^{ }$

可交换方阵

满足交换律。 $\mathbf{A}\mathbf{B}=\mathbf{B}\mathbf{A}$ 可推出 $\mathbf{A}$ 与 $\mathbf{B}$ 为同阶方阵。 单位矩阵与所有方阵可交换,互逆矩阵可交换。 可交换在计算与证明中很有用。

标准形

$$
\begin{bmatrix}
\mathbf{I}r & \mathbf{O}\
\mathbf{O} & \mathbf{O}\
\end{bmatrix}
{m \times n}
$$

为矩阵 $\mathbf{A}_{m \times n}$ 的标准形,其中 $r = R(\mathbf{A})$, 矩阵与其标准形等价 。

正交向量组

两两正交且不含零向量的向量组。如果正交向量组的所有向量模为1,则称为 标准(规范)正交向量组。

正交方阵(Orthogonal matrix)

满足 $\mathbf{A}^{-1}=\mathbf{A^T}$。 也即 $\mathbf{A}\mathbf{A^T}=\mathbf{A^T}\mathbf{A}=\mathbf{I}$, 矩阵的行(列)向量组是标准正交向量组。

实二次型及其矩阵

实二次型 $f(\mathbf{X})$ 即系数为实数的 n 元二次 齐次 多项式。\
其对应 实对称方阵 $\mathbf{A}=(a{i,j}){n\times n}$ 的元素 $a_{i,j}$ 为二次型 $x_i x_j$ 的系数, 有 $f(\mathbf{X})=\mathbf{X^T A X}$。\
$\mathbf{A}$ 的秩称为 二次型的秩。

正定二次型

二次型的取值部大于零为正定二次型,总小于零为负定二次型,总大于等于零为半正定,总小于等于零为半负定

矩阵操作

初等变换

  • 交换两行(列)位置
  • 非零数乘某一行(列)
  • 把某行的倍数加到另一行

计算

数乘

矩阵数乘计算类似一个数

  • $k(\mathbf{A} +\mathbf{B}) = k\mathbf{A} + k\mathbf{B}$
  • $(k+l)\mathbf{A} = k \mathbf{A} + l \mathbf{A}$
向量内积

又称 数量积, 点乘,值为对应元素乘积的和,是一个数值。在空间中, $\mathbf{a}\cdot \mathbf{b} = ||\mathbf{a}||\,||\mathbf{b}||\cos <\mathbf{a},\mathbf{b}>$
有性质:

  • $|\mathbf{a}\cdot\mathbf{b}|\le||\mathbf{a}||\,||\mathbf{b}||$
  • $||\mathbf{a}+\mathbf{b}||\le ||\mathbf{a}|| + ||\mathbf{b}||$
  • 正交 $\mathbf{a}\bot\mathbf{b} \Leftrightarrow \mathbf{a}\cdot\mathbf{b}$

$\mathbf{b}$ 在 $\mathbf{a}$ 上的 投影:

$$ ||\mathbf{b}||\cos<\mathbf{a},\mathbf{b}>=\frac{\mathbf{a}\times\mathbf{b}}{||\mathbf{a}||} $$

向量外积

又称 向量积, 叉乘, 记作 $\mathbf{a}\times\mathbf{b}$, 结果为一个向量,模为 $||\mathbf{a}\times\mathbf{b}||=||\mathbf{a}||\,||\mathbf{b}||\cos<\mathbf{a},\mathbf{b}>$, 方向符合右手法则,以拳为起点,四指沿 $\mathbf{a}$ 指向,臂沿 $\mathbf{b}$ 指向,外积方向为拇指指向。 外积只作用于三维向量。 外积与相乘向量正交,可用于求解 平面法向量。

$$ \mathbf{a}\times\mathbf{b} =
\left|\begin{array}{}
\mathbf{i} & \mathbf{j} & \mathbf{k} \
a_1 & a_2 & a_3 \
b_1 & b_2 & b_3
\end{array}\right|
$$

混合积: $(\mathbf{a}\times\mathbf{b})\cdot\mathbf{c}$。 结果为数值,也仅用于三维向量,如果混合积为零,三向量共面。

矩阵相乘

没有交换律

  • 结合律 $(\mathbf{A}\mathbf{B})\mathbf{C}=\mathbf{A}(\mathbf{B}\mathbf{C})$
  • 分配律 $\mathbf{A}(\mathbf{B}+\mathbf{C}) = \mathbf{A}\mathbf{B} + \mathbf{A}\mathbf{C}$
转置

行列互换 。注意矩阵乘积的转置,检查行列数

  • $(\mathbf{A}\mathbf{B})^\mathbf{T} = \mathbf{B^T}\mathbf{A^T}$
  • $(\mathbf{A}+\mathbf{B})^\mathbf{T} = \mathbf{A^T} + \mathbf{B^T}$
  • $(\mathbf{A^T})^T = \mathbf{A}$
  • $(k\mathbf{A})^\mathbf{T} = k \mathbf{A^T}$

$\mathbf{A^T}\mathbf{A}$ 得到列向量的两两乘积矩阵,$\mathbf{A}\mathbf{A^T}$ 得到行向量的两两乘积矩阵

行列式
  • $\det (\mathbf{A} \mathbf{B}) = \det \mathbf{A} \det \mathbf{B}$
  • $\det (k \mathbf{A}) = k^n \det \mathbf{A}$
  • $\det (\mathbf{A} + \mathbf{B}) \ne \det \mathbf{A} + \det \mathbf{B}$

矩阵特征

行列式

对 n 阶 方阵 $\mathbf{A}$ 的行列式 $\det \mathbf{A}$ 为

$$ \det \mathbf{A} = \sum{j=1}^n a{i,j}\mathbf{A}_{i,j} $$

其中,i 为任意一行编号, $A{i,j}$ 为代数余子式,参考以下定义:\
余子式:元素 $a
{i,j}$ 的余子式为除去第 i 行 j 列的方阵的行列式,记作 $M{i,j}$。\
代数余子式: $A
{i,j}=(-1)^{i+j}M_{i,j}$

很明显,行列式的计算是一个递归的过程。特别 用于二三阶行列式 的简便计算方法:

三阶矩阵的行列式为每条红线上的元素的乘积之和,减去蓝线上元素乘积之和。(参考 Wikipedia 行列式)

秩

最高阶非零行列式的阶数。即,对矩阵 A,存在一个非零 r 阶子式,且任意 r+1 阶子式都为 0,则 A 的秩 R(A) = r \
k 阶子式: 矩阵取 k 行 k 列,其 $k^2$ 个交点按原来的相对位置构成 k 阶 行列式, 称其为 k 阶子式。

特征值(Eigenvalue)

对 方阵 A ,存在数 $\lambda$ 和 非零向量 $\mathbf{\alpha}$ 使得

$$ \mathbf{A\alpha} = \lambda \mathbf{\alpha} $$

也即 $(\lambda \mathbf{I} - \mathbf{A})\mathbf{\alpha} = \mathbf{0}$, 则称 $\lambda,\;\mathbf{\alpha}$ 分别为方阵 $\mathbf{A}$ 的特征值和特征向量。

矩阵性质

可逆

$$\mathbf{A}\mathbf{B}=\mathbf{B}\mathbf{A}=\mathbf{I}$$

满足该条件的 $\mathbf{A}$, $\mathbf{B}$ 为可逆矩阵,互为对方的逆矩阵,记 $\mathbf{A}^{-1} = \mathbf{B}$

充要条件
  • $\mathbf{A}$ 为方阵且 $\mathbf{A}\mathbf{B}=\mathbf{I}$
  • $\det \mathbf{A} \ne 0$
  • $r(\mathbf{A})=n$
  • 可表为有限个初等矩阵的乘积
  • 所有特征值全不为零
性质
  • $(\mathbf{A}\mathbf{B})^{-1}=\mathbf{B}^{-1}\mathbf{A}^{-1}$
  • $(\lambda\mathbf{A})^{-1}=\mathbf{A}^{-1}\lambda^{-1}$
  • $(\mathbf{A^T})^{-1} = (\mathbf{A}^{-1})^\mathbf{T}$
  • $\mathbf{A}^{-1} = (\det \mathbf{A})^{-1} \mathbf{A}^{ * }$
  • $\det \mathbf{A} \det \mathbf{A}^{-1}=1$
用行初等变换求逆矩阵

将矩阵施以行初等变换化为单位矩阵,同时将整个变化过程运用于单位矩阵得到逆矩阵

同型

两矩阵行列数相等

等价

对矩阵 A 施以初等变换能转化成 B,称二者等价。也即,存在可逆矩阵 P、Q,使得

$$ \mathbf{B} = \mathbf{P}\mathbf{A}\mathbf{Q} $$

性质: 等价矩阵同型等秩同标准形

相似

对于 n 阶方阵 A,B,如果存在可逆矩阵 P,使得

$$ \mathbf{P}^{-1}\mathbf{A}\mathbf{P}=\mathbf{B} $$

则称 A 与 B 相似,记为 $\mathbf{A} \sim \mathbf{B}$。 相似矩阵的特征值相同。

向量正交

两向量内积为零则正交

合同

对方阵 $\mathbf{A},\,\mathbf{B}$, 若存在可逆矩阵 $\mathbf{C}$, 使得

$$ \mathbf{B} = \mathbf{C^T A C} $$

则称 $\mathbf{A},\,\mathbf{B}$ 合同。

向量空间

发表于 2016-05-17   |   分类于 Math
矩阵相关

参考: 向量空间

向量空间

设 V 是一个非空集合,P 是一个数域。如果在 V 中定义了加法运算 “+”,P 与 V 定义了数乘运算 “$\cdot$”, 且满足八条运算规则(参考: 向量空间),则称系统 $(\mathbf{V},\mathbf{P},+,\cdot)$ 为线性空间。关键词:向量集合,加法数乘运算,八条规则。

基与维数

向量空间所有向量的一组最大线性无关组称为一组基,基向量的个数为空间维数。如果一组基是规范正交向量组,则称为 规范正交基。

坐标

向量空间一组基: $\mathbf{\varepsilon}_1,\mathbf{\varepsilon}_2,…,\mathbf{\varepsilon}_n$, 对 $\alpha$ 有:

$$ \mathbf{\alpha} = a_1 \mathbf{\varepsilon}_1 + a_2 \mathbf{\varepsilon}_2 + … + a_n \mathbf{\varepsilon}_n $$

称数组 $(a_1,a_2,…,a_n)$ 为 $\mathbf{\alpha}$ 在基 $\mathbf{\varepsilon}_1,\mathbf{\varepsilon}_2,…,\mathbf{\varepsilon}_n$ 下的坐标。

求解坐标,一般思路是求解方程组 $[\mathbf{\varepsilon}_1,\mathbf{\varepsilon}_2,…,\mathbf{\varepsilon}_n] \mathbf{X} =\mathbf{\alpha}$, 而当基为规范正交基时可简化成 $a_i=\mathbf{\alpha} \cdot \mathbf{\varepsilon}_i$

基变换与坐标变换

旧基变换到新基:

$$ (\mathbf{\varepsilon}_1’,\mathbf{\varepsilon}_2’,…,\mathbf{\varepsilon}_n’) = (\mathbf{\varepsilon}_1,\mathbf{\varepsilon}_2,…,\mathbf{\varepsilon}_n) \mathbf{A} $$

$\mathbf{A}$ 称为 过渡矩阵, 可逆。

对应旧坐标变换到新坐标:

$$ \begin{bmatrix}
a_1’ \
a_2’ \
\vdots \
a_n’ \end{bmatrix}
= \mathbf{A}^{-1} \begin{bmatrix}
a_1 \
a_2 \
\vdots \
a_n \end{bmatrix}
$$

Ubuntu 杂记

发表于 2016-05-16   |   分类于 Tools

日常命令

解压到指定目录

tar 用 -C 参数, unzip 用 -d 参数

time 命令

  • 系统内建 time 命令,shell 有另一个 /usr/bin/time,默认执行前者
  • 输出运行时间到文件用 -o 参数

nohup

ssh 连接退出时会话关闭,之前会话所打开的进程会收到 SIGHUP 信号,有些程序会因此关闭。而我所遇到的后台程序多是选择无视 : - ) ,但是遇到 ssh 非正常退出,这些后台程序也因此关闭 : - ( 。保险起见,使用 nohup 。

ps aux

显示所有运行进程

sshpass

ssh 命令行直接输入密码

last 与 lastb

分别查看登陆与登陆失败记录

update-alternatives 命令切换

1
update-alternatives --config cmd # 查看命令切换配置

uname

  • -a 查看内核版本,所有信息
  • -m 查看系统位数

ssh-keygen -t rsa

生成 ssh 密钥对

输出到屏幕及文件

1
2
echo 'hello world' 2>&1 | tee log.txt
echo 'hello world' |& tee log.txt # bash version 4

ssh连接测试

1
ssh -T git@git.oschina.net

解压目录下所有zip文件

1
for f in *.zip; do unzip $f; done

shell

变量可见性 + source + export

  • shell 变量是默认只对本 shell 可见
  • 使用 export 命令可以使变量对子 shell 可见,但仅以复制(传值)形式
  • source(同“.”): 在当前 shell 执行脚本,不开启子 shell

所以,如果需使脚本变量对当前 shell 及子 shell 可见,需要结合 source 和 export

while + 文件 + 字符串分割

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# 从 $in 文件读入用“,”分割的行,将每行前2个域输出到 $out 文件
OLD_IFS="$IFS"
IFS="," # 内部域分隔符 (Internal Field Seprator),默认为空白符,这里设置为 “,”
while read line # 按行读入
do
arr=($line) # 分割行,存入 arr 数组
echo ${arr[0]} # 输出第0个元素
echo ${arr[1]}
done < $in > $out # 从$in文件读入,从$out文件输出
IFS="$OLD_IFS" # 恢复默认

运行脚本

  • 脚本运行前即读入所有命令,即使删除也正常运行

case 语句

1
2
3
4
5
6
7
8
9
10
11
12
# case 语句示例
case "$1" in
start) # 匹配字符串
echo start
;; # break
stop)
echo stop
;; # break
*)
echo "Usage: test start|stop"
;;
esac

读入参数

1
2
3
4
5
6
7
# ask to suspend system, if so, request for password
read -p "suspend system? (yes/no): " cmd
if [ "$cmd" = "yes" ]
then
read -s -p "sudo needed, please enter passwd: " pswd
echo $pswd | sudo -S pm-suspend-hybrid # 挂起休眠混合模式,挂起数据存入 ram,休眠存入 disk
fi

日常操作

防止某软件自动更新

1
2
3
nvidia-smi # 查看驱动版本
dpkg --get-selections nvidia*
sudo apt-mark hold nvidia-375

打开终端中文乱码

ctrl+alt+f1打开终端,中文乱码。

  • 解决方案一:用支持中文的终端通过ssh连接
  • 解决方案二:使用fbterm,参考博文
    1
    2
    3
    4
    5
    6
    # 安装
    sudo apt install fbterm
    # 使用
    sudo fbterm
    # 退出
    exit

监视磁盘运行

1
2
3
4
5
6
7
8
9
sudo iotop    # 查看读写速度(包括各进程)

# 安装 apt-get install sysstat
# 最后一列为CPU时间占用率,反应繁忙程度
iostat -dx 1

lsblk # 查看各磁盘容量

pydf # 查看磁盘容量及使用率

安装中文输入法

1
2
sudo apt-get install fcitx-table-wbpy
# 重启系统

apt update使用代理

1
2
3
export http_proxy="http://hostname:port"
export ftp_proxy="http://hostname:port"
sudo apt-get update

安装chrome

1
2
3
4
5
cd /tmp
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
# 如果软件依赖报错,执行
sudo apt-get -f install

chrome 带socks5启动

1
2
3
google-chrome --proxy-server="socks5://addr_ip:port"
# addr_ip:port 为代理ip及端口,如,localhost:1080
# 如果 chrome 已装代理插件,如 SwitchyOmega,选择使用系统代理

交换区增删

交换区可以视作一个文件。运用命令:mkswap 格式化文件,swapon 启动交换区, swapoff 撤销交换区(不删除)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建 1GB 的文件,bs一次传输字节数, count 传输次数
# 文件大小=bs * count 字节,1K=1024, 1M=1K*1K, 1G=1M*1K
sudo dd if=/dev/zero of=/swapfile bs=1K count=1M
# 设置文件权限
sudo chown root:root /swapfile
sudo chmod 0600 /swapfile

sudo mkswap /swapfile # 格式化
sudo swapon /swapfile # 激活

# 设置开机自动挂载
sudo vi /etc/fstab # 编辑,添加以下配置
##################添加内容
/swapfile none swap sw 0 0
##################

########### 撤销交换区 ###########
sudo swapoff /swapoff
sudo vi /etc/fstab # 编辑,删除以下配置
##################删除内容
/swapfile none swap sw 0 0
##################
sudo rm /swapfile # 可删除文件

挂载新硬盘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看硬盘使用情况
df -h
# 用下面两条命令找到新的硬盘,比如/dev/sdb
lsblk
sudo fdisk -l
# 格式化硬盘
sudo mkfs -t ext4 /dev/sdb
# 可选,设置卷标,比如home2nd
# 查看UUID,比如0943c0ae-8a25-45c0-b4c4-08b76baa73d3
sudo blkid
sudo e2label /dev/sdb home2nd
# 创建挂载目录
sudo mkdir /home2nd
# 编辑 /etc/fstab,加入:
UUID=0943c0ae-8a25-45c0-b4c4-08b76baa73d3 /home2nd ext4 defaults 0 0

sudo reboot

ssh 无密码登陆

1
2
3
ssh-keygen -t rsa # 生成密钥,如果已生成可跳过
ssh-copy-id user@server_addr # 将密钥推送到服务器
ssh ssh_rtunnel@server_B_addr # 检验能否成功无密码登陆

增删用户

添加用户

1
2
3
4
5
6
7
8
sudo adduser <username> #添加一个普通用户
# useradd 是相对底层的命令
# sudo useradd -s /bin/bash -m <username> #-m 创建主目录
sudo usermod -aG <usergroup> username
# 可选将用户加入用户组,如 sudo组,可能需要logout再login生效
# 下面的命令起同样的效果
# sudo adduser <username> <usergroup>
# sudo passwd <username> # 初始化或修改用户密码

修改已添加用户的shell

1
sudo usermod -s /bin/bash user # 修改已添加用户的shell为 bash

使用户能够在登陆屏登陆,在 /etc/lightdm/lightdm.conf加入:

1
2
[SeatDefaults]
greeter-show-manual-login=true

删除用户:

1
2
sudo deluser <username>
sudo rm -r /home/<username>

切换用户主目录

  • 修改/etc/passwd
  • mv 主目录

主目录下的文件夹名改回英文

1
2
export LANG=en_US
xdg-user-dirs-gtk-update

之后注销。参考中文Ubuntu主目录下的文档文件夹改回英文

ssh 反向 tunnel

两台主机,局域网主机LAN A,拥有公网IP主机SERVER B,建立反向 tunnel,从外网通过B访问A。

第一步:在SERVER B创建用户,并实现A无密码登陆B,详见“增删用户”及“ssh 无密码登陆”部分。

1
2
3
4
5
6
7
8
9
10
11
# login SERVER B
sudo useradd -m ssh_rtunnel # 添加一个普通用户 ssh_rtunnel
sudo passwd ssh_rtunnel # 初始化密码
###################################################
# login LAN A
ssh-keygen -t rsa # 生成密钥,如果已生成可跳过
ssh-copy-id ssh_rtunnel@server_B_addr # 将密钥推送到SERVER B
ssh ssh_rtunnel@server_B_addr # 检验能否成功无密码登陆
###################################################
# login SERVER B
sudo usermod -s /bin/false ssh_rtunnel # 防止 ssh_rtunnel 执行 shell 命令

第二步:SERVER B配置

1
2
3
4
5
6
7
# login SERVER B
sudo vi /etc/ssh/sshd_config # 向 sshd_config 文件添加:
##################添加内容
GatewayPorts clientspecified
##################

sudo service sshd restart # 重启 ssh 服务

第三步:LAN A创建 tunnel

1
2
3
4
5
6
# login LAN A
sudo apt-get install autossh
autossh -fN -R :2210:localhost:22 ssh_rtunnel@server_B_addr
# 创建 tunnel。SERVER B在2210端口收到的数据都会传向LAN A的22号端口
# 由于 22 号端口是 ssh 连接端口,故该 tunnel 可用于 ssh 连接
# 可将这条命令加入 /etc/profile 使之开机自启

最后可在任何能访问到SERVER B的主机上访问LAN A

1
ssh -p 2210 user_on_LAN_A@server_B_addr

检查进程是否运行

1
2
3
4
5
6
7
8
9
10
11
12
if ! ps -p $PID > /dev/null # 如果进程不存在
then
echo not runnig
fi

# 每8秒检查一次进程是否结束
while ps -p $PID > /dev/null # 如果进程存在
do
sleep 8
done
# 进程已结束
echo not runnig

查看父进程ID

1
2
3
4
ps -o ppid= 1 # 查看1号进程父进程,注意空格
ps -f 1 # 详细信息
pstree -p 1 | less # 查看1号进程的子进程树。用less分页显示
pstree -s -p 1 # 同时查看父进程

Nvidia显卡信息

1
2
3
4
5
6
nvidia-smi
# 查询gpu指定信息,用逗号分隔,这里查看已用显存大小(M)
nvidia-smi --format=csv,noheader,nounits --query-gpu=memory.used
nvidia-smi --format=csv --query-gpu=power.draw,utilization.gpu,fan.speed,temperature.gpu
# 更多查询选项
nvidia-smi --help-query-gpu

查看硬件信息

1
2
3
4
5
6
sudo lshw # 所有硬件信息
sudo lshw -C cpu # cpu 信息
sudo lshw -C memory # 内在信息
sudo lshw -C display # 显卡信息
nvidia-smi -q # nvidia 显卡信息
sudo lshw -C storage # 硬盘信息

文本换行符转换

  • todos, fromdos 命令
  • vi 编辑器命令:
    1
    2
    :set fileformat=dos
    :set fileformat=unix

压缩包中文文件名乱码

解压,解决方式一:

1
unzip -O CP936 zipfile

解压,解决方式二, 在 ubuntu 文件区内 :

1
2
LANG=C 7z x CompressedFile
convmv -f GBK -t UTF8 CompressedFile --notest

压缩,使用 7z 命令压缩。

防暴力登陆盗取密码

  • 使用 last 与 lastb 检查最近登陆情况
  • denyhosts 工具防 ssh 猜测密码
denyhosts 安装
1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install denyhosts  # denyhosts 不同版本配置有差别
sudo vi /etc/denyhosts.conf # 可选配置 denyhosts
# RESET_ON_SUCCESS = yes # 如果登录成功,重置计数
# DEVY_THRESHOLD_INVALID = 5 # 允许无效用户登录失败次数
# DEVY_THRESHOLD_VALID = 10
# DEVY_THRESHOLD_ROOT = 1
# DEVY_THRESHOLD_RESTRICTED = 1
sudo service denyhosts start # 运行

ls /etc/rc2.d | grep denyhosts # 如果有输出,证明安装程序已经设置开机自启

vi /etc/hosts.deny # 一段时间后可查看被禁 ip

如果自己 ip 被屏蔽了,可以换个 ip 登陆,再参考 删除 DenyHosts 屏蔽 ip 方法,其中 WORK_DIR 可能为 /var/lib/denyhosts。

本机端口转发

1
2
3
4
5
6
7
8
9
10
sudo vi /etc/sysctl.conf
# 添加下句
# net.ipv4.ip_forward=1
sudo sysctl -p
sudo iptables -t nat -A PREROUTING -d 本机IP -p tcp --dport 源端口 -j DNAT --to-destination 本机IP:目的端口
sudo vi /etc/rc.local
# 将命令写入,实现开机启动
# iptables -t nat -A PREROUTING -d 本机IP -p tcp --dport 源端口 -j DNAT --to-destination 本机IP:目的端口
# 用此命令查看nat列表
sudo iptables -t nat --list

发送邮件

用 heirloom-mailx 工具

heirloom-mailx 安装
1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install heirloom-mailx
sudo vi /etc/nail.rc # 必须配置发送账号及其 stmp 服务器
###############配置
set from=USER@163.com
set smtp=smtp.163.com
set smtp-auth-user=USER
set smtp-auth-password=PASSWORD
set smtp-auth=login
###############

# 发送邮件
echo "邮件内容" | heirloom-mailx -s "邮件标题" toWho@email.address

安装配置网络代理——shadowsocks

  • shadowsocks 简介
  • shadowsocks github 主页

服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo apt-get install python-pip
sudo pip install shadowsocks # 安装 shadowsocks

sudo vi /etc/shadowsocks.conf # 编辑配置文件
###############配置
{
"server":"server ip",
"server_port":8388,
"local_port":1080,
"password":"your password",
"timeout":600,
"method":"aes-256-cfb"
}
###############

# 启动
sudo /usr/local/bin/ssserver -v --log-file /var/log/shadowsocks.log -c /etc/shadowsocks.conf -d start

sudo vi /etc/rc.local # 加入以下命令以开机自启
###############配置
/usr/local/bin/ssserver -v --log-file /var/log/shadowsocks.log -c /etc/shadowsocks.conf -d start
###############

vi /var/log/shadowsocks.log # 可查看运行日志

主页下可以找到 windows 客户端下载 与 android 客户端下载。

Ubuntu 客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sudo apt-get install python-pip
sudo pip install shadowsocks # 安装 shadowsocks

vi ~/.shadowsocks.conf # 编辑配置文件
###############配置
{
"server":"server ip",
"server_port":8388,
"local_port":1080,
"password":"your password",
"timeout":600,
"method":"aes-256-cfb"
}
###############

nohup sslocal -c ~/.shadowsocks.conf &>/dev/null & # 启动,可将输出重定向作为日志
vi ~/.profile # 开机自启,加入下列命令
###############配置
nohup sslocal -c ~/.shadowsocks.conf &>/dev/null &
###############

Ubuntu图形客户端

1
2
3
4
5
sudo add-apt-repository ppa:hzwhuang/ss-qt5
sudo apt-get update
sudo apt-get install shadowsocks-qt5
# 启动
ss-qt5

文件处理之 sed

参考网页:远有青山——Sed 命令详解 正则表达式元字符 , 东方雨中漫步者——linux之sed用法,学习 进步——linux sed命令详解

sed [选项] [输入文件]

常用选项:

  • -i 直接修改读取的档案内容
  • -n 使用安静(silent)模式。在一般sed的用法中,所有来自STDIN的资料一般都会被列出到萤幕上。但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来。

常用命令:

  • s:字符串替换
  • p: 打印

元字符:

  • $:行尾或最后一行
  • ^: 行开头
1
2
sed -i '$s/./a/1' file.txt # 最后一行第一个字符替换为 'a'
sed -n "/^root$/p" file.txt # 打印内容为root的行

rc.local开机启动脚本

首先检测是否支持rc.local

1
2
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

参考:https://www.claudiokuenzler.com/blog/783/ubuntu-18.04-rc.local-file-not-exist-launch-with-systemd-rc-local

在新版的Ubuntu中默认不支持rc.local开机执行,可在/etc/init.d下加入rc.local脚本以支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#! /bin/sh
### BEGIN INIT INFO
# Provides: rc.local
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: Run /etc/rc.local if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

do_start() {
if [ -x /etc/rc.local ]; then
/etc/rc.local
return $?
fi
}

case "$1" in
start)
do_start
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop|status)
# No-op
exit 0
;;
*)
echo "Usage: $0 start|stop" >&2
exit 3
;;
esac

执行以下命令:

1
2
3
4
sudo chown root:root /etc/init.d/rc.local
sudo chmod 755 /etc/init.d/rc.local
cd /etc/init.d
sudo update-rc.d rc.local defaults 99

随后可编辑/etc/rc.local脚本,注意权限755,用户为root。注:/etc/rc.local首行加#!/bin/bash

1
2
sudo chown root:root /etc/rc.local
sudo chmod 755 /etc/rc.local

参考文档:

  • https://www.linuxidc.com/Linux/2017-09/147166.htm
  • https://www.claudiokuenzler.com/blog/783/ubuntu-18.04-rc.local-file-not-exist-launch-with-systemd-rc-local

文件

/etc/network/if-up.d 目录

网络建立后会执行其下脚本

/usr/local 与 /opt

两者都是手动(非 apt)安装程序目录,当然都需要 root 权限。不同在于,/usr/local 下有 bin, src, include 之类目录,程序各部分分家,遵从系统程序安装习惯,而 /opt 就没有这个约束,所以,像 Tomcat 这种拥有自己目录结构的程序应该置于 /opt 下,并且拥有独立的目录,如 /opt/tomcat。

/etc/rc#.d

目录,# 是数字,代表运行级别。其下有多个脚本,多是 /etc/init.d 目录下脚本的链接,在转换到相应运行级别时按序执行,如 init 0,会执行 rc0.d 下脚本。文件命名以 K, S 开头,分别表示关闭、开启服务。

/etc/rc.local

开机后系统自动执行的脚本

/etc/init.d

存放各种管理服务——如 mysql——的脚本的目录。可以用 service 命令调用这些脚本以执行服务的启动关闭等操作,当然也可直接执行,如

1
2
sudo service mysql status
sudo /etc/init.d/mysql status

/etc/issue

系统发布版本

/proc/cpuinfo

cpu 信息。processor 逻辑 cpu 编号,总计为 cpu 线程数,physical id 物理 cpu 编号,总计为 cpu 个数,core id 为 cpu 的(对应某cpu的)核心编号,总计为 cpu 核心数。机器可有多个 cpu,每个 cpu 可有多个核心,每个核心可以开多个线程。

/proc/meminfo

内存信息。也可用 free 命令查看内存

常识

运行级别

  1. 关机
  2. 单用户,Does not configure network interfaces, start daemons, or allow non-root logins
  3. 多用户,无网络连接 Does not configure network interfaces or start daemons
  4. 多用户,启动网络连接,仅启动命令行界面 Starts the system normally.
  5. 用户自定义
  6. 多用户,带图形界面
  7. 重启

摘自wikipedia, 在Debian Linux中,2-5这四个运行级别合为多用户状态,默认2。可用 init 命令切换运行状态。

C/C++ 操作符优先级

发表于 2016-05-12   |   分类于 C/C++

参考

  • cppreference: C++ Operator Precedence
  • C语言中文网:C语言运算符的优先级和结合性一览表

优先级

  1. 单目运算符,只需一个操作数,先右后左,越靠近操作数越优先,如:++*p.f 即 ++(*(p.f))
  2. 算术运算符:+, -, *, /, %
  3. 移位运算符:>>, <<
  4. 关系运算符:>, <, == 等
  5. 位逻辑运算符: &, |, ^
  6. 逻辑运算符:&&, ||
  7. 条件运算符:先右
  8. 赋值运算符:先右,如:a=b=b+c 即 a=(b=b+c)
  9. 逗号: 自左向右运算,仅保留最后一个值

其实没有必要记下来,如果不确定就加括号。 :P

容易出错的情况

这是 C语言中文网 博文中附的,总结得非常好,就直接借鉴了:

RPCS —— SGD 下降速率方案与 LIBMF 分析

发表于 2016-05-11   |   分类于 ML

声明

先导知识:随机梯度下降法(SGD),矩阵分解。

本文是对学习 LIBMF 2.01 的备忘录,其中相当多的内容直接来自于论文: W.-S. Chin, Y. Zhuang, Y.-C. Juan, and C.-J. Lin. A Learning-rate Schedule for Stochastic Gradient Methods to Matrix Factorization. PAKDD, 2015.
另外可参考LIBMF分析的姊妹篇:FSPD算法与LIBMF API浅析

简介

RPCS 是一种在随机梯度下降过程中动态改变下降速率以提高效率的算法。此方法被用于分解矩阵的开源 API LIBMF (2.01)中,由台湾大学机器学习团队开发。

矩阵分解与SGD

运用SGD分解矩阵,更详细的说明请参考:FSPD算法与LIBMF API浅析的简介部分,这里引用损失函数:
$$\min{P, Q} \sum{u, v}((r_{u,v} - p_u^\mathrm{T}q_v)^2 - \lambda ||p_u||^2 - \lambda ||qv||^2) \label{opt} \tag{1}$$
SGD 需要分解矩阵 $R
{u,v}$,求解出最优的 $P{k,u}$ 与 $Q{k,v}$, 其中 ${\lambda}$ 是正则化参数。

求解出梯度:
$$gu = \frac{1}{2} (-e{u,v} q_v + \lambda p_u) \label{gradP} \tag{2}$$

$$hv = \frac{1}{2} (-e{u,v} p_u + \lambda q_v) \label{gradQ} \tag{3}$$

其中,$e{u,v} = r{u,v} - p_u^\mathrm{T} q_v$

$P$, $Q$ 下降公式分别为:
$$p_u \leftarrow p_u - \eta g_u \label{descP} \tag{4}$$
$$q_v \leftarrow q_v - \eta h_v \label{descQ} \tag{5}$$

其中 $\eta$ 为下降速率。

下降速率方案

下降速率 $\eta$ 对梯度下降法有重要的影响,合适的 $\eta$ 往往能减小所需迭代下降的次数。

固定速率

固定速率 $\eta$,相比其他方法,无需计算 $\eta$ 的开销。

单调下降(MDS)

Monotonically Decreasing Schedule (MDS)方法,在第 $z$ 次下降中:
$$\eta^z = \frac{\alpha}{1 + \beta z^{1.5}}$$
其中 $\alpha$, $\beta$ 为指定常数。$\eta$ 随着迭代的进行逐渐下降,类似的公式就不在此列举。

Bold-driver Schedule (BDS)

设 $\Delta_z$ 为损失函数 $(\ref{opt})$ 的值在第z次迭代与在前次迭代之差,BDS的方案是:

if $\Deltaz \lt 0$ then $\eta{z+1} = \alpha \etaz$ else $\eta{z+1} = \beta \eta_z$

其中 $\alpha \gt 1$ 而 $0 \lt \beta \lt 1$。也就是说,当损失函数成功下降时,$\eta$ 增大,反之减小。

Per-coordinate Schedule (PCS)

研发者给出中间矩阵 $G_u$ 和 $P_v$,并给出更新公式 :
显然 $G_u$, $P_v$ 与 $g_u$, $p_v$ 相关。然后转换下降公式 $(\ref{descP})$, $(\ref{descQ})$ 为:
$$p_u \leftarrow p_u - \eta G_u^{-1/2} g_u \label{PCSDescP} \tag{6}$$
$$q_v \leftarrow q_v - \eta H_v^{-1/2} h_v \label{PCSDescQ} \tag{7}$$

RPCS

Reduced Per-coordinate Schedule (RPCS) 在 RCS 基础上改进并用于矩阵分解。

各元素统一 $\eta$

如果以 $p_u$ 各元素为单位(而非向量)思考式子 $(\ref{PCSDescP})$,可发现每个元素的下降速率是不同的。这造成的问题是,$G_u$ 必须记录每个 $p_u$ 元素的下降速率,共 $k$ 个,考虑到整个 $P$ 矩阵,将消耗 $m \times k$ 个单元。

RPCS的方案是,将 $G$, $H$ 的更新公式改为:
$$G_u \leftarrow G_u + \frac{g_u^\mathrm{T}g_u}{k} \label{RPCSUpdateG} \tag{8}$$
$$H_v \leftarrow H_v + \frac{h_v^\mathrm{T}h_v}{k}$$
$G_v$ 变成了标量,只需1个存储单元,空间开销大大减小。$H_v$ 同理。而且,研究者证明,使用相同的 $\eta$ 对 PCS 方法几乎没影响。

合并循环

研究者注意到 $p_u$ 是一个向量,一次更新需要一个循环,而每次循环需要计算一次 $(g_u)_i$ (即 $g_u$ 的当前更新的第 $i$ 个元素)。同时,$G_u$ 每次更新同样需要一个循环,并且每次需计算 $(g_u)_i$。RPCS 利用这一点,将2个循环合并而无需重复计算 $(g_u)_i$。$qu$ 同理。作者提供的一次迭代伪代码:

Twin Learners (TL)

RPCS 的下降速率总是下降的,然而,作者发现,在经历了头几次迭代后,下降速率急剧下降,甚至在第一次迭代后,下降速率就已经减半。其原因可能是,因为最初没有经过下降,用随机方法初始化的 $P$ 与最优解相差较大,使得梯度误差 $e_{u,v}$,梯度 $g_u$ 较大,导致 $G_u$ 过大,下降速率急剧下降。

TL 方案将 $pu$ 的更新分为2个部分,$p{1:k}$ (取 $pu$ 1至个元素构成一个向量)与 $p{(k+1):u}$, 前者称为慢速学习部分,后者称为快速学习部分。相应有 $G{1:k}$ 与 $G{(k+1):u}$,它们同样分别用式子 $(\ref{RPCSUpdateG})$ 更新。与 RPCS 不同的是,在第一次下降中,$G_{(k+1):u}$ 不更新,也就是说,快速学习部分第一次迭代速率不作下降。

作者的实验表明,慢速学习部分相对 RPCS 在头几次迭代后,下降速率下降得更大,但快速学习部分,因为慢速学习部分“吸收了”误差带来的影响,保持着较高的下降速率。$q_v$ 同理。TL 使得下降次数相对 RPCS 有显著减少。

1…678
Blunt

Blunt

email:summer15y@163.com

72 日志
7 分类
37 标签
© 2019 Blunt
由 Hexo 强力驱动
主题 - NexT.Muse