SuperYOLO安装以及训练自定义数据集
实验环境
本次使用的关键实验环境如下
Windows11
python=3.8
torch 2.0.1+cu117
CUDA:0 (NVIDIA GeForce RTX 3050 Laptop GPU, 4095.5MB)
Cuda compilation tools, release 11.7, V11.7.99
环境安装
Anaconda
创建虚拟环境super-yolo
并进入
conda create -n super-yolo python=3.8 -y
conda activate super-yolo
拉取super-yolo
项目并进入项目目录
官网地址:icey-zhang/SuperYOLO: SuperYOLO is accepted by TGRS (github.com)
git clone https://github.com/icey-zhang/SuperYOLO.git
cd SuperYOLO
安装pytorch环境
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
安装项目环境
pip install -r requirements.txt
经测试,后面运行项目会缺少库,还需安装如下库
pip install numba timm
训练官方数据集
官方数据集下载地址
或者使用我的下载地址
下载完后解压到某个目录即可,数据集格式如下
你的存放路径
├── dataset
│ ├── VEDAI
│ │ ├── images
│ │ ├── labels
│ │ ├── fold01.txt
│ │ ├── fold01test.txt
│ │ ├── fold02.txt
│ │ ├── .....
│ ├── VEDAI_1024
│ │ ├── images
│ │ ├── labels
-
处理数据集
修改data/transform.py
文件中的数据集存放路径修改前
PATH = '/home/data/zhangjiaqing/dataset/'
修改为自己的存放路径
PATH = r'D:\Users\13055\Documents\BaiduDisk\dataset'+'/'
运行
data/transform.py
,划分下数据集,更新训练时用的txt
文件python data/transform.py
-
修改配置文件
修改数据集配置文件
data/SRvedai.yaml
中数据集存放路径修改前
train: /home/data/zhangjiaqing/dataset/VEDAI/fold01_write.txt test: /home/data/zhangjiaqing/dataset/VEDAI/fold01test_write.txt val: /home/data/zhangjiaqing/dataset/VEDAI/fold01test_write.txt
修改后
train: D:\Users\13055\Documents\BaiduDisk\dataset\VEDAI/fold01_write.txt test: D:\Users\13055\Documents\BaiduDisk\dataset\VEDAI/fold01test_write.txt val: D:\Users\13055\Documents\BaiduDisk\dataset\VEDAI/fold01test_write.tx
-
开始训练
python train.py --cfg models/SRyolo_MF.yaml --super --train_img_size 1024 --hr_input --data data/SRvedai.yaml --ch 64 --input_mode RGB+IR+MF
-
运行存在的问题
-
AssertionError: train: No labels in D:\Users\13055\Documents\BaiduDisk\dataset\VEDAI_1024\images.cache. Can not train without labels.
问题报错如下
Traceback (most recent call last): File "train.py", line 673, in <module> train(hyp, opt, device, tb_writer) File "train.py", line 212, in train dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt, File "D:\projects\python\SuperYOLO\utils\datasets.py", line 92, in create_dataloader_sr dataset = LoadImagesAndLabels_sr(path, imgsz, batch_size, File "D:\projects\python\SuperYOLO\utils\datasets.py", line 701, in __init__ assert nf > 0 or not augment, f'{prefix}No labels in {cache_path}. Can not train without labels. See {help_url}' AssertionError: train: No labels in D:\Users\13055\Documents\BaiduDisk\dataset\VEDAI_1024\images.cache. Can not train without labels. See https://github.com/ultralytics/yolov3/wiki/Train-Custom-Data
问题原因
Windows下路径问题,区别在于’/‘与’\',问题出在
utils/datasets.py
中img2label_paths
方法处理路径替换时出错,未能正常处理,这个方法作用是根据images
路径计算出labels
路径解决方案
修改
img2label_paths
中的逻辑处理img2label_paths
中源代码def img2label_paths(img_paths): # Define label paths as a function of image paths sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings return [x.replace(sa, sb, 1).replace('_' + x.split('_')[-1], '.txt') for x in img_paths] #replace('.' + x.split('.')[-1], '.txt')
修改后(注意数据集存放路径不要包含
'/images/'
,否则该方法会失效)def img2label_paths(img_paths): # Define label paths as a function of image paths return [x.replace('/images/', '/labels/').replace('_' + x.split('_')[-1], '.txt') for x in img_paths]
-
AttributeError: module 'numpy' has no attribute 'int'
问题报错如下
Traceback (most recent call last): File "train.py", line 673, in <module> train(hyp, opt, device, tb_writer) File "train.py", line 212, in train dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt, File "D:\projects\python\SuperYOLO\utils\datasets.py", line 92, in create_dataloader_sr dataset = LoadImagesAndLabels_sr(path, imgsz, batch_size, File "D:\projects\python\SuperYOLO\utils\datasets.py", line 718, in __init__ bi = np.floor(np.arange(n) / batch_size).astype(np.int) # batch index File "D:\software\anaconda3\envs\super-yolo\lib\site-packages\numpy\__init__.py", line 284, in __getattr__ raise AttributeError("module {!r} has no attribute " AttributeError: module 'numpy' has no attribute 'int'
问题原因
numpy
版本问题,np.int
不可用解决方案
全局搜索将
np.int
换为np.int64
报错主要集中在
utils/datasets.py
与utils/general.py
,替换这俩文件里边的即可 -
RuntimeError: result type Float can't be cast to the desired output type __int64
完整报错
Traceback (most recent call last): File "train.py", line 673, in <module> train(hyp, opt, device, tb_writer) File "train.py", line 396, in train loss, lbox , lobj , lcls = compute_loss(pred, targets.to(device)) # loss scaled by batch_size File "D:\projects\python\SuperYOLO\utils\loss.py", line 118, in __call__ tcls, tbox, indices, anchors = self.build_targets(p, targets) # targets File "D:\projects\python\SuperYOLO\utils\loss.py", line 218, in build_targets indices.append((b, a, gj.clamp_(0, gain[3] - 1), gi.clamp_(0, gain[2] - 1))) # image, anchor, grid indices 该网格是哪张图片的,并由哪个锚框进行预测 RuntimeError: result type Float can't be cast to the desired output type __int64
问题原因
解决方案
将
utils/loss.py
中的下面这句indices.append((b, a, gj.clamp_(0, gain[3] - 1), gi.clamp_(0, gain[2] - 1)))
换为
indices.append((b, a, gj.clamp(0, int(gain[3]) - 1), gi.clamp(0, int(gain[2]) - 1)))
-
-
运行成功
训练自定义数据集
动手之前先批判以下官方代码,其代码是建立在Ultralytics
的Yolov5
基础上,Ultralytics
官方给的代码中原来是images
目录下文件个数与labels
目录下文件个数一致,且文件名一一对应的,作者在其基础上修改的自动划分数据集是值得提倡的,但是省便签文件是不值得提倡的。作者的数据集中images
下多张图片对应一个labels
,其数据加载过程不符合大多数人的数据集,将其修改为我的数据集格式
数据集格式
我的数据集中,images目录下的文件数与labels目录下一致,且文件名一致,文件后缀不同,这也是大多数人的数据集格式
├── images
│ ├── s1.jpg
│ ├── s2.jpg
├── labels
│ ├── s1.txt
│ ├── s2.txt
注意:该项目中区分训练集与测试集方法是用的fold01.txt
与fold01test.txt
,上述images与labels应该包含全部数据集
fold01.txt
与fold01test.txt
需要自备,其内容格式如下
000001.jpg
0001.jpg
fold01.txt
存储训练集文件名
fold01test.txt
存储测试集文件名
再将原来数据集中的images
与labels
目录用自己的这俩替换,此时目录如下
你的存放路径
├── dataset
│ ├── VEDAI
│ │ ├── images
│ │ ├── labels
│ │ ├── fold01.txt
│ │ ├── fold01test.txt
│ ├── VEDAI_1024
│ │ ├── images
│ │ ├── labels
前期也看不懂它的多个txt
文件,仅使用fold01.txt
与fold01test.txt
,为了不影响转化代码运行,还需对data/transform.py
稍微修改
for i in ['01','02','03','04','05','06','07','08','09','10']:
改为
for i in ['01']:
运行data/transform.py
,划分下数据集,更新训练时用的txt
文件
python data/transform.py
至此,数据准备完成
我的数据集最终目录如下
你的存放路径
├── dataset
│ ├── VEDAI
│ │ ├── images
│ │ ├── labels
│ │ ├── fold01.txt
│ │ ├── fold01test.txt
│ │ ├── fold01_write.txt
│ │ ├── fold01test_write.txt
│ ├── VEDAI_1024
│ │ ├── images
│ │ ├── labels
修改数据集加载代码
修改utils/datasets.py
-
修改根据图片找标签路径逻辑
修改处
def img2label_paths(img_paths): # Define label paths as a function of image paths sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings return [x.replace(sa, sb, 1).replace('_' + x.split('_')[-1], '.txt') for x in img_paths] #replace('.' + x.split('.')[-1], '.txt')
修改后(Windows)
def img2label_paths(img_paths): # Define label paths as a function of image paths return [x.replace('/images/', '/labels/').replace( x.split('.')[-1], 'txt') for x in img_paths]
修改后(Linux)
def img2label_paths(img_paths): # Define label paths as a function of image paths return [x.replace(sa, sb, 1).replace( x.split('.')[-1], 'txt') for x in img_paths]
-
LoadImagesAndLabels
中修改
ir
路径逻辑(这里我也不懂是干嘛的,只保证修改后能运行)修改处
self.ir_files = img2ir_paths(self.img_files)
修改后
self.ir_files = self.img_files
-
LoadImagesAndLabels_sr
方法中修改处
for j in range(len(self.img_files)): self.img_files[j] = self.img_files[j].rstrip() + '_co.png' #self.img_path + self.img_files[j].rstrip() + '_co.png'
修改后
for j in range(len(self.img_files)): self.img_files[j] = self.img_files[j].rstrip()
修改处
self.ir_files = img2ir_paths(self.img_files)
修改后
self.ir_files = self.img_files
修改data/SRvedai.yaml
这里主要是修改类别为自己数据集类别,和YOLOv5原版是一样的格式,照着改就行,再者就是自己数据集路径问题了
开始训练
后续根据自己需求训练参数,这里主要是起到运行项目测试作用
python train.py --cfg models/SRyolo_noFocus_small.yaml --train_img_size 512 --data data/SRvedai.yaml --ch 3 --input_mode RGB
运行截图
源代码
百度云盘链接:https://pan.baidu.com/s/1-fqkI5dUm70s53BGOqEXnA?pwd=f603