Yolov3实践:研究并实现基于YOLOV3的遥感影像目标检测方法
参考:
https://github.com/eriklindernoren/PyTorch-YOLOv3github.com
实验环境:ubuntu16.04 + pytorch1.2.0 + cuda10.0
一、数据集介绍
1.1 自制的遥感影像数据集
数据集地址:
链接:https://pan.baidu.com/s/1zdLBg4qRH6HxvCzXk3FXPw
提取码:vy0v
1.2 示例
汽车图片(car)
飞机图片(plane)
二、训练自己的数据集
代码地址:
https://github.com/zigangzhao-ai/Pytorch-Yolov3---Remote-sensing-imagegithub.com
训练好的模型:
链接:https://pan.baidu.com/s/1HE6zm5QxkN8T_VvGLWtUsw
提取码:7159
├── config
│ ├── custom.data
│ └── yolov3_custom.cfg
├── data
│ ├── custom # 自己的数据
│ │ ├── images/0520 # 自己的数据
│ │ └── labels/0520 # 自己的数据
│ │ └── classes.names # 自己的数据
│ │ ├── train.txt # 自己的数据
│ │ └── valid.txt # 自己的数据
│ └── owndata # 自己的用于可视化的图片
├── scripts
│ ├── xml_to_json.py #xml -->json
│ ├── generate_labels.py #生成train.txt和每个图片的标注信息
│ └── k_means.py #聚类得出自己数据集的anchor
├── output #可视化图片输出
├── checkpoints #存放训练的模型
├── detect_owndata.py # 检测网络
├── train.py # 训练网络
├── test.py # 测试网络
├── models.py # yolo算法网络
├── requirements.txt # 需要安装的依赖
├── utils
│ ├── __init__.py
│ ├── datasets.py
│ ├── augmentations.py
│ ├── parse_config.py
│ └── utils.py
└── weights
└── download_weights.sh # 预训练的权重下载脚本
2.1 数据准备
01.主要是得到train.txt和vaild.txt以及labels中每张图片的标注信息
我的方法可能比较笨拙,主要是借助一些脚本以及自己的改动来实现
首先,我的数据集是自制的SAR图像数据集,包括.jpg图片以及对应的xml标签(VOC格式)
附注:打标签遇到一个问题,打完之后所有的width和height为0
如下图所示:
还好图片的width和height为定值,width=1280,height=659,我就没有重新打标签了。
我的做法是先将xml转为json格式,再把所有的json和图片放到一个文件夹中,利用脚本(xml_json.py 和generate_labels.py) 得到对应的train.txt和valid.txt以及labels中每张图片的标注信息
02.获取自己数据集的anchor,利用kmeans聚类,对自己的数据集的真实标注利用脚本(k_means.py)进行聚类,得到所需的9个anchor
2.2 开始训练
cd config
bash create_custom_model.sh 2(我的数据集是2类-car/plane)
然后将yolov3-custom.cfg中的anchor换成我们得到的anchor
之后运行
python3 train.py --model_def config/yolov3-custom.cfg --data_config config/custom.data
三、测试
3.1 测试map
python3 test.py --model_def config/yolov3-custom.cfg --data_config config/custom.data
200 epoch map=64.7%
3.2 可视化结果:
四、遇到的问题
问题1:
参考:https://github.com/eriklindernoren/PyTorch-YOLOv3/issues/183
后来查找了半天原因,数据读取部分都没有问题,后来才发现自己的train.txt后面有空白行,入下所示,去掉空白行后,成功运行。
问题2:
解决:参考https://github.com/eriklindernoren/PyTorch-YOLOv3/issues/157
Came across too. Maybe it's because of lacking some boundary checking when the code was parsing your label files. Several ground truth boxes might partly outside image after +-*/.... I added rude boundary assignments in utils/utils.py, build_targets func:
b, target_labels = target[:, :2].long().t()
gx, gy = gxy.t()
gw, gh = gwh.t()
gi, gj = gxy.long().t()
########## add
gi[gi < 0] = 0
gj[gj < 0] = 0
gi[gi > nG - 1] = nG - 1
gj[gj > nG - 1] = nG - 1
###################
# Set masks
obj_mask[b, best_n, gj, gi] = 1
noobj_mask[b, best_n, gj, gi] = 0
This aims to avoid gi[i] and gj[i] exceeding bound of size[2, 3] of noobj_mask. You would make some more precise corrections~
问题3:
解决:参考
在utils/datasets.py
class ImageFolder中
改img = transforms.ToTensor()(Image.open(img_path))
为img = transforms.ToTensor()(Image.open(img_path).convert('RGB'))