You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch训练时如何让模型优先关注类别3以提升其预测准确率?

在PyTorch中优先提升特定类别(类别3)预测准确率的实现方法

要让模型在训练时优先关注类别3、提升其预测准确率,可通过损失加权、采样策略调整、样本级权重定制等方式实现,以下是具体代码示例和说明:

1. 类别加权交叉熵损失(最常用)

给类别3分配更高的损失权重,让模型对该类别的错误惩罚更重,是最直接的实现方式。

import torch
import torch.nn as nn
from torch.utils.data import DataLoader, Dataset

# 自定义数据集(模拟场景)
class CustomDataset(Dataset):
    def __init__(self):
        self.data = torch.randn(100, 10)  # 100个样本,特征维度10
        self.labels = torch.randint(0, 5, (100,))  # 标签为0-4的5个类别

# 定义简单分类模型
model = nn.Linear(10, 5)

# 设置类别权重:类别3权重设为5,其余类别为1(可根据需求调整)
class_weights = torch.tensor([1.0, 1.0, 1.0, 5.0, 1.0])
criterion = nn.CrossEntropyLoss(weight=class_weights)

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 构建数据加载器
dataset = CustomDataset()
dataloader = DataLoader(dataset, batch_size=8, shuffle=True)

# 训练循环
model.train()
for epoch in range(10):
    total_loss = 0.0
    for batch_data, batch_labels in dataloader:
        optimizer.zero_grad()
        outputs = model(batch_data)
        loss = criterion(outputs, batch_labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {total_loss/len(dataloader):.4f}")

关键点:CrossEntropyLoss的weight参数接收与类别数长度一致的张量,权重值越高,模型对该类别的错误越敏感。

2. 样本级加权(更灵活)

如果需要对类别3中的特定样本(比如难分类样本)单独加权,可动态生成样本权重计算损失。

# 训练循环中修改损失计算逻辑
model.train()
for epoch in range(10):
    total_loss = 0.0
    for batch_data, batch_labels in dataloader:
        optimizer.zero_grad()
        outputs = model(batch_data)
        
        # 生成样本权重:类别3的样本权重设为5,其余为1
        sample_weights = torch.where(batch_labels == 3, torch.tensor(5.0), torch.tensor(1.0))
        
        # 先计算每个样本的交叉熵损失,再乘以样本权重后取平均
        ce_loss = nn.CrossEntropyLoss(reduction='none')(outputs, batch_labels)
        weighted_loss = (ce_loss * sample_weights).mean()
        
        weighted_loss.backward()
        optimizer.step()
        total_loss += weighted_loss.item()
    print(f"Epoch {epoch+1}, Loss: {total_loss/len(dataloader):.4f}")

关键点:设置reduction='none'让损失函数返回每个样本的损失值,再通过权重实现对特定样本的重点关注。

3. 加权随机采样(提升类别3样本占比)

通过修改DataLoader的采样策略,让训练时更多抽取类别3的样本,增加模型对该类别的学习机会。

from torch.utils.data import WeightedRandomSampler

# 统计数据集中每个类别的样本数量
dataset = CustomDataset()
class_counts = [torch.sum(dataset.labels == i).item() for i in range(5)]

# 计算基础采样权重(反比于类别数量),给类别3提升权重
base_weights = 1.0 / torch.tensor(class_counts, dtype=torch.float)
base_weights[3] *= 5  # 类别3权重放大5倍

# 为每个样本分配对应类别的权重
sample_weights = base_weights[dataset.labels]

# 创建加权采样器
sampler = WeightedRandomSampler(weights=sample_weights, num_samples=len(dataset), replacement=True)

# 使用采样器构建DataLoader
dataloader = DataLoader(dataset, batch_size=8, sampler=sampler)

# 后续训练循环同方法1

关键点:WeightedRandomSampler会根据样本权重随机抽取样本,权重越高的样本被选中概率越大,适合类别3样本数量较少的场景。

4. 硬样本挖掘(针对类别3难分类样本)

单独分离类别3的样本,重点计算其损失并加权,聚焦难分类样本的学习。

model.train()
for epoch in range(10):
    total_loss = 0.0
    for batch_data, batch_labels in dataloader:
        optimizer.zero_grad()
        outputs = model(batch_data)
        
        # 筛选类别3的样本
        class3_mask = (batch_labels == 3)
        if class3_mask.any():
            # 计算类别3样本的损失并加权
            class3_loss = nn.CrossEntropyLoss()(outputs[class3_mask], batch_labels[class3_mask]) * 5
            # 计算其他类别的损失
            other_loss = nn.CrossEntropyLoss()(outputs[~class3_mask], batch_labels[~class3_mask]) if (~class3_mask).any() else 0
            total_batch_loss = class3_loss + other_loss
        else:
            total_batch_loss = nn.CrossEntropyLoss()(outputs, batch_labels)
        
        total_batch_loss.backward()
        optimizer.step()
        total_loss += total_batch_loss.item()
    print(f"Epoch {epoch+1}, Loss: {total_loss/len(dataloader):.4f}")

关键点:单独处理类别3的损失,确保模型每次迭代都重点学习该类别的难分样本。

内容的提问来源于stack exchange,提问作者Joey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 15:36:34