从零开始使用MMSegmentation训练Segformer
从零开始使用MMSegmentation训练Segformer
写在前面:最新想要用最新的分割算法如:Segformer or SegNeXt 在自己的数据集上进行训练,但是有不是搞语义分割出身的,而且也没有系统的学过MMCV以及MMSegmentation。所以就折腾了很久,感觉利用MMSegmentation搭建框架可能比较系统,但是对于不熟悉的或者初学者非常不友好,因此记录一下自己training Segformer的心路历程。
Segformer paper: https://arxiv.org/abs/2105.15203>
官方实现: https://github.com/NVlabs/SegFormer>
纯Torch版Segformer: https://github.com/camlaedtke/segmentation_pytorch>
方法


由于本人不是研究语义分割的,所以只能简要地介绍一下Segformer。
SegFormer的动机在于:
① ViT作为backbone只能输出固定分辨率的特征图,这对于密集预测任务显然不够友好;
② 由于self-attention操作的存在,transformer的运算量和参数两都非常大,不利于大尺度图像的分割。
为此作者提出了相应的创新:
① 先是对transformer进行层次化结构设计,得到多层级的特征图;
② 构造轻量级的decoder,仅使用MLP进行特征聚合。
③ 除此之外,SegFormer抛弃了位置信息编码,选择采用MixFCN来学习位置信息,这样可以很好地扩充到不同尺度的测试环境下(避免由于尺寸变化,需要对positional-encoding进行插值,从而影响性能)。最后提出的模型在ADE20k上达到了新sota,并且在速度、性能和鲁棒性上都表现很好。
程序复现
在重新训练过程中主要参考了:手把手教你使用Segformer训练自己的数据
作者给的教程比较详细, 但是有几处修改并不合适,导致我复现出来的结果没啥效果,因此记录一下自己的采坑记录。
自己的主要配置为:
CUDA 10.1
Pytorch 1.10.0, torchvision 0.11.1
MMCV-full 1.3.0
其中在安装MMCV-full过程中还遇到了很多问题,主要是版本不适配的原因导致的。
在安装好环境后,首先从Github下载SegFormer的项目工程: https://github.com/NVlabs/SegFormer
然后进去SegFormer目录:
pip install -r requirements.txt
pip install -e . --use
安装需要的依赖。
数据集准备
代码默认用的是ADE20K数据集进行训练
ADE20K数据集 格式如下,按照要求放就完了
├── data
│ ├── ade
│ │ ├── ADEChallengeData2016
│ │ │ ├── annotations
│ │ │ │ ├── training
│ │ │ │ ├── validation
│ │ │ ├── images
│ │ │ │ ├── training
│ │ │ │ ├── validation
但是@中科哥哥使用的是VOC的数据格式,因此就使用了VOC的数据格式
├── VOCdevkit
│ ├── VOC2012
│ │ ├── ImageSets
│ │ │ ├── Segmentation
│ │ │ │ ├── train.txt
│ │ │ │ ├── val.txt
│ │ │ │ ├── trainval.txt│ │ │ ├── JPEGImages
│ │ │ │ ├── *.jpg #所有图片│ │ │ ├── SegmentationClass
│ │ │ │ ├── *.jpg #所有标签图
在这里可以根据自己的需要修改
下面是我自己的数据格式:
├── VOCdevkit
│ ├── VOC2012
│ │ ├── ImageSets
│ │ │ ├── Segmentation
│ │ │ │ ├── train.txt
│ │ │ │ ├── val.txt
│ │ │ │ ├── test.txt│ │ │ ├── JPEGImages
│ │ │ │ ├── *.png#所有图片│ │ │ ├── SegmentationClass
│ │ │ │ ├── *.png #所有标签图
其实完全可以简洁一点:
├── MFNet
│ ├── Segmentation
│ │ ├── train.txt
│ │ ├── val.txt
│ │ ├── test.txt│ ├── Images
│ │ ├── *.png#所有图片│ ├── Label
│ │ ├── *.png #所有标签图
其中: train.txt; val.txt; test.txt; 只要图片名,不需要后缀和路径 如下

后面的程序修改都基于复杂的版本进行介绍(自己在程序复现时使用的复杂的目录,因为是按照的教程来的)
数据准备好之后可以在SegFormer目录先新建一个/datasets/ 目录来存放自己的数据集
程序修改
-
在 mmseg/datasets/voc.py修改自己数据集的类别即修改CLASSES 和 PALETTE在我自己的数据集中一共由于9个类别,所以修改如下:

-
在 mmseg/models/decode_heads/segformer_head.py 中BatchNorm 方式(如果使用单卡训练的话就修改,多卡训练的话就不用修改)。 将第59行的SyncBN 修改为 BN

-
修改 local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py 的配置文件(这里我们使用的是B5模型,需要使用哪个模型就修改对应的配置文件即可,配置文件都位于:**local_configs/segformer/**下 );主要修改
__base__=[]中的数据集文件路径(也就是下图中的第二行)
指定dataset_type的类型,此处
dataset_type = 'PascalVOCDataset'
data_root = '/data1/timer/Segmentation/SegFormer/datasets/VOC2012' 也可以给相对路径。
然后根据自己的数据需要修改文件中的crop_size, train_pipline中的img_scale,以及test_pipline中的img_scale

同时好需要在data字典中指定 img_dir, ann_dir, 以及split的路径,如果是单卡训练的话需要将norm_cfg 的type由的SyncBN 修改为 BN
接下来继续修改模型相关的文件,主要是给定预训练权重的位置即修改:pretrained 以及backbone[‘type’],这里的type因为使用的是B5的结构所以type就指定为mit_b5,然后预训练权重需要从项目中给定的链接下载。值得注意的是还需要指定decode_head[‘num_classes’] (这个需要根据你的数据集来指定,因为我的数据集中包含9类,所以这里就设置为9了)
- 在 local_configs/base/models/segformer.py 修改
norm_cfg[‘type’]=‘BN’
num_classes=9 (这里修改成你数据集对应的类别的数量)

5. 在 tools/train.py中修改
parser.add_argument('--config', default='/data1/timer/Segmentation/SegFormer/local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py')
parser.add_argument('--work-dir', default='res_MFNet')
其中 /data1/timer/Segmentation/SegFormer/local_configs/segformer/B5/segformer.b5.640x640.ade.160k.py 是配置文件的路径
res_MFNet是训练日志和模型保存的路径
同时指定GPU的卡号
group_gpus.add_argument('--gpu-ids',type=int, default=[0],help='ids of gpus to use ''(only applicable to non-distributed training)')
6. 进入tools目录下运行
python train.py
即可开始训练模型。
由于本人也在摸索阶段,有不当之处,恳请各位不吝赐教。也欢迎大家交流:2458707789@qq.com
相关文章:
从零开始使用MMSegmentation训练Segformer
从零开始使用MMSegmentation训练Segformer 写在前面:最新想要用最新的分割算法如:Segformer or SegNeXt 在自己的数据集上进行训练,但是有不是搞语义分割出身的,而且也没有系统的学过MMCV以及MMSegmentation。所以就折腾了很久&am…...
会利用信息差赚钱的人才是聪明人
毕业后找不到工作,穷到只剩下时间,大小做了20多份副业兼职,终于找到了可靠的渠道, 我是专科生,学历不好,专业拉胯。毕业后,我找了两三份工作。要么工资太低,只能交房租,…...
【机器学习】Adaboost
1.什么是Adaboost AdaBoost(adapt boost),自适应推进算法,属于Boosting方法的学习机制。是一种通过改变训练样本权重来学习多个弱分类器并进行线性结合的过程。它的自适应在于:被前一个基本分类器误分类的样本的权值会…...
深度学习神经网络基础知识(二)权重衰减、暂退法(Dropout)
专栏:神经网络复现目录 深度学习神经网络基础知识(二) 本文讲述神经网络基础知识,具体细节讲述前向传播,反向传播和计算图,同时讲解神经网络优化方法:权重衰减,Dropout等方法,最后进行Kaggle实…...
[面试直通版]网络协议面试核心之HTTP,HTTPS,DNS-DNS安全
点击->计算机网络复习的文章集<-点击 目录 典型问题: 部分现象 DNS劫持 DNS欺骗 DDoS攻击 典型问题: 什么是DNS劫持,DNS欺骗,是什么原理如何防范DNS攻击? 部分现象 错误域名解析到纠错导航页面错误域名解析…...
【OJ】A+B=X
📚Description: 数列S中有n个整数,判断S中是否存在两个数A、B,使之和等于X。 ⏳Input: 第一行为T,输入包括T组测试数据。 每组数据第一行包括两个数字n和X,第二行有n个整数,表示数列S,(1&l…...
Python实现性能自动化测试,还可以如此简单
Python实现性能自动化测试,还可以如此简单 目录:导读 一、思考❓❔ 二、基础操作🔨🔨 三、综合案例演练🔨🔨 四、总结💡💡 写在最后 一、思考❓❔ 1.什么是性能自动化测试? 性…...
Leetcode力扣秋招刷题路-0080
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 80. 删除有序数组中的重复项 II 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长…...
Java实现JDBC工具类DbUtils的抽取及程序实现数据库的增删改操作
封装DbUtils 工具类 不知道我们发现没有,不管是对数据库进行查询,还是标准的JDBC 步骤,其开端都是先实现JDBC 的加载注册,接着是获取数据库的连接,最后都是实现关闭连接,释放资源的操作。那我们何不直接把…...
【docker】拉取镜像环境报错解决#ERROR: Get https://registry-1.docker.io/v2/
🍁博主简介 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 文章目录问题报错原因解决方法问题 ERROR…...
java中NumberFormat 、DecimalFormat的介绍及使用,java数字格式化,BigDecimal数字格式化
文章目录前言一、NumberFormat1、概述2、实例化方法3、货币格式化4、百分比格式化5、NumberFormat的坑5.1、不同的格式化对象处理相同数值返回结果不同问题源码分析:二、DecimalFormat1、概述2、常用方法3、字符及含义0与#的区别分组分隔符的使用“%” 将数字乘以10…...
2023什么是分销商城系统?营销,核心功能
大家好,我是你们熟悉而又陌生的好朋友梦龙,一个创业期的年轻人 分销商城是指由网络营销运营商提供的,用于协助供给商搭建、管理及运作其网络销售渠道,协助分销商获取货源渠道的平台。简单来说,就是企业应用无线裂变分…...
天翼数字生活C++客户端实习
面试C客户端实习的岗位,相对不难 面试官:实习主要做的是国产操作系统下的应用,主要做的是视频监控、安防相关的工具,具体就是一个叫做 天翼云眼的软件,目前在windows下和电视下都有对应的应用,就是现在想在…...
Java 接口
文章目录1、接口的概念2、接口的定义3、接口的使用4、接口和抽象类1、接口的概念 类是一种具体的实现体,而接口定义了一种规范(抽象方法),接口定义了某一批类所需要遵循的规范,接口不关心类内部的属性和方法的具体实现…...
【React】react-router 路由详解
🚩🚩🚩 💎个人主页: 阿选不出来 💨💨💨 💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记. 💨💨💨 💎目…...
DaVinci 偏好设置:系统 - 内存和 GPU
偏好设置 - 系统/内存和 GPUPreferences - System/Memory and GPU内存和 GPU Memory and GPU 选项卡提供了内存配置以及 GPU 配置的相关设置。内存配置Memory Configuration系统内存System Memory列出了所用电脑的总的可用内存。限制 Resolve 内存使用到Limit Resolve memory u…...
视频知识点(22)- 教你认清楚YUV420P和YUV420SP的真正差异在哪里
*《音视频开发》系列-总览* 前言 在视频技术领域,存在着非常多的颜色空间模型,YUV颜色空间就是其中之一。我们没有必要把所有的颜色空间都搞明白,只需要关注自己所从事的领域的常用颜色空间模型即可,同样,YUV颜色空间模型也有非常多的子类型,我们也没有必要都搞得清清楚楚…...
企业电子招标采购系统源码Spring Cloud + Spring Boot + MybatisPlus + Redis + Layui
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
面试常问-Alpha测试和Beta测试
Alpha测试 Alpha测试是一种验收测试,在识别典型用户可能执行的任务并对其进行测试之前,执行该测试是为了识别所有可能的问题和错误。 尽可能简单地说,这种测试之所以被称为alpha,只是因为它是在软件开发的早期、接近开发结束时和…...
html理论基础
组织:中国互动出版网(http://www.china-pub.com/)RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)E-mail:ouyangchina-pub.com译者:黄俊(hujiao hj_c…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
手动给中文分词和 直接用神经网络RNN做有什么区别
手动分词和基于神经网络(如 RNN)的自动分词在原理、实现方式和效果上有显著差异,以下是核心对比: 1. 实现原理对比 对比维度手动分词(规则 / 词典驱动)神经网络 RNN 分词(数据驱动)…...


