文章目录
前言
最近看西瓜书的SVM,貌似不是很理解,赶紧来看看李宏毅的补一补。
本节主要内容包括:
Hinge Loss的由来
Kernel Method
公式输入请参考:在线Latex公式
前情回顾(二分类Binary Classification)
监督学习,training data中每个x对应有y hat
三板斧:
这里的
δ
\delta
δ是用来计算
g
(
x
n
)
g(x^n)
g(xn)是否与
y
^
n
\widehat y^n
y
n相同,相同为0(正确),不同为1(犯错)。整个loss函数是希望
y
^
n
\widehat y^n
y
n犯的错误越少越好。但是上面的loss函数是不可导的,没有办法用GD来求解。因此把
δ
\delta
δ用一个approximate的函数来替换:
Step 3:GD求解
上面步骤2中的approximate的函数我们可以自己找函数来进行替换。
approximate的Loss函数
先看坐标轴,横轴为
y
^
n
f
(
x
)
\widehat y^nf(x)
y
nf(x),纵轴为approximate的Loss(
l
(
f
(
x
n
)
,
y
^
n
)
l(f(x^n),\widehat y^n)
l(f(xn),y
n))。意思是
y
^
n
\widehat y^n
y
n和
f
(
x
)
f(x)
f(x)同号的时候希望
f
(
x
)
f(x)
f(x)越大越好,
y
^
n
\widehat y^n
y
n和
f
(
x
)
f(x)
f(x)异号的时候希望
f
(
x
)
f(x)
f(x)越小越好
下面各种替代方案解析一下:
square loss
使用square loss的时候approximate的Loss函数可写为:
l
(
f
(
x
n
)
,
y
^
n
)
=
(
y
^
n
f
(
x
n
)
−
1
)
2
l(f(x^n),\widehat y^n)=(\widehat y^nf(x^n)-1)^2
l(f(xn),y
n)=(y
nf(xn)−1)2
当
y
^
n
=
1
\widehat y^n=1
y
n=1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
(
f
(
x
n
)
−
1
)
2
l(f(x^n),\widehat y^n)=(f(x^n)-1)^2
l(f(xn),y
n)=(f(xn)−1)2
当
y
^
n
=
−
1
\widehat y^n=-1
y
n=−1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
(
−
f
(
x
n
)
−
1
)
2
=
(
f
(
x
n
)
+
1
)
2
l(f(x^n),\widehat y^n)=(-f(x^n)-1)^2=(f(x^n)+1)^2
l(f(xn),y
n)=(−f(xn)−1)2=(f(xn)+1)2
在图上看出来(红线),这个方案不合理,原因很简单,我们不希望
y
^
n
f
(
x
)
\widehat y^nf(x)
y
nf(x)同号时
f
(
x
)
f(x)
f(x)越大loss值越大。
Sigmoid+Square Loss
使用Sigmoid+Square loss的时候approximate的Loss函数可写为:
l
(
f
(
x
n
)
,
y
^
n
)
=
(
σ
(
y
^
n
f
(
x
n
)
)
−
1
)
2
l(f(x^n),\widehat y^n)=\left (\sigma(\widehat y^nf(x^n))-1\right )^2
l(f(xn),y
n)=(σ(y
nf(xn))−1)2
当
y
^
n
=
1
\widehat y^n=1
y
n=1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
(
σ
(
f
(
x
n
)
)
−
1
)
2
l(f(x^n),\widehat y^n)=(\sigma(f(x^n))-1)^2
l(f(xn),y
n)=(σ(f(xn))−1)2
当
y
^
n
=
−
1
\widehat y^n=-1
y
n=−1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
(
σ
(
−
f
(
x
n
)
)
−
1
)
2
=
(
1
−
σ
(
f
(
x
n
)
)
+
1
)
2
=
(
σ
(
f
(
x
n
)
)
)
2
l(f(x^n),\widehat y^n)=(\sigma(-f(x^n))-1)^2=(1-\sigma(f(x^n))+1)^2=\left (\sigma\left (f(x^n)\right)\right)^2
l(f(xn),y
n)=(σ(−f(xn))−1)2=(1−σ(f(xn))+1)2=(σ(f(xn)))2
在图上看出来(蓝线),这个方案不合理,原因很简单,Sigmoid+Square函数计算效率低(下面有说明)。
Sigmoid + cross entropy(logistic regression)
使用Sigmoid+cross entropy loss的时候approximate的Loss函数可写为:
l
(
f
(
x
n
)
,
y
^
n
)
=
l
n
(
1
+
e
x
p
(
−
y
^
n
f
(
x
n
)
)
)
l(f(x^n),\widehat y^n)=ln(1+exp(-\widehat y^nf(x^n)))
l(f(xn),y
n)=ln(1+exp(−y
nf(xn)))
当
y
^
n
f
(
x
n
)
\widehat y^nf(x^n)
y
nf(xn)趋向于正无穷大的时候,
e
x
p
(
−
y
^
n
f
(
x
n
)
)
exp(-\widehat y^nf(x^n))
exp(−y
nf(xn))趋向于0,
l
n
(
1
+
0
)
=
0
ln(1+0)=0
ln(1+0)=0
当
y
^
n
f
(
x
n
)
\widehat y^nf(x^n)
y
nf(xn)趋向于负无穷大的时候,
e
x
p
(
−
y
^
n
f
(
x
n
)
)
exp(-\widehat y^nf(x^n))
exp(−y
nf(xn))趋向于∞,
l
n
(
1
+
∞
)
=
∞
ln(1+∞)=∞
ln(1+∞)=∞
σ
(
f
(
x
)
)
\sigma(f(x))
σ(f(x))是概率分布,cross entropy是求分布之间的相似度。
从图上看是绿色线,这里的线除了一个
l
n
2
ln2
ln2,除这个可以使得这个曲线成为Ideal loss的upper bound,upper bound的作用为:当Ideal loss没有办法求导计算的时候,我们可以计算Ideal loss的upper bound,来minimize Ideal loss。
然后看看Sigmoid + cross entropy和Sigmoid+Square的比较,注意黑点,意味着当
y
^
n
f
(
x
n
)
\widehat y^nf(x^n)
y
nf(xn)在负无穷大的地方,做GD的值很小,也就验证了为什么Sigmoid+Square效率比Sigmoid + cross entrop低。
Hinge Loss
使用Hinge loss的时候approximate的Loss函数可写为:
l
(
f
(
x
n
)
,
y
^
n
)
=
m
a
x
(
0
,
1
−
y
^
n
f
(
x
n
)
)
l(f(x^n),\widehat y^n)=max(0,1-\widehat y^nf(x^n))
l(f(xn),y
n)=max(0,1−y
nf(xn))
当
y
^
n
=
1
\widehat y^n=1
y
n=1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
m
a
x
(
0
,
1
−
f
(
x
n
)
)
l(f(x^n),\widehat y^n)=max(0,1-f(x^n))
l(f(xn),y
n)=max(0,1−f(xn)),当
1
−
f
(
x
)
<
0
1-f(x)<0
1−f(x)<0,即
f
(
x
)
>
1
f(x)>1
f(x)>1,函数得到最小值0。
当
y
^
n
=
−
1
\widehat y^n=-1
y
n=−1时,
l
(
f
(
x
n
)
,
y
^
n
)
=
m
a
x
(
0
,
1
+
f
(
x
n
)
)
l(f(x^n),\widehat y^n)=max(0,1+f(x^n))
l(f(xn),y
n)=max(0,1+f(xn)),当
1
+
f
(
x
)
<
0
1+f(x)<0
1+f(x)<0,即
f
(
x
)
<
−
1
f(x)<-1
f(x)<−1,函数得到最小值0。
也就是说
f
(
x
)
>
1
f(x)>1
f(x)>1和
f
(
x
)
<
−
1
f(x)<-1
f(x)<−1的时候就可以使得函数得到最小值,画出图形如下,紫色线。
这里为什么Hinge Loss函数中设置的值为1?因为为1的时候,Hinge Loss函数刚好是Ideal loss的upper bound。
然后看看Sigmoid + cross entropy和Hinge Loss的比较,注意黑点,在过了横轴值为1的点,Hinge Loss就没有变化了,而Sigmoid + cross entropy还可以继续下降。两个Loss函数在效率上都差不多,但Hinge Loss不怎么怕outlier,学习出来的结果会比较robust,后面讲kernel的时候会比较明显。
关于outlier:Sigmoid + cross entropy比较像偏科生,某门课程会考得比较好,但是有些科目比较差;
Hinge Loss则每个科目都比较均衡,都会及格,所以有outlier的时候Hinge Loss反而会有比较好的结果。
Linear SVM
-
Step 1: Function (Model)
线性SVM(传统SVM是解决线性可分问题)的模型是下面这个样子, x i x_i xi是样本的i个特征, w i w_i wi是对应的权重。
f ( x ) = ∑ i w i x i + b f(x)=\sum_iw_ix_i+b f(x)=i∑wixi+b
上面的式子可以写为向量点乘的形式:
把w和b串起来(contract)的vector看做一个新的权重w,这个新的w就是模型的参数,要通过training data找出来。
-
Step 2: Loss function
Total Loss如下,后面是正则化项,整个 L ( f ) L(f) L(f)是凸函数,因为第一项和第二项的图像如下面所示,可以看出来两项都是凸函数,凸函数加凸函数还是凸函数。
既然是凸函数,那么做GD,无论是什么地方开始都会得到结果。
但是可以从上图看出,这个凸函数有些棱角(由于Hinge loss的棱角造成的)的地方不可导。 -
Step 3: gradient descent?
有地方不可导,能不能GD?
答案:可以!Recall relu, maxout network
Compared with logistic regression(这个用的crossentropy), linear SVM has different loss function(这个用的hinge loss)
Linear SVM GD计算
GD就是要求偏导,先对w求偏导,红框部分根据蓝框可以得到结果
x
i
n
x_i^n
xin
前面一项对
f
(
x
n
)
f(x^n)
f(xn)求导考虑两种方式:
因此偏导最后的形式如下:
GD的更新为:
Linear SVM的另外一个形式
把要最小化的total loss函数L写为:
L
(
f
)
=
∑
n
l
(
f
(
x
n
)
,
y
^
n
)
+
λ
∣
∣
w
∣
∣
2
L(f)=\sum_nl(f(x^n),\widehat y^n)+\lambda||w||_2
L(f)=n∑l(f(xn),y
n)+λ∣∣w∣∣2
其中可以用
ϵ
n
\epsilon^n
ϵn来代替第一项
L
(
f
)
=
∑
n
ϵ
n
+
λ
∣
∣
w
∣
∣
2
L(f)=\sum_n\epsilon^n+\lambda||w||_2
L(f)=n∑ϵn+λ∣∣w∣∣2
其中:
ϵ
n
=
m
a
x
(
0
,
1
−
y
^
n
f
(
x
n
)
)
\epsilon^n=max(0,1-\widehat y^nf(x^n))
ϵn=max(0,1−y
nf(xn))
上面这个
ϵ
n
\epsilon^n
ϵn可以等价于(如果没有加最小化total loss的限制是不等价的,因为
ϵ
n
≥
0
\epsilon^n≥0
ϵn≥0及下面一个条件,可以去取
f
(
x
)
f(x)
f(x)很大,例如∞也可以满足条件。):
ϵ
n
≥
0
\epsilon^n≥0
ϵn≥0
ϵ
n
≥
1
−
y
^
n
f
(
x
n
)
)
\epsilon^n≥1-\widehat y^nf(x^n))
ϵn≥1−y
nf(xn))即:
y
^
n
f
(
x
n
)
)
≥
1
−
ϵ
n
\widehat y^nf(x^n))≥1-\epsilon^n
y
nf(xn))≥1−ϵn
ϵ
n
\epsilon^n
ϵn就是Slack variable,就是李航里面提到的软间隔的概率。
以上也称为Quadratic Programming (QP) Problem(二次规划问题)
Kernel
Dual Representation
假设我们找到了可以最小化total loss的weight,记为
w
∗
w^*
w∗,它其实是所有data的linear的combination,写为:
w
∗
=
∑
n
α
n
∗
x
n
w^*=\sum_n\alpha^*_nx^n
w∗=n∑αn∗xn
这个找
w
∗
w^*
w∗的方法一般都是采用拉格朗日对偶性求解,具体参阅李航《统计学习方法》附录C。
这里,李老师用另外一种方法来证明这个事情。先给出之前推出来的对
w
i
w_i
wi做GD的式子:
w
i
←
w
i
−
η
∑
n
c
n
(
w
)
x
i
n
w_i\leftarrow w_i-\eta\sum_nc^n(w)x_i^n
wi←wi−ηn∑cn(w)xin
如果
w
w
w有
k
k
k个dimension,则变成:
我们把
w
1
w_1
w1到
w
k
w_k
wk串成一个vector,
x
1
x_1
x1到
x
k
x_k
xk串成一个vector,上面的东西变成:
w
←
w
−
η
∑
n
c
n
(
w
)
x
n
w\leftarrow w-\eta\sum_nc^n(w)x^n
w←w−ηn∑cn(w)xn
如果
w
w
w初始化为0,上面的式子的解为:
c
n
(
w
)
c^n(w)
cn(w)(这里没看懂)
根据GD的定义有:
c
n
(
w
)
=
∂
l
(
f
(
x
n
)
,
y
^
n
)
∂
f
(
x
n
)
c^n(w)=\frac {\partial l(f(x^n),\widehat y^n)}{\partial f(x^n)}
cn(w)=∂f(xn)∂l(f(xn),y
n)
上式的右边可以翻上面的笔记可知,这个玩意对于Hinge Loss而言很多情况下是等于0的,也就意味着组成
w
∗
w^*
w∗的
α
n
∗
x
n
\alpha^*_nx^n
αn∗xn中的
α
n
∗
\alpha^*_n
αn∗有很多值为0,也就是一个稀疏矩阵,那些
x
n
x^n
xn对应的
α
n
∗
\alpha^*_n
αn∗不为0,则成为support vector。
这里再次给出SVM对比LR要robust的原因:
对于LR而言,组成w的x对应的α都是非0的,所以如果里面的x有outlier就会影响到w的值(就是所有的数据对w都会有影响);
对于SVM,组成w的x对应的α是可以为0的,所以当x有outlier的时候没关系,把它的α设置为0就可以使得outlier不影响w。
现在在理解了w是x的线性组合的基础上,我们可以进一步写出w的向量化表示:
重新把之前的三板斧写出来。
上图中注意
α
T
\alpha^T
αT和
X
T
X^T
XT两个转置的方向,这里先计算
X
T
x
X^Tx
XTx
下面那里有个K函数,就是后面的的核函数。注意:由于
α
n
\alpha_n
αn是稀疏的,所以求
x
n
⋅
x
x^n \cdot x
xn⋅x效率并不是很低(只用求非零项)。
在step 1中,我们得到的模型为:
f
(
x
)
=
∑
n
α
n
K
(
x
n
,
x
)
f(x)=\sum_n\alpha_nK(x^n,x)
f(x)=n∑αnK(xn,x)
里面
α
n
\alpha_n
αn是我们不知道的,所以:
Step 2,3 目的就是要找一组
{
α
1
∗
,
.
.
.
α
n
∗
,
.
.
.
α
N
∗
,
}
\left \{ \alpha_1^*,...\alpha_n^*,...\alpha_N^*,\right \}
{α1∗,...αn∗,...αN∗,},最小化total loss函数
L
L
L
注意下面的等号带入了STEP 1的结果,由于最外面已经是n个数据求和,为了不重复就用了
n
′
n'
n′。
We don’t really need to know vector x
We only need to know the inner project between a pair of vectors x and z
记为:
K
(
x
,
z
)
K(x,z)
K(x,z)
以上称为:Kernel Trick,这个东西不仅仅可以用在SVM,还可以用于LR。
Kernel Trick
Kernel trick is useful when we transform all
x
x
x to
ϕ
(
x
)
\phi(x)
ϕ(x)
假设我们有:
x
=
[
x
1
x
2
]
x=\begin{bmatrix}x_1\\ x_2 \end{bmatrix}
x=[x1x2]
要变换为:
ϕ
(
x
)
=
[
x
1
2
2
x
1
x
2
x
2
2
]
\phi(x)=\begin{bmatrix}x_1^2\\ \sqrt 2x_1x_2\\x_2^2 \end{bmatrix}
ϕ(x)=⎣⎡x122x1x2x22⎦⎤
接下如果要算核函数:
K
(
x
,
z
)
=
ϕ
(
x
)
⋅
ϕ
(
z
)
=
[
x
1
2
2
x
1
x
2
x
2
2
]
⋅
[
z
1
2
2
z
1
z
2
z
2
2
]
K(x,z)=\phi(x)\cdot\phi(z)=\begin{bmatrix}x_1^2\\ \sqrt 2x_1x_2\\x_2^2 \end{bmatrix}\cdot\begin{bmatrix}z_1^2\\ \sqrt 2z_1z_2\\z_2^2 \end{bmatrix}
K(x,z)=ϕ(x)⋅ϕ(z)=⎣⎡x122x1x2x22⎦⎤⋅⎣⎡z122z1z2z22⎦⎤
=
x
1
2
z
1
2
+
2
x
1
x
2
z
1
z
2
+
x
2
2
z
2
2
=
(
x
1
z
1
+
x
2
z
2
)
2
=
[
x
1
x
2
]
⋅
[
z
1
z
2
]
=x_1^2z_1^2+2x_1x_2z_1z_2+x_2^2z_2^2=(x_1z_1+x_2z_2)^2=\begin{bmatrix}x_1\\ x_2 \end{bmatrix}\cdot\begin{bmatrix}z_1\\ z_2 \end{bmatrix}
=x12z12+2x1x2z1z2+x22z22=(x1z1+x2z2)2=[x1x2]⋅[z1z2]
=
(
x
⋅
z
)
2
=(x\cdot z)^2
=(x⋅z)2
意味着,我们把x和z做feature transform投影到另外的平面后,再做inner product等同于把x和z在做feature transform之前先做inner product后平方。后者明显比较快!
Directly computing
K
(
x
,
z
)
K(x,z)
K(x,z) can be faster than “feature transformation + inner product” sometimes.
举个栗子:
现在又k维的x和z
要投影到更高维的平面,在这个平面我们要考虑feature两两之间的关系。
然后用Kernel Trick来进行计算:
注意观察平方项展开后蓝色部分等于于
ϕ
(
x
)
\phi(x)
ϕ(x),红色部分等于
ϕ
(
z
)
\phi(z)
ϕ(z)
Kernel based 的方法
Radial Basis Function Kernel
在这个方法里面李老师证明了RBF kernel用transform 后的高维vector内积(
ϕ
(
x
)
\phi(x)
ϕ(x)和
ϕ
(
z
)
\phi(z)
ϕ(z))的话是不行的,因为它们有无穷多维,应该先内积后平方!先来看RBF kernel的函数样式:
这里是衡量x和z的相似度,如果x=z,kernel的值为1,如果x≠z,kernel的值为0.,下面来看为什么是无穷多维。把上式的L2 Norm展开:
并用
C
x
C
z
C_xC_z
CxCz做为新的notation,然后把后面的
e
x
p
(
x
⋅
z
)
exp(x\cdot z)
exp(x⋅z)用泰勒级数展开:
然后把求和项(有无穷多项)写开:
写开后的每一项都可以看做两个向量的内积,然后把这些向量可以分别按照红色和蓝色箭头方向堆叠起来得到
ϕ
(
x
)
\phi(x)
ϕ(x)和
ϕ
(
z
)
\phi(z)
ϕ(z),可以看到这个是无穷多维的,因此无法直接计算。
RBF相当于在无穷多维上进行计算,因此比较容易overfitting。
Sigmoid Kernel
Sigmoid Kernel的核函数如下:
Sigmoid Kernel的核函数可以写为哪两个
ϕ
(
x
)
\phi(x)
ϕ(x)和
ϕ
(
z
)
\phi(z)
ϕ(z)的内积?老师没讲,要自己回去用泰勒展开看看。
When using sigmoid kernel, we have a 1 hidden layer network.把sigmoid核函数带入SVM的结果:
这个可以看做只有一个隐藏层的NN,
t
a
n
h
(
x
n
⋅
x
)
tanh(x^n\cdot x)
tanh(xn⋅x),相当于下面样子,分别用
x
1
x^1
x1、
x
2
x^2
x2。。。
x
n
x^n
xn当做权重,x作为输入
加上后面的输出层
The number of support vectors is the number of neurons.
Kernel小结
第一行说,我们可以自己定义核函数带代替高维特征
第二行说,尤其在高维特征比较难描述的时候,如:时序数据
第三行说,核函数是不是随便乱定义?不是有一个Mercer定理可以来check核函数
然后大概的举了一个声音信号定义核函数的例子,但只给了参考,没有细讲:
其他SVM方法
最后svm和dl做了一下对比,提到SVM的kernel是可以学习的(但没有dl学得那么彻底),如果有好几个kernel,把他们combine起来,他们中间的weight可以learn的。