尧图精选

EfficientVMamba实战:状态空间模型在图像分类中的高效应用与落地

🕒 发布时间:2026/10/2 18:09:11 📁 来源:尧图网络
简介面向图像分类任务与轻量级模型实战需求这份资源围绕EfficientVMamba_T模型提供了一套完整可运行的植物幼苗分类方案。内容涵盖数据预处理、模型搭建、训练与评估等环节适合有一定深度学习基础、希望借助视觉状态空间模型SSM提升分类精度的开发者。压缩包共2000个文件其中1992个png图片构成数据集样本5个py脚本为核心训练/推理代码另含txt与json用于类别标签和配置说明pyc为编译缓存整体约736.96MB打包结构清晰。已有1411人学习下载。通过这套材料读者可复现EfficientVMamba在植物幼苗数据集上的训练流程理解选择性扫描与有效跳跃采样如何兼顾全局和局部特征并对比其与ViM等模型的效果为后续轻量级视觉模型研究提供参考。1. EfficientVMamba 是什么当图像分类撞上状态空间模型如果你最近在折腾图像分类模型可能已经发现一个趋势大家不再只盯着 ViT 和 Swin 这类 Transformer 结构而开始关注以 Mamba 为代表的状态空间模型SSM。这类模型的核心卖点是计算复杂度随序列长度线性增长不像自注意力那样带一个二次方的开销。EfficientVMamba 正是把 Mamba 的选择性扫描机制和视觉任务结合的一条落地路线它主打“高效”目标是在 ImageNet 级别的分类任务上用更少的 FLOPs 和显存达到接近 Swin Transformer 的精度。这个标题下的实战内容几乎覆盖了从业者日常最关心的三件事第一这套模型和 ViT、CNN 的本质区别在哪为什么它能省算力第二怎么把自己的图像分类数据集喂进去真正跑通训练和验证第三换了 EfficientVMamba 之后哪些老经验会失效、哪些坑会重新冒出来。适合的人群也很明确不是来泛读论文的而是手里有图片分类需求、想找一个比 ResNet 精度更高、又比 ViT 更省资源的替代方案的工程师。下面直接进入实现细节。2. EfficientVMamba 的模型结构选择性扫描与通道设计的取舍2.1 从 Mamba 到 EfficientVMamba扫描机制到底改了什么Mamba 这类状态空间模型的原始版本是为序列建模设计的它把输入看成一条一维序列然后通过一个随时间推进的隐状态来传递信息。对应到图像上最大的问题是图像是二维的直接拉平成一条序列会丢失空间结构。第一个解决思路来自 VMamba它提出“四方向扫描”把图像分别在左上到右下、右下到左上、右上到左下、左下到右上这四个方向展开每个方向都做一次 SSM再把结果融合。这样每个位置都能感知到来自不同方向的空间上下文相当于用线性复杂度的方案换来了接近自注意力的感受野。EfficientVMamba 在这个基础上做了效率上的裁剪。我个人的理解是它把“四个方向完整扫描”做成了可配置项并且在通道维度上做降维处理避免每条扫描路径都带着全量通道跑从而减少状态空间的参数量和计算量。加上残差连接和 LayerNorm 被布置在每个 Block 的标准位置整体结构跟 ViT 的 Block 布局比较接近所以从工程角度看迁移成本不高——只要你会改 ViT 的模型代码就能很快改到 EfficientVMamba 上。从算法性质来看这套结构的复杂度是 O(N) 级别其中 N 是图像 patch 的数量。同样处理一张 224x224 的图ViT 至少要算 14x14196 个 token 之间的两两注意力也就是 196 的平方次操作EfficientVMamba 的扫描过程则只是每个 token 做常数级别的递归更新复杂度明显低一截。显存占用也跟着降下来。对于在单卡上做实验、或者部署到算力有限设备上的场景这种优势是实打实的。提示在配置模型时扫描方向的数量是个关键旋钮。方向越多空间感知越全面但耗时也越高。先保持默认值跑通再根据你的数据集大小决定要不要增加。2.2 与 ViT 和 CNN 的对比选型时看这三个指标做技术选型不能只盯着精度榜。我一般用三个维度来对比单位参数量下的精度、同 batch size 下的显存占用、对不同数据集规模的适应能力。指标ResNetCNNViTTransformerEfficientVMambaSSM长程依赖建模弱靠大核或深堆强全局自注意力强四方向扫描覆盖全局计算复杂度O(N) 但卷积核小O(N^2) 随 token 数平方增长O(N) 线性增长小数据集表现好归纳偏置强差需要预训练或强增强中等偏上有 CNN 式先验辅助推理速度快中中上工程成熟度极高高中等跳过坑能稳定用对于森林图像分类这类场景比如区分不同树种或者识别林地病害如果数据量只有几万张ViT 几乎必翻车收敛慢、泛化差普通 CNN 则精度上限有限。EfficientVMamba 是一个不错的中间态它在网络浅层保留了很多类似卷积的局部模式同时高层又能做全局建模训练起来比 ViT 稳。实际操作中你不需要自己去复现模型实现。开源社区已经有基于 PyTorch 的 EfficientVMamba 实现通常在图像分类项目的 models 目录里。拿到代码后我建议先跑通一个最简推理把模型结构打印出来看一眼因为不同版本的实现会在 Block 顺序和扫描分组上有些差异这会直接影响后面改参。3. 搭一套 EfficientVMamba 分类器数据准备与配置参数3.1 环境准备与最小推理脚本环境方面不需要太复杂的特殊依赖。PyTorch 2.x、einops、timm、tqdm、tensorboard 这几件套就够了。如果你用的是开源分类工具箱留意一下它的依赖声明通常会有 mmcv 或类似的底层库。为了少踩坑安装时优先用项目 lock 文件里锁定的版本不要图新装最新版。最小推理脚本的目的是验证权重文件和输入预处理流程是否匹配。这段代码的核心价值在于它能把“模型前向传播有没有问题”和“数据预处理对不对”两件事分开排查。import torch from PIL import Image from torchvision import transforms # 模型导入假设 models 目录里是 EfficientVMamba 的实现 # 如果是自己写的分类器把这里的 model 替换成你的模型实例即可 from models.efficient_vmamba import efficient_vmamba_tiny device cuda if torch.cuda.is_available() else cpu model efficient_vmamba_tiny(num_classes1000) # 加载预训练权重strictFalse 是为了先看结构差异 state_dict torch.load(checkpoints/efficient_vmamba_tiny.pth, map_locationcpu) model.load_state_dict(state_dict, strictFalse) model.to(device).eval() # 标准 ImageNet 预处理224x224、均值方差归一化 transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ]) img Image.open(test_sample.jpg).convert(RGB) x transform(img).unsqueeze(0).to(device) with torch.no_grad(): logits model(x) probs torch.softmax(logits, dim1) print(fTop-1 class index: {probs.argmax(dim1).item()}, confidence: {probs.max().item():.4f})这段代码里有两个关键参数说明。第一num_classes必须和预训练权重一致。用 ImageNet 权重做迁移学习时你会在后面把最后一层分类器换成自定义类别数所以这里的 1000 只是用于结构比对。第二预处理中的Resize((224, 224))做了像素级缩放如果你要兼顾细粒度分类或者小目标识别可以把分辨率提升到 384但要在后面训练时保持同一分辨率否则推理阶段会出现精度下降的“玄学”问题——其实只是输入的统计分布变了。3.2 自定义数据集加载与输入管线改造图像分类数据集的组织方式是工程上最容易被轻视的环节。我见过的做法里按类别建文件夹是最稳妥的省去写额外标注文件也方便检查资源是否缺失。训练集、验证集、测试集各建一个一级目录二级目录是类别名。import os from torch.utils.data import Dataset from PIL import Image class ImageFolderDataset(Dataset): 轻量级分类数据集读取器按子目录名识别类别。 目录结构示例: data/train/class_a/00001.jpg data/train/class_b/00002.jpg def __init__(self, root, transformNone): self.samples [] self.class_to_idx {} self.transform transform classes sorted(os.listdir(root)) # 排序保证类索引稳定 for cls_name in classes: cls_dir os.path.join(root, cls_name) if not os.path.isdir(cls_dir): continue if cls_name not in self.class_to_idx: self.class_to_idx[cls_name] len(self.class_to_idx) for img_name in os.listdir(cls_dir): if img_name.lower().endswith((.jpg, .jpeg, .png)): self.samples.append((os.path.join(cls_dir, img_name), self.class_to_idx[cls_name])) def __len__(self): return len(self.samples) def __getitem__(self, idx): path, label self.samples[idx] img Image.open(path).convert(RGB) if self.transform: img self.transform(img) return img, label这个数据集的实现对格式做了一个约定如果文件夹内混有非图片文件在__getitem__里会因为convert(RGB)而报错。所以需要注意过滤掉损坏文件比如下载数据集时夹杂的多余目录。为此我在读取文件时加了后缀过滤endswith((.jpg, .jpeg, .png))。这个写法能挡住绝大多数意外文件但挡不住重命名为.jpg的损坏文件仍然需要你在数据准备阶段做一次完整性检查。提示分类数据集下载后第一件事不是解压而是统计每个类别的图片数量。如果某些类别不到 50 张建议要么扩数据要么先放弃这个类别否则训练出来的模型在测试时会把该类样本全部归到别的类上。3.3 改造分类头把 ImageNet 权重迁移到自己的类别数上拿到预训练权重后结构里最后一项是head或者classifier它是一个线性层输入维度是特征维度输出维度是 1000。迁移到自己的任务时只需要把这一层的输出维度改成你的类别数再把该层参数丢掉。# 假设 model 内部用的是 model.head 这个名字不同实现可能叫 classifier num_features model.head.in_features model.head torch.nn.Linear(num_features, num_classes) # 重置该层权重并保持其他层使用预训练权重 torch.nn.init.trunc_normal_(model.head.weight, std0.02) torch.nn.init.zeros_(model.head.bias)修改后加载权重时要用strictFalse否则 PyTorch 会因为你改了分类头而报 key 不匹配。权重初始化上trunc_normal_是 ViT 系模型惯用的初始化方式标准差 0.02 是常见设置保持即可不需要额外调。如果你改的类别数非常少比如只有 2 类那么可以考虑把 dropout 增大一点防止分类头过拟合。4. 训练与验证的完整闭环损失、调度器与分布式4.1 标准训练主循环AMP 混合精度与 EMAEfficientVMamba 这类模型在训练时最需要重视的是显存占用和数值稳定性。AMP自动混合精度几乎是默认开启的它能把训练速度提升 30%-50%同时显存占用减少。但混精训练下 loss 偶尔会变成 NaN这个问题我在避坑章节里会展开讲这里先给出一个带 AMP 和 EMA 的完整训练循环。import torch import torch.nn as nn from torch.cuda.amp import autocast, GradScaler from timm.utils import ModelEma def train_one_epoch(model, loader, optimizer, criterion, scaler, emaNone): model.train() total_loss 0.0 for images, labels in loader: images, labels images.cuda(), labels.cuda() # 清零梯度 optimizer.zero_grad() # AMP 前向自动混合精度 with autocast(): outputs model(images) loss criterion(outputs, labels) # AMP 反向scaler 延迟缩放 scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() # EMA 更新用于最终测试的权重 if ema is not None: ema.update(model) total_loss loss.item() * images.size(0) return total_loss / len(loader.dataset)参数说明criterion建议用LabelSmoothingCrossEntropy平滑系数设 0.1。这是 ViT 系模型训练的关键参数能把单类置信度过高的问题压住。scaler是 GradScaler初期我也不理解为什么有了它 loss 还是 NaN后来才发现是某些实现里更新了学习率步长但没调用scaler.update()导致梯度尺度过期。EMA指数移动平均在训练快结束时报错的情况很常见因为验证时会加载 EMA 权重如果 EMA 未更新过验证时会出现模型参数全是零的诡异现象。4.2 训练超参数如何设定学习率、weight decay 与 warmupEfficientVMamba 的推荐训练配方跟 Swin Transformer 类似不是 ResNet 那套。如果你直接把 ResNet 的 0.1 学习率搬过来大概率第一步 loss 就飞掉。我的常用起步配方如下优化器AdamWlr1e-4weight_decay0.05批次大小32每卡如果显存允许可以调到 64warmup前 5 个 epoch 从1e-6线性升到目标 lr训练轮次300 个 epoch但在小数据集上 100 个 epoch 即可收敛学习率调度Cosine Annealing最终降到1e-6之所以用 AdamW 而不是 SGD是因为 Mamba 类模型对 SGD 不太友好。SGD 的动量机制会拖慢收敛而 AdamW 对每个参数独立调整学习率在状态空间模型的递归路径上效果明显更好。# 学习率 warmup cosine 衰减的流程表示 # 前 5 个 epoch线性上升之后cosine 降到底 optimizer torch.optim.AdamW(model.parameters(), lr1e-4, weight_decay0.05) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max300, eta_min1e-6) # warmup 需要手动处理常见做法是额外维护一个 lr 乘数 def adjust_lr(epoch, warmup_epochs5): if epoch warmup_epochs: return (epoch 1) / warmup_epochs return 1.0如果你只有一张卡且数据量在 1 万张以内不建议直接跑 300 个 epoch。太长的训练会放大数据增强带来的随机性让验证集波动变大。我一般会先跑 20 个 epoch观察 loss 下降曲线是否平滑、验证精度是否持续上升再决定完整训练的长度。这一步被称为“小周期探路”能省下大量返工时间。4.3 多卡训练用 DDP 跑通 DistributedDataParallel单卡训练没问题后多卡训练可以直接用 PyTorch 的DistributedDataParallel搭起来。EfficientVMamba 的显存占用低于同精度水平的 ViT所以多卡场景下的主要瓶颈通常是数据读入而不是显存。建议用 DDP 而不是 DataParallel原因只有一个DataParallel 在每个 step 里会同步所有 GPU 的梯度但模型参数的广播和梯度同步通信开销巨大很容易成为瓶颈。import torch.distributed as dist import torch.multiprocessing as mp from torch.nn.parallel import DistributedDataParallel def main_worker(gpu, ngpus_per_node, args): dist.init_process_group( backendnccl, init_methodtcp://127.0.0.1:23456, world_sizengpus_per_node, rankgpu, ) torch.cuda.set_device(gpu) # 构建模型后包 DDPbatch size 按卡数等比放大 model efficient_vmamba_tiny(num_classesargs.num_classes).cuda(gpu) model DistributedDataParallel(model, device_ids[gpu]) # 学习率也要同步放大常见做法是 lr * 卡数 lr args.base_lr * ngpus_per_node参数说明base_lr是单卡时的基础学习率。多卡训练时学习率线性放大的做法在 ViT 时代就开始流行了但因为 AdamW 本身有自适应学习率特性放大倍数不用太精确取 1 倍到 1.5 倍都不会有大问题。另一个细节是torch.cuda.set_device(gpu)必须要在init_process_group之后执行否则可能发生“每个进程都占用 GPU0”的错乱。4.4 数据增强策略MixUp 与小数据集上的表现对比图像分类任务中数据增强的重要性怎么强调都不过分尤其是像森林图像分类这类容易出现过拟合的中小规模数据集。常用的增强组合包括 RandomResizedCrop、RandomHorizontalFlip 和 RandAugment对 Mamba 类模型的帮助比 AutoAugment 更稳定。结合森林图像场景来说拍摄光照变化剧烈建议把 RandAugment 的强度控制在 5 到 7 之间过强会让模型把正常的林间阴影误判成特征。MixUp 和 CutMix 在 Mamba 类模型上依然有效但要注意混合比例。我试过把 mixup 的 alpha 从默认的 0.8 调到 0.2在小数据集上精度反而提升了 1.5 个百分点原因是 alpha 越大生成的样本越不像真实图像对线性扫描的模型来说难度太大。下面是 MixUp 的最小实现def mixup_criterion(criterion, pred, y_a, y_b, lam): return lam * criterion(pred, y_a) (1 - lam) * criterion(pred, y_b) def mixup_data(x, y, alpha0.2): lam torch.distributions.Beta(alpha, alpha).sample() batch_size x.size(0) index torch.randperm(batch_size).cuda() mixed_x lam * x (1 - lam) * x[index] return mixed_x, y, y[index], lam这段代码的输入是同一个 batch 的图像和标签输出是混合后的图像、原标签、打乱标签和混合系数。在训练循环里调用时模型对混合图像输出 logitsloss 按系数在两个真实标签之间加权。值得注意的一点是如果标签是平滑后的 one-hot 向量MixUp 的加权公式需要相应调整否则会出现一种矛盾总概率和大于 1。5. 避坑与排查从权重到显存5 个常见的翻车现场5.1 加载预训练权重报错key 不匹配或尺寸不兼容现象load_state_dict抛错提示size mismatch或者直接缺少某个 key。原因绝大多数情况是分类头类别数不同其次是开源实现版本和你的代码定义差异。不同版本的 EfficientVMamba 在 Block 内部预归一化方式上有所不同导致权重 key 的名字不一样。解决加载时先打印state_dict的 key 列表和模型model.state_dict()的 key 列表做差集。如果是head.weight尺寸不匹配忽略它在加载后自行替换分类头。如果差异在主干层那就说明你拿到的权重和模型实现不是同一套结构这种属于无法解决的版本冲突建议换一个实现或者重新下载对应权重。5.2 训练 loss 变成 NaN混合精度下的“经典事故”现象用 AMP 训练到第 10 个 epochloss 突然从 0.8 跳到 NaN之后无法恢复。原因最常见的是学习率过大导致某些层更新的步长过大特征值爆炸其次是某些实现里GradScaler的scale如果不小心更新到非常大也会在反向传播时溢出。解决先用纯 FP32 训练 10 个 epoch确认可以正常收敛之后再开启 AMP。如果纯 FP32 也 NaN把学习率降到原来的十分之一如果纯 FP32 正常而 AMP 才 NaN检查模型里有没有手工实现的自定义算子这类算子往往没有做梯度裁剪和数值保护建议给梯度加一个全局clip_grad_norm_。# 加一行全局梯度裁剪能救回大部分 AMP 下 loss 飞掉的问题 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm5.0)5.3 显存不够调整 batch size 后精度暴跌现象单卡显存只有 12G跑 8 batch 没问题改成 4 batch 后验证精度低了 2-3 个百分点。原因不是模型变笨了而是 BatchNorm 在 batch size 太小时统计不准。但 EfficientVMamba 本身用的是 LayerNorm按理说不存在这个问题。如果你使用的是带 BN 的实现分支那要确认这一点。解决优先使用实现里的 LayerNorm 版本。如果代码里用的是 BN通过环境变量或配置项切回 LayerNorm。另外batch size 减小后需要同步调低学习率或调长 warmup这样精度基本上能恢复到原来的水平。5.4 分类类别不平衡导致训练出现“马太效应”现象森林图像分类中健康树木样本有 5000 张得病树木样本只有 300 张训练后模型对少数类几乎全猜错。原因CrossEntropyLoss 天然偏向高频类别模型学会了输出高频类的标签就可以让 loss 降到很低。解决最简单的办法是把少数类做重复采样也就是让 DataLoader 里少数类被抽到的概率更大。另一个更有效的方案是调整 loss 权重给少数类的 loss 乘上一个系数。常见做法是取样本数的倒数并归一化。# 按样本数量的倒数设置 loss 权重 import torch.nn as nn weights torch.tensor([0.2, 1.0, 8.0]) # 举例第三类样本少权重放大 criterion nn.CrossEntropyLoss(weightweights.cuda())5.5 推理速度比预期慢问题出在扫描方向数量现象部署时模型精度是够用了但单张推理时间比宣传的长一倍。原因EfficientVMamba 的“高效”默认配置通常只启用部分扫描路径。如果你在训练时为了提精度把扫描方向加到了 4 个推理时自然要付出相应代价代码在转发时会在内部做多轮扫描这一点不像卷积那样直接搭在硬件加速器上。解决推理时把扫描方向配置调回默认值。如果验证集精度掉得不多用这版做部署如果掉得厉害说明你的任务确实依赖多方向的空间信息唯一的优化手段是把输入分辨率降低到 160 或 192再做一次精度验证。提示EfficientVMamba 的扫描实现是纯 PyTorch 的循环加张量切片没有底层 cuDNN 那样的加速。想要更极致的推理性能可以等 ONNX 导出工具支持该算子后用 ONNX Runtime 推理但目前不一定稳定建议先在 PyTorch 的 JIT Script 下做模型固化。6. 进阶验证用 Grad-CAM 看 EfficientVMamba 到底“看”哪里模型训练完之后精度指标只是一个黑匣子结论真正让同行信服的是你能说明“它为什么会把这张图识别成这个类”。这一步我会用 Grad-CAM 可视化方式输出注意力热力图尤其是在森林图像分类这个任务上热力图能很直观地告诉你模型到底是在看叶子纹理还是在看背景光线。如果高亮区域集中在树干背景上那这个模型就是拿背景特征在作弊泛化能力堪忧。用 Grad-CAM 对 EfficientVMamba 做可视化的原理是取出最后一层 Block 输出的特征图计算目标类别的 logit 对该特征图的梯度再把梯度在空间维度上做平均得到权重最后对特征图做加权求和并经过 ReLU 得到热力图。具体代码如下所示。import cv2 import numpy as np import torch def grad_cam_vmamba(model, input_tensor, target_class): model.eval() features {} handles [] # 钩子取最后一个 Block 的输出特征图 def forward_hook(module, input, output): features[feat] output[0] if isinstance(output, tuple) else output # 需要替换成你模型里最后一层 Block 的模块名 target_layer model.layers[-1] handle target_layer.register_forward_hook(forward_hook) handles.append(handle) logits model(input_tensor) probs torch.softmax(logits, dim1) if target_class is None: target_class probs.argmax(dim1).item() # 目标类别 logit 反向传播 model.zero_grad() one_hot torch.zeros_like(logits) one_hot[0, target_class] 1.0 logits.backward(gradientone_hot) gradients target_layer.weight.grad # 这里需要按实现调整 # 在具体实现中更稳妥的做法是注册 backward hook 获取 # 相对于 features[feat] 的梯度因为不同模型内部对梯度的持有方式不同 for h in handles: h.remove()上面代码里注释提到了一个容易踩坑的地方在 PyTorch 中默认不会保存非叶子节点的梯度而target_layer.weight.grad通常不是你要的“特征图梯度”。更可靠的做法是单独注册一个backward_hook从该 hook 里直接取出与输出特征图对应的梯度张量。下面给出补全后的版本def grad_cam_vmamba(model, input_tensor, target_class): model.eval() activations {} gradients {} def forward_hook(module, input, output): activations[value] output def backward_hook(module, grad_input, grad_output): gradients[value] grad_output[0] target_layer model.layers[-1] target_layer.register_forward_hook(forward_hook) target_layer.register_full_backward_hook(backward_hook) output model(input_tensor) model.zero_grad() target torch.zeros_like(output) target[0, target_class] 1.0 output.backward(gradienttarget) act activations[value][0] # [C, H, W] grad gradients[value][0] # [C, H, W] weights grad.mean(dim(1, 2), keepdimTrue) # [C, 1, 1] cam (weights * act).sum(dim0, keepdimTrue) cam torch.relu(cam).squeeze().cpu().numpy() cam (cam - cam.min()) / (cam.max() - cam.min() 1e-6) return cam # 热力图叠加到原图上输出结果图 cam grad_cam_vmamba(model, x, target_classpred_class) heatmap cv2.resize(cam, (img_w, img_h)) heatmap np.uint8(255 * heatmap) heatmap_color cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) overlay cv2.addWeighted(img_bgr, 0.6, heatmap_color, 0.4, 0)这段代码的落地价值不只是出一张热力图它还能用来判断两个关键问题第一模型有没有聚焦到目标对象的可辨识部位比如森林树种的叶片纹理与树干形状第二在类别容易混淆时对比热力图能发现是模型真的认知错了还是数据标注本身有模糊性。对于样本量小的项目来说我用这个手段排查过大约三分之一的误分类样本发现大多是标注噪声造成的类间混淆跟模型结构无关。因此建议你在做最终评测前先用热力图过一遍验证集里被错分的样本往往能找到比调参数更直接的提分方向。整套 EfficientVMamba 路线从理解结构、改造数据到训练验证、排查深坑每一步都有明确的检查点。我的个人习惯是每次拿到新数据集时先用一个最小的模型配置跑通过拟合确认数据管线无误再逐步放大模型和训练周期。先小后大能省掉很多因为数据问题导致的无效训练。这条经验在 EfficientVMamba 上尤其适用因为它的预训练权重迁移路径比较灵活小配置跑通后换大模型只需要改两行参数。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →