CUB-200-2011 数据集实战:3步完成 PyTorch 数据加载与 15 个关键点可视化
CUB-200-2011 数据集实战3步完成 PyTorch 数据加载与 15 个关键点可视化在细粒度图像分类领域CUB-200-2011 数据集因其丰富的标注信息和挑战性而备受研究者青睐。本文将带你从零开始快速掌握该数据集的核心使用方法重点解决三个工程难题如何高效加载多模态标注数据、如何处理复杂的文件映射关系以及如何实现关键点的精准可视化。1. 数据准备与环境搭建1.1 数据集结构解析下载并解压 CUB-200-2011 数据集后你会看到如下目录结构CUB_200_2011/ ├── images/ # 200个子目录每个对应一种鸟类 ├── parts/ # 关键点标注 │ ├── parts.txt │ ├── part_locs.txt │ └── part_click_locs.txt ├── attributes/ # 属性标注 ├── images.txt # 图像ID与路径映射 ├── bounding_boxes.txt # 边界框坐标 ├── train_test_split.txt # 官方划分 └── image_class_labels.txt # 图像类别标签关键文件说明文件每行格式描述images.txtimage_id image_name图像ID到路径的映射bounding_boxes.txtimage_id x y w h边界框坐标左上x,y 宽高part_locs.txtimage_id part_id x y visible关键点坐标及可见性1.2 安装必要依赖推荐使用 conda 创建虚拟环境conda create -n cub python3.8 conda activate cub pip install torch torchvision matplotlib pandas2. 构建 PyTorch 数据管道2.1 数据集类设计我们创建一个继承自torch.utils.data.Dataset的类完整处理所有标注信息import os import torch from PIL import Image import pandas as pd class CUBDataset(torch.utils.data.Dataset): def __init__(self, root, transformNone, trainTrue): self.root root self.transform transform # 加载所有映射文件 self._load_metadata() # 根据train_test_split筛选数据 self._filter_split(train) def _load_metadata(self): # 加载图像路径映射 images_df pd.read_csv(os.path.join(self.root, images.txt), sep , names[img_id, img_path]) # 加载边界框 bbox_df pd.read_csv(os.path.join(self.root, bounding_boxes.txt), sep , names[img_id, x, y, w, h]) # 加载类别标签 class_df pd.read_csv(os.path.join(self.root, image_class_labels.txt), sep , names[img_id, class_id]) # 加载训练测试划分 split_df pd.read_csv(os.path.join(self.root, train_test_split.txt), sep , names[img_id, is_train]) # 加载关键点 parts_df pd.read_csv(os.path.join(self.root, parts/part_locs.txt), sep , names[img_id, part_id, x, y, visible]) # 合并所有信息 self.metadata images_df.merge(bbox_df, onimg_id) \ .merge(class_df, onimg_id) \ .merge(split_df, onimg_id) # 处理关键点将长格式转为宽格式每张图一行包含所有关键点 self.parts parts_df.pivot(indeximg_id, columnspart_id, values[x, y, visible]) def _filter_split(self, train): split_flag 1 if train else 0 self.metadata self.metadata[self.metadata[is_train] split_flag] def __len__(self): return len(self.metadata) def __getitem__(self, idx): row self.metadata.iloc[idx] img_id row[img_id] # 加载图像 img_path os.path.join(self.root, images, row[img_path]) img Image.open(img_path).convert(RGB) # 获取边界框并裁剪 bbox (row[x], row[y], row[x]row[w], row[y]row[h]) img img.crop(bbox) # 获取关键点相对边界框的坐标 parts self.parts.loc[img_id] keypoints [] for part_id in range(1, 16): # 共15个关键点 x parts[x][part_id] - row[x] y parts[y][part_id] - row[y] visible parts[visible][part_id] keypoints.append([x, y, visible]) # 转换为tensor keypoints torch.tensor(keypoints, dtypetorch.float32) class_id torch.tensor(row[class_id] - 1, dtypetorch.long) # 转为0-based # 应用变换 if self.transform: img self.transform(img) return img, keypoints, class_id2.2 数据增强策略针对细粒度分类任务推荐使用以下变换组合from torchvision import transforms train_transform transforms.Compose([ transforms.RandomResizedCrop(224, scale(0.8, 1.0)), transforms.RandomHorizontalFlip(), transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) val_transform transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])2.3 创建数据加载器dataset_train CUBDataset(path/to/CUB_200_2011, transformtrain_transform, trainTrue) dataset_val CUBDataset(path/to/CUB_200_2011, transformval_transform, trainFalse) train_loader torch.utils.data.DataLoader( dataset_train, batch_size32, shuffleTrue, num_workers4) val_loader torch.utils.data.DataLoader( dataset_val, batch_size32, shuffleFalse, num_workers4)3. 关键点可视化实现3.1 关键点信息解析CUB-200-2011 定义了15个鸟类关键点喙尖 (beak tip)喙基部 (beak base)左眼 (left eye)右眼 (right eye)头顶 (crown)颈部 (nape)左翼 (left wing)右翼 (right wing)尾部 (tail)左脚 (left foot)右脚 (right foot)胸部 (breast)背部 (back)左腿 (left leg)右腿 (right leg)3.2 可视化代码实现import matplotlib.pyplot as plt import numpy as np def visualize_sample(dataset, index): img, keypoints, class_id dataset[index] # 反归一化图像 img img.numpy().transpose((1, 2, 0)) mean np.array([0.485, 0.456, 0.406]) std np.array([0.229, 0.224, 0.225]) img std * img mean img np.clip(img, 0, 1) # 创建绘图 plt.figure(figsize(10, 10)) plt.imshow(img) # 绘制关键点 colors plt.cm.hsv(np.linspace(0, 1, 15)) for i, (x, y, visible) in enumerate(keypoints): if visible 0.5: # 只绘制可见点 plt.scatter(x, y, c[colors[i]], s100, labelfPart {i1}, edgecolorswhite) # 添加图例 plt.legend(bbox_to_anchor(1.05, 1), locupper left) plt.title(fClass: {class_id.item()1}) plt.axis(off) plt.tight_layout() plt.show() # 示例可视化训练集第一个样本 visualize_sample(dataset_train, 0)3.3 批量可视化技巧对于研究分析我们常需要批量查看关键点分布def plot_keypoints_distribution(dataset, num_samples9): plt.figure(figsize(15, 15)) indices np.random.choice(len(dataset), num_samples, replaceFalse) for i, idx in enumerate(indices): img, keypoints, _ dataset[idx] img img.numpy().transpose((1, 2, 0)) img std * img mean img np.clip(img, 0, 1) plt.subplot(3, 3, i1) plt.imshow(img) # 绘制所有可见关键点 for x, y, visible in keypoints: if visible 0.5: plt.scatter(x, y, cred, s10) plt.axis(off) plt.tight_layout() plt.suptitle(Random Samples with Keypoints, y1.02) plt.show() plot_keypoints_distribution(dataset_train)4. 高级应用与性能优化4.1 数据加载加速技巧当处理大规模数据时可以采用以下优化策略预加载关键点数据将关键点信息预先转换为numpy数组存储使用内存映射文件对于大型标注文件使用np.memmap并行加载设置num_workers为CPU核心数优化后的数据集类初始化def _load_metadata_optimized(self): # 使用更高效的文件读取方式 self.images np.loadtxt(os.path.join(self.root, images.txt), dtypestr) self.bboxes np.loadtxt(os.path.join(self.root, bounding_boxes.txt)) # 预加载关键点到内存 parts np.loadtxt(os.path.join(self.root, parts/part_locs.txt)) self.keypoints np.zeros((len(self.images), 15, 3)) # (N, 15, 3) for img_id, part_id, x, y, visible in parts: self.keypoints[int(img_id)-1, int(part_id)-1] [x, y, visible]4.2 自定义数据采样策略针对类别不平衡问题实现加权随机采样from torch.utils.data import WeightedRandomSampler # 计算每个类别的样本数 class_counts np.bincount([dataset_train[i][2] for i in range(len(dataset_train))]) class_weights 1. / class_counts sample_weights class_weights[[dataset_train[i][2] for i in range(len(dataset_train))]] sampler WeightedRandomSampler(sample_weights, len(sample_weights)) balanced_loader DataLoader(dataset_train, batch_size32, samplersampler)4.3 多任务学习框架同时利用关键点和类别信息进行多任务学习import torch.nn as nn class MultiTaskModel(nn.Module): def __init__(self, num_classes200): super().__init__() # 共享的特征提取器 self.backbone torchvision.models.resnet50(pretrainedTrue) in_features self.backbone.fc.in_features self.backbone.fc nn.Identity() # 移除原始全连接层 # 分类头 self.classifier nn.Linear(in_features, num_classes) # 关键点回归头 self.keypoint_regressor nn.Sequential( nn.Linear(in_features, 512), nn.ReLU(), nn.Linear(512, 15*2) # 预测15个点的(x,y)坐标 ) def forward(self, x): features self.backbone(x) # 分类输出 class_logits self.classifier(features) # 关键点输出 (batch_size, 15, 2) keypoints self.keypoint_regressor(features).view(-1, 15, 2) return class_logits, keypoints训练时需要定义复合损失函数def multitask_loss(class_logits, keypoints_pred, targets): class_target, keypoints_target targets # 分类损失 cls_loss F.cross_entropy(class_logits, class_target) # 关键点损失只计算visible1的点 visible keypoints_target[:, :, 2] 0.5 kp_loss F.mse_loss( keypoints_pred[visible], keypoints_target[:, :, :2][visible] ) return cls_loss 0.1 * kp_loss # 加权求和

相关新闻

Windows 11硬件限制终极解决方案:Flyoobe让旧电脑重获新生

Windows 11硬件限制终极解决方案:Flyoobe让旧电脑重获新生

Windows 11硬件限制终极解决方案:Flyoobe让旧电脑重获新生 【免费下载链接】FlyOOBE Fly through your Windows 11 setup 🐝 项目地址: https://gitcode.com/gh_mirrors/fl/FlyOOBE 还在为老旧电脑无法升级Windows 11而烦恼吗?Flyoobe…

2026/7/8 22:44:31阅读更多 →
Scikit-learn 1.4 交叉验证实战:5折KNN调参,准确率提升至98.2%

Scikit-learn 1.4 交叉验证实战:5折KNN调参,准确率提升至98.2%

Scikit-learn 1.4 交叉验证实战:5折KNN调参,准确率提升至98.2%当我们在处理机器学习项目时,最令人沮丧的莫过于看到一个在训练集上表现完美的模型,在实际应用中却频频出错。这种现象背后隐藏着一个关键概念——泛化能力。本文将带…

2026/7/8 22:44:31阅读更多 →
如何在5分钟内创建专属AI语音:RVC语音克隆完整指南

如何在5分钟内创建专属AI语音:RVC语音克隆完整指南

如何在5分钟内创建专属AI语音&#xff1a;RVC语音克隆完整指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Conversion…

2026/7/8 22:44:31阅读更多 →
YOLOv5 模型转换 OpenVINO IR 格式:3步从 PyTorch 到 INT8 量化部署

YOLOv5 模型转换 OpenVINO IR 格式:3步从 PyTorch 到 INT8 量化部署

YOLOv5模型高效部署指南&#xff1a;从PyTorch到OpenVINO INT8量化的完整实践为什么选择OpenVINO部署YOLOv5&#xff1f;在计算机视觉领域&#xff0c;YOLOv5因其出色的实时检测性能而广受欢迎。但当我们需要将训练好的模型部署到生产环境时&#xff0c;往往会面临性能瓶颈——…

2026/7/8 23:49:36阅读更多 →
YOLOP 与 YOLOP-v2 对比评测:BDD100K 数据集 3 项任务性能与速度分析

YOLOP 与 YOLOP-v2 对比评测:BDD100K 数据集 3 项任务性能与速度分析

YOLOP与YOLOP-v2全景驾驶感知系统深度评测&#xff1a;BDD100K数据集三项任务全面对比 在自动驾驶技术快速发展的今天&#xff0c;全景驾驶感知系统作为车辆"环境理解"的核心组件&#xff0c;其性能直接决定了自动驾驶的安全性和可靠性。YOLOP系列作为多任务学习领域…

2026/7/8 23:49:36阅读更多 →
图像去雾 3 大流派实战对比:增强、恢复、融合方法在 RESIDE 数据集上的 PSNR/SSIM 评测

图像去雾 3 大流派实战对比:增强、恢复、融合方法在 RESIDE 数据集上的 PSNR/SSIM 评测

图像去雾三大技术路线实战评测&#xff1a;从理论到RESIDE数据集性能对比引言&#xff1a;为什么我们需要关注图像去雾技术&#xff1f;清晨的浓雾笼罩着城市&#xff0c;无人机拍摄的画面变得模糊不清&#xff1b;自动驾驶汽车在雾天行驶时&#xff0c;摄像头难以准确识别前方…

2026/7/8 23:49:36阅读更多 →
洛雪音乐桌面版终极指南:免费聚合六大音乐平台的完整教程

洛雪音乐桌面版终极指南:免费聚合六大音乐平台的完整教程

洛雪音乐桌面版终极指南&#xff1a;免费聚合六大音乐平台的完整教程 【免费下载链接】lx-music-desktop 一个基于 Electron 的音乐软件 项目地址: https://gitcode.com/GitHub_Trending/lx/lx-music-desktop 你是否厌倦了在不同音乐平台间来回切换&#xff1f;是否想在…

2026/7/8 23:49:36阅读更多 →
Three.js 着色器天空教程

Three.js 着色器天空教程

着色器天空 Shader Sky ▶ 在线运行案例 案例合集&#xff1a; 三维可视化功能案例&#xff08;threehub.cn&#xff09;开源仓库github地址&#xff1a; https://github.com/z2586300277/three-cesium-examples400个案例代码: 网盘链接 你将学到什么 ShaderMaterial 自定…

2026/7/8 23:49:36阅读更多 →
语义分割 5 大损失函数实战对比:Cross-Entropy vs. Dice Loss vs. Focal Loss

语义分割 5 大损失函数实战对比:Cross-Entropy vs. Dice Loss vs. Focal Loss

语义分割五大损失函数深度解析&#xff1a;从理论到实战引言在计算机视觉领域&#xff0c;语义分割是一项基础而关键的任务&#xff0c;它要求模型能够精确识别图像中每个像素的类别归属。与简单的图像分类不同&#xff0c;语义分割需要模型在像素级别做出精细判断&#xff0c;…

2026/7/8 23:44:35阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述&#xff1a;从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目&#xff0c;叫 skills4/skills &#xff0c;它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景&#xff1a;一个旨在展示或教授某种技能的仓库&#xff0c;本身却成了安…

2026/7/8 5:12:14阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示&#xff1a;因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战&#xff1a;从“黑箱预测”到“可信推理”2026年6月&#xff0c;第7届机器学习与趋势国际会议&#xff08;MLT 2026&#xff09;将在悉尼召开。会议议程中&#xff0c;“因果与可解释机器学习…

2026/7/8 7:00:12阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时&#xff0c;通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中&#xff0c;是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/8 2:26:06阅读更多 →
作为一个给团队打绩效的人,我想说几句

作为一个给团队打绩效的人,我想说几句

我每半年都会给团队成员打绩效&#xff0c;也会参与和 CTO 的绩效校准&#xff0c;所以从管理者的视角&#xff0c;说说这件事 首先&#xff0c;我先把结论告诉你&#xff1a;接受结果&#xff0c;但一定要把原因问清楚。 因为当绩效公布到你这里的时候&#xff0c;结果基本已…

2026/7/8 0:01:17阅读更多 →
A股股指期货:全维度解析(多表格结构化完整版)

A股股指期货:全维度解析(多表格结构化完整版)

一、基础定义与核心本质股指期货全称股票价格指数期货&#xff0c;是中国金融期货交易所&#xff08;中金所&#xff09;上市的标准化金融期货合约&#xff0c;交易标的为 A 股大盘指数&#xff0c;约定未来特定时间按约定价格现金交割指数涨跌差价&#xff0c;不交割一篮子股票…

2026/7/8 0:01:17阅读更多 →
iOS越狱新手指南:从困惑到掌控,3天解锁iPhone无限潜能的真实故事

iOS越狱新手指南:从困惑到掌控,3天解锁iPhone无限潜能的真实故事

iOS越狱新手指南&#xff1a;从困惑到掌控&#xff0c;3天解锁iPhone无限潜能的真实故事 【免费下载链接】Jailbreak iOS 26.4 - 26, 17 - 17.7.5 & iOS 18 - 18.7.3 Jailbreak Tools, Cydia/Sileo/Zebra Tweaks & Jailbreak News Updates || AI Jailbreak Finder &…

2026/7/8 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时&#xff0c;发现推理速度只有可怜的 1-2 FPS&#xff0c;而别人的演示视频却能跑到 30 FPS 以上&#xff0c;那么问题很可能不在模型本身&#xff0c;而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后&#xff0c;会直接使用官方示例…

2026/7/8 6:59:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一&#xff1a;为什么你需要了解 Coze 和 Dify&#xff1f;如果你对 AI 应用开发感兴趣&#xff0c;但一看到“大模型”、“智能体”、“工作流”这些词就头疼&#xff0c;觉得门槛太高&#xff0c;那这篇文章就是为你准备的。很多开发者&#xff0c;包括我自己&#…

2026/7/8 13:42:39阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会&#xff1a;配图一直是个让人头疼的问题。2026年&#xff0c;AI生图工具已经非常成熟了&#xff0c;但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1&#xff1a;速度之王2026年6月11日&#xff0c…

2026/7/8 13:42:39阅读更多 →