损失函数机器学习的“裁判”是怎么给你打分的?

一、损失函数是啥?大白话讲明白

想象你在猜朋友的身高,想尽量猜准。每次猜完,裁判说:“偏了5厘米!”这个“偏了多少”就是损失函数的活儿——它算预测和真实的差距。模型靠这个反馈调整,直到猜得跟真的一样。
但不同任务,裁判的规矩不同。预测身高是比数字,识图是做选择题,找肿瘤是拼细节。我们挑几个常见任务,拆解损失函数怎么优化它们,配上完整代码直接上手!

二、回归任务:预测房价

任务:预测房价(单位:万元),数据比如[100, 110, 150],模型要贴近真实值。

均方误差 (Mean Squared Error, MSE):严格的精确教练

怎么打分?
MSE把误差平方后平均,小错小罚,大错大罚。
公式 ( L = 1 n ∑ ( y − y ^ ) 2 ) ( L = \frac{1}{n} \sum (y - \hat{y})^2 ) (L=n1(yy^)2)
完整模型代码 (PyTorch):

import torch
import torch.nn as nn

# 定义简单线性回归模型
class LinearRegression(nn.Module):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(1, 1)  # 输入1个特征,输出1个预测值
    
    def forward(self, x):
        return self.linear(x)

# MSE损失函数
def mse_loss(pred, target):
    return torch.mean((pred - target) ** 2)

# 数据准备
X = torch.tensor([[1.0], [2.0], [3.0]])  # 假设输入特征(比如房子面积)
y = torch.tensor([[100.0], [110.0], [150.0]])  # 真实房价

# 初始化模型和优化器
model = LinearRegression()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 训练
for epoch in range(100):
    pred = model(X)  # 前向传播
    loss = mse_loss(pred, y)  # 计算MSE损失
    optimizer.zero_grad()  # 清空梯度
    loss.backward()  # 反向传播
    optimizer.step()  # 更新参数
    if epoch % 20 == 0:
        print(f"Epoch {epoch}, MSE Loss: {loss.item():.4f}")

# 测试
test_X = torch.tensor([[4.0]])
pred = model(test_X)
print(f"预测房价: {pred.item():.4f}")

生活比喻:你猜房价100万,实际110万,MSE说:“差10万,扣100分!”猜成50万,直接扣3600分,够狠。
任务优化:房价波动小(100-200万),MSE逼模型精确预测,避免大偏差。训练100次后,模型能根据面积合理猜价。
优点:精确,优化顺畅。
缺点:遇到怪价(比如1000万),会被拖垮。

三、 分类任务:猫狗图像分类

任务:判断图片是猫(1)还是狗(0),输出概率比如[0.9, 0.2, 0.8]。

交叉熵损失 (Cross-Entropy Loss):挑自信的刺

怎么打分?
看预测概率和真实标签差距,越自信错越扣得多。
公式 ( L = − 1 n ∑ [ y log ⁡ ( y ^ ) + ( 1 − y ) log ⁡ ( 1 − y ^ ) ] ) ( L = -\frac{1}{n} \sum [y \log(\hat{y}) + (1 - y) \log(1 - \hat{y})] ) (L=n1[ylog(y^)+(1y)log(1y^)])
完整模型代码

import torch
import torch.nn as nn

# 定义简单分类模型
class SimpleClassifier(nn.Module):
    def __init__(self):
        super(SimpleClassifier, self).__init__()
        self.fc = nn.Linear(2, 1)  # 假设2个特征输入,输出1个概率
        self.sigmoid = nn.Sigmoid()
    
    def forward(self, x):
        return self.sigmoid(self.fc(x))

# 数据准备
X = torch.tensor([[1.0, 2.0], [2.0, 1.0], [3.0, 3.0]])  # 假设特征(比如像素值)
y = torch.tensor([1, 0, 1])  # 真实标签:1=猫,0=狗

# 初始化模型和优化器
model = SimpleClassifier()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
loss_fn = nn.BCELoss()  # 二分类交叉熵

# 训练
for epoch in range(100):
    pred = model(X)  # 前向传播,输出概率
    loss = loss_fn(pred.squeeze(), y.float())  # 计算交叉熵损失
    optimizer.zero_grad()  # 清空梯度
    loss.backward()  # 反向传播
    optimizer.step()  # 更新参数
    if epoch % 20 == 0:
        print(f"Epoch {epoch}, Cross-Entropy Loss: {loss.item():.4f}")

# 测试
test_X = torch.tensor([[2.5, 2.5]])
pred = model(test_X)
print(f"预测猫的概率: {pred.item():.4f}")

生活比喻:你90%确定是猫,真的是猫,扣分少。90%说是猫,其实是狗,交叉熵说:“太自信了,重罚!”
任务优化:猫狗各一半,交叉熵推模型把猫概率拉到0.99,狗到0.01。训练后,模型能根据特征判断猫狗。
优点:分类王牌。
缺点:猫少狗多时,可能偏狗。

四、目标检测任务:找图里的车

任务:预测车的边界框坐标,比如真实[50, 50, 20, 20](x, y, 宽, 高),预测[52, 55, 22, 18]。

Huber损失:边界框的优化神器

怎么打分?
小误差平方,大误差线性,用delta控制切换。
完整模型代码

import torch
import torch.nn as nn

# 定义边界框回归模型
class BoxRegressor(nn.Module):
    def __init__(self):
        super(BoxRegressor, self).__init__()
        self.fc = nn.Linear(2, 4)  # 假设2个特征输入,输出4个坐标
    
    def forward(self, x):
        return self.fc(x)

# Huber损失函数
def huber_loss(pred, target, delta=5.0):
    error = pred - target
    abs_error = torch.abs(error)
    return torch.where(abs_error <= delta, 0.5 * error ** 2, delta * abs_error - 0.5 * delta ** 2).mean()

# 数据准备
X = torch.tensor([[1.0, 2.0], [2.0, 1.0]])  # 假设特征
y = torch.tensor([[50.0, 50.0, 20.0, 20.0], [60.0, 60.0, 25.0, 25.0]])  # 真实坐标

# 初始化模型和优化器
model = BoxRegressor()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 训练
for epoch in range(100):
    pred = model(X)  # 前向传播
    loss = huber_loss(pred, y, delta=5.0)  # 计算Huber损失
    optimizer.zero_grad()  # 清空梯度
    loss.backward()  # 反向传播
    optimizer.step()  # 更新参数
    if epoch % 20 == 0:
        print(f"Epoch {epoch}, Huber Loss: {loss.item():.4f}")

# 测试
test_X = torch.tensor([[1.5, 1.5]])
pred = model(test_X)
print(f"预测边界框: {pred.detach().numpy()}")

生活比喻:框偏2像素,Huber说:“小事,轻罚。”偏50像素,它说:“大了,但线性扣,不崩溃。”
任务优化:目标检测中,框得准,但偶尔有怪预测。设delta=5,Huber兼顾精度和稳定性,训练后能合理预测车框。
优点:适合坐标回归。
缺点:delta要调准。

五、分割任务:找医学图像里的肿瘤

任务:分割肿瘤,真实掩码[1, 0, 1](1=肿瘤),预测概率[0.9, 0.1, 0.8]。

Dice损失:重叠率的王牌

怎么打分?
算预测和真实的交集除以并集,关注重叠。
完整模型代码

import torch
import torch.nn as nn

# 定义简单分割模型
class SegmentationNet(nn.Module):
    def __init__(self):
        super(SegmentationNet, self).__init__()
        self.fc = nn.Linear(2, 3)  # 假设2个特征输入,输出3个像素概率
        self.sigmoid = nn.Sigmoid()
    
    def forward(self, x):
        return self.sigmoid(self.fc(x))

# Dice损失函数
def dice_loss(pred, target, smooth=1e-5):
    intersection = (pred * target).sum()
    union = pred.sum() + target.sum()
    return 1 - (2. * intersection + smooth) / (union + smooth)

# 数据准备
X = torch.tensor([[1.0, 2.0]])  # 假设特征
y = torch.tensor([[1.0, 0.0, 1.0]])  # 真实掩码

# 初始化模型和优化器
model = SegmentationNet()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

# 训练
for epoch in range(100):
    pred = model(X)  # 前向传播
    loss = dice_loss(pred, y)  # 计算Dice损失
    optimizer.zero_grad()  # 清空梯度
    loss.backward()  # 反向传播
    optimizer.step()  # 更新参数
    if epoch % 20 == 0:
        print(f"Epoch {epoch}, Dice Loss: {loss.item():.4f}")

# 测试
test_X = torch.tensor([[1.5, 1.5]])
pred = model(test_X)
print(f"预测掩码概率: {pred.detach().numpy()}")

生活比喻:圈中80%肿瘤,Dice说:“不错,扣20分。”漏一半,它说:“50%罚,加油!”
任务优化:肿瘤占5%,背景95%,Dice只看重叠,不被背景干扰。训练后,模型能精准圈肿瘤。
优点:抗不平衡。
缺点:边界细节不敏感。

六、任务配对裁判

损失函数是模型的“教练”,各有绝活:

  • MSE:严格,房价稳定时用。
  • Huber:中庸,边界框稳准狠。
  • 交叉熵:自信王,猫狗平衡时强。
  • Dice:重叠专家,分割肿瘤无敌。

代码跑起来,调调参数(比如delta),任务效果蹭蹭涨。想优化啥具体项目,比如预测租金、找鸟?告诉我,我再细化!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello.Reader

请我喝杯咖啡吧😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值