news 2026/10/2 2:42:05

EfficientNet图像分类实战:从原理到训练调优与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EfficientNet图像分类实战:从原理到训练调优与避坑指南

简介:这是一份基于 PyTorch 的图像分类 EfficientNet 实战代码包,面向有一定深度学习基础、希望快速掌握 EfficientNet 训练与推理流程的读者,也适合用于课程设计、毕业设计或图像分类算法对比实验。压缩包共 8 个文件,包含 5 个 Python 脚本、2 个编译生成的 pyc 缓存文件及 1 个已训练好的 pth 模型权重,整体约 38.27 MB。其中 Python 脚本覆盖数据集封装、模型定义、训练、测试与单图预测等关键环节,pth 权重则保存了完整训练结果,可直接加载验证分类效果。资源已吸引 1205 人学习,代码与权重搭配使用,可帮助读者快速跑通 EfficientNet 实验,理解从数据加载、训练调参到模型评估与推理部署的完整链路,并在此基础上迁移到自己的分类任务中。整体结构清晰,适合作为深度学习图像分类项目的入门参考与实践模板。

1. 图像分类EfficientNet实战.zip:这个压缩包解决什么问题

同样是做图像分类,换一个骨干网络,参数量能少一半、精度反而更高——这是图像分类EfficientNet实战.zip这个项目包最有价值的点。EfficientNet是 Google 在 2019 年提出的卷积骨干网络,靠网络结构搜索和一套复合缩放策略,在 ImageNet 上以远小于 ResNet 的参数量拿到当时的领先精度。之后很多图像分类算法实现、迁移学习项目都把它当默认首选主网络,直到 transformer 图像分类模型(比如 ViT、Swin)出来之前,它一直是精算比最划算的 CNN 选择。

这个 zip 里装的就是一套完整的图像分类落地代码:数据集怎么组织、训练脚本怎么写、超参怎么设、模型怎么验证、踩了哪些坑怎么排查。它适合两类人:刚接触图像分类、想跑通从数据到模型的完整链路的学生或转行者;已经在做分类任务、想给自己的项目换个更高精度和算力比的骨干网络的工程师。你不需要重新发明什么,照着项目里的流程,把数据和脚本对上,就能在本地 GPU 上跑出自己的分类模型。

2. EfficientNet的底层逻辑:三个关键设计决定它快且准

很多人拿到 EfficientNet 就当成一个黑盒 backbone 直接用,但它和 ResNet 的差异不是"层更深、更宽"这么简单。它有三个核心设计:网络结构搜索得到的基线、移动倒残差模块(MBConv)、以及复合缩放策略。不理解这三个设计,你就不知道换型号时该动哪个参数,也不知道为什么别人调参能上 90 而你卡在 85。

2.1 复合缩放:同时调整深度、宽度、分辨率

传统做法是把模型加宽或加深,网络宽度、深度、输入分辨率是三个分开调的东西。EfficientNet 的做法是用一个全局系数 phi 同时缩放这三个维度:深度按 alpha^phi 缩放,宽度按 beta^phi 缩放,分辨率按 gamma^phi 缩放,并且约束 alpha、beta、gamma 的乘积关系,让算力增长均匀分配到三个维度上。

这个设计的意义很直接:同样增加一倍计算量,均匀分配三维得到的精度提升,比单独加深或单独加宽要好。体现在代码里就是 timm 里 model_name 从 efficientnet_b0 换到 efficientnet_b4,输入尺寸也要跟着变——B0 是 224,B4 是 380,B7 是 600。如果你只换了模型名,还用 224 去喂 B7,那就是把复合缩放的预设给废了,精度和速度都会不对。

这也是调参时最容易忽略的点:finetune 的输入分辨率必须和模型预设对应。很多人抱怨训练 EfficientNet 精度不如预期,打开代码一看,Resize 写死了 224,模型却是 B5——预设分辨率是 456,等于强制缩图后训练,信息已经丢了。

2.2 MBConv与SE注意力:为什么它比ResNet省参数

EfficientNet 的重复单元叫 MBConv(Mobile Inverted Bottleneck Conv),从 MobileNetV2 继承而来,再加了 SE 注意力。它的计算方式是:先用 1x1 卷积把通道数升上去,再用 depthwise(逐通道)卷积做空间特征提取,接着过 SE 注意力对通道加权,最后 1x1 卷积把通道降回来,并接残差连接。

省参数的关键在 depthwise 卷积:每个通道单独做卷积,而不是像标准卷积那样每个输出通道要遍历全部输入通道。标准 3x3 卷积的计算量是输入通道数乘输出通道数乘 9,depthwise 只有输入通道数乘 9。SE 注意力则在通道维度上做 squeeze 和 excitation,用很小的中间层(通常压缩到 1/4)给每个通道算一个权重,让模型自己学会"该关注哪些特征图"。这两个结构叠加起来,就是 EfficientNet 在同样精度下参数量和计算量远小于 ResNet 的原因。

实际使用时的感受是:一个能跑到 90% 精度的 EfficientNet-B1 模型,权重文件只有十几 MB,推理单张图在普通消费级显卡上几毫秒到十几毫秒。如果你的部署端是 CPU 或边缘设备,这个精算比优势比任何训练技巧都值钱。

2.3 从B0到B7:按显存和精度需求选型号

timm 库里 EfficientNet 按参数量从小到大排了 B0 到 B7 八个标准型号,外加一批带噪声训练版本(_ns、_rs 等)。我一般的选择原则是这样的:

型号参数量预设分辨率约Top1精度适用场景
B0约530万224约77%快速验证、CPU推理、小数据集
B1约780万240约79%通用分类、入门级GPU
B2约920万260约80%精度要求中等的业务场景
B3约1200万300约81%12GB显存可跑的较优选择
B4约1900万380约83%精度优先、显存充足时使用
B5-B73000万以上456/528/600约84%高精度竞赛、后台离线任务

显存估算要按分辨率的平方算:B0 输入 224,B4 输入 380,输入面积大约是 2.9 倍,特征图内存也近似按这个倍数涨。12GB 显存的卡跑 B4,batch_size 往往只能开到 16 到 24。如果你只有一张 8GB 卡,老老实实选 B0 或 B1,先跑通流程,精度不够再加模型,不要一上来就 B7——大概率直接 OOM,浪费一下午。

2.4 环境准备:解压后先把这三样装齐

这个项目包默认用 PyTorch 和 timm 运行。解压之后先做环境检查,别急着跑代码。

# 解压项目包(假设压缩包是英文路径下的 zip) unzip -q image_classification_efficientnet.zip -d efficientnet_project # 进入项目目录 cd efficientnet_project # 安装关键依赖:torch、torchvision、timm,缺了哪样都跑不起来 pip install torch torchvision timm

提示:解压后先看一眼目录里是否有 data 或 train/val 之类的数据文件夹。如果没有,需要自己准备图像分类数据集,格式见下一章。用 unzip 加 -q 是为了避免解压时刷屏,也能更快发现路径异常。

依赖装完后,用下面这段验证环境是否就绪:

python -c "import torch, timm; print(torch.__version__, timm.__version__)" python -c "print(torch.cuda.is_available())"

第二行输出 True 才表示能用 GPU 训练。如果你在 Windows 上遇到中文路径乱码导致数据集加载失败,这是 zip 包文件名编码的问题,我在第 4 章的避坑部分专门写了处理办法,这里先跳过。

3. 跑通图像分类全流程:数据、训练脚本与参数调优

环境就绪之后,核心问题就是怎么把数据喂进去、怎么把训练跑起来。图像分类项目里常见做法是用 torchvision 的 ImageFolder 组织数据,它按文件夹名自动生成类别标签,省去自己写 dataset 的功夫。本章给出一套能直接用的完整训练流程。

3.1 数据组织:按ImageFolder的目录规则准备图片

ImageFolder 要求数据按"类别名/图片文件"的层级摆放。无论你是自己收集的图像分类数据集,还是从网上下载的数据集压缩包,标准做法是整理成下面这个结构:

data/ ├── train/ │ ├── cat/ # 每类一个文件夹 │ │ ├── cat_001.jpg │ │ └── ... │ ├── dog/ │ └── ... └── val/ ├── cat/ ├── dog/ └── ...

准备命令可以这样写:

mkdir -p data/train data/val # 把原始图片按类目移动到对应目录,这里以 cat 为例 mkdir -p data/train/cat data/val/cat mv cat_sample_*.jpg data/train/cat/ # val 里放一部分和 train 不重叠的图片,用于验证 mv cat_test_*.jpg data/val/cat/

关键点是 train 和 val 的图片不能有交集,否则验证集的精度会虚高。类别文件夹名会直接变成 ImageFolder 的 class_to_idx 映射,类别名尽量用英文,避免中文路径在部分系统上乱码。如果你的数据集下载下来是扁平结构、每张图带一个 label 文件,那需要先按 label 批量移动到对应文件夹,这步只执行一次。

3.2 完整训练脚本:代码结构、数据加载和训练循环

下面的训练脚本可以直接落到项目里跑,前提是你按照 3.1 的目录结构准备好了数据。默认用 EfficientNet-B0 + 预训练权重,训练 30 个 epoch。

import torch import torch.nn as nn import timm from torch.utils.data import DataLoader from torchvision import datasets, transforms device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 数据路径:按项目包 data/train、data/val 的结构 train_dir = 'data/train' val_dir = 'data/val' # 训练集增强:随机裁剪到 224x224(B0 预设分辨率) train_tf = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ColorJitter(0.2, 0.2, 0.2), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 验证集只做缩放和中心裁剪,不做随机增强 val_tf = 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]) ]) train_set = datasets.ImageFolder(train_dir, train_tf) val_set = datasets.ImageFolder(val_dir, val_tf) train_loader = DataLoader(train_set, batch_size=64, shuffle=True, num_workers=4) val_loader = DataLoader(val_set, batch_size=64, shuffle=False, num_workers=4) # num_classes 从数据集自动读取,换数据集不用改代码 model = timm.create_model('efficientnet_b0', pretrained=True, num_classes=len(train_set.classes)) model.to(device) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-4) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=30) def evaluate(model, loader): model.eval() correct = 0 total = 0 with torch.no_grad(): for images, labels in loader: images, labels = images.to(device), labels.to(device) outputs = model(images) _, preds = torch.max(outputs, 1) correct += (preds == labels).sum().item() total += labels.size(0) return correct / total best_acc = 0.0 for epoch in range(30): model.train() total_loss = 0.0 correct = 0 total = 0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() * images.size(0) _, preds = torch.max(outputs, 1) correct += (preds == labels).sum().item() total += labels.size(0) scheduler.step() train_acc = correct / total val_acc = evaluate(model, val_loader) print(f'Epoch {epoch+1}: loss {total_loss/total:.4f}, ' f'train_acc {train_acc:.4f}, val_acc {val_acc:.4f}') if val_acc > best_acc: best_acc = val_acc torch.save(model.state_dict(), 'best_model.pth')

代码逻辑分四块:数据装载、模型构建、训练循环、验证评价。最关键的一行是 timm.create_model 里指定了 pretrained=True 和 num_classes,前者加载 ImageNet 预训练权重,后者把分类头替换成你自己的类别数。evaluate 函数里用了 torch.no_grad() 来关闭梯度计算,否则验证阶段也会占用显存,batch 大一点就会 OOM。

loss 累加用了 loss.item() 乘 batch 大小,而不是直接累加 loss 张量,是为了避免梯度图一直积累导致内存泄漏;这是个很多新手会踩的隐性坑。

3.3 参数细读:学习率、batch_size、权重衰减怎么设

图像分类模型微调的参数设置其实比网络结构影响更大。项目的默认参数按经验如下:

参数推荐值说明
学习率1e-4(微调)/ 1e-3(从头训练)预训练权重下用 1e-4 起步最稳
batch_sizeB0: 64,B4: 16~24跟显存走,不够就减半
权重衰减1e-4 ~ 1e-5防止过拟合,不应不设
Epoch30 ~ 50小数据集 30 够,大数据集再加
学习率调度CosineAnnealing比 step decay 更平滑,精度更高

一个常见分歧是学习率:有人直接从 1e-3 开始微调,EfficientNet 前几个 epoch loss 很容易震荡甚至 NaN,因为分类头是新初始化的,梯度差异大。我一般用 AdamW + 1e-4,然后前 5 个 epoch 做线性 warmup,后面接 cosine 退火,这也是大部分图像分类竞赛方案的标准路径。

3.4 数据增强:对付小数据集的首选手段

如果你的图像分类数据集每类只有几百张,光靠 EfficientNet 的预训练权重还不够,过拟合会很快出现。训练脚本里已经加了 RandomResizedCrop、RandomHorizontalFlip 和 ColorJitter,这三项是最便宜的增强,基本没副作用。

# 如果数据量特别少,可以再加 RandAugment,timm 里直接可用 from timm.data import RandAugment train_tf.transforms.insert(0, RandAugment(num_ops=2, magnitude=9))

RandAugment 会自动组合旋转、翻转、颜色变换、锐化等策略,比手动逐个加增强省事,但要注意 magnitude 别超过 10,否则图像被改得过于激进,模型反而学不到真实特征。视觉上验证的方式是:把增强后的图保存几张下来看一眼,如果人眼看都认不出类别,那就是增强过度了,这个判断永远比任何论文参数都靠谱。

4. EfficientNet训练避坑:五个翻车现场与排查方案

跑通一遍容易,跑出理想精度难。这一章把最常见的几个故障现象、原因和排查路径直接列出来,都是我实际训练时踩过、或者帮别人排查过的血泪经验。

4.1 现象:损失不降反升,训练几轮后直接变成 NaN

原因基本锁定两个:学习率过大,或者数据里有异常图片。EfficientNet 用的 SiLU 激活函数对梯度幅值比 ReLU 更敏感,1e-3 的学习率即使有预训练权重也容易在前几个 epoch 把权重推出正常范围,梯度爆炸后 loss 变成 NaN。另一个冷门原因是数据里混入了全黑、全白或者损坏的图片文件,归一化之后出现极端值。

解决方法是分两步排查:先把学习率降到 1e-4,加一个梯度裁剪 clip_grad_norm_(model.parameters(), max_norm=1.0);如果还在 NaN,就写脚本遍历数据集删除损坏图片,或者用 PIL 打开失败的图片直接过滤。大多数情况是学习率问题,改完就正常。

4.2 现象:选了个大模型,一跑训练直接 CUDA out of memory

原因很直接:B4 的预设分辨率是 380,对比 B0 的 224,输入面积大了约 2.9 倍,特征图内存也按这个比例涨。很多人把模型从 B0 换到 B4,batch_size 还保持 64,12GB 显存瞬间就炸了。

解决思路按优先级排:先把 batch_size 降到 16 或 8,看是否跑得动;不行就把输入分辨率手动缩到 320,代价是精度损失但内存下降显著;再不行开启梯度累积,模拟大 batch。稳妥的组合是 B3 + 300 分辨率 + batch 32,12GB 显卡一般能跑。不要硬上大模型,小模型调好参数往往比大模型调不明白得分更高。

4.3 现象:训练集精度接近满分,验证集精度差一大截

这是典型的过拟合。EfficientNet 参数量是少,但预训练模型在 ImageNet 上学到的特征对你的任务不一定完全适用,数据量不足时会很快记住训练集。

解决做法有四个:一是降低学习率,让模型在预训练权重附近微调而不是大改;二是加重数据增强,RandAugment 的 magnitude 从 9 调到 14 这种激进设置反而能提升泛化;三是把权重衰减提高到 1e-4;四是减小模型,B1 换 B0。如果这些还压不住,检查一下 train 和 val 是否有重复图片,数据集切分不合理造成的"过拟合"是数据问题,不是模型问题。

4.4 现象:zip解压后数据集路径中文乱码,ImageFolder 加载报错

这是一个和图像分类模型本身无关、却最浪费时间的坑。Windows 上压缩的 zip 包,默认文件名编码是 GBK,在 Linux 上用 unzip 解压后中文目录名变成乱码,ImageFolder 找不到类别目录,直接报错。

解决方法是解压时指定编码:

# 指定 GBK 编码解压,中文文件名正常还原 unzip -O GBK image_classification_efficientnet.zip -d efficientnet_project

如果你的 unzip 版本不支持 -O 参数,用 7z 也可以:7z x 压缩包名。还有更省事的做法:解压后统一重命名成英文路径,一劳永逸。批量重命名可以用 mv 配合循环脚本,几行就能搞定。

4.5 现象:精度卡在某个值上不去,怎么调都动弹不了

这是最玄学也最常见的情况。先别急着调学习率,按下面顺序逐个检查:一是确认验证集预处理和训练时一致,Resize+CenterCrop 是 256+224 还是 300+224,两边不一致会导致输入分布对不上;二是看类别是否均衡,某个类只有几十张,模型直接放弃学习这一类;三是检查 scheduler 是否生效,很多代码忘了 scheduler.step(),学习率一直没降,loss 自始至终在那波动。

最后一个容易忽略的点:混合精度的 scale 因子没处理好,小 loss 长期被忽略导致梯度不更新,看起来就是精度卡死。把 AMP 的 GradScaler 打印出来看,如果 scale 一直在增大而不更新,就该手动检查梯度或者去掉混合精度重跑一轮对比。

5. 推理与验证:把模型从训练搬到实际图片

训练出 best_model.pth 只是第一步,真正检验分类效果的是推理环节。这里的"推理"不单是拿模型跑一张图,还包括能否稳定输出可解释的预测结果、能否科学评估模型在新数据上的表现。工程上这两件事通常要一起做。

5.1 单张图片推理脚本:加载权重、预处理、输出TopK

训练时模型分类头是 len(train_set.classes) 个输出,推理时类别顺序必须和训练时一致,所以训练脚本里最好把类别列表保存下来。常见做法是存成 json:

# 训练结束后保存类别列表,推理时加载 import json with open('classes.json', 'w') as f: json.dump(train_set.classes, f)

推理脚本如下:

import json import torch import timm from PIL import Image from torchvision import transforms with open('classes.json', 'r') as f: classes = json.load(f) model = timm.create_model('efficientnet_b0', pretrained=True, num_classes=len(classes)) model.load_state_dict(torch.load('best_model.pth', map_location='cpu')) model.eval() val_tf = 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]) ]) img = Image.open('test.jpg').convert('RGB') x = val_tf(img).unsqueeze(0) with torch.no_grad(): logits = model(x) probs = torch.softmax(logits, dim=1)[0] top3 = torch.topk(probs, 3) for score, idx in zip(top3.values.tolist(), top3.indices.tolist()): print(f'{classes[idx]}: {score:.4f}')

这段代码用 map_location='cpu' 加载权重,方便在没有 GPU 的机器上做推理验证,也避免把显卡占用掉。预处理要和训练验证集完全一致:Resize 256、CenterCrop 224、同一套 mean/std。只要这中间任何一个数字和训练时不一样,结果都会偏差,这是推理部署里最容易犯的低级错误。

5.2 用混淆矩阵算真实的分类效果

只看 top-1 准确率会掩盖类别间的问题:某个类被另一个类系统性误判,准确率数字完全看不出来。用混淆矩阵能直观看到对角线上哪些类亮、哪些类暗。下面的代码用 sklearn 生成矩阵并用 seaborn 画图:

import torch import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix def collect_predictions(model, loader, device): model.eval() y_true, y_pred = [], [] with torch.no_grad(): for images, labels in loader: images = images.to(device) outputs = model(images) _, preds = torch.max(outputs, 1) y_true.extend(labels.numpy()) y_pred.extend(preds.cpu().numpy()) return y_true, y_pred y_true, y_pred = collect_predictions(model, val_loader, device) cm = confusion_matrix(y_true, y_pred) plt.figure(figsize=(8, 6)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=train_set.classes, yticklabels=train_set.classes) plt.xlabel('Predicted') plt.ylabel('True') plt.savefig('confusion_matrix.png')

看到矩阵后,凡是某一列的其他类数值偏高,说明模型把那些类都判成了同一个类,优先检查那一个类的样本是不是和另一个特别相似,或者那一类在训练集里数量过少。这一步能直接指出下一步该增强哪个类的数据,比盲目加 epoch 有效得多。

5.3 模型导出:TorchScript与ONNX的可选操作

如果模型要部署到服务端或移动端,PyTorch 的 .pth 权重文件不够通用,常见做法是导出成 TorchScript 或 ONNX。TorchScript 仍由 PyTorch 生态托管,适合 Python 服务;ONNX 适合跨框架和硬件加速。

# 用 torch.jit.trace 导出 TorchScript,example 需要一张和输入尺寸一致的张量 python -c " import torch, timm model = timm.create_model('efficientnet_b0', pretrained=True, num_classes=10) model.load_state_dict(torch.load('best_model.pth')) model.eval() example = torch.rand(1, 3, 224, 224) traced = torch.jit.trace(model, example) traced.save('model.pt') "

ONNX 导出类似:torch.onnx.export(model, example, "model.onnx", opset_version=12)。导出的模型最好用 onnxruntime 加载跑一遍,和 PyTorch 输出对比一下数值差异,差异在 1e-4 以内才算没导出坏。这一步别省,因为优化器版本差异可能导致算子变换后结果偏离,损失一点点精度还算小事,输出结构变了才是大问题。

6. 进阶:混合精度与断点续训,把训练效率再提一档

模型精度稳定之后,下一步就是缩短训练时间、避免意外中断造成返工。两个技巧效果最直接:混合精度训练和带状态断点续训。

混合精度用 PyTorch 自带的 amp 模块即可,改动量很小:

scaler = torch.cuda.amp.GradScaler() for images, labels in train_loader: images, labels = images.to(device), labels.to(device) optimizer.zero_grad() with torch.cuda.amp.autocast(): outputs = model(images) loss = criterion(outputs, labels) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()

注意梯度裁剪如果用到了,需要写成 scaler.unscale_ 之后再 clip,顺序错了裁剪就不生效。这套改动在 30 系列及以上显卡上能提速约 30% 到 50%,B4 以上的大模型收益更明显。不要关掉 GradScaler,否则前几个 epoch 的梯度幅度波动会直接把你打回 NaN。

断点续训要把 optimizer、scheduler、epoch 一起存下来,只存 model.state_dict() 意味着中断后学习率状态全丢了。我习惯每个 epoch 结束存一次带后缀的 checkpoint,只保留最后两个版本:

torch.save({ 'model': model.state_dict(), 'optimizer': optimizer.state_dict(), 'scheduler': scheduler.state_dict(), 'epoch': epoch, 'best_acc': best_acc, }, f'checkpoint_{epoch}.pth')

恢复时用 torch.load 后依次 load_state_dict 即可。这两个习惯组合起来,一个周末训练一个大模型完全不虚。我之前有一次跑 B5 到第 22 轮断电,重启后因为只有模型权重,学习率和动量全丢了,从头再训 22 轮才恢复到之前的精度,那种回头路走一次就记住了。现在我的所有图像分类脚本都默认带 checkpoint 和 amp,算是项目包里最值得保留的两个功能,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:41:07

小样本目标检测实战:基于YOLOv8的火星月球陨石坑识别

简介:面向计算机视觉目标检测任务的火星与月球陨石坑数据集,提供VOC与YOLO两种主流标注格式,可直接用于训练陨石坑识别模型,也可作为目标检测入门练习数据。资源共398个文件,压缩包约10.27MB,内含火星月球表…

作者头像 李华
网站建设 2026/10/2 2:40:58

安全试炼场:沙盒技术的原理、落地与业务价值

开头先聊一个现象:现在网络安全行业里,沙盒技术已经是“硬通货”了。邮件网关拦截可疑附件、EDR里分析未知进程、威胁情报平台提炼IOC、甚至金融客户上架App前的行为审查,背后几乎都有“沙盒”在干活。很多人第一次接触沙盒,大多是…

作者头像 李华
网站建设 2026/10/2 2:40:55

Python智能坐姿检测实战:关键点检测与角度阈值校准全解析

简介:面向计算机相关专业课程设计、期末大作业与毕业设计的智能坐姿检测系统完整项目,基于 Python 实现,覆盖从数据准备、姿态估计、模型训练到界面展示与音频提醒的完整链路。压缩包共 15 个文件,以 11 个 Python 脚本为主干&…

作者头像 李华
网站建设 2026/10/2 2:40:08

YOLOv8人脸表情识别实战:权重选型与数据集制作避坑指南

简介:YOLOv8人脸表情识别训练权重与配套数据集,面向有目标检测基础、希望快速落地表情识别项目的开发者。资源不仅提供了训练好的权重,还包含已划分train/val/test的完整数据集,并内置data.yaml配置文件,支持YOLOv5、Y…

作者头像 李华
网站建设 2026/10/2 2:39:37

YOLOv5垃圾检测实战:PyQt界面+标注数据集+高mAP权重

简介:本资源是一套开箱即用的YOLOv5垃圾目标检测完整实践方案,面向计算机视觉初学者、AI项目开发者及环境监测类应用研究者,解决生活垃圾图像识别与快速部署难题。压缩包共2000个文件,含1858个标注用txt标签文件(对应C…

作者头像 李华