L1和L2损失函数

L1和L2损失函数

简介

最近参加了某高校的夏令营面试,被问到一个基础的损失函数的概念,发现自己对于模式识别的掌握可以说不能再皮毛了。夏令营估计是凉了,还是老老实实总结经验好好学习为好,别搞那么多花里胡哨了。

L1 损失函数

说明:下面矩阵的维度使用规则

行 --> 维度,列 --> 样本数

L1 损失函数也叫平均绝对值误差(MAE),不妨设标签为 Y = ( y 1 , y 2 , . . . y m ) 1 × m Y = (y1, y2, ... y_m)_{1 \times m} Y=(y1,y2,...ym)1×m, 样本 X i j ( n × m ) X_{ij (n \times m)} Xij(n×m),经过一个黑箱有对标签的估计函数: f ( X ) = Y ^ f(X) = \hat{Y} f(X)=Y^ 。这个时候,L1损失函数记为这个估计和真实标签的平均误差,也就是:

L o s s 1 = 1 m ∑ i = 1 m ∣ y i − f ( x i ) ∣ Loss1 = \frac{1}{m} \sum_{i = 1}^{m}|y_i - f(x_{i})| Loss1=m1i=1myif(xi)

我们知道,绝对值函数 y = f ( x ) y = f(x) y=f(x) 的样子如下:

在这里插入图片描述

我们容易看出这个损失函数具有如下缺点:

  • 梯度恒定,不论预测值是否接近真实值,这很容易导致发散,或者错过极值点。
  • 导数不连续,导致求解困难。这也是L1损失函数不广泛使用的主要原因。

但它同样有自己的优点:

  • 收敛速度比L2损失函数要快,这是通过对比函数图像得出来的,L1能提供更大且稳定的梯度。
  • 对异常的离群点有更好的鲁棒性,下面会以例子证实。

如果看到更多或者有新的思考会及时补充,我也是昨天才开始打基础。

L2 损失函数

沿用上面对标签和样本的符号定义,L2损失函数也叫平均平方损失函数(MSE),它的数学形式如下:

L o s s 2 = 1 m ∑ i = 1 m ( y i − f ( x i ) ) 2 Loss2 = \frac{1}{m} \sum_{i=1}^{m} (y_i - f(x_i))^2 Loss2=m1i=1m(yif(xi))2

我们知道,平方函数 f ( x ) = x 2 f(x) = x^2 f(x)=x2 的样子如下:

在这里插入图片描述

我们看出这个损失函数具有如下缺点:

  • 收敛速度比L1慢,因为梯度会随着预测值接近真实值而不断减小。
  • 对异常数据比L1敏感,这是平方项引起的,异常数据会引起很大的损失。

但它的优点是显而易见的:

  • 它使训练更容易,因为它的梯度随着预测值接近真实值而不断减小,那么它不会轻易错过极值点,但也容易陷入局部最优。
  • 它的导数具有封闭解,优化和编程非常容易,所以很多回归任务都是用MSE作为损失函数。

一个例子

举一个简单的线性回归作为例子。我们使用 y i = x i + ϵ i y_i = x_i + \epsilon _i yi=xi+ϵi 生成m个样本,其中 ϵ i ∼ N ( 0 , 1 ) \epsilon_i \sim N(0,1) ϵiN(0,1) 。 然后使用 Y 1 × m = w 1 × n x n × m + b 1 × m Y_{1\times m} = w_{1 \times n} x_{n \times m} + b_{1 \times m} Y1×m=w1×nxn×m+b1×m 进行回归,为了方便可视化,我们取 n = 1 n = 1 n=1。也就是回归一条直线。

  1. 对于L1,我在这里使用梯度下降法进行求解:

    • 初始化 w i , b i w_i, b_i wi,bi, 求出当前预测值 y i ^ = w i x i + b i \hat{y_i} = w_ix_i + b_i yi^=wixi+bi

    • 求解梯度,对于 L o s s 1 ( w , b ) Loss1(w,b) Loss1(w,b) d w i = ∂ L o s s 1 ∂ w = lim ⁡ δ → 0 L o s s 1 ( w + δ , b ) − L o s s ( w , b ) δ dw_i = \frac{\partial Loss1}{\partial w} = \lim_{\delta \rightarrow 0} \frac{Loss1(w+\delta, b) - Loss(w,b)}{\delta} dwi=wLoss1=limδ0δLoss1(w+δ,b)Loss(w,b) d b i = ∂ L o s s 1 ∂ b = lim ⁡ δ → 0 L o s s 1 ( w , b + δ ) − L o s s ( w , b ) δ db_i =\frac{\partial Loss1}{\partial b} = \lim_{\delta \rightarrow 0} \frac{Loss1(w, b+\delta) - Loss(w,b)}{\delta} dbi=bLoss1=limδ0δLoss1(w,b+δ)Loss(w,b)

    • 更新参数: w i + 1 = w i − α d w i w_{i+1} = w_i - \alpha dw_i wi+1=wiαdwi b i + 1 = b i − α d b i b_{i+1} = b_i - \alpha db_i bi+1=biαdbi α \alpha α为学习率。

    • 不断重复上述过程。

  2. 对于L2, 直接使用最小二乘法即可:

    • 先对 Y = W X + B Y = WX + B Y=WX+B 写成 Y = W ^ X ^ Y = \hat{W} \hat{X} Y=W^X^,只需要把 B B B 写在 W W W 的最后列,然后对 X X X 的最后行补1即可。
    • 对L2损失函数写成矩阵形式: L o s s 2 = ( Y − W ^ X ^ ) ( Y − W ^ X ^ ) T Loss2 = (Y-\hat{W}\hat{X}) (Y-\hat{W}\hat{X})^T Loss2=(YW^X^)(YW^X^)T
    • 求导: ∂ L o s s 2 ∂ W ^ = 2 ( W ^ X ^ − Y ) X T ^ = 0 \frac{\partial Loss2}{\partial{\hat{W}}} = 2(\hat{W}\hat{X} - Y)\hat{X^T} = 0 W^Loss2=2(W^X^Y)XT^=0, 解得: W ^ = Y X T ^ ( X ^ X T ^ ) − 1 \hat{W} = Y\hat{X^T}(\hat{X}\hat{X^T})^{-1} W^=YXT^(X^XT^)1

注意,上述步骤可能漏掉样本数的累加和平均,但思路就是这样,细节在代码体现。

  1. 我们尝试30个样本数据,无异常数据情况下:

    • 回归效果:

    在这里插入图片描述

    • L1损失收敛情况:

      在这里插入图片描述

  2. 故意制造离群点情况下:

    • 回归效果:

      在这里插入图片描述

    • L1损失收敛情况:

    在这里插入图片描述

代码

clc
clear

% 1. generate sample
N = 30;
eps = normrnd(0,1,1,N);	% nx1

x = (1 : N) ; % 1xn
y = x + eps;   % 1xn
% disturb points
y(28) = -20;
y(15) = -30;

% 2. init w and b
w = rand;
b = rand;


% 3. iterate L1 methord 
iterN = 200;
learning_rate = 1e-2;
mae = zeros(1, iterN+1);
yy = w*x + b;
mae(1) = absLoss(y,yy)/N;

decay = 0.9;
decayT = 20;
for k = 1:iterN
    if mod(k, decayT) == 0  % learning rate is decaying as iterations increase
        learning_rate = learning_rate * decay;
    end
	[dw,db] = findGradient(yy, w, b, x, y);
	
	% update w b
	w = w - learning_rate*dw;
	b = b - learning_rate*db;
	
	yy = w*x + b;
	mae(k+1) = absLoss(y,yy)/N;
	
end

y1 = w*x + b;

% 4. use L2 methord
x2 = [x; ones(1, N)];
w2 = y*x2' * (x2*x2')^-1;
y2 = w2 * x2; 


% 5. compare L1 and L2
figure(1);
plot(x, y1, 'linewidth', 2);
hold on;
plot(x, y2, 'linewidth', 2);
scatter(x, y, 'r', 'filled');
legend('L1', 'L2', 'ori');
grid on;

figure(2);
plot(1:length(mae), mae, 'linewidth', 2);
grid on;

function a = absLoss(y,yy)
	a = sum(abs(y-yy)) / length(y);
end

% get the gradient
function [dw, db] = findGradient(yy, w, b, x, y)
	eps = 1e-5;
	nw = w + eps;
	nb = b + eps;
	
	dw = (absLoss(nw*x + b, y) - absLoss(yy, y))/eps;
	db = (absLoss(w*x + nb, y) - absLoss(yy, y))/eps;
end


最后

有很多不足之处,将会持续更新修改,夏令营经历也会更新,但比较慢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值