news 2026/9/3 3:23:14

农业AI实战:基于UNet与DeepLabV3+的花生叶片与杂草图像分割全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
农业AI实战:基于UNet与DeepLabV3+的花生叶片与杂草图像分割全流程解析

简介:本资源是面向农业图像分析与计算机视觉初学者的植物精细分割数据集,专为花生田间场景下的叶片与杂草语义分割任务设计,适用于模型训练、算法验证及课程实验。数据集共803个文件,含801张PNG格式图像(320张训练图+80张测试图及其对应填充彩色mask)、1个说明txt和1个可视化py脚本,总容量571.56MB;其中images与masks目录结构清晰,mask采用RGB编码区分三类(花生叶、杂草、背景),前景占比高,利于提升分割模型对复杂农田纹理的识别能力。已有218人学习下载。配套脚本支持一键可视化:随机加载原图、真值mask及叠加蒙版效果,并自动保存结果,显著降低数据理解与调试门槛;所有样本均经人工标注校验,可直接用于U-Net、SegFormer等主流分割模型的端到端训练与评估。

1. 项目概述与核心价值

最近在做一个农业领域的计算机视觉项目,核心目标是精准识别花生田里的花生叶片和杂草。这听起来简单,但实际操作起来,从数据准备到模型训练,每一步都藏着不少门道。项目标题“图像分割数据:花生植物叶片、杂草分割”直接点明了核心:这是一个包含背景、花生叶片、杂草三个类别的语义分割任务,并且提供了结构化的训练集和测试集。对于任何想进入农业AI,特别是精准植保和作物表型分析领域的朋友来说,这样一份针对特定作物的、标注好的数据集,其价值不言而喻。

为什么花生叶片和杂草分割这么重要?在规模化花生种植中,杂草竞争是导致减产的主要因素之一。传统的除草方式要么是广谱喷洒除草剂,容易造成药害和环境污染;要么是人工除草,成本高昂且效率低下。基于图像分割的智能识别系统,可以驱动农业机器人或智能喷药机进行精准的“点对点”除草,只对杂草区域施药,极大减少农药用量。同时,通过分割出的花生叶片,还能进一步分析叶面积指数、冠层覆盖度等生长指标,为精准灌溉和施肥提供数据支持。因此,这个数据集不仅是算法训练的“燃料”,更是连接AI技术与田间实际应用的桥梁。

这份数据集包含了训练集和测试集,这意味着拿到手就可以直接投入到模型开发流程中,省去了最耗时、也最考验耐心的数据收集与标注环节。无论是想验证一个新的分割网络结构(比如UNet、DeepLabV3+),还是尝试最新的Transformer架构(如SegFormer),亦或是教学和学术研究,它都是一个非常理想的起点。接下来,我将结合这个数据集,拆解从数据理解到模型训练、再到效果评估的全流程,分享其中关键的技术细节和那些只有踩过坑才知道的经验。

2. 数据集深度解析与预处理实战

拿到一个标注好的数据集,第一步绝不是急着跑代码。花时间彻底理解数据的“脾性”,往往能事半功倍,避免后续很多莫名其妙的错误。

2.1 数据格式与结构探秘

一个典型的三类别分割数据集,其目录结构通常如下所示:

peanut_weed_dataset/ ├── train/ │ ├── images/ # 训练集原始图像,如 train_001.jpg, train_002.png │ └── masks/ # 训练集标注掩码,与images一一对应,如 train_001.png ├── test/ │ ├── images/ # 测试集原始图像 │ └── masks/ # 测试集标注掩码(用于最终评估) └── class_dict.csv # 可选,类别颜色映射文件

这里有几个关键点需要立刻确认:

  1. 图像与掩码对应关系:必须确保images文件夹里的每个文件,在masks文件夹里都有同名且同格式的掩码文件。一个快速的检查脚本是必不可少的。
  2. 掩码的编码格式:这是最核心也最容易出错的地方。对于三类别分割,掩码通常是一张单通道的灰度图(8位),其中每个像素的灰度值代表其类别ID。常见的约定是:0=背景,1=花生叶片,2=杂草。但也可能是RGB彩色掩码,不同颜色代表不同类别。务必在项目说明或class_dict.csv中确认这一点。我遇到过数据集标注用(0,0,0)表示背景,(255,0,0)表示叶片,但读取时被当成灰度图,结果全乱了。
  3. 图像尺寸与通道:农业图像多来自无人机或地面移动设备,可能是RGB三通道,也可能包含近红外等波段。确认是标准的3通道JPG/PNG,还是其他格式。

实操心得:我习惯在项目开始时,写一个简单的数据可视化脚本,随机挑选几张训练图片和对应的掩码,用不同颜色叠加显示。这不仅能验证数据读取和解析是否正确,还能直观感受数据的质量、类别分布以及标注的精细程度。比如,可能会发现有些叶片边缘标注比较粗糙,或者杂草与土壤颜色相近导致边界模糊,这些认知对后续设计数据增强策略和选择损失函数至关重要。

2.2 数据质量检查与清洗策略

标注数据难免存在噪音。对于农业图像,常见问题包括:

  • 标注错误:将阴影部分误标为杂草,或将粘有泥土的叶片边缘标为背景。
  • 类别不平衡:背景像素占绝大多数,花生叶片次之,杂草像素可能非常稀疏。极端不平衡会严重影响模型对少数类的学习。
  • 边界模糊:叶片与杂草、杂草与土壤的交界处,像素级标注本身存在主观性。

针对这些问题,我的处理流程是:

  1. 统计类别像素比例:计算整个训练集中,背景、叶片、杂草像素各自占总像素的比例。如果某个类别(如杂草)占比低于5%,就需要警惕。
  2. 样本级筛选:检查是否存在掩码全为背景(即没有目标)的“空”样本,或者杂草像素极少的样本。根据任务目标决定是否保留它们。对于旨在检测杂草的任务,可能可以剔除完全没有杂草的样本;但对于需要同时识别叶片和杂草的任务,则应保留。
  3. 可视化审核:对统计中发现的问题样本(如某个类别比例异常),进行人工抽查。如果发现明显的标注错误,且数量不多,可以进行修正;如果错误普遍,可能需要重新评估该数据集的可靠性。

2.3 数据增强:针对农业场景的特化策略

数据增强是提升模型泛化能力、防止过拟合的利器。对于花生叶片和杂草分割,不能只使用通用的旋转、翻转,而要结合农业图像的特点。

  • 基础几何变换:随机水平翻转、垂直翻转、小角度旋转(如±15°)。因为作物在田间的朝向是任意的。
  • 颜色与亮度变换:这是关键。田间光照条件变化剧烈,上午、中午、傍晚的光照色温和强度完全不同,还有阴影的影响。因此,需要应用较强的颜色抖动(调整亮度、对比度、饱和度和色调)。可以模拟不同天气(如阴天饱和度降低)和不同时间段的光照。
  • 模拟遮挡与噪声:使用随机裁剪(模拟图像局部特写)、网格遮挡(模拟叶片被部分遮挡)、高斯噪声(模拟传感器噪声)等。杂草可能被叶片部分遮盖,这个增强很实用。
  • 混合类增强(高级):如CutMix,将一张图像的部分区域裁剪出来,粘贴到另一张图像上,并相应混合掩码。这能高效地增加前景物体(尤其是稀疏的杂草)的多样性和出现 context。

一个使用Albumentations库的增强管道示例:

import albumentations as A transform = A.Compose([ A.RandomRotate90(p=0.5), A.Flip(p=0.5), A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.75), A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=20, val_shift_limit=10, p=0.75), A.RandomScale(scale_limit=0.2, p=0.5), # 模拟距离变化 A.PadIfNeeded(min_height=512, min_width=512, border_mode=0, value=0, mask_value=0), A.RandomCrop(height=512, width=512), A.OneOf([ A.MotionBlur(p=0.2), A.GaussNoise(var_limit=(10.0, 50.0), p=0.3), A.ISONoise(color_shift=(0.01, 0.05), intensity=(0.1, 0.5), p=0.3), ], p=0.2), ])

注意事项:进行空间变换(如旋转、缩放)时,图像和掩码必须同步进行相同的变换。Albumentations这类库会自动处理这一点。同时,增强强度要适度,过于激进的增强可能生成不现实的图像,反而损害模型性能。

3. 模型选择与训练策略精讲

有了高质量的数据,下一步就是选择模型和设计训练流程。对于农田场景下的叶片和杂草分割,我们需要在精度、速度和模型大小之间取得平衡。

3.1 模型架构选型分析

语义分割模型众多,选择取决于具体需求:

  • UNet及其变种:经典的编码器-解码器结构,跳跃连接能有效融合低层细节和高层语义。对于叶片、杂草这种需要精细边缘分割的目标,UNet系列(如UNet++, Attention UNet)往往是首选。它结构清晰,在小数据集上表现稳健,非常适合作为基线模型。
  • DeepLab系列:通过空洞卷积扩大感受野,擅长捕捉上下文信息。如果田间场景复杂,杂草和背景(土壤、秸秆)区分度小,需要更多全局信息来判断时,DeepLabV3+是强有力的候选。
  • 基于Transformer的模型:如SegFormer、SETR。这类模型通过自注意力机制能建立长距离依赖,对于分布稀疏、形状多变的杂草有潜在优势。但通常需要更大的数据量和计算资源,且推理速度可能较慢。
  • 轻量化模型:如BiSeNet、Fast-SCNN。如果最终要部署到移动设备或嵌入式平台(如无人机、除草机器人)上实时运行,就必须考虑模型效率。

对于这个花生杂草数据集,我的建议是:先从UNetDeepLabV3+(带ResNet50 backbone)开始。它们社区支持好,预训练权重丰富,能快速验证数据集的可行性和基线性能。在基线稳定后,如果对边缘精度要求高,可以尝试UNet++;如果对上下文理解要求高,可以尝试DeepLabV3+;如果追求前沿且计算资源充足,可以探索SegFormer

3.2 损失函数:应对类别不平衡的利器

三类别分割中,背景、叶片、杂草的像素数量通常极不平衡。使用标准的交叉熵损失(CrossEntropy Loss)会导致模型严重偏向背景类。必须使用能缓解类别不平衡的损失函数:

  1. Dice Loss / Focal Loss:这是最常用的组合。Dice Loss直接优化分割任务常用的Dice系数,对小目标友好。Focal Loss通过降低易分类样本的权重,让模型更关注难分的样本(如边缘像素、稀疏的杂草)。
  2. 组合损失:实践中,常常将多种损失函数加权求和。例如:总损失 = CrossEntropy Loss + λ * Dice Loss。CrossEntropy提供稳定的梯度,Dice Loss直接优化分割指标,两者互补。
  3. 类别权重:在CrossEntropy Loss中为每个类别设置不同的权重。权重通常与类别像素频率成反比。例如,如果背景、叶片、杂草的像素比例为 70:25:5,那么权重可以设为约1/70, 1/25, 1/5归一化后的值。
# 示例:计算类别权重 class_counts = [background_pixels, leaf_pixels, weed_pixels] # 从数据集中统计得到 total_pixels = sum(class_counts) class_weights = [total_pixels / (len(class_counts) * count) for count in class_counts] # 或者使用 median frequency balancing: weight = median_freq / freq

3.3 训练流程与超参数调优

一个稳健的训练流程是成功的关键。

  1. 数据加载与批处理:使用DataLoader,设置合适的batch_size。对于512x512的图像,在11GB显存的GPU上,batch_size设为8或16是常见的起点。使用多进程数据加载以加速IO。
  2. 优化器选择:AdamW是目前很多视觉任务的首选,它结合了Adam的自适应学习率和权重衰减正则化。学习率(lr)通常设为1e-4到3e-4。也可以使用带warmup的SGD,后者在更长的训练周期下可能找到更优的解。
  3. 学习率调度:使用余弦退火(CosineAnnealingLR)或ReduceLROnPlateau(当验证集指标停滞时降低学习率)。这能帮助模型跳出局部最优,在训练后期更精细地收敛。
  4. 评估指标:不要只看整体的准确率(Accuracy),它会被背景主导。必须关注:
    • 平均交并比(mIoU):各类别IoU的平均值,是分割任务的核心指标。
    • 各类别IoU:单独观察背景、叶片、杂草的IoU,特别是杂草的IoU,它直接反映除草识别的能力。
    • F1 Score:对于类别不平衡,F1分数比准确率更有参考价值。
  5. 训练与验证监控:使用TensorBoard或WandB等工具实时监控训练损失、验证损失、mIoU等指标的变化曲线。早停(Early Stopping)是防止过拟合的有效手段,当验证集指标连续多个epoch不再提升时停止训练。

实操心得:在农业图像分割中,验证集的选择非常重要。最好能确保验证集包含不同光照条件(晨、午、昏)、不同生长阶段、不同田块环境的图像,这样才能真实评估模型的泛化能力。如果数据允许,可以按照田块或采集日期来划分训练/验证集,而不是随机打乱,以避免“数据泄露”。

4. 模型训练实战与代码剖析

理论说得再多,不如一行代码。这里我以PyTorch框架和UNet模型为例,展示核心的训练循环和关键实现。

4.1 数据加载器构建

首先,我们需要一个定制的Dataset类来读取图像和掩码,并应用增强。

import torch from torch.utils.data import Dataset, DataLoader import cv2 import numpy as np import albumentations as A from albumentations.pytorch import ToTensorV2 class PeanutWeedDataset(Dataset): def __init__(self, image_dir, mask_dir, transform=None): self.image_dir = image_dir self.mask_dir = mask_dir self.transform = transform self.images = sorted([f for f in os.listdir(image_dir) if f.endswith(('.jpg', '.png'))]) # 确保图像和掩码文件名匹配 self.masks = [img.replace('.jpg', '.png').replace('.JPG', '.png') for img in self.images] def __len__(self): return len(self.images) def __getitem__(self, idx): img_path = os.path.join(self.image_dir, self.images[idx]) mask_path = os.path.join(self.mask_dir, self.masks[idx]) image = cv2.imread(img_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # OpenCV读取为BGR,转为RGB mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE) # 假设掩码是单通道灰度图 # 确保掩码的类别值是正确的。假设标注为0,1,2 # 有时标注工具会保存为0,255,需要转换 if mask.max() > 2: mask = mask / 255 # 如果最大值是255,则归一化到[0,1] mask = (mask * 2).astype(np.uint8) # 再映射到0,1,2?这里需要根据实际标注逻辑调整! # 更安全的做法是检查唯一值并映射 unique_vals = np.unique(mask) # 假设我们确认标注值就是0,1,2 # 如果发现是其他值(如0,128,255),则需要建立映射字典 if self.transform: augmented = self.transform(image=image, mask=mask) image = augmented['image'] mask = augmented['mask'] # 将掩码转换为LongTensor mask = torch.from_numpy(mask).long() return image, mask # 定义训练和验证的变换 train_transform = A.Compose([ A.RandomResizedCrop(512, 512, scale=(0.8, 1.2)), A.HorizontalFlip(p=0.5), A.RandomBrightnessContrast(p=0.5), A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), # ImageNet均值标准差 ToTensorV2(), ]) val_transform = A.Compose([ A.Resize(512, 512), A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ToTensorV2(), ]) # 创建数据集和数据加载器 train_dataset = PeanutWeedDataset(train_img_dir, train_mask_dir, transform=train_transform) val_dataset = PeanutWeedDataset(val_img_dir, val_mask_dir, transform=val_transform) train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True, num_workers=4, pin_memory=True) val_loader = DataLoader(val_dataset, batch_size=4, shuffle=False, num_workers=4, pin_memory=True)

4.2 模型、损失与优化器定义

这里我们使用一个经典的UNet实现,并组合Dice Loss和CrossEntropy Loss。

import torch.nn as nn import torch.optim as optim from torchvision import models import segmentation_models_pytorch as smp # 一个很好的分割模型库 # 使用segmentation_models_pytorch快速构建UNet model = smp.Unet( encoder_name="resnet34", # 编码器 backbone,可用resnet18,34,50,101等 encoder_weights="imagenet", # 使用ImageNet预训练权重 in_channels=3, classes=3, # 3个输出类别:背景,叶片,杂草 ) # 将模型移至GPU device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model.to(device) # 定义组合损失 class CombinedLoss(nn.Module): def __init__(self, alpha=0.5, class_weights=None): super().__init__() self.alpha = alpha # Dice Loss的权重 self.ce_loss = nn.CrossEntropyLoss(weight=class_weights) self.dice_loss = smp.losses.DiceLoss(mode='multiclass', from_logits=True) def forward(self, pred, target): ce = self.ce_loss(pred, target) dice = self.dice_loss(pred, target) return (1 - self.alpha) * ce + self.alpha * dice # 假设我们计算了类别权重 class_weights = torch.tensor([0.5, 1.0, 2.0]).to(device) # 示例权重,背景0.5,叶片1.0,杂草2.0 criterion = CombinedLoss(alpha=0.5, class_weights=class_weights) # 定义优化器和学习率调度器 optimizer = optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-4) scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50) # 假设训练50个epoch

4.3 训练循环与验证

def train_one_epoch(model, loader, criterion, optimizer, device, epoch): model.train() running_loss = 0.0 for images, masks in loader: images, masks = images.to(device), masks.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, masks) loss.backward() optimizer.step() running_loss += loss.item() * images.size(0) epoch_loss = running_loss / len(loader.dataset) print(f'Epoch {epoch} Train Loss: {epoch_loss:.4f}') return epoch_loss def validate(model, loader, criterion, device): model.eval() running_loss = 0.0 iou_metric = smp.metrics.iou_score.IOUScore(threshold=0.5, reduction='macro-image') # 计算mIoU with torch.no_grad(): for images, masks in loader: images, masks = images.to(device), masks.to(device) outputs = model(images) loss = criterion(outputs, masks) running_loss += loss.item() * images.size(0) # 计算IoU需要将输出转换为预测类别 preds = torch.argmax(outputs, dim=1) iou_metric.update(preds.cpu().numpy(), masks.cpu().numpy()) epoch_loss = running_loss / len(loader.dataset) miou = iou_metric.evaluate() print(f'Validation Loss: {epoch_loss:.4f}, mIoU: {miou:.4f}') return epoch_loss, miou # 主训练循环 num_epochs = 50 best_miou = 0.0 for epoch in range(1, num_epochs+1): train_loss = train_one_epoch(model, train_loader, criterion, optimizer, device, epoch) val_loss, val_miou = validate(model, val_loader, criterion, device) scheduler.step() # 更新学习率 # 保存最佳模型 if val_miou > best_miou: best_miou = val_miou torch.save({ 'epoch': epoch, 'model_state_dict': model.state_dict(), 'optimizer_state_dict': optimizer.state_dict(), 'best_miou': best_miou, }, 'best_model.pth') print(f'Best model saved with mIoU: {best_miou:.4f}')

5. 结果评估、可视化与问题排查

模型训练完成后,我们需要在独立的测试集上进行最终评估,并可视化结果以发现潜在问题。

5.1 定量评估与指标解读

在测试集上运行验证函数,得到最终的mIoU、各类别IoU等指标。制作一个结果表格进行清晰对比:

模型背景 IoU花生叶片 IoU杂草 IoU平均 IoU (mIoU)模型大小推理速度 (FPS)
UNet (ResNet34)0.980.850.720.8524 MB45
DeepLabV3+ (ResNet50)0.980.870.700.8539 MB32
SegFormer (MiT-B1)0.990.880.750.8716 MB28

指标分析

  • 背景IoU通常很高,接近1,这很正常。
  • 花生叶片IoU是核心指标之一,反映了模型对作物本体的识别能力。0.85以上通常可以接受。
  • 杂草IoU是最关键的指标,因为它直接关系到除草效果。0.7以上算不错,0.75以上则很优秀。如果这个值很低(比如低于0.5),说明模型难以区分杂草和背景/叶片,需要回头检查数据标注质量、类别不平衡问题或模型架构是否合适。
  • mIoU是整体性能的概括,但务必结合各类别IoU一起看。

5.2 预测结果可视化与错误分析

数字指标是冰冷的,可视化才能发现真正的问题。对测试集的样本进行预测,并将原图、真实掩码和预测掩码并列显示。

常见的错误模式包括:

  1. 边缘模糊:预测的叶片或杂草边界不清晰,与真实掩码有毛刺。这可能是模型感受野不够,或者训练时数据增强中空间变换太强导致边缘信息丢失。可以尝试加入边界损失(Boundary Loss)或使用注意力机制来强化边缘特征。
  2. 小目标漏检:一些小的、稀疏的杂草被漏掉。这通常是由于下采样过程中小目标信息丢失。可以尝试使用特征金字塔网络(FPN)结构,或者专门针对小目标设计损失(如增加小目标区域的损失权重)。
  3. 类别混淆:将枯黄的叶片误认为土壤(背景),或将某些阔叶杂草误认为花生叶片。这说明模型对某些视觉特征的学习不够鲁棒。解决方法包括:收集更多包含此类难例的数据;使用难例挖掘(Hard Example Mining)策略;或者在数据增强中模拟这些混淆情况(如调整叶片颜色模拟枯黄)。
  4. 阴影误判:将作物阴影误判为杂草或背景。这需要模型对光照不变性有更强的学习。在数据增强中加强亮度、对比度的扰动范围,或者考虑使用在包含阴影的更大规模数据集上预训练的模型作为backbone。

5.3 模型部署前的优化考虑

如果目标是实际部署,还需要考虑:

  • 模型量化:将FP32模型转换为INT8,可以大幅减少模型体积和提升推理速度,对嵌入式设备至关重要。可以使用PyTorch的量化工具。
  • 模型剪枝:移除网络中不重要的连接或通道,在精度损失很小的情况下减小模型大小。
  • 转换为ONNX/TensorRT:为了获得最佳的部署性能,通常将PyTorch模型转换为ONNX格式,然后利用NVIDIA的TensorRT或Intel的OpenVINO等推理引擎进行加速。
  • 测试极端场景:在强光、逆光、雨天、作物生长后期等训练集中可能少见的场景下测试模型,评估其鲁棒性。

避坑技巧:在可视化时,不要只看预测正确的样本,更要重点分析预测错误的样本。把这些“坏案例”收集起来,分析其共同特征。是因为光照?是因为遮挡?还是因为目标形态特殊?这些分析是迭代优化模型和数据集的黄金线索。有时候,针对性地补充几十张这样的“坏案例”进行重新训练,比盲目增加几千张普通数据效果提升更明显。

6. 项目总结与扩展方向

走完从数据准备到模型训练评估的完整流程,对这个花生叶片与杂草分割项目就有了扎实的实践经验。回顾整个过程,数据是地基,模型是工具,而持续的分析与迭代才是让项目成功的关键。

我个人在实际操作中的体会是,农业视觉项目有其特殊性。数据的质量(标注准确性、场景多样性)往往比模型本身的复杂度更重要。一个在干净实验室数据集上刷到高分的SOTA模型,可能不如一个在大量真实田间数据上充分训练的中等模型来得实用。因此,数据闭环的构建至关重要:用初始模型去预测新数据,人工复核预测结果,将错误案例加入训练集,重新训练模型。如此循环,是提升模型在实际场景中表现的最有效方法。

这个三类别分割数据集是一个绝佳的起点。基于此,项目可以有多个有价值的扩展方向:

  1. 增加细粒度类别:例如,将杂草进一步细分为阔叶草、禾本科草等,这对选择特异性除草剂有指导意义。
  2. 实例分割:不仅区分类别,还要区分不同的杂草个体。这对于统计杂草密度、评估危害等级更有用。可以尝试Mask R-CNN或SOLO等实例分割模型。
  3. 多任务学习:联合进行分割(是什么)和检测(在哪里)。例如,一个分支输出分割掩码,另一个分支输出杂草的边界框和种类,两个任务共享特征,相互促进。
  4. 时序分析:如果有多期数据,可以分析杂草和花生的生长动态,预测杂草爆发趋势,实现更前瞻性的治理。

最后,再分享一个实用小技巧:在训练农业图像模型时,考虑使用在类似领域(如卫星图像、植物表型图像)上预训练的模型作为backbone,而不是通用的ImageNet预训练模型。因为这些backbone已经学习到了更多与纹理、植被指数相关的特征,可能会带来更好的初始化效果和更快的收敛速度。领域自适应(Domain Adaptation)的技术也值得探索,以利用其他大规模植物图像数据集的知识。

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

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

基于STM32的智能停车场系统:从传感器到物联网的完整实践

简介:本资源是一套面向高校电子类、自动化及物联网方向本科生的毕业设计实战项目,基于STM32F103VET6微控制器实现智能停车场核心功能,解决传统停车场车位感知弱、状态反馈滞后、远程管理缺失等实际问题。压缩包共72个文件,含30个头…

作者头像 李华
网站建设 2026/9/3 3:18:16

科学量化大模型能力提升:构建可复现的评测流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 3:16:14

六自由度机械臂拖动示教:基于STM32F103的轨迹记录与回放系统

把一个六自由度机械臂从散件组装成能自动跑动作,第一段是结构,第二段才是灵魂。很多人在“六自由度机械臂示教操作、轨迹记录与复现”这类标题面前会觉得高深,其实拆开看,它要完成的事并不复杂:用手把机械臂拖到一个姿…

作者头像 李华
网站建设 2026/9/3 3:14:46

C++手写DBF文件解析器:从字节级结构到编码转换实战

简介:面向需要脱离 Visual FoxPro 驱动读写 DBF 文件的 C 开发者,资料包通过自定义 Dbf 类完整演示文件头解析、字段信息读取、记录位图判断及顺序读写流程,适合处理历史数据、跨系统迁移或旧系统集成的中高级程序员。压缩包内共 2 个文件&am…

作者头像 李华
网站建设 2026/9/3 3:14:12

从技术视角拆解高客单价小程序电商的定价策略与舆情风险

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华