OHEM在线难例挖掘原理及在代码中应用

2023-11-08 20:20

本文主要是介绍OHEM在线难例挖掘原理及在代码中应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

OHEM在线难例挖掘原理及在代码中应用

  • OHEM原理
  • 应用
    • PyTorch代码示例1:
    • PyTorch代码示例2:

OHEM原理

OHEM(Online Hard Example Mining)在线难例挖掘是一种用于优化神经网络训练的方法。通过在每个迭代中选择最难的样本进行训练,来提高模型的性能。在代码中可以通过使用损失函数和自定义采样器来实现。在传统的训练过程中,模型会在训练集中遇到大量易于分类的样本,而只有少量的难以分类的样本。这样一来,模型就会倾向于预测易于分类的样本,而忽略难以分类的样本。这样会导致模型无法很好地泛化到测试集上。

OHEM通过挖掘在线难例实现强化模型对难例的学习。具体来说,OHEM在每个batch的训练中选择一定数量(通常为batch size的1/2)的难例样本,这些难例样本的损失函数被优先考虑。因此,模型会更加关注难以分类的样本,在训练过程中逐渐学会处理难例样本的能力,提高模型的泛化性能。

应用

在自己的代码中应用OHEM,可以通过以下步骤:

  1. 定义一个损失函数,例如交叉熵损失。

  2. 在每个batch的训练过程中,计算所有样本的损失值,并按照损失值从大到小排序。

  3. 选择一定数量的样本作为难例样本,例如选择损失值排名前50%的样本。

  4. 将难例样本的损失函数乘以一个权重(例如2),以增加对难例样本的惩罚。

  5. 将难例样本和非难例样本的损失函数加权平均,得到本batch的总损失值。

  6. 根据总损失值更新模型参数。

PyTorch代码示例1:

import torch.nn.functional as F
import torch.optim as optim# 定义损失函数
loss_fn = F.cross_entropy
# 定义优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)for epoch in range(num_epochs):for i, (inputs, labels) in enumerate(train_loader):# 前向传播outputs = model(inputs)# 计算所有样本的损失值loss = loss_fn(outputs, labels)# 按照损失值排序_, indices = torch.sort(loss, descending=True)# 选择难例样本num_hard = batch_size // 2hard_indices = indices[:num_hard]# 计算难例样本的损失函数,并乘以权重hard_loss = loss_fn(outputs[hard_indices], labels[hard_indices]) * 2# 将难例样本和非难例样本的损失函数加权平均total_loss = (loss.mean() * (batch_size - num_hard) + hard_loss) / batch_size# 反向传播和更新参数optimizer.zero_grad()total_loss.backward()optimizer.step()

在以上代码中,我们首先定义了一个交叉熵损失函数,然后在每个batch的训练过程中,按照损失值从大到小排序,并选择损失值排名前50%的样本作为难例样本。难例样本的损失函数乘以了一个权重2,以增加对难例样本的惩罚。最终,我们将难例样本和非难例样本的损失函数加权平均得到本batch的总损失值,并根据总损失值更新模型参数。

PyTorch代码示例2:

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import ToTensor# 定义模型
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 10, kernel_size=5)self.conv2 = nn.Conv2d(10, 20, kernel_size=5)self.fc = nn.Linear(320, 10)def forward(self, x):x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2))x = nn.functional.relu(nn.functional.max_pool2d(self.conv2(x), 2))x = x.view(-1, 320)x = self.fc(x)return x# 定义OHEM损失函数
class OHMELoss(nn.Module):def __init__(self, ratio=3):super(OHMELoss, self).__init__()self.ratio = ratiodef forward(self, input, target):loss = nn.functional.cross_entropy(input, target, reduction='none')num_samples = len(loss)num_hard_samples = int(num_samples / self.ratio)_, indices = torch.topk(loss, num_hard_samples)ohem_loss = torch.mean(loss[indices])return ohem_loss# 加载数据集
train_dataset = MNIST(root='data', train=True, transform=ToTensor(), download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)# 初始化模型和损失函数
model = Net()
criterion = OHMELoss()# 训练模型
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
epochs = 10
for epoch in range(epochs):for batch_idx, (data, target) in enumerate(train_loader):optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()if batch_idx % 100 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))# 测试模型
test_dataset = MNIST(root='data', train=False, transform=ToTensor())
test_loader = DataLoader(test_dataset, batch_size=1000)
model.eval()
correct = 0
with torch.no_grad():for data, target in test_loader:output = model(data)_, predicted = torch.max(output.data, 1)correct += (predicted == target).sum().item()
print('Test Accuracy:', correct / len(test_loader.dataset))

在代码中,我们首先定义了模型,并使用OHMELoss作为损失函数。OHMELoss定义中的ratio=3表示每个迭代中选择三倍于正常的样本数量进行训练。

在训练过程中,我们使用torch.topk函数选择最难的样本进行训练。在测试过程中,我们使用model.eval()将模型设为评估模式,并计算模型的准确率。

这个示例展示了如何在PyTorch中使用OHEM进行训练,但具体的实现方式可能因应用场景而异。

这篇关于OHEM在线难例挖掘原理及在代码中应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/372275

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

电力系统中的A类在线监测装置—APView400

随着电力系统的日益复杂和人们对电能质量要求的提高,电能质量在线监测装置在电力系统中得到广泛应用。目前,市场上的在线监测装置主要分为A类和B类两种类型,A类和B类在线监测装置主要区别在于应用场景、技术参数、通讯协议和扩展性。选择时应根据实际需求和应用场景综合考虑,并定期维护和校准。电能质量在线监测装置是用于实时监测电力系统中的电能质量参数的设备。 APView400电能质量A类在线监测装置以其多核

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n