个人学习笔记
date:2023.01.02
参考网址:CS231N官方笔记 线性分类
KNN有几个缺点:
线性分类主要包含如下要素:
(一) score function
f ( x i , W , b ) = W x i + b f(x_{i},W,b) = Wx_{i}+b f(xi,W,b)=Wxi+b
如上等式,已假设输入图像 x i \bold x_{i} xi展开为shape为[D,1]
的列向量,权重矩阵 W \bold W W是一个shape为[C,D]
的矩阵,C表示分类数。得到一个[C,1]
的列向量,表示各类的一个得分情况。 b \bold b b为bias偏重项,是一个[C,1]
的列向量。
该方法的优点(相较于KNN):
[4,1]
的列向量[3,4]
,其中3表示3个分类,4表示每个分类下的4个pixels有不同的权重。既每一行都是一个类别的权重分类器。[3,1]
列向量,表示每个分类的得分,再加上偏正项就是最终得分。因为 f ( x i ; W ; b ) \bold f(x_{i};W;b) f(xi;W;b)是一个线性函数,如果将其可视化,就是如下图所示。
如果W被改变,那么直线会发生旋转
如果没有偏正项,那么 x i = 0 \bold x_{i}=0 xi=0的时候就永远在原点处。
如果将最终得到的权重矩阵每一行又转换为image尺寸,则会得到如下图形。
所以可以认为,线性分类实质上是模板匹配(template matching),我们训练最终就是得到一个模板,因此局限性非常大,同一类别下的实物只要有些许差异也许就不能被识别。且如上图所示,我们是用一条直线在二维平面上进行分类,因此局限性也很大(很多情况仅用直线是分类不了的)
L ( x , y ) = 1 N ∑ i = 1 N L i ( f ( x i ; W ) , y i ) L(x,y) = \frac{1}{N}\sum_{i=1}^{N}L_{i}(f(x_{i};W),y_{i}) L(x,y)=N1i=1∑NLi(f(xi;W),yi)
SVM loss 目的是想让正确类别的得分远远高于错误类别的得分,至少要高过某一个安全边距(fixed margin Δ Δ Δ)。当正确类别得分远高于错误类别得分时,损失值会很小。
公式:
L i = ∑ j ≠ y i m a x ( 0 , s j − s y i + Δ ) L_{i} = \sum_{j\not =y_{i}} max(0,s_{j}-s_{y_{i}}+\Delta ) Li=j=yi∑max(0,sj−syi+Δ)
s j s_{j} sj为其他分类得分, s y i s_{y_{i}} syi为第i个样本得分, Δ \Delta Δ为自己设定的边距。
如果 s y i > s j + △ s_{y_{i}}>s_{j}+\triangle syi>sj+△ ,既样本得分远大于其他分类得分,那么取损失为0; 否则取损失为 s j − s y i + Δ s_{j}-s_{y_{i}}+\Delta sj−syi+Δ
上述损失函数又叫Hinge Loss SVM,由下图可见,该损失函数理论上最小值为0,最大值为 ∞ \infty ∞。
初次训练时,一般以趋于均值的权重矩阵开始,因此得到的分数都接近0,此时损失值应为 L o s s = C − 1 Loss = C - 1 Loss=C−1 (C为分类数,由公式可得,可用来验证)
如果有权重矩阵W使得损失值为0,W不是唯一的, λ W ( λ > 1 ) \lambda W(\lambda>1) λW(λ>1)也可能使损失值为0.
python实现(不包含正则项)
def L_i_vectorized(x, y, W):
"""
A faster half-vectorized implementation. half-vectorized
refers to the fact that for a single example the implementation contains
no for loops, but there is still one loop over the examples (outside this function)
"""
delta = 1.0
scores = W.dot(x)
# compute the margins for all classes in one vector operation
margins = np.maximum(0, scores - scores[y] + delta)
# on y-th position scores[y] - scores[y] canceled and gave delta. We want
# to ignore the y-th position and only consider margin on max wrong class
margins[y] = 0
loss_i = np.sum(margins)
return loss_i
L i = ∑ j ≠ y i m a x ( 0 , s j − s y i + Δ ) 2 L_{i} = \sum_{j\not =y_{i}} max(0,s_{j}-s_{y_{i}}+\Delta )^2 Li=j=yi∑max(0,sj−syi+Δ)2
损失函数用来权衡我们对预测值的不满意度,若使用平方项,则表示更坏的结果将接受更严重的惩罚。
分类器在训练集上表现如何不重要,在测试集上表现如何才重要。如果在训练集上表现得完美,那么可能导致过拟合现象。
当score function是高阶多项式时且完美拟合训练集,此时损失值为0,那么将会有很多个权重矩阵使得损失值也为0(上面提到)
ps. 如果W对应的损失值为15,那么2W对应的损失值为30.
所以假如正则项去对权重矩阵进行惩罚,越高阶惩罚力度越大。
正则项的目的是鼓励模型更简约(Occam’s Razor)
加入正则项损失后的损失函数
L ( x , y ) = 1 N ∑ i = 1 N L i ( f ( x i ; W ) , y i ) + λ R ( w ) L(x,y) = \frac{1}{N}\sum_{i=1}^{N}L_{i}(f(x_{i};W),y_{i})+\lambda R(w) L(x,y)=N1i=1∑NLi(f(xi;W),yi)+λR(w)
(一) L 2 正则项 {\color{Purple}L2正则项} L2正则项
R ( W ) = ∑ k ∑ l W k , l 2 R(W) = \sum_{k} \sum_{l} W_{k,l}^2 R(W)=k∑l∑Wk,l2
(二) L 1 正则项 {\color{Purple}L1正则项} L1正则项
R ( W ) = ∑ k ∑ l ∣ W k , l ∣ R(W) = \sum_{k} \sum_{l} |W_{k,l}| R(W)=k∑l∑∣Wk,l∣
假如有如上数据,data loss都一样。
根据L2正则项, R ( w 2 ) = 0.5 R(w2) = 0.5 R(w2)=0.5而 R ( w 1 ) = 1 R(w1)=1 R(w1)=1,因此选择w2权重矩阵更合适。
但对于L1正则项, R ( w 2 ) = 1 R(w2) = 1 R(w2)=1且 R ( w 1 ) = 1 R(w1)=1 R(w1)=1,此处为特例。
一般来说,L2正则项鼓励输入列向量中的每个pixel都能影响到得分结果(所以选择w2,这样每个元素都乘以0.25,从而影响得分);而L1正则项则鼓励多使用稀疏矩阵。
一般来说,我们通过损失函数来纠正权重矩阵,而不去纠正偏重项,因为偏重项对结果的影响微乎其微。
(一)一般形式 \color{purple}(一) 一般形式 (一)一般形式
其中交叉熵为如下形式:
令 q ( x ) = e f y i ∑ j e f j , p ( x ) = 1 q(x)=\frac{e^{f_{y_{i}}}}{\sum_j e^{f_{j}}}, p(x)=1 q(x)=∑jefjefyi,p(x)=1
(二)交叉熵形式 \color{purple}(二) 交叉熵形式 (二)交叉熵形式
讨论:
代码演示(错误演示和正确演示)
f = np.array([123, 456, 789]) # example with 3 classes and each having large scores
p = np.exp(f) / np.sum(np.exp(f)) # Bad: Numeric problem, potential blowup
# instead: first shift the values of f so that the highest number is 0:
f -= np.max(f) # f becomes [-666, -333, 0]
p = np.exp(f) / np.sum(np.exp(f)) # safe to do, gives the correct answer