PyTorch +YOLO + Label Studio + 图像识别 深度学习项目实战 (二)
文章目录
- [PyTorch +YOLO + Label Studio + 图像识别 深度学习项目实战 (二)](#PyTorch +YOLO + Label Studio + 图像识别 深度学习项目实战 (二))
-
- [图像识别 和 图像分类 区别](#图像识别 和 图像分类 区别)
-
- [1. 图像识别 (Image Recognition) / 图像分类 (Image Classification)](#1. 图像识别 (Image Recognition) / 图像分类 (Image Classification))
- [2. 目标检测 (Object Detection)](#2. 目标检测 (Object Detection))
- [3. 主要区别总结 📊](#3. 主要区别总结 📊)
- [目标 流程](#目标 流程)
-
- [1. 收集数据文件夹](#1. 收集数据文件夹)
- [2. 收集数据 ](#2. 收集数据
) - [3. 功能: 计算数据集的均值和标准差,用于归一化](#3. 功能: 计算数据集的均值和标准差,用于归一化)
- [4.🔄 对比 ImageNet 参数:](#4.🔄 对比 ImageNet 参数:)
- [✅ 建议: 差异很小,可以继续使用 ImageNet 参数](#✅ 建议: 差异很小,可以继续使用 ImageNet 参数)
-
-
- [5. 训练](#5. 训练)
- [6. 测试](#6. 测试)
-
图像识别 和 图像分类 区别
1. 图像识别 (Image Recognition) / 图像分类 (Image Classification)
核心任务: 将一张图片归类到预定义的某个类别中。
输入: 一张完整的图片。
输出: 一个或几个标签,代表这张图片最可能的类别。
关注点: 整张图片的内容或主题。
举例:
给定一张图片,模型判断这张图片是"猫"。
给定一张图片,模型判断这张图片是"风景"。
(它不会告诉你图片里有几只猫,或者猫在哪里。)
类比: 你看了一张照片,然后说:"哦,这是一张关于猫的照片。" 🐱
2. 目标检测 (Object Detection)
核心任务: 在一张图片中找出所有感兴趣的目标(物体),并准确地标出它们的位置(通常用一个矩形框,称为边界框 Bounding Box),同时识别出每个目标的类别。
输入: 一张完整的图片。
输出: 多个边界框,每个边界框都带着一个类别标签和置信度得分。
关注点: 图片中各个独立目标的位置和类别。
举例:
给定一张图片,模型不仅能识别出里面有"猫"和"狗",还能用框把猫和狗分别框出来,并标注它们的类别。
在自动驾驶中,识别出图片中的"行人"、"汽车"、"交通标志",并框出它们的位置。
类比: 你看了一张照片,然后指着照片说:"看,这里有一只猫(指着猫),那边还有一只狗(指着狗)。" 🐕🐈
3. 主要区别总结 📊
特征 图像识别 (Image Recognition / Classification) 目标检测 (Object Detection)
输出形式 单个或多个类别标签 多个边界框 + 每个框的类别标签
粒度 图片级别:对整张图片进行分类 对象级别:对图片中的每个对象进行分类和定位
目标 "这张图是什么?" "图中有什么?在哪里?有多少?"
复杂性 相对较低,只涉及分类 相对较高,既涉及分类又涉及定位
应用场景 图片内容分类、图片搜索、垃圾邮件识别 自动驾驶、安防监控、人脸识别、工业质检
目标 流程

1. 收集数据文件夹
bash
D:\Classification\koala_platypus>tree
卷 新加卷 的文件夹 PATH 列表
卷序列号为 2C3A-6894
D:.
├─img_cvs
├─source
│ ├─koala /100 图片
│ └─platypus /100 图片
├─test
├─train
│ ├─koala
│ └─platypus
├─val
│ ├─koala
│ └─platypus
└─__pycache__
2. 收集数据 
bash
source_path: 原始数据集路径 (D:\Classification\source)
================================================================================
🐨🦆 Koala vs Platypus 数据集拆分工具
================================================================================
📂 原始数据路径: D:\Classification\koala_platypus\source
📂 训练集路径: D:\Classification\koala_platypus\train
📂 验证集路径: D:\Classification\koala_platypus\val
📊 数据集划分: 训练集 80% | 验证集 20%
🎲 随机种子: 42
================================================================================
✅ 找到 2 个类别: ['koala', 'platypus']
📁 创建目录结构...
✅ D:\Classification\koala_platypus\train
✅ D:\Classification\koala_platypus\val
✅ D:\Classification\koala_platypus\train\koala
✅ D:\Classification\koala_platypus\val\koala
✅ D:\Classification\koala_platypus\train\platypus
✅ D:\Classification\koala_platypus\val\platypus
================================================================================
🔄 开始拆分数据集...
================================================================================
📊 KOALA 类别:
总图片数: 100
训练集: 80 张 (80%)
验证集: 20 张 (20%)
处理进度: [100/100] (100.0%)
📊 PLATYPUS 类别:
总图片数: 100
训练集: 80 张 (80%)
验证集: 20 张 (20%)
处理进度: [100/100] (100.0%)
================================================================================
✅ 数据集拆分完成!
================================================================================
📊 总图片数: 200 张
📊 训练集: 160 张 (80.0%)
📊 验证集: 40 张 (20.0%)
📋 各类别详情:
koala: 训练集 80 张 | 验证集 20 张
platypus: 训练集 80 张 | 验证集 20 张
================================================================================
🎉 数据集已准备就绪,可以开始训练模型了!
================================================================================
3. 功能: 计算数据集的均值和标准差,用于归一化
bash
python calculate_mean_std.py
bash
================================================================================
📊 数据集归一化参数计算工具
================================================================================
📂 数据路径: D:\Classification\koala_platypus\source
📐 图片尺寸: (224, 224)
================================================================================
✅ 找到 200 张图片
🔄 正在计算均值和标准差...
处理进度: 100%|██████████████████████████████████████████████████████████████████████| 200/200 [00:03<00:00, 57.33it/s]
================================================================================
✅ 计算完成!
================================================================================
📊 数据集统计信息:
总图片数: 200
总像素数: 10,035,200
🎨 RGB 均值 (Mean):
R 通道: 0.436843
G 通道: 0.419627
B 通道: 0.365986
📏 RGB 标准差 (Std):
R 通道: 0.230029
G 通道: 0.225605
B 通道: 0.234155
================================================================================
💡 使用方法:
================================================================================
在训练脚本中使用以下代码:
```python
normalize = transforms.Normalize(
mean=[0.436843, 0.419627, 0.365986],
std=[0.230029, 0.225605, 0.234155]
)
================================================================================
4.🔄 对比 ImageNet 参数:
================================================================================
ImageNet Mean: [0.485000, 0.456000, 0.406000]
您的数据集: [0.436843, 0.419627, 0.365986]
ImageNet Std: [0.229000, 0.224000, 0.225000]
您的数据集: [0.230029, 0.225605, 0.234155]
📉 与 ImageNet 的差异:
均值平均差异: 0.041515
标准差平均差异: 0.003929
✅ 建议: 差异很小,可以继续使用 ImageNet 参数
💾 参数已保存到: D:\Classification\koala_platypus\normalization_params.txt
5. 训练
train_mobilenet.py
修改 ImageNet 的差异:
# ImageNet 标准归一化参数(使用预训练模型必须用这个)
normalize = transforms.Normalize(
mean=[0.436, 0.419, 0.365],
std=[0.230, 0.225, 0.234]
)
python
def main():
print("\n" + "=" * 80)
print(" " * 15 + "🚀 Koala vs Platypus - MobileNetV2 轻量化训练")
print("=" * 80)
# 创建模型
print("\n📦 正在创建 MobileNetV2 模型...")
model = MobileNetV2Classifier(
num_classes=2,
pretrained=True,
freeze_features=True # 冻结特征层,只训练分类头,更快收敛、避免过拟合、在小数据集上效果更稳
)
total_params = sum(p.numel() for p in model.parameters())
trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f" ✅ 模型创建成功!")
print(f" 📊 总参数量: {total_params:,}")
print(f" 📊 可训练参数: {trainable_params:,} ({100*trainable_params/total_params:.1f}%)")
# 加载数据
print("\n📂 正在加载数据...")
train_loader, val_loader = train_val_data_process()
# 训练
print("\n🏋️ 开始训练...")
train_process = train_model_process(
model=model,
train_dataloader=train_loader,
val_dataloader=val_loader,
num_epochs=50
)
# 绘图
plot_training_process(train_process)
print("\n" + "=" * 80)
print(" " * 25 + "🎉 训练完成!")
print("=" * 80)
print("\n💡 下一步:")
print(" 1. 查看 training_mobilenet.png 分析训练效果")
print(" 2. 使用 test_mobilenet.py 测试模型")
print(" 3. 最佳模型已保存至 best_mobilenet.pth\n")
html
================================================================================
🚀 Koala vs Platypus - MobileNetV2 轻量化训练
================================================================================
📦 正在创建 MobileNetV2 模型...
🔒 特征提取层已冻结,仅训练分类头
✅ 模型创建成功!
📊 总参数量: 2,388,098
📊 可训练参数: 164,226 (6.9%)
📂 正在加载数据...
📊 训练集: 160 张
📊 验证集: 40 张
📂 类别: ['koala', 'platypus']
🏋️ 开始训练...
🎯 开始训练 (设备: cuda)
================================================================================
Epoch [1/50]
训练 - Loss: 1.0514, Acc: 53.12%
验证 - Loss: 0.6507, Acc: 62.50%
学习率: 1.00e-04
✅ 验证准确率提升 (0.00% → 62.50%), 保存模型...
--------------------------------------------------------------------------------
Epoch [2/50]
训练 - Loss: 0.7581, Acc: 58.12%
验证 - Loss: 0.3717, Acc: 90.00%
学习率: 1.00e-04
✅ 验证准确率提升 (62.50% → 90.00%), 保存模型...
--------------------------------------------------------------------------------
Epoch [3/50]
训练 - Loss: 0.5650, Acc: 70.00%
验证 - Loss: 0.2195, Acc: 95.00%
学习率: 1.00e-04
✅ 验证准确率提升 (90.00% → 95.00%), 保存模型...
--------------------------------------------------------------------------------
6. 测试
python test_mobilenet.py
bash
def predict_single_image(self, image_path, threshold=0.7):
"""
单张图片预测
Args:
image_path: 图片路径
threshold: 置信度阈值
"""
try:
# 加载图片
img = Image.open(image_path).convert('RGB')
img_tensor = self.transform(img).unsqueeze(0).to(self.device)
# 预测
with torch.no_grad():
output = self.model(img_tensor)
probabilities = F.softmax(output, dim=1)
confidence, predicted = torch.max(probabilities, 1)
predicted_class = self.class_names[predicted.item()]
confidence_score = confidence.item()
# 判断是否低于阈值
if confidence_score < threshold:
predicted_class = "uncertain"
# 打印结果
print(f"\n📸 图片: {os.path.basename(image_path)}")
print(f" 🏷️ 预测类别: {predicted_class}")
print(f" 📊 置信度: {confidence_score*100:.2f}%")
if confidence_score < threshold:
print(f" ⚠️ 置信度低于阈值 {threshold*100:.1f}%,建议人工复核")
# 显示所有类别概率
print(f" 详细概率:")
for i, class_name in enumerate(self.class_names):
prob = probabilities[0][i].item() * 100
bar = "█" * int(prob / 5) # 简单进度条
print(f" {class_name:12s}: {prob:5.2f}% {bar}")
return predicted_class, confidence_score
except Exception as e:
print(f"❌ 预测失败: {e}")
return None, None