news 2026/6/8 17:09:39

PyTorch实现的10种常见植物图像分类项目:含训练代码、预处理数据集与ResNet模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PyTorch实现的10种常见植物图像分类项目:含训练代码、预处理数据集与ResNet模型

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

简介:直接可用的植物图像分类实战资源,基于PyTorch搭建CNN分类流程,覆盖10类日常可见植物(如蒲公英、三叶草、向日葵等)。提供完整可运行代码:train.py负责训练主逻辑,dataset.py封装图像加载与增强,resnet.py内置适配的ResNet18结构;数据按ImageFolder标准组织在train/和val/文件夹中,开箱即读;requirements.txt明确依赖版本,兼容Python 3.6+及主流PyTorch版本;训练过程自动保存最佳模型、记录loss/acc曲线,支持断点续训;推理脚本预留接口,方便后续部署测试。所有模块解耦清晰,替换骨干网络(如换成VGG或EfficientNet)只需修改一行配置;适合零基础入门图像分类,也适用于农业场景中轻量级识别需求的快速验证。

1. 这不是“又一个图像分类Demo”,而是一套能真正种进田埂边的植物识别工具

我带过三届AI方向的本科生课程,也给五家农业技术公司做过视觉识别落地支持。每次讲到图像分类,学生第一反应是MNIST手写数字、CIFAR-10小图集——但当他们真想识别自家大棚里的番茄病斑、田埂边的杂草种类、或者果园里刚冒头的嫩芽品种时,立刻卡在第一步:没有一张真实场景下的植物图,能直接喂进模型里跑通。这套资源,就是我从2021年夏天开始,在浙江绍兴一处蓝莓种植基地的遮阳棚下,用手机拍了17轮、筛掉4327张模糊/背光/重叠样本后,亲手整理、标注、清洗、增强出来的10类常见野生与栽培植物数据集。它不追求ImageNet级别的百万量级,但每一张图都来自真实光照、不同拍摄角度、自然背景干扰——蒲公英不是在白底图库中“摆拍”,而是在水泥缝里顶着风摇晃;三叶草不是实验室培养皿里的标本,而是混在草坪里被踩过两脚还泛着水光的活体。

关键词里写的“植物分类、PyTorch、ResNet、图像识别、深度学习”,不是标签堆砌,而是整套方案的骨架:PyTorch是它的呼吸系统——轻量、可调试、便于教学;ResNet是它的脊椎——足够稳健扛住小样本波动;图像识别是它的感官——不追求像素级分割,但要一眼分清狗尾草和马唐;深度学习是它的学习方式——不是黑箱调参,而是每一步增强、每一处归一化、每一次梯度裁剪,都留有注释和替换接口。它面向两类人:一类是刚学完《动手学深度学习》第5章的在校生,你不需要懂反向传播的数学推导,只要会改num_classes=10、会运行python train.py,就能看到loss曲线从8.2一路跌到0.17;另一类是农业合作社的技术员,你可能没写过一行PyTorch,但只要把新拍的50张草莓苗照片放进train/new_strawberry/文件夹,改两行路径,就能让模型在3小时内学会区分健康苗与黄化苗。这不是玩具,是我在绍兴基地实测过——用一台i5-8265U+GTX1050Ti的旧笔记本,训练24小时后,对田间随机抓拍的蒲公英识别准确率达91.3%,误判最多的是把它当成同科的苦荬菜,而这恰恰是农业专家最关心的“近缘种混淆”问题。下面,我就按真实项目推进顺序,带你一层层拆开这个包:从数据怎么长成标准模样,到模型为何选ResNet18而非50,再到训练时那些藏在日志背后的“心跳信号”。

2. 数据不是原料,是土壤——10类植物图像的采集逻辑与预处理哲学

2.1 为什么是这10类?不是更多,也不是更少

很多人拿到数据集第一反应是数类别数:“哦,10类,比CIFAR-10多一类”。但农业场景里,类别选择从来不是凑整数。我们最终锁定的10类,是基于华东地区农田、林缘、城市绿地三大典型生境的实地踏查结果:

  • 蒲公英(Taraxacum officinale):入侵性强,常与作物争肥,叶片形态变异大(莲座状/羽裂状),是检验模型鲁棒性的“压力测试项”;
  • 三叶草(Trifolium repens):低矮匍匐,易被遮挡,叶片常沾泥水,考验模型对局部特征的捕捉能力;
  • 向日葵(Helianthus annuus):花盘巨大,纹理丰富,但田间常因逆光导致花心过曝,是光照鲁棒性关键样本;
  • 狗尾草(Setaria viridis):禾本科杂草代表,穗状花序细长,与马唐、稗草形态接近,构成“混淆组A”;
  • 马唐(Digitaria sanguinalis):同为禾本科,但叶片更宽、叶脉更凸,与狗尾草并列训练,强制模型学习细微差异;
  • 车前草(Plantago asiatica):基生叶呈莲座状,叶脉放射状明显,但雨后叶片反光严重,是图像增强重点对象;
  • 酢浆草(Oxalis corniculata):三小叶+黄色小花,但野外常与白车轴草混淆,构成“混淆组B”;
  • 白车轴草(Trifolium repens):注意,它和前面的“三叶草”是同一物种(中文俗名混用),此处特指人工草坪中修剪整齐的个体,与野外蓬乱形态形成对比,训练模型理解“同一物种不同生长状态”;
  • 紫云英(Astragalus sinicus):豆科绿肥作物,蝶形花冠,但花期短、花色易受土壤pH影响偏粉或偏紫,考验色彩恒常性;
  • 荠菜(Capsella bursa-pastoris):十字花科,总状花序+倒三角形角果,是早春田埂标志性物种,但幼苗期与蔊菜极似,构成“混淆组C”。

提示:你可能会问“为什么不加水稻、小麦?”——因为它们在苗期形态高度一致,单靠RGB图像无法可靠区分,必须引入近红外或多光谱信息。本项目坚持纯RGB输入,所以主动排除这类“光学不可分”物种。这是农业AI落地的第一课:不为技术而技术,先定义问题边界

2.2 图像采集的“非标准化”实践:如何让数据拒绝“图库感”

标准数据集常要求白底、正视角、无遮挡。但真实农田里,你永远拍不到这样的图。我们的采集规则故意反其道而行:

  • 背景不做清除:所有图像保留原始背景——泥土、碎石、其他植物叶片、甚至农具阴影。模型必须学会在复杂背景下定位目标;
  • 角度不限制:俯拍(无人机视角)、平视(人眼高度)、仰拍(从地面仰拍茎秆)、斜侧(模拟行走中抓拍)全部收录;
  • 光照不控制:正午强光(叶片反光)、清晨薄雾(轮廓模糊)、阴天散射光(色彩饱和度低)、傍晚暖光(色温偏移)各占约25%;
  • 状态全覆盖:幼苗期(<5cm高)、生长期(叶片舒展)、开花期(花序可见)、结籽期(果实/种子清晰)均按比例采样。

最终每个类别收集原始图像1200~1500张,经人工初筛剔除严重模糊、完全遮挡、非目标物种误入等样本后,剩余约1100张/类。这不是为了凑数量,而是确保模型见过“植物在真实世界中的所有狼狈样子”。

2.3 预处理流水线:从raw图到tensor的七步淬炼

dataset.py里的PlantDataset类不是简单调用torchvision.transforms,而是按农业图像特性定制的七步流水线。我逐行解释设计意图:

# 步骤1:随机旋转±15° —— 模拟手持拍摄抖动,防止模型对绝对方向过拟合 transforms.RandomRotation(degrees=15, fill=(128, 128, 128)), # 步骤2:随机水平翻转 —— 农田无左右之分,但需防止单侧特征依赖 transforms.RandomHorizontalFlip(p=0.5), # 步骤3:随机垂直翻转(p=0.1)—— 虽然植物有上下,但田埂边倒伏植株常见,低概率触发增强真实性 transforms.RandomVerticalFlip(p=0.1), # 步骤4:颜色扰动(核心!)—— 农业图像最大噪声源是光照色温漂移 transforms.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.1), # 步骤5:高斯模糊(半径0.5~1.5px)—— 模拟低端摄像头或运动模糊,提升泛化力 transforms.GaussianBlur(kernel_size=(3, 3), sigma=(0.5, 1.5)), # 步骤6:随机擦除(RandomErasing)—— 模拟叶片被虫蛀、泥点溅射、镜头污渍等局部遮挡 transforms.RandomErasing(p=0.3, scale=(0.02, 0.2), ratio=(0.3, 3.3), value='random'), # 步骤7:归一化 —— 关键!不用ImageNet均值,而用本数据集统计值: # mean=[0.423, 0.491, 0.352], std=[0.245, 0.252, 0.221] # (计算过程:遍历全部train图像,按通道求均值/标准差,非粗暴套用[0.485,0.456,0.406])

注意:ColorJitterhue=0.1是刻意压低的。植物色素化学性质稳定,色相偏移过大(如设为0.5)会导致蒲公英黄花变紫,违背生物学常识。所有增强参数都经过绍兴基地实拍图回测——当增强后图像仍能被农技员肉眼认出物种,才算合格。

2.4 数据集划分的“生态学逻辑”:为何val集不随机切分

常规做法是train_test_split(random_state=42)。但我们采用按采集日期分层划分:2023年4月、5月、6月采集的图像全归入train;7月、8月(高温高湿期)采集的归入val。理由很实在:农业模型最大的失效风险不是精度不够,而是季节迁移失效。7-8月叶片更厚、蜡质层更重、虫害斑点多,如果val集混入春季图像,模型可能在真实夏季部署时准确率暴跌20%以上。实测显示,按时间划分的val集上,模型准确率比随机划分低3.2%,但这恰恰暴露了模型在高温场景下的弱点——比如对车前草叶面反光的误判率上升,这正是我们需要针对性增强的方向。

3. 模型不是黑箱,是可拆卸的农机——ResNet18的农业适配改造

3.1 为什么选ResNet18?放弃ResNet50的三个硬理由

看到resnet.py里实现的是ResNet18而非更“高级”的50或101,新手常疑惑:“是不是作者偷懒?” 实际上,这是在绍兴基地用三台不同配置设备实测27轮后的理性选择:

对比维度ResNet18ResNet50农业场景权重
单epoch训练耗时(GTX1050Ti)42秒118秒★★★★★(边缘设备算力有限)
内存占用(batch=32)2.1GB4.8GB★★★★☆(旧笔记本常仅8GB内存)
小样本收敛速度(1100张/类)第12epoch达90% val_acc第28epoch达90% val_acc★★★★☆(快速验证需求迫切)
近缘种区分能力(狗尾草vs马唐)混淆矩阵显示差异特征激活更强更多关注全局纹理,局部差异弱化★★★☆☆(农业更重细粒度)
模型体积(.pth文件)44MB98MB★★★☆☆(田间平板部署需精简)

结论很清晰:ResNet18不是妥协,而是精准匹配。它像一台小型旋耕机——功率不如大型拖拉机,但在狭窄田埂、温室苗床、手持终端上,反而更灵活、更省油、更易维护。resnet.py里所有改动都围绕这个定位:

  • 移除了ResNet50中冗余的bottleneck结构,保持basic block的简洁性;
  • conv1卷积核从7×7改为5×5——农田图像目标通常占据画面较大比例,无需大感受野捕获超远距离关联;
  • maxpool层后增加nn.Dropout2d(p=0.1)——抑制因叶片纹理相似导致的通道过拟合;
  • 全连接层前插入nn.AdaptiveAvgPool2d((4, 4))——强制模型学习更紧凑的空间特征表示,减少对图像尺寸的敏感性。

3.2 resnet.py的“农业友好”代码细节解析

打开resnet.py,你会看到几个不起眼但关键的修改:

class ResNet18(nn.Module): def __init__(self, num_classes=10, dropout_p=0.1): super().__init__() # ... 标准ResNet18 backbone初始化 ... # 【关键改造1】:替换原始fc层,加入Dropout和ReLU self.classifier = nn.Sequential( nn.Dropout(p=dropout_p), # 防止全连接层过拟合 nn.Linear(512, 128), # 先降维到128,避免高维稀疏 nn.ReLU(inplace=True), # 引入非线性,增强判别力 nn.Dropout(p=dropout_p/2), # 后续层Dropout减半,渐进式正则 nn.Linear(128, num_classes) # 最终输出10类 ) # 【关键改造2】:自定义初始化,针对农业图像特点 for m in self.classifier.modules(): if isinstance(m, nn.Linear): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') nn.init.constant_(m.bias, 0) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = torch.flatten(x, 1) # 【关键改造3】:添加特征可视化钩子(调试用,训练时注释掉) # self.features = x.detach().cpu().numpy() # 可导出中间特征分析混淆原因 x = self.classifier(x) return x

实操心得:classifier里先降维到128再输出,是解决农业图像“类内差异大、类间差异小”的妙招。比如蒲公英幼苗和开花期叶片纹理天差地别,但128维空间能更好聚合同一物种的不同状态表征。我在调试时发现,去掉这层降维,模型对蒲公英的召回率会下降5.7%,因为它总把开花期蒲公英错判为向日葵(两者花盘纹理相似)。

3.3 骨干网络替换指南:一行代码切换VGG/EfficientNet

train.py里模型加载逻辑设计为工厂模式:

# 在train.py开头定义 MODEL_REGISTRY = { 'resnet18': lambda nc: resnet.ResNet18(num_classes=nc), 'vgg11': lambda nc: vgg.vgg11(num_classes=nc), 'efficientnet_b0': lambda nc: efficientnet.efficientnet_b0(num_classes=nc) } # 训练主函数中 model = MODEL_REGISTRY[args.model_name](num_classes=10)

要切换模型,只需改train.py中这一行:

# 原始命令 python train.py --model_name resnet18 # 改为VGG11(适合教学演示,结构透明) python train.py --model_name vgg11 # 或EfficientNet-B0(精度更高,但需升级PyTorch>=1.7) python train.py --model_name efficientnet_b0

注意:vgg.pyefficientnet.py已预置在包中,但未默认启用。这是因为VGG参数量大(138M)、训练慢;EfficientNet虽高效,但对小样本泛化不如ResNet稳定。我们把选择权交给你,但附上实测建议:入门用ResNet18,教学拆解用VGG11,追求精度上限且有GPU资源时再试EfficientNet

4. 训练不是跑通就行,是读懂模型的“呼吸节奏”——train.py全流程深挖

4.1 训练脚本的四大核心模块设计哲学

train.py表面是300行代码,实则封装了四个精密协作的模块:

  • 数据流模块get_dataloaders()——不只是加载图像,而是动态调整batch_size:当检测到GPU显存紧张时,自动从32降至16,避免OOM中断;
  • 优化器模块get_optimizer()——采用分层学习率:backbone层用1e-4,classifier层用1e-3,让新任务头部快速收敛,骨干微调更稳;
  • 调度器模块get_scheduler()——使用OneCycleLR而非StepLR:在总epoch的30%阶段线性升lr至峰值,后70%阶段余弦退火。实测比StepLR快收敛5个epoch,且val_acc峰值高0.8%;
  • 检查点模块save_checkpoint()——不仅保存最佳模型,还打包当前args配置、train_losses历史、val_accuracies序列,确保结果100%可复现。

4.2 关键超参选择背后的“田间实验报告”

train.py默认参数不是随意设定,而是基于27组对照实验的最优解:

超参数默认值选择依据实测对比(vs 其他值)
batch_size32GTX1050Ti显存极限(2.1GB),更大则OOM;更小则梯度噪声大,收敛慢bs=16:loss震荡大,acc峰值低1.2%
lr(classifier)1e-3classifier层从零学习,需较高lr;backbone微调用1e-4lr=1e-2:early overfitting,val_acc第8epoch即下降
weight_decay1e-4平衡正则强度:太小(1e-5)近缘种混淆率↑;太大(1e-3)导致欠拟合wd=1e-3:蒲公英→苦荬菜误判率↑12%
num_epochs50ResNet18在本数据集上,50epoch后val_acc曲线完全平缓,继续训练无增益epoch=30:未达收敛,acc低2.1%;epoch=80:过拟合风险↑

提示:train.py中所有超参都支持命令行覆盖,例如:
bash python train.py --lr 0.001 --weight_decay 0.0001 --num_epochs 60
但建议新手先用默认值跑通,再根据自己的val曲线微调——比如你的val_acc在40epoch后停滞,说明可能需要增大weight_decay;如果train_loss持续下降但val_acc不升,可能是lr太大导致震荡。

4.3 日志系统的“农业诊断学”:如何从loss/acc曲线读出问题

train.py内置的日志不仅打印数字,更提供诊断线索。观察logs/train_log.txt中的典型片段:

Epoch [1/50] Train Loss: 2.1452 Acc: 42.3% | Val Loss: 1.8921 Acc: 48.7% Epoch [2/50] Train Loss: 1.7823 Acc: 51.6% | Val Loss: 1.6204 Acc: 56.2% ... Epoch [25/50] Train Loss: 0.4218 Acc: 87.3% | Val Loss: 0.5127 Acc: 85.1% Epoch [26/50] Train Loss: 0.3982 Acc: 88.5% | Val Loss: 0.5389 Acc: 84.2% ← 注意!val_acc↓

当出现Val Loss ↑ & Val Acc ↓组合(如第26epoch),这是过拟合早期信号。此时train.py会自动触发:
- 降低学习率(乘以0.5);
- 增加Dropout率(dropout_p从0.1→0.15);
- 记录该epoch的混淆矩阵(保存在logs/confusion_epoch26.npy)。

打开混淆矩阵,你会发现:蒲公英误判为苦荬菜的数量从3个飙升到11个。这提示你——需要加强蒲公英与苦荬菜的对比学习。解决方案很简单:在dataset.py中,为这两个类别添加mixup增强(已预留接口,取消注释即可)。

4.4 断点续训与最佳模型保存的工业级实现

train.py的检查点管理远超基础功能:

  • 断点续训:运行python train.py --resume logs/checkpoint_epoch32.pth,自动加载:
  • 模型权重与优化器状态;
  • 当前epoch计数(接着33开始);
  • 学习率调度器步数;
  • train_lossesval_accuracies历史列表(保证曲线连续);
  • 最佳模型保存:不仅保存最高val_acc模型,还保存:
  • best_model_acc.pth:最高准确率模型;
  • best_model_f1.pth:最高F1-score模型(对近缘种更重要);
  • last_epoch.pth:最后一轮完整模型(用于继续训练);
  • 模型压缩:训练结束时自动运行torch.quantization.quantize_dynamic(),生成best_model_quantized.pth,体积缩小40%,推理速度提升2.3倍,专为树莓派等边缘设备准备。

实操心得:在绍兴基地,我们曾因雷击导致训练中断。得益于断点续训,32epoch后恢复仅耗时17分钟(重新加载权重+校验数据),而从头训练需12小时。工业级健壮性,不是锦上添花,而是生存必需

5. 推理不是终点,是下一次播种的起点——部署前的实战校验与避坑指南

5.1 inference.py:三行代码完成田间推理

inference.py设计极度简化,只为一个目标:让农技员也能操作。

# 1. 加载训练好的模型(自动适配CPU/GPU) model = torch.load('logs/best_model_acc.pth', map_location='cpu') model.eval() # 2. 加载单张图像并预处理(复用dataset.py中的val_transform) img = Image.open('field_photos/dandelion_001.jpg') img_tensor = val_transform(img).unsqueeze(0) # 添加batch维度 # 3. 推理并输出结果 with torch.no_grad(): output = model(img_tensor) probs = torch.nn.functional.softmax(output, dim=1) pred_class = torch.argmax(probs, dim=1).item() confidence = probs[0][pred_class].item() print(f"预测类别: {CLASS_NAMES[pred_class]} (置信度: {confidence:.3f})")

运行命令:

python inference.py --image_path field_photos/dandelion_001.jpg --model_path logs/best_model_acc.pth

输出:

预测类别: 蒲公英 (置信度: 0.927)

注意:CLASS_NAMES列表严格按train/文件夹子目录顺序排列,确保索引0对应蒲公英、1对应三叶草……这避免了因文件系统排序差异导致的类别错位。已在Ubuntu/Windows/macOS三平台验证。

5.2 常见问题排查速查表:那些让你抓狂的“田间Bug”

问题现象根本原因解决方案
RuntimeError: CUDA out of memoryGPU显存不足(常见于batch_size=32时加载大图)① 降低--batch_size至16;② 在dataset.py中将resize尺寸从256×256改为224×224;③ 使用--device cpu强制CPU推理
ValueError: Expected more than 1 value per channelBatchNorm层在batch_size=1时失效(单图推理常见)inference.py中,将model.eval()后添加:model.apply(lambda m: setattr(m, 'training', False) if isinstance(m, nn.BatchNorm2d) else None)
ModuleNotFoundError: No module named 'efficientnet'尝试运行EfficientNet但未安装依赖执行pip install efficientnet-pytorch;或改用已预装的ResNet18
val_acc stuck at ~10%(随机猜)数据集路径错误:train.pydata_dir指向空文件夹或结构不符(如缺少train/val子目录)检查目录树是否为:data_root/train/蒲公英/xxx.jpg,data_root/val/蒲公英/xxx.jpg;确保子目录名与CLASS_NAMES完全一致(中文编码无BOM)
Prediction: 蒲公英 → 苦荬菜 (conf: 0.89)近缘种混淆(二者同属菊科,叶片形态相似)① 在dataset.py中为这两个类别启用mixup;② 用logs/confusion_epochXX.npy分析误判样本,针对性采集更多区分性图像(如苦荬菜叶背有明显绒毛)

5.3 农业场景专属避坑技巧:来自绍兴基地的血泪经验

  • 技巧1:光照校准贴纸
    田间拍摄时,在画面一角固定一张标准灰卡(18%反射率)。推理前,用OpenCV自动检测灰卡区域,对整张图做白平衡校正。我们在inference.py预留了calibrate_lighting()函数接口,实测可将蒲公英在强光下的误判率从32%降至9%。

  • 技巧2:叶片遮挡模拟训练
    农技员反馈:“模型认得整株蒲公英,但认不出只露出半片叶子的”。解决方案:在dataset.py中新增LeafOcclusion增强类,用随机形状(椭圆/多边形)遮挡叶片中心区域,强制模型学习边缘特征。已集成,取消注释即可启用。

  • 技巧3:模型“抗遗忘”机制
    部署后,用户可能不断添加新类别(如新增“稻蓟马”害虫)。我们设计了增量学习接口:python train.py --incremental --new_class_dir data/new_pest/,自动冻结backbone,仅训练classifier新分支,5分钟内完成适配,不破坏原有10类识别能力。

6. 这套资源的真正价值:不在代码本身,而在它教会你如何思考农业AI

我在绍兴基地最后一天,一位老农技员指着屏幕上准确识别出的蒲公英,问我:“这玩意儿,能告诉我它是不是快开花了?” 我愣住了——原来我们精心设计的10分类,对他而言只是起点。他真正需要的,是“蒲公英发育阶段识别:幼苗/莲座/抽薹/开花/结籽”,是“同一张图里同时框出蒲公英和狗尾草并计算面积占比”,是“连续三天图像对比,判断杂草生长速率”。

这套资源的价值,从来不是让你复制粘贴跑出91.3%的准确率。它的价值在于:当你亲手把1100张蒲公英图从手机导入、用dataset.py看到增强后的效果、在train.py里调整weight_decay看到val曲线变化、用inference.py对着田埂拍照得到结果时,你已经完成了农业AI工程师的第一课——理解问题比炫技模型重要一百倍

所以,别急着改模型、换框架。先去小区花园拍50张蒲公英,按train/格式组织好;再运行一遍train.py,盯着logs/train_log.txt里每一行数字;最后,拿着inference.py的结果,去问身边懂植物的人:“它说得对吗?哪里不对?”——那个答案,才是你下一个项目的真正起点。

我至今记得绍兴基地那台旧笔记本风扇的嗡鸣声,和窗外真实的蒲公英在风里飘散的样子。技术终会迭代,但扎根真实场景的思考方式,永远是最锋利的锄头。

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

简介:直接可用的植物图像分类实战资源,基于PyTorch搭建CNN分类流程,覆盖10类日常可见植物(如蒲公英、三叶草、向日葵等)。提供完整可运行代码:train.py负责训练主逻辑,dataset.py封装图像加载与增强,resnet.py内置适配的ResNet18结构;数据按ImageFolder标准组织在train/和val/文件夹中,开箱即读;requirements.txt明确依赖版本,兼容Python 3.6+及主流PyTorch版本;训练过程自动保存最佳模型、记录loss/acc曲线,支持断点续训;推理脚本预留接口,方便后续部署测试。所有模块解耦清晰,替换骨干网络(如换成VGG或EfficientNet)只需修改一行配置;适合零基础入门图像分类,也适用于农业场景中轻量级识别需求的快速验证。


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

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

病毒暴露日概率推断:基于潜伏期分布的贝叶斯建模方法

1. 项目概述&#xff1a;从确诊日倒推感染日&#xff0c;不是猜谜&#xff0c;是概率建模“Estimating the Date of Virus Exposure, Given the Date of Diagnosis”——这个标题乍看像一道临床医学题&#xff0c;实则是一次典型的流行病学反向推断工程。它不依赖抗体滴度或病毒…

作者头像 李华
网站建设 2026/6/8 17:01:55

3分钟解决!Switch手柄连接PC完整指南:BetterJoy终极教程

3分钟解决&#xff01;Switch手柄连接PC完整指南&#xff1a;BetterJoy终极教程 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput 项目地址: https:/…

作者头像 李华
网站建设 2026/6/8 17:00:57

VMware迁移上云的十个关键关卡

将本地VMware虚拟机迁移到云端&#xff0c;不是简单的文件拷贝。虚拟机在源端运行在ESXi Hypervisor之上&#xff0c;依赖特定的虚拟硬件和驱动。目标云平台基于KVM或其它虚拟化技术&#xff0c;硬件抽象层完全不同。这意味着迁移不只是搬运数据&#xff0c;而是需要完成虚拟硬…

作者头像 李华
网站建设 2026/6/8 16:59:05

百度自然排名靠后怎么用GEO优化补救

这是企业最常遇到的困境之一&#xff1a;网站做了&#xff0c;内容发了&#xff0c;但核心关键词在百度的自然排名就是上不去——被老牌网站压着&#xff0c;被百度自家产品&#xff08;百科、知道、文库&#xff09;压着&#xff0c;被付费广告位压着。花再多精力写文章、做外…

作者头像 李华
网站建设 2026/6/8 16:59:05

从信息说明看CBCX外汇值得关注吗?

从信息说明看CBCX外汇值得关注吗&#xff1f;观察CBCX外汇这类平台&#xff0c;重点不在声量大小&#xff0c;而在基础流程是否经得起反复使用。CBCX给人的整体印象&#xff0c;是把信息说明放在比较基础的位置处理。信息说明透明&#xff0c;意味着用户能在需要时找到规则、费…

作者头像 李华