YOLOv8改進 | 2023主干篇 | EfficientViT替換Backbone(高效的視覺變換網絡)

一、本文介紹

本文給大家帶來的改進機制是EfficientViT(高效的視覺變換網絡),EfficientViT的核心是一種輕量級的多尺度線性注意力模塊,能夠在只使用硬件高效操作的情況下實現全局感受野和多尺度學習。本文帶來是2023年的最新版本的EfficientViT網絡結構,論文題目是'EfficientViT: Multi-Scale Linear Attention for High-Resolution Dense Prediction'這個版本的模型結構(這點大家需要注意以下)。同時本文通過介紹其模型原理,然后手把手教你添加到網絡結構中去,最后提供我完美運行的記錄,如果大家運行過程中的有任何問題,都可以評論區留言,我都會進行回復。親測在小目標檢測和大尺度目標檢測的數據集上都有大幅度的漲點效果(mAP直接漲了大概有0.1左右)

推薦指數:?????

漲點效果:?????

專欄回顧:YOLOv8改進系列專欄——本專欄持續復習各種頂會內容——科研必備????

訓練結果對比圖->??

這次試驗我用的數據集大概有七八百張照片訓練了150個epochs,雖然沒有完全擬合但是效果有很高的漲點幅度,所以大家可以進行嘗試畢竟不同的數據集上效果也可能差很多,同時我在后面給了多種yaml文件大家可以分別進行實驗來檢驗效果。

可以看到這個漲點幅度mAP直接漲了大概有0.1左右。

目錄

一、本文介紹

二、EfficientViT模型原理

2.1??EfficientViT的基本原理

2.2?多尺度線性注意力機制

2.3?輕量級和硬件高效操作

2.4?顯著的性能提升和速度加快

三、EfficienViT的完整代碼

四、手把手叫你天EfficienViT網絡結構

修改一

修改二

修改三?

修改四

修改五?

修改六?

修改七

五、EfficientViT2023yaml文件

六、成功運行記錄?

七、本文總結


二、EfficientViT模型原理

論文地址:官方論文地址

代碼地址:官方代碼地址

?


2.1??EfficientViT的基本原理

EfficientViT是一種高效的視覺變換網絡,專為處理高分辨率圖像而設計。它通過創新的多尺度線性注意力機制來提高模型的性能,同時減少計算成本。這種模型優化了注意力機制,使其更適合于硬件實現,能夠在多種硬件平臺上,包括移動CPU、邊緣GPU和云GPU上實現快速的圖像處理。相比于傳統的高分辨率密集預測模型,EfficientViT在保持高性能的同時,大幅提高了計算效率。

我們可以將EfficientViT的基本原理概括為以下幾點:

1. 多尺度線性注意力機制:EfficientViT采用了一種新型的多尺度線性注意力機制,這種方法旨在提高模型處理高分辨率圖像時的效率和效果。

2. 輕量級和硬件高效操作:與傳統的高分辨率密集預測模型不同,EfficientViT通過輕量級和硬件高效的操作來實現全局感受野和多尺度學習,這有助于降低計算成本。

3. 顯著的性能提升和速度加快:在多種硬件平臺上,包括移動CPU、邊緣GPU和云GPU,EfficientViT實現了相比之前的模型顯著的性能提升和加速。


2.2?多尺度線性注意力機制

多尺度線性注意力機制是一種輕量級的注意力模塊,用于提高處理高分辨率圖像時的效率。它旨在通過簡化的操作來實現全局感受野和多尺度學習,這對于高分辨率密集預測尤其重要。這種注意力機制在保持硬件效率的同時,能夠有效捕獲長距離依賴關系,是高分辨率視覺識別任務的理想選擇。

下圖展示了EfficientViT的構建模塊,左側是EfficientViT的基本構建塊,包括多尺度線性注意力模塊和帶有深度卷積的前饋網絡(FFN+DWConv)。右側詳細展示了多尺度線性注意力,它通過聚合鄰近令牌來獲得多尺度的Q/K/V令牌。

?

在通過線性投影層得到Q/K/V令牌之后,使用輕量級的小核卷積生成多尺度令牌,然后通過ReLU線性注意力對這些多尺度令牌進行處理。最后,這些輸出被聯合起來,送入最終的線性投影層以進行特征融合。這種設計旨在以計算和存儲效率高的方式捕獲上下文信息和局部信息。


2.3?輕量級和硬件高效操作

EfficientViT中的輕量級和硬件高效操作主要指的是在模型中采用了簡化的注意力機制和卷積操作,這些設計使得EfficientViT能夠在各種硬件平臺上高效運行。具體來說,模型通過使用多尺度線性注意力和深度卷積的前饋網絡,以及在注意力模塊中避免使用計算成本高的Softmax函數,實現了既保持模型性能又顯著減少計算復雜性的目標。這些操作包括使用多尺度線性注意力機制來替代傳統的Softmax注意力,以及采用深度可分離卷積(Depthwise Convolution)來減少參數和計算量。

下圖為大家展示的是EfficientViT的宏觀架構:

?

EfficientViT的宏觀架構包括一個標準的后端骨干網絡和頭部/編碼器-解碼器設計。EfficientViT模塊被插入到骨干網絡的第三和第四階段。這種設計遵循了常見的做法,即將來自最后三個階段(P2, P3, 和 P4)的特征送入頭部,并采用加法來融合這些特征,以簡化和提高效率。頭部設計簡單,由幾個MBConv塊和輸出層組成。在這個框架中,EfficientViT通過提供一種新的輕量級多尺度注意力機制,能夠高效處理高分辨率的圖像,同時保持對不同硬件平臺的適應性。


2.4?顯著的性能提升和速度加快

顯著性能提升和速度加快主要是指模型在各種硬件平臺上,相對于以前的模型,在圖像處理任務中表現出了更好的效率和速度。這得益于EfficientViT在設計上的優化,如多尺度線性注意力和深度可分離卷積等。這些改進使得模型在處理高分辨率任務時,如城市景觀(Cityscapes)數據集,能夠在保持性能的同時大幅減少計算延遲。在某些應用中,EfficientViT與現有最先進模型相比,提供了多達數倍的GPU延遲降低,這些優化使其在資源受限的設備上具有很高的實用性。

三、EfficienViT的完整代碼

import torch.nn as nn
import torch
from inspect import signature
from timm.models.efficientvit_mit import val2tuple, ResidualBlock
from torch.cuda.amp import autocast
import torch.nn.functional as Fclass LayerNorm2d(nn.LayerNorm):def forward(self, x: torch.Tensor) -> torch.Tensor:out = x - torch.mean(x, dim=1, keepdim=True)out = out / torch.sqrt(torch.square(out).mean(dim=1, keepdim=True) + self.eps)if self.elementwise_affine:out = out * self.weight.view(1, -1, 1, 1) + self.bias.view(1, -1, 1, 1)return outREGISTERED_NORM_DICT: dict[str, type] = {"bn2d": nn.BatchNorm2d,"ln": nn.LayerNorm,"ln2d": LayerNorm2d,
}# register activation function here
REGISTERED_ACT_DICT: dict[str, type] = {"relu": nn.ReLU,"relu6": nn.ReLU6,"hswish": nn.Hardswish,"silu": nn.SiLU,
}class FusedMBConv(nn.Module):def __init__(self,in_channels: int,out_channels: int,kernel_size=3,stride=1,mid_channels=None,expand_ratio=6,groups=1,use_bias=False,norm=("bn2d", "bn2d"),act_func=("relu6", None),):super().__init__()use_bias = val2tuple(use_bias, 2)norm = val2tuple(norm, 2)act_func = val2tuple(act_func, 2)mid_channels = mid_channels or round(in_channels * expand_ratio)self.spatial_conv = ConvLayer(in_channels,mid_channels,kernel_size,stride,groups=groups,use_bias=use_bias[0],norm=norm[0],act_func=act_func[0],)self.point_conv = ConvLayer(mid_channels,out_channels,1,use_bias=use_bias[1],norm=norm[1],act_func=act_func[1],)def forward(self, x: torch.Tensor) -> torch.Tensor:x = self.spatial_conv(x)x = self.point_conv(x)return xclass DSConv(nn.Module):def __init__(self,in_channels: int,out_channels: int,kernel_size=3,stride=1,use_bias=False,norm=("bn2d", "bn2d"),act_func=("relu6", None),):super(DSConv, self).__init__()use_bias = val2tuple(use_bias, 2)norm = val2tuple(norm, 2)act_func = val2tuple(act_func, 2)self.depth_conv = ConvLayer(in_channels,in_channels,kernel_size,stride,groups=in_channels,norm=norm[0],act_func=act_func[0],use_bias=use_bias[0],)self.point_conv = ConvLayer(in_channels,out_channels,1,norm=norm[1],act_func=act_func[1],use_bias=use_bias[1],)def forward(self, x: torch.Tensor) -> torch.Tensor:x = self.depth_conv(x)x = self.point_conv(x)return xclass MBConv(nn.Module):def __init__(self,in_channels: int,out_channels: int,kernel_size=3,stride=1,mid_channels=None,expand_ratio=6,use_bias=False,norm=("bn2d", "bn2d", "bn2d"),act_func=("relu6", "relu6", None),):super(MBConv, self).__init__()use_bias = val2tuple(use_bias, 3)norm = val2tuple(norm, 3)act_func = val2tuple(act_func, 3)mid_channels = mid_channels or round(in_channels * expand_ratio)self.inverted_conv = ConvLayer(in_channels,mid_channels,1,stride=1,norm=norm[0],act_func=act_func[0],use_bias=use_bias[0],)self.depth_conv = ConvLayer(mid_channels,mid_channels,kernel_size,stride=stride,groups=mid_channels,norm=norm[1],act_func=act_func[1],use_bias=use_bias[1],)self.point_conv = ConvLayer(mid_channels,out_channels,1,norm=norm[2],act_func=act_func[2],use_bias=use_bias[2],)def forward(self, x: torch.Tensor) -> torch.Tensor:x = self.inverted_conv(x)x = self.depth_conv(x)x = self.point_conv(x)return xclass EfficientViTBlock(nn.Module):def __init__(self,in_channels: int,heads_ratio: float = 1.0,dim=32,expand_ratio: float = 4,norm="bn2d",act_func="hswish",):super(EfficientViTBlock, self).__init__()self.context_module = ResidualBlock(LiteMLA(in_channels=in_channels,out_channels=in_channels,heads_ratio=heads_ratio,dim=dim,norm=(None, norm),),IdentityLayer(),)local_module = MBConv(in_channels=in_channels,out_channels=in_channels,expand_ratio=expand_ratio,use_bias=(True, True, False),norm=(None, None, norm),act_func=(act_func, act_func, None),)self.local_module = ResidualBlock(local_module, IdentityLayer())def forward(self, x: torch.Tensor) -> torch.Tensor:x = self.context_module(x)x = self.local_module(x)return xclass ResBlock(nn.Module):def __init__(self,in_channels: int,out_channels: int,kernel_size=3,stride=1,mid_channels=None,expand_ratio=1,use_bias=False,norm=("bn2d", "bn2d"),act_func=("relu6", None),):super().__init__()use_bias = val2tuple(use_bias, 2)norm = val2tuple(norm, 2)act_func = val2tuple(act_func, 2)mid_channels = mid_channels or round(in_channels * expand_ratio)self.conv1 = ConvLayer(in_channels,mid_channels,kernel_size,stride,use_bias=use_bias[0],norm=norm[0],act_func=act_func[0],)self.conv2 = ConvLayer(mid_channels,out_channels,kernel_size,1,use_bias=use_bias[1],norm=norm[1],act_func=act_func[1],)def forward(self, x: torch.Tensor) -> torch.Tensor:x = self.conv1(x)x = self.conv2(x)return xclass LiteMLA(nn.Module):r"""Lightweight multi-scale linear attention"""def __init__(self,in_channels: int,out_channels: int,heads: int or None = None,heads_ratio: float = 1.0,dim=8,use_bias=False,norm=(None, "bn2d"),act_func=(None, None),kernel_func="relu6",scales: tuple[int, ...] = (5,),eps=1.0e-15,):super(LiteMLA, self).__init__()self.eps = epsheads = heads or int(in_channels // dim * heads_ratio)total_dim = heads * dimuse_bias = val2tuple(use_bias, 2)norm = val2tuple(norm, 2)act_func = val2tuple(act_func, 2)self.dim = dimself.qkv = ConvLayer(in_channels,3 * total_dim,1,use_bias=use_bias[0],norm=norm[0],act_func=act_func[0],)self.aggreg = nn.ModuleList([nn.Sequential(nn.Conv2d(3 * total_dim,3 * total_dim,scale,padding=get_same_padding(scale),groups=3 * total_dim,bias=use_bias[0],),nn.Conv2d(3 * total_dim, 3 * total_dim, 1, groups=3 * heads, bias=use_bias[0]),)for scale in scales])self.kernel_func = build_act(kernel_func, inplace=False)self.proj = ConvLayer(total_dim * (1 + len(scales)),out_channels,1,use_bias=use_bias[1],norm=norm[1],act_func=act_func[1],)@autocast(enabled=False)def relu_linear_att(self, qkv: torch.Tensor) -> torch.Tensor:B, _, H, W = list(qkv.size())if qkv.dtype == torch.float16:qkv = qkv.float()qkv = torch.reshape(qkv,(B,-1,3 * self.dim,H * W,),)qkv = torch.transpose(qkv, -1, -2)q, k, v = (qkv[..., 0 : self.dim],qkv[..., self.dim : 2 * self.dim],qkv[..., 2 * self.dim :],)# lightweight linear attentionq = self.kernel_func(q)k = self.kernel_func(k)# linear matmultrans_k = k.transpose(-1, -2)v = F.pad(v, (0, 1), mode="constant", value=1)kv = torch.matmul(trans_k, v)out = torch.matmul(q, kv)out = torch.clone(out)out = out[..., :-1] / (out[..., -1:] + self.eps)out = torch.transpose(out, -1, -2)out = torch.reshape(out, (B, -1, H, W))return outdef forward(self, x: torch.Tensor) -> torch.Tensor:# generate multi-scale q, k, vqkv = self.qkv(x)multi_scale_qkv = [qkv]device, types = qkv.device, qkv.dtypefor op in self.aggreg:if device.type == 'cuda' and types == torch.float32:qkv = qkv.to(torch.float16)x1 = op(qkv)multi_scale_qkv.append(x1)multi_scale_qkv = torch.cat(multi_scale_qkv, dim=1)out = self.relu_linear_att(multi_scale_qkv)out = self.proj(out)return out@staticmethoddef configure_litemla(model: nn.Module, **kwargs) -> None:eps = kwargs.get("eps", None)for m in model.modules():if isinstance(m, LiteMLA):if eps is not None:m.eps = epsdef build_kwargs_from_config(config: dict, target_func: callable) -> dict[str, any]:valid_keys = list(signature(target_func).parameters)kwargs = {}for key in config:if key in valid_keys:kwargs[key] = config[key]return kwargsdef build_norm(name="bn2d", num_features=None, **kwargs) -> nn.Module or None:if name in ["ln", "ln2d"]:kwargs["normalized_shape"] = num_featureselse:kwargs["num_features"] = num_featuresif name in REGISTERED_NORM_DICT:norm_cls = REGISTERED_NORM_DICT[name]args = build_kwargs_from_config(kwargs, norm_cls)return norm_cls(**args)else:return Nonedef get_same_padding(kernel_size: int or tuple[int, ...]) -> int or tuple[int, ...]:if isinstance(kernel_size, tuple):return tuple([get_same_padding(ks) for ks in kernel_size])else:assert kernel_size % 2 > 0, "kernel size should be odd number"return kernel_size // 2def build_act(name: str, **kwargs) -> nn.Module or None:if name in REGISTERED_ACT_DICT:act_cls = REGISTERED_ACT_DICT[name]args = build_kwargs_from_config(kwargs, act_cls)return act_cls(**args)else:return Noneclass ConvLayer(nn.Module):def __init__(self,in_channels: int,out_channels: int,kernel_size=3,stride=1,dilation=1,groups=1,use_bias=False,dropout=0,norm="bn2d",act_func="relu",):super(ConvLayer, self).__init__()padding = get_same_padding(kernel_size)padding *= dilationself.dropout = nn.Dropout2d(dropout, inplace=False) if dropout > 0 else Noneself.conv = nn.Conv2d(in_channels,out_channels,kernel_size=(kernel_size, kernel_size),stride=(stride, stride),padding=padding,dilation=(dilation, dilation),groups=groups,bias=use_bias,)self.norm = build_norm(norm, num_features=out_channels)self.act = build_act(act_func)def forward(self, x: torch.Tensor) -> torch.Tensor:if self.dropout is not None:x = self.dropout(x)device, type = x.device, x.dtypechoose = Falseif device.type == 'cuda' and type == torch.float32:x = x.to(torch.float16)choose = Truex = self.conv(x)if self.norm:x = self.norm(x)if self.act:x = self.act(x)if choose:x = x.to(torch.float16)return xclass IdentityLayer(nn.Module):def forward(self, x: torch.Tensor) -> torch.Tensor:return xclass OpSequential(nn.Module):def __init__(self, op_list: list[nn.Module or None]):super(OpSequential, self).__init__()valid_op_list = []for op in op_list:if op is not None:valid_op_list.append(op)self.op_list = nn.ModuleList(valid_op_list)def forward(self, x: torch.Tensor) -> torch.Tensor:for op in self.op_list:x = op(x)return xclass EfficientViTBackbone(nn.Module):def __init__(self,width_list: list[int],depth_list: list[int],in_channels=3,dim=32,expand_ratio=4,norm="ln2d",act_func="hswish",) -> None:super().__init__()self.width_list = []# input stemself.input_stem = [ConvLayer(in_channels=3,out_channels=width_list[0],stride=2,norm=norm,act_func=act_func,)]for _ in range(depth_list[0]):block = self.build_local_block(in_channels=width_list[0],out_channels=width_list[0],stride=1,expand_ratio=1,norm=norm,act_func=act_func,)self.input_stem.append(ResidualBlock(block, IdentityLayer()))in_channels = width_list[0]self.input_stem = OpSequential(self.input_stem)self.width_list.append(in_channels)# stagesself.stages = []for w, d in zip(width_list[1:3], depth_list[1:3]):stage = []for i in range(d):stride = 2 if i == 0 else 1block = self.build_local_block(in_channels=in_channels,out_channels=w,stride=stride,expand_ratio=expand_ratio,norm=norm,act_func=act_func,)block = ResidualBlock(block, IdentityLayer() if stride == 1 else None)stage.append(block)in_channels = wself.stages.append(OpSequential(stage))self.width_list.append(in_channels)for w, d in zip(width_list[3:], depth_list[3:]):stage = []block = self.build_local_block(in_channels=in_channels,out_channels=w,stride=2,expand_ratio=expand_ratio,norm=norm,act_func=act_func,fewer_norm=True,)stage.append(ResidualBlock(block, None))in_channels = wfor _ in range(d):stage.append(EfficientViTBlock(in_channels=in_channels,dim=dim,expand_ratio=expand_ratio,norm=norm,act_func=act_func,))self.stages.append(OpSequential(stage))self.width_list.append(in_channels)self.stages = nn.ModuleList(self.stages)@staticmethoddef build_local_block(in_channels: int,out_channels: int,stride: int,expand_ratio: float,norm: str,act_func: str,fewer_norm: bool = False,) -> nn.Module:if expand_ratio == 1:block = DSConv(in_channels=in_channels,out_channels=out_channels,stride=stride,use_bias=(True, False) if fewer_norm else False,norm=(None, norm) if fewer_norm else norm,act_func=(act_func, None),)else:block = MBConv(in_channels=in_channels,out_channels=out_channels,stride=stride,expand_ratio=expand_ratio,use_bias=(True, True, False) if fewer_norm else False,norm=(None, None, norm) if fewer_norm else norm,act_func=(act_func, act_func, None),)return blockdef forward(self, x: torch.Tensor) -> dict[str, torch.Tensor]:outputs = []for stage_id, stage in enumerate(self.stages):x = stage(x)if x.device.type == 'cuda':x = x.to(torch.float16)outputs.append(x)return outputsdef efficientvit_backbone_b0(**kwargs) -> EfficientViTBackbone:backbone = EfficientViTBackbone(width_list=[3, 16, 32, 64, 128],depth_list=[1, 2, 2, 2, 2],dim=16,**build_kwargs_from_config(kwargs, EfficientViTBackbone),)return backbonedef efficientvit_backbone_b1(**kwargs) -> EfficientViTBackbone:backbone = EfficientViTBackbone(width_list=[3, 32, 64, 128, 256],depth_list=[1, 2, 3, 3, 4],dim=16,**build_kwargs_from_config(kwargs, EfficientViTBackbone),)return backbonedef efficientvit_backbone_b2(**kwargs) -> EfficientViTBackbone:backbone = EfficientViTBackbone(width_list=[3, 48, 96, 192, 384],depth_list=[1, 3, 4, 4, 6],dim=32,**build_kwargs_from_config(kwargs, EfficientViTBackbone),)return backbonedef efficientvit_backbone_b3(**kwargs) -> EfficientViTBackbone:backbone = EfficientViTBackbone(width_list=[3, 64, 128, 256, 512],depth_list=[1, 4, 6, 6, 9],dim=32,**build_kwargs_from_config(kwargs, EfficientViTBackbone),)return backbone


四、手把手教你添加EfficienViT網絡結構

這個主干的網絡結構添加起來算是所有的改進機制里最麻煩的了,因為有一些網略結構可以用yaml文件搭建出來,有一些網絡結構其中的一些細節根本沒有辦法用yaml文件去搭建,用yaml文件去搭建會損失一些細節部分(而且一個網絡結構設計很多細節的結構修改方式都不一樣,一個一個去修改大家難免會出錯),所以這里讓網絡直接返回整個網絡,然后修改部分 yolo代碼以后就都以這種形式添加了,以后我提出的網絡模型基本上都會通過這種方式修改,我也會進行一些模型細節改進。創新出新的網絡結構大家直接拿來用就可以的。下面開始添加教程->

(同時每一個后面都有代碼,大家拿來復制粘貼替換即可,但是要看好了不要復制粘貼替換多了)


修改一

我們復制網絡結構代碼到“ultralytics/nn/modules”目錄下創建一個py文件復制粘貼進去 ,我這里起的名字是EfficientV2。


修改二

找到如下的文件"ultralytics/nn/tasks.py" 在開始的部分導入我們的模型如下圖。

from .modules.EfficientV2 import efficientvit_backbone_b0,efficientvit_backbone_b1,efficientvit_backbone_b2,efficientvit_backbone_b3


修改三?

添加如下一行代碼


修改四

找到七百多行大概把具體看圖片,按照圖片來修改就行,添加紅框內的部分,注意沒有()只是函數名。

        elif m in {efficientvit_backbone_b0, efficientvit_backbone_b1, efficientvit_backbone_b2, efficientvit_backbone_b3}:m = m()c2 = m.width_list  # 返回通道列表backbone = True


修改五?

下面的兩個紅框內都是需要改動的。?

        if isinstance(c2, list):m_ = mm_.backbone = Trueelse:m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args)  # modulet = str(m)[8:-2].replace('__main__.', '')  # module typem.np = sum(x.numel() for x in m_.parameters())  # number paramsm_.i, m_.f, m_.type = i + 4 if backbone else i, f, t  # attach index, 'from' index, type


修改六?

如下的也需要修改,全部按照我的來。

代碼如下把原先的代碼替換了即可。?

        save.extend(x % (i + 4 if backbone else i) for x in ([f] if isinstance(f, int) else f) if x != -1)  # append to savelistlayers.append(m_)if i == 0:ch = []if isinstance(c2, list):ch.extend(c2)if len(c2) != 5:ch.insert(0, 0)else:ch.append(c2)


修改七

修改七和前面的都不太一樣,需要修改前向傳播中的一個部分,?已經離開了parse_model方法了。

可以在圖片中開代碼行數,沒有離開task.py文件都是同一個文件。 同時這個部分有好幾個前向傳播都很相似,大家不要看錯了,是70多行左右的!!!,同時我后面提供了代碼,大家直接復制粘貼即可,有時間我針對這里會出一個視頻。

代碼如下->

    def _predict_once(self, x, profile=False, visualize=False):"""Perform a forward pass through the network.Args:x (torch.Tensor): The input tensor to the model.profile (bool):  Print the computation time of each layer if True, defaults to False.visualize (bool): Save the feature maps of the model if True, defaults to False.Returns:(torch.Tensor): The last output of the model."""y, dt = [], []  # outputsfor m in self.model:if m.f != -1:  # if not from previous layerx = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f]  # from earlier layersif profile:self._profile_one_layer(m, x, dt)if hasattr(m, 'backbone'):x = m(x)if len(x) != 5: # 0 - 5x.insert(0, None)for index, i in enumerate(x):if index in self.save:y.append(i)else:y.append(None)x = x[-1] # 最后一個輸出傳給下一層else:x = m(x)  # runy.append(x if m.i in self.save else None)  # save outputif visualize:feature_visualization(x, m.type, m.i, save_dir=visualize)return x

到這里就完成了修改部分,但是這里面細節很多,大家千萬要注意不要替換多余的代碼,導致報錯,也不要拉下任何一部,都會導致運行失敗,而且報錯很難排查!!!很難排查!!!?

五、EfficientViT2023yaml文件

復制如下yaml文件進行運行!!!?

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPss: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPsm: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPsl: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, efficientvit_backbone_b0, []]  # 4- [-1, 1, SPPF, [1024, 5]]  # 5# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 6- [[-1, 3], 1, Concat, [1]]  # 7 cat backbone P4- [-1, 3, C2f, [512]]  # 8- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 9- [[-1, 2], 1, Concat, [1]]  # 10 cat backbone P3- [-1, 3, C2f, [256]]  # 11 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]] # 12- [[-1, 8], 1, Concat, [1]]  # 13 cat head P4- [-1, 3, C2f, [512]]  # 14 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]] # 15- [[-1, 5], 1, Concat, [1]]  # 16 cat head P5- [-1, 3, C2f, [1024]]  # 17 (P5/32-large)- [[11, 14, 17], 1, Detect, [nc]]  # Detect(P3, P4, P5)


六、成功運行記錄?

下面是成功運行的截圖,已經完成了有1個epochs的訓練,圖片太大截不全第2個epochs了。?


七、本文總結

到此本文的正式分享內容就結束了,在這里給大家推薦我的YOLOv8改進有效漲點專欄,本專欄目前為新開的平均質量分98分,后期我會根據各種最新的前沿頂會進行論文復現,也會對一些老的改進機制進行補充,目前本專欄免費閱讀(暫時,大家盡早關注不迷路~),如果大家覺得本文幫助到你了,訂閱本專欄,關注后續更多的更新~

專欄回顧:YOLOv8改進系列專欄——本專欄持續復習各種頂會內容——科研必備

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215005.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215005.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215005.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

?sqlite3 --- SQLite 數據庫 DB-API 2.0 接口模塊?

源代碼: Lib/sqlite3/ SQLite 是一個C語言庫,它可以提供一種輕量級的基于磁盤的數據庫,這種數據庫不需要獨立的服務器進程,也允許需要使用一種非標準的 SQL 查詢語言來訪問它。一些應用程序可以使用 SQLite 作為內部數據存儲。可…

量子算力引領未來!玻色量子出席第二屆CCF量子計算大會

?8月19日至20日,中國計算機學會(CCF)主辦的第二屆CCF量子計算大會暨中國量子計算峰會(CQCC 2023)在中國合肥成功舉辦。本屆大會以“量超融合,大國算力”為主題,設有量子計算軟件、硬件、應用生…

【C++類模板對象做函數參數】

類模板實例化出的對象,向函數傳參的方式 一共有三種傳入方式: 指定傳入的類型 — 直接顯示對象的數據類型參數模板化 — 將對象中的參數變為模板進行傳遞整個類模板化 — 將這個對象類型 模板化進行傳遞 總結:比較廣泛使用的是第一種&…

計算機網絡(三)

(十一)路由算法 A、路由算法分類 動態路由和靜態路由 靜態路由:人工配制,路由信息更新慢,優先級高。這種在實際網絡中要投入成本大,準確但是可行性弱。 動態路由:路由更新快,自動…

12/11

完善對話框,點擊登錄對話框,如果賬號和密碼匹配,則彈出信息對話框,給出提示”登錄成功“,提供一個Ok按鈕,用戶點擊Ok后,關閉登錄界面,跳轉到其他界面 如果賬號和密碼不匹配&#xf…

css的Grid布局

1.簡單布局 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr; 布局樣式 column-gap: 24px; 列間距 row-gap: 24px; 行間距 } 2.排列布局 center垂直方向居中對其 end靠下對齊 3.水平方向對齊 center居中 end靠右對齊 space-between兩段對齊 4.對…

【SpringBoot】Spring Boot 單體應用升級 Spring Cloud 微服務

Spring Cloud 是在 Spring Boot 之上構建的一套微服務生態體系,包括服務發現、配置中心、限流降級、分布式事務、異步消息等,因此通過增加依賴、注解等簡單的四步即可完成 Spring Boot 應用到 Spring Cloud 升級。 Spring Boot 應用升級為 Spring Cloud…

插入排序和希爾排序

目錄 前言 一.插入排序 1.思想 2.實現 3.特點 二,希爾排序 1.思想 2,實現 3.特點 前言 排序算法是計算機科學中的基礎工具之一,對于數據處理和算法設計有著深遠的影響。了解不同排序算法的特性和適用場景,能夠幫助程序員在特定情況下選擇最合適的…

如何使用玻璃材質制作3D鉆石模型

在線工具推薦: 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時,有幾種不同的風格&#xf…

Spark與PySpark(1.概述、框架、模塊)

目錄 1.Spark 概念 2. Hadoop和Spark的對比 3. Spark特點 3.1 運行速度快 3.2 簡單易用 3.3 通用性強 3.4 可以允許運行在很多地方 4. Spark框架模塊 4.1 Spark Core 4.2 SparkSQL 4.3 SparkStreaming 4.4 MLlib 4.5 GraphX 5. Spark的運行模式 5.1 本地模式(單機) Local運行模…

初識Vue 解決vue在啟動時生成的提示

讓我為大家簡單介紹一下吧&#xff01; Vue是一套用于構建用戶界面的漸進式javaScript框架 當我們引入vue.js后 <script src"../js/vue.js"></script>我們發現&#xff0c;當我們打開網頁時&#xff0c;控制臺會出現以下內容 那我們該怎么解決呢&…

【設計模式--結構型--組合模式】

設計模式--結構型--組合模式 組合模式定義結構案例組合模式的分類優點使用場景 組合模式 定義 又稱部分整體模式&#xff0c;是用于把一組相似的對象當作一個單一的對象。組合模式依據樹型結構來組合對象&#xff0c;用來表示部分以及整體層次&#xff0c;這種類型的設計模式…

新增模板中心和系統設置模塊,支持飛書平臺對接,DataEase開源數據可視化分析平臺v2.1.0發布

這一版本的功能升級包括&#xff1a;新增模板中心&#xff0c;用戶可以通過模板中心的模板快速創建儀表板和數據大屏&#xff1b;新增“系統設置”功能模塊&#xff0c;該模塊包含系統參數、認證設置、嵌入式管理、平臺對接四個子模塊。在“系統參數”子模塊中&#xff0c;用戶…

代碼上傳的gitee平臺

1.首先我們訪問工作臺 - Gitee.com進行注冊和登錄 2.我們創建一個倉庫&#xff1a; 3.在本地創建我們的項目 在這文件夾里面我們打開git bush,執行 一下操作&#xff1a; git init &#xff1a;初始化倉庫 git status&#xff1a;檢查狀態 git add . &#xff1a;將當前文件…

ubuntu 命令行安裝 conda

安裝包地址&#xff1a; Index of / 找到對應的版本&#xff0c;右鍵點復制鏈接 wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.shbash Anaconda3-2023.09-0-Linux-x86_64.sh https://linzhji.blog.csdn.net/article/details/126530244

BERT大模型:英語NLP的里程碑

BERT的誕生與重要性 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;大模型標志著自然語言處理&#xff08;NLP&#xff09;領域的一個重要轉折點。作為首個利用掩蔽語言模型&#xff08;MLM&#xff09;在英語語言上進行預訓練的模型&…

Keepalived+Nginx實現高可用(上)

一、背景與簡介 為了服務的高可用性&#xff0c;避免單點故障問題&#xff0c;通常我們使用"冗余設計思想"進行架構設計。冗余設計思想&#xff0c;本質就是將同一個應用或者服務放置在多臺不同的服務器上[雞蛋不放在同一個籃子里]&#xff0c;這樣減少整體服務宕機的…

ACWing week 3(C語言) 725.完全數

一個整數&#xff0c;除了本身以外的其他所有約數的和如果等于該數&#xff0c;那么我們就稱這個整數為完全數。 例如&#xff0c;66 就是一個完全數&#xff0c;因為它的除了本身以外的其他約數的和為 1236 現在&#xff0c;給定你 N 個整數&#xff0c;請你依次判斷這些數是…

ESP32網絡開發實例-搭建ESP32固件遠程升級服務器

搭建ESP32固件遠程升級服務器 文章目錄 搭建ESP32固件遠程升級服務器1、ESP32設備自動升級流程2、軟件準備3、硬件準備4、代碼實現4.1 固件升級服務器代碼實現4.2 基礎固件代碼4.3 新固件代碼實現我們在前面的文章中,已經實現了OTA方式升級固件的兩種方式:在Arduino IDE 中升…

數據結構與算法-動態規劃-機器人達到指定位置方法數

機器人達到指定位置方法數 來自左程云老師書中的一道題 【題目】 假設有排成一行的 N 個位置&#xff0c;記為 1~N&#xff0c;N 一定大于或等于 2。開始時機器人在其中的 M 位置上&#xff08;M 一定是 1&#xff5e;N 中的一個&#xff09;&#xff0c;機器人可以往左走或…