背景意义

研究背景与意义

随着全球气候变化和人口增长的加剧,温室农业作为一种高效的农业生产方式,逐渐受到重视。温室能够提供一个可控的生长环境,优化作物的生长条件,提高产量和质量。然而,传统的温室管理依赖于人工监测和管理,效率低下且容易出现误差。因此,利用先进的计算机视觉技术对温室进行智能化管理,成为了当前农业科技研究的重要方向。

在这一背景下,遥感技术的应用为温室的监测和管理提供了新的可能性。通过遥感图像获取温室的实时数据,结合图像处理和深度学习技术,可以实现对温室内作物生长状态的自动化分析和监测。尤其是实例分割技术,可以精确地识别和分离出温室内的作物,进而为后续的生长分析、病虫害监测和产量预测提供数据支持。

本研究基于改进的YOLOv11模型,构建一个高效的遥感图温室实例分割系统。该系统利用3900张标注为“温室”的图像数据集,能够实现对温室内作物的精确分割与识别。通过对YOLOv11模型的改进,提升其在实例分割任务中的表现,能够有效应对温室环境中的复杂背景和光照变化,提高分割精度和实时性。

此外,本研究的成果不仅可以为温室农业的智能化管理提供技术支持,还可以为相关领域的研究提供借鉴。通过对温室实例分割的深入研究,推动计算机视觉技术在农业中的应用,助力实现农业生产的数字化和智能化转型,从而提升农业生产效率,保障粮食安全,促进可持续发展。

图片效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

数据集信息

本项目数据集信息介绍

本项目所使用的数据集以“detectron160”为主题,专门针对遥感图像中的温室实例分割任务进行设计和构建。该数据集的主要目标是为改进YOLOv11模型提供高质量的训练数据,确保其在温室检测和分割方面的性能得到显著提升。数据集中包含的类别数量为1,具体类别为“greenhouse”,这意味着所有的标注和数据均围绕温室这一特定对象展开。通过集中于单一类别,数据集能够提供更为精确和深入的特征学习,进而提升模型在特定场景下的识别能力。

在数据集的构建过程中,研究团队采用了多种遥感图像采集技术,确保数据的多样性和代表性。这些图像涵盖了不同的地理区域、气候条件以及不同生长阶段的温室,力求反映出真实世界中温室的多样性和复杂性。此外,数据集中的图像经过精细的标注,确保每个温室实例都被准确地框定和分割,从而为模型的训练提供了可靠的监督信号。

在数据预处理阶段,团队还对图像进行了标准化处理,以适应YOLOv11模型的输入要求。数据集的规模和质量将直接影响模型的训练效果,因此在数据集的选择和构建上,团队注重数据的完整性和准确性,力求为后续的模型训练和评估提供坚实的基础。通过使用“detectron160”数据集,本项目旨在实现对遥感图像中温室的高效检测与分割,为农业监测和管理提供更为智能化的解决方案。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心代码

以下是代码中最核心的部分,并附上详细的中文注释:

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Function
import pywt

创建小波滤波器
def create_wavelet_filter(wave, in_size, out_size, type=torch.float):
# 使用PyWavelets库创建小波对象
w = pywt.Wavelet(wave)

# 获取小波的分解滤波器
dec_hi = torch.tensor(w.dec_hi[::-1], dtype=type)  # 高频滤波器
dec_lo = torch.tensor(w.dec_lo[::-1], dtype=type)  # 低频滤波器

# 生成分解滤波器
dec_filters = torch.stack([
    dec_lo.unsqueeze(0) * dec_lo.unsqueeze(1),  # 低频-低频
    dec_lo.unsqueeze(0) * dec_hi.unsqueeze(1),  # 低频-高频
    dec_hi.unsqueeze(0) * dec_lo.unsqueeze(1),  # 高频-低频
    dec_hi.unsqueeze(0) * dec_hi.unsqueeze(1)   # 高频-高频
], dim=0)

# 重复滤波器以适应输入通道数
dec_filters = dec_filters[:, None].repeat(in_size, 1, 1, 1)

# 获取小波的重构滤波器
rec_hi = torch.tensor(w.rec_hi[::-1], dtype=type).flip(dims=[0])
rec_lo = torch.tensor(w.rec_lo[::-1], dtype=type).flip(dims=[0])

# 生成重构滤波器
rec_filters = torch.stack([
    rec_lo.unsqueeze(0) * rec_lo.unsqueeze(1),  # 低频-低频
    rec_lo.unsqueeze(0) * rec_hi.unsqueeze(1),  # 低频-高频
    rec_hi.unsqueeze(0) * rec_lo.unsqueeze(1),  # 高频-低频
    rec_hi.unsqueeze(0) * rec_hi.unsqueeze(1)   # 高频-高频
], dim=0)

# 重复滤波器以适应输出通道数
rec_filters = rec_filters[:, None].repeat(out_size, 1, 1, 1)

return dec_filters, rec_filters

小波变换
def wavelet_transform(x, filters):
b, c, h, w = x.shape # 获取输入的形状
pad = (filters.shape[2] // 2 - 1, filters.shape[3] // 2 - 1) # 计算填充
# 进行卷积操作,执行小波变换
x = F.conv2d(x, filters.to(x.dtype).to(x.device), stride=2, groups=c, padding=pad)
x = x.reshape(b, c, 4, h // 2, w // 2) # 重塑输出形状
return x

逆小波变换
def inverse_wavelet_transform(x, filters):
b, c, _, h_half, w_half = x.shape # 获取输入的形状
pad = (filters.shape[2] // 2 - 1, filters.shape[3] // 2 - 1) # 计算填充
x = x.reshape(b, c * 4, h_half, w_half) # 重塑输入形状
# 进行转置卷积操作,执行逆小波变换
x = F.conv_transpose2d(x, filters.to(x.dtype).to(x.device), stride=2, groups=c, padding=pad)
return x

定义小波变换的自定义函数
class WaveletTransform(Function):
@staticmethod
def forward(ctx, input, filters):
ctx.filters = filters # 保存滤波器
with torch.no_grad():
x = wavelet_transform(input, filters) # 执行小波变换
return x

@staticmethod
def backward(ctx, grad_output):
    grad = inverse_wavelet_transform(grad_output, ctx.filters)  # 执行逆小波变换
    return grad, None

定义小波卷积层
class WTConv2d(nn.Module):
def init(self, in_channels, out_channels, kernel_size=5, stride=1, bias=True, wt_levels=1, wt_type=‘db1’):
super(WTConv2d, self).init()

    assert in_channels == out_channels  # 输入通道数必须等于输出通道数

    self.in_channels = in_channels
    self.wt_levels = wt_levels
    self.stride = stride

    # 创建小波滤波器
    self.wt_filter, self.iwt_filter = create_wavelet_filter(wt_type, in_channels, in_channels, torch.float)
    self.wt_filter = nn.Parameter(self.wt_filter, requires_grad=False)  # 不需要训练的小波滤波器
    self.iwt_filter = nn.Parameter(self.iwt_filter, requires_grad=False)  # 不需要训练的逆小波滤波器
    
    # 定义小波变换和逆小波变换的应用函数
    self.wt_function = wavelet_transform_init(self.wt_filter)
    self.iwt_function = inverse_wavelet_transform_init(self.iwt_filter)

    # 基础卷积层
    self.base_conv = nn.Conv2d(in_channels, in_channels, kernel_size, padding='same', stride=1, groups=in_channels, bias=bias)
    self.base_scale = _ScaleModule([1, in_channels, 1, 1])  # 缩放模块

    # 定义小波卷积层
    self.wavelet_convs = nn.ModuleList(
        [nn.Conv2d(in_channels * 4, in_channels * 4, kernel_size, padding='same', stride=1, groups=in_channels * 4, bias=False) for _ in range(self.wt_levels)]
    )
    self.wavelet_scale = nn.ModuleList(
        [_ScaleModule([1, in_channels * 4, 1, 1], init_scale=0.1) for _ in range(self.wt_levels)]
    )

def forward(self, x):
    # 前向传播过程
    x_ll_in_levels = []  # 存储低频信息
    x_h_in_levels = []   # 存储高频信息
    shapes_in_levels = [] # 存储形状信息

    curr_x_ll = x  # 当前低频信号

    # 小波变换过程
    for i in range(self.wt_levels):
        curr_shape = curr_x_ll.shape
        shapes_in_levels.append(curr_shape)
        if (curr_shape[2] % 2 > 0) or (curr_shape[3] % 2 > 0):
            curr_pads = (0, curr_shape[3] % 2, 0, curr_shape[2] % 2)  # 处理边界情况
            curr_x_ll = F.pad(curr_x_ll, curr_pads)

        curr_x = self.wt_function(curr_x_ll)  # 执行小波变换
        curr_x_ll = curr_x[:, :, 0, :, :]  # 获取低频部分
        
        # 处理高频部分
        shape_x = curr_x.shape
        curr_x_tag = curr_x.reshape(shape_x[0], shape_x[1] * 4, shape_x[3], shape_x[4])
        curr_x_tag = self.wavelet_scale[i](self.wavelet_convs[i](curr_x_tag))
        curr_x_tag = curr_x_tag.reshape(shape_x)

        x_ll_in_levels.append(curr_x_tag[:, :, 0, :, :])  # 存储低频信息
        x_h_in_levels.append(curr_x_tag[:, :, 1:4, :, :])  # 存储高频信息

    next_x_ll = 0  # 初始化下一个低频信号

    # 逆小波变换过程
    for i in range(self.wt_levels - 1, -1, -1):
        curr_x_ll = x_ll_in_levels.pop()  # 获取当前低频信息
        curr_x_h = x_h_in_levels.pop()  # 获取当前高频信息
        curr_shape = shapes_in_levels.pop()  # 获取当前形状信息

        curr_x_ll = curr_x_ll + next_x_ll  # 组合低频信息

        curr_x = torch.cat([curr_x_ll.unsqueeze(2), curr_x_h], dim=2)  # 合并低频和高频信息
        next_x_ll = self.iwt_function(curr_x)  # 执行逆小波变换

        next_x_ll = next_x_ll[:, :, :curr_shape[2], :curr_shape[3]]  # 修剪输出

    x_tag = next_x_ll  # 获取最终输出
    assert len(x_ll_in_levels) == 0  # 确保所有低频信息都已处理
    
    x = self.base_scale(self.base_conv(x))  # 通过基础卷积层和缩放模块处理输入
    x = x + x_tag  # 添加小波变换的输出
    
    return x

定义缩放模块
class _ScaleModule(nn.Module):
def init(self, dims, init_scale=1.0):
super(_ScaleModule, self).init()
self.dims = dims
self.weight = nn.Parameter(torch.ones(*dims) * init_scale) # 初始化权重

def forward(self, x):
    return torch.mul(self.weight, x)  # 执行缩放操作

代码核心部分说明:
小波滤波器创建:create_wavelet_filter 函数生成小波变换和逆变换所需的滤波器。
小波变换和逆变换:wavelet_transform 和 inverse_wavelet_transform 函数分别执行小波变换和逆变换。
自定义函数:WaveletTransform 和 InverseWaveletTransform 类实现了小波变换的前向和反向传播。
小波卷积层:WTConv2d 类实现了一个结合小波变换的卷积层,能够在卷积过程中同时处理低频和高频信息。
缩放模块:_ScaleModule 类用于对卷积输出进行缩放,提供了可训练的缩放因子。
这个程序文件wtconv2d.py实现了一个基于小波变换的二维卷积层,主要用于深度学习中的图像处理任务。程序中使用了PyTorch库,结合了小波变换的数学原理,提供了对输入图像的多层次分析和重构。

首先,文件导入了必要的库,包括PyTorch的核心模块和功能模块,以及用于小波变换的pywt库。程序定义了几个重要的函数和类。

create_wavelet_filter函数用于创建小波变换的滤波器。它接受小波类型、输入和输出通道数,并返回用于小波分解和重构的滤波器。函数中通过pywt.Wavelet获取小波的高通和低通滤波器,并将其转换为PyTorch张量格式。

wavelet_transform和inverse_wavelet_transform函数分别实现了小波变换和逆小波变换。它们使用了PyTorch的卷积操作,将输入张量进行分解或重构。具体来说,小波变换将输入图像分解为低频和高频部分,而逆小波变换则将这些部分重构回原始图像。

接下来,定义了WaveletTransform和InverseWaveletTransform两个类,分别实现了小波变换和逆小波变换的前向和反向传播功能。这些类继承自torch.autograd.Function,允许在计算图中进行自定义的前向和反向传播操作。

wavelet_transform_init和inverse_wavelet_transform_init函数用于初始化小波变换和逆小波变换的应用函数,返回一个可以直接调用的函数。

WTConv2d类是这个文件的核心部分,继承自nn.Module,实现了一个自定义的卷积层。构造函数中,首先检查输入和输出通道数是否相等,然后初始化小波滤波器和基本卷积层。该类支持多层次的小波变换,通过wavelet_convs和wavelet_scale来处理不同层次的特征。

在forward方法中,输入数据经过小波变换和卷积操作,逐层处理并最终重构。该方法还处理了输入的填充和步幅,以确保输出的尺寸符合预期。最后,经过基本卷积层和缩放模块的处理,返回最终的输出。

_ScaleModule类是一个简单的缩放模块,用于对输入张量进行缩放操作。它通过一个可学习的参数来调整输入的权重。

整体来看,这个程序实现了一个结合小波变换的卷积层,能够有效地提取图像特征,并在深度学习模型中应用。通过小波变换,可以在不同的频率和空间尺度上分析图像,从而提高模型的表现。

10.4 metaformer.py
以下是代码中最核心的部分,并附上详细的中文注释:

import torch
import torch.nn as nn
import torch.nn.functional as F

class MF_Attention(nn.Module):
“”"
自注意力机制(Self-Attention)实现,参考Transformer论文。
“”"
def init(self, dim, head_dim=32, num_heads=None, qkv_bias=False,
attn_drop=0., proj_drop=0., proj_bias=False):
super().init()

    # 设置每个头的维度
    self.head_dim = head_dim
    # 缩放因子
    self.scale = head_dim ** -0.5

    # 计算头的数量
    self.num_heads = num_heads if num_heads else dim // head_dim
    if self.num_heads == 0:
        self.num_heads = 1
    
    # 总的注意力维度
    self.attention_dim = self.num_heads * self.head_dim

    # 定义线性层用于计算Q、K、V
    self.qkv = nn.Linear(dim, self.attention_dim * 3, bias=qkv_bias)
    # 定义注意力丢弃层
    self.attn_drop = nn.Dropout(attn_drop)
    # 定义输出的线性层
    self.proj = nn.Linear(self.attention_dim, dim, bias=proj_bias)
    # 定义输出丢弃层
    self.proj_drop = nn.Dropout(proj_drop)

def forward(self, x):
    # 获取输入的批量大小、高度、宽度和通道数
    B, H, W, C = x.shape
    N = H * W  # 计算总的序列长度

    # 计算Q、K、V
    qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)
    q, k, v = qkv.unbind(0)  # 将Q、K、V分开

    # 计算注意力得分
    attn = (q @ k.transpose(-2, -1)) * self.scale
    attn = attn.softmax(dim=-1)  # 应用softmax
    attn = self.attn_drop(attn)  # 应用丢弃

    # 计算输出
    x = (attn @ v).transpose(1, 2).reshape(B, H, W, self.attention_dim)
    x = self.proj(x)  # 投影到原始维度
    x = self.proj_drop(x)  # 应用丢弃
    return x  # 返回输出

class MetaFormerBlock(nn.Module):
“”"
MetaFormer块的实现。
“”"
def init(self, dim,
token_mixer=nn.Identity, mlp=Mlp,
norm_layer=partial(LayerNormWithoutBias, eps=1e-6),
drop=0., drop_path=0.,
layer_scale_init_value=None, res_scale_init_value=None
):
super().init()

    # 第一层归一化
    self.norm1 = norm_layer(dim)
    # 令牌混合器
    self.token_mixer = token_mixer(dim=dim, drop=drop)
    # 路径丢弃
    self.drop_path1 = DropPath(drop_path) if drop_path > 0. else nn.Identity()
    # 层缩放
    self.layer_scale1 = Scale(dim=dim, init_value=layer_scale_init_value) \
        if layer_scale_init_value else nn.Identity()
    self.res_scale1 = Scale(dim=dim, init_value=res_scale_init_value) \
        if res_scale_init_value else nn.Identity()

    # 第二层归一化
    self.norm2 = norm_layer(dim)
    # MLP
    self.mlp = mlp(dim=dim, drop=drop)
    # 路径丢弃
    self.drop_path2 = DropPath(drop_path) if drop_path > 0. else nn.Identity()
    # 层缩放
    self.layer_scale2 = Scale(dim=dim, init_value=layer_scale_init_value) \
        if layer_scale_init_value else nn.Identity()
    self.res_scale2 = Scale(dim=dim, init_value=res_scale_init_value) \
        if res_scale_init_value else nn.Identity()
    
def forward(self, x):
    # 进行维度转换
    x = x.permute(0, 2, 3, 1)
    # 第一部分的前向传播
    x = self.res_scale1(x) + \
        self.layer_scale1(
            self.drop_path1(
                self.token_mixer(self.norm1(x))
            )
        )
    # 第二部分的前向传播
    x = self.res_scale2(x) + \
        self.layer_scale2(
            self.drop_path2(
                self.mlp(self.norm2(x))
            )
        )
    return x.permute(0, 3, 1, 2)  # 返回到原始维度

代码核心部分说明:
MF_Attention类:实现了自注意力机制,包含了计算Q、K、V的线性层,注意力得分的计算,以及输出的投影。
MetaFormerBlock类:实现了MetaFormer的基本构建块,包含了归一化、令牌混合、MLP等组件,支持残差连接和路径丢弃。
这些类是构建MetaFormer模型的基础,提供了注意力机制和基本的块结构。

这个程序文件 metaformer.py 实现了一些用于构建 MetaFormer 模型的基础组件,主要包括各种层和模块的定义。以下是对文件中各个部分的详细说明。

首先,文件导入了一些必要的库,包括 torch 和 torch.nn,以及一些来自 timm 库的功能。这些库为构建深度学习模型提供了基础。

接下来,定义了一些基本的模块:

Scale 类用于按元素乘法缩放输入向量。它接受一个维度和一个初始值,创建一个可训练的参数用于缩放。

SquaredReLU 和 StarReLU 是两种激活函数的实现。SquaredReLU 计算 ReLU 的平方,而 StarReLU 则结合了缩放和偏置的 ReLU 变体。

MF_Attention 类实现了基本的自注意力机制,类似于 Transformer 中的自注意力。它通过线性变换生成查询、键和值,然后计算注意力权重并应用于值。

RandomMixing 类实现了一种随机混合机制,通过一个随机矩阵对输入进行变换。

LayerNormGeneral 和 LayerNormWithoutBias 提供了不同形式的层归一化,支持多种输入形状和可选的缩放与偏置。

SepConv 类实现了分离卷积,这是一种高效的卷积方式,常用于轻量级网络中。

Pooling 类实现了一种池化操作,特别适用于 PoolFormer 模型。

Mlp 类实现了多层感知机(MLP),包括线性层、激活函数和 dropout。

ConvolutionalGLU 类实现了一种卷积门控线性单元(GLU),结合了卷积和激活函数。

接下来,定义了两个主要的 MetaFormer 块:

MetaFormerBlock 类实现了一个标准的 MetaFormer 块,包含归一化、令牌混合、MLP 和残差连接。它使用了前面定义的组件来构建块的结构。

MetaFormerCGLUBlock 类是另一个 MetaFormer 块的实现,使用了卷积门控线性单元作为 MLP 部分,其他结构与 MetaFormerBlock 类似。

整体来看,这个文件实现了构建 MetaFormer 模型所需的多个基础组件,提供了灵活的层和模块,可以用于构建不同的网络架构。每个模块都具有良好的可扩展性和可重用性,适合用于各种深度学习任务。

源码文件

在这里插入图片描述

源码获取

欢迎大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐