文章目录
- 损失函数
-
- 1. 多类支持向量机损失
- 2. 正则化
- 3. Softmax分类器
- 4. SVM和Softmax的比较
- 优化
-
- 1. 梯度
- 2. 梯度下降
- 3. 特征工程
损失函数
我们使用损失函数(Loss Function)(有时也叫代价函数Cost Function或目标函数Objective)来衡量我们对结果的不满意程度。直观地讲,当评分函数输出结果与真实结果之间差异越大,损失函数输出越大,反之越小。
1. 多类支持向量机损失
多类支持向量机损失(Multiclass Support Vector Machine Loss) 想要SVM在正确分类上的得分始终比不正确分类上的得分高出一个边界值 Δ \Delta Δ。
第 i i i 个数据中包含图像 x i x_i xi? 的像素和代表正确类别的标签 y i y_i yi?。评分函数输入像素数据,然后通过公式 f ( x i , W ) f(x_i, W) f(xi?,W) 来计算不同分类类别的分值。这里我们将分值简写为 s s s。针对第 j j j 个类别的得分就是第 j j j 个元素: s j = f ( x i , W ) j s_j = f(x_i, W)_j sj?=f(xi?,W)j?。针对第 i i i 个数据的多类SVM的损失函数定义如下:
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??+Δ)
折叶损失(hinge loss):关于0的阀值: m a x ( 0 , ? ) max(0, -) max(0,?) 函数,它常被称为折叶损失。平方折叶损失SVM(即L2-SVM),它使用的是 m a x ( 0 , ? ) 2 max(0, -)^2 max(0,?)2,更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好。可以通过交叉验证来决定到底使用哪个。
Δ \Delta Δ设置:在绝大多数情况下设为 Δ = 1 \Delta = 1 Δ=1 是安全的。超参数 Δ \Delta Δ 和 λ \lambda λ 看起来是两个不同的超参数,但实际上他们一起控制同一个权衡:即损失函数中的数据损失和正则化损失之间的权衡。
权重 W W W 的大小对于分类分值有直接影响:当我们将 W W W 中值缩小,分类分值之间的差异也变小,反之亦然。因此,不同分类分值之间的边界的具体值(比如 Δ = 1 \Delta = 1 Δ=1 或 Δ = 10 \Delta = 10 Δ=10)从某些角度来看是没意义的,因为权重自己就可以控制差异变大和缩小。也就是说,真正的权衡是我们允许权重能够变大到何种程度(通过正则化强度 λ \lambda λ 来控制)。
- 无正则化的多类支持向量机损失Python
2. 正则化
遇到的问题:假设有一个数据集和一个权重集 W W W 能够正确地分类每个数据,即所有的边界都满足,对于所有的 i i i 都有 L i = 0 L_i = 0 Li?=0。问题在于这个 W W W 并不唯一:可能有很多相似的 W W W 都能正确地分类所有的数据。一个简单的例子:如果 W W W 能够正确分类所有数据,即对于每个数据,损失值都是 0 0 0。那么当 λ > 0 \lambda > 0 λ>0 时,任何数乘 λ W \lambda W λW 都能使得损失值为 0 0 0。
消除模糊性:我们希望能向某些特定的权重 W W W 添加一些偏好,对其他权重则不添加,以此来消除模糊性。方法是向损失函数增加一个正则化惩罚(regularization penalty) R ( W ) R(W) R(W) 部分。最常用的正则化惩罚是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?
完整的多类SVM损失函数:它由两个部分组成:数据损失(data loss),即所有样例的的平均损失 L i L_i Li?,以及正则化损失(regularization loss)。完整公式如下所示:
L = 1 N ∑ i L i + λ R ( W ) L = \frac{1}{N} \sum_i L_i + \lambda R(W) L=N1?i∑?Li?+λR(W)
其完整的展开式为:
L = 1 N ∑ i ∑ j ? = y i [ m a x ( 0 , f ( x i ; W ) j ? f ( x i ; W ) y i + Δ ) ] + λ ∑ k ∑ l W k , l 2 L= \frac{1}{N} \sum_i \sum_{j \not= y_i} [max(0, f(x_i; W)_j - f(x_i; W)_{y_i} + \Delta)] + \lambda \sum_k \sum_l W_{k, l}^2 L=N1?i∑?j??=yi?∑?[max(0,f(xi?;W)j??f(xi?;W)yi??+Δ)]+λk∑?l∑?Wk,l2?
- N N N 是训练集的数据量。
- 用超参数 λ \lambda λ 来计算正则化惩罚的权重。该超参数无法简单确定,需要通过交叉验证来获取。
3. Softmax分类器
与SVM不同,Softmax的输出,归一化的分类概率更加直观。在Softmax分类器中,函数映射 f ( x i ; W ) = W x i f(x_i; W) = Wx_i f(xi?;W)=Wxi?保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失
(hinge loss)替换为交叉熵损失
(cross-entropy loss)。公示如下:
L i = ? log ? ( e f y i ∑ j e f j ) L_i = - \log(\frac{e^{f_{y_i}}}{\sum_j e^{f_j}}) Li?=?log(∑j?efj?efyi???)
- f j f_j fj? 来表示分类评分向量 f f f 中的第 j j j 个元素。
- 整个数据集的损失值是数据集中所有样本数据的损失值 L i L_i Li? 的均值与正则化损失 R(W) 之和。
- f j ( z ) = e z j ∑ k e z k f_j(z) = \frac{e^{z_j}}{\sum_k e^{z_k}} fj?(z)=∑k?ezk?ezj??被称作softmax 函数。其输入值是一个向量,向量中元素为任意实数的评分值( z z z 中的),函数对其进行压缩,输出一个向量,其中每个元素值在0到1之间,且所有元素之和为1。
4. SVM和Softmax的比较
下图所示为两种分类器的工作过程:
- 多类别SVM损失函数:当得分超过某个阈值边放弃优化。
- Softmax损失函数:不断将概率质量向正确类别聚集。
优化
1. 梯度
梯度总是指向函数增长速度最快的方向。所以我们损失函数应沿负梯度方向进行更新。
梯度计算
- 多元函数梯度计算: ? f ( x , y ) = ( ? f ? x , ? f ? y ) \nabla f(x, y) = (\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y}) ?f(x,y)=(?x?f?,?y?f?)
- 根绝偏导数的定义, f ( x , y ) f(x, y) f(x,y) 在点 ( a , b ) (a, b) (a,b) 关于 x x x 的偏导数为: ? f ? x = lim ? h → 0 f ( a + h , b ) ? f ( a , b ) h \frac{\partial f}{\partial x} = \lim_{h \to 0} \frac{f(a + h, b) - f(a, b)}{h} ?x?f?=limh→0?hf(a+h,b)?f(a,b)?
计算梯度有两种方法:
- 数值梯度法:利用有限差值计算梯度。
def eval_numerical_gradient(f, x):"""一个f在x处的数值梯度法的简单实现- f是只有一个参数的函数- x是计算梯度的点"""fx = f(x) # 在原点计算函数值grad = np.zeros(x.shape)h = 0.00001# 对x中所有的索引进行迭代it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])while not it.finished:# 计算x+h处的函数值ix = it.multi_indexold_value = x[ix]x[ix] = old_value + h # 增加hfxh = f(x) # 计算f(x + h)x[ix] = old_value # 存到前一个值中 (非常重要)# 计算偏导数grad[ix] = (fxh - fx) / h # 坡度it.iternext() # 到下个维度return grad
- 分析梯度法:由相应公式直接求得梯度表达式。
【注】:常常使用第一个方法作为第二个方法的测试单元。
2. 梯度下降
对于损失函数:
L ( W ) = 1 N ∑ i L i ( x i , y i ; W ) + λ R ( W ) L(W) = \frac{1}{N} \sum_i L_i(x_i, y_i;W) + \lambda R(W) L(W)=N1?i∑?Li?(xi?,yi?;W)+λR(W)
其梯度为:
? W L ( W ) = 1 N ∑ i ? W L i ( x i , y i ; W ) + λ ? W R ( W ) \nabla_W L(W) = \frac{1}{N} \sum_i \nabla_WL_i(x_i, y_i;W) + \lambda \nabla_W R(W) ?W?L(W)=N1?i∑??W?Li?(xi?,yi?;W)+λ?W?R(W)
普通梯度下降:程序重复地计算梯度然后对参数进行更新。
# 普通的梯度下降
while True:weights_grad = evaluate_gradient(loss_fun, data, weights)weights += - step_size * weights_grad # 进行梯度更新
小批量数据梯度下降:在大规模的应用中,训练数据可以达到百万级量级。如果像这样计算整个训练集,来获得仅仅一个参数的更新就太浪费了。一个常用的方法是计算训练集中的小批量(batches)数据。
# 普通的小批量数据梯度下降
while True:data_batch = sample_training_data(data, 256) # 256个数据weights_grad = evaluate_gradient(loss_fun, data_batch, weights)weights += - step_size * weights_grad # 参数更新
随机梯度下降:小批量数据策略有个极端情况,那就是每个批量中只有1个数据样本,这种策略被称为随机梯度下降(Stochastic Gradient Descent 简称SGD),有时候也被称为在线梯度下降。
3. 特征工程
思想:特征空间的转换。
常用方法:
- 色彩直方图
- 图像的方向梯度
- 词袋模型