KirigiriSuzumiya 33b223351a | 1 year ago | |
---|---|---|
.. | ||
README.assets | 1 year ago | |
detection-results | 1 year ago | |
submitsample | 1 year ago | |
提交文件 | 1 year ago | |
README.md | 1 year ago | |
result_sol.py | 1 year ago | |
result_together.py | 1 year ago | |
test.py | 1 year ago |
2022/6/19 雾切凉宫
项目平台链接
AIstudio链接(可一键运行,提供免费算力):基于可见光图像的柑橘花果梢识别挑战赛 - 飞桨AI Studio (baidu.com)
OpenI链接(提供算力):Learning-Develop-Union/easy-competition-paddle
中国是柑橘的重要原产地之一,柑橘资源丰富,优良品种繁多,并且柑橘是南方重要的经济作物之一。柑橘不同生育时期的措施直接或间接影响着柑橘产量,其中春梢是一年中最重要的枝梢,保花坐果膨果需要大量的有机营养。春梢过少甚至不出梢时,就不能制造足够的营养供幼果生长。柑橘花期是柑橘结果的保证,柑橘在花期会大量开花,这样会消耗大量的养分,可能会导致树势生长不良,花期需要注重花的量,不能太少也不能太多,以保证后期柑橘果实的产量。花期应该注意补充好营养,来补充开花消耗的大量营养。因此本赛题以柑橘新梢、花朵、花苞和青果进行识别检测。
*以上为在未标注数据集中的检测结果
这个任务是一个典型的目标检测任务,可以使用Paddle目标检测套件PaddleDetection
PaddleDetection支持各类**目标检测相关及衍生任务,**提供而大量先进学术模型与基于大数据集(类似coco)的预训练模型。能够以非常短的时间与训练组网成本完成赛事并取得不差的的成绩。
*上图来自PaddleDetection官方repo
PaddleDetection的训练流程大致如下:
yml
yml
使用讯飞比赛数据集2022 iFLYTEK A.I.开发者大赛-讯飞开放平台 (xfyun.cn)(目前比赛已结束,下载初赛数据集)
图片集,包含训练集和测试集数据。train表示训练集目录,test表示测试集目录
# 解压数据集
!unzip data/data151336/dataset.zip -d work/train
划分训练、验证、测试集
PaddleX有方便的VOC数据集分割方法,所以这里使用Paddlex的功能。后文中所有代码都要求Paddlex版本>=2.0
# 安装paddlex
!pip install paddlex
# 将VOC数据集分割
!paddlex --split_dataset --format VOC --dataset_dir work/train/dataset/train --val_value 0.2 --test_value 0.1
数据集按照如下方式进行组织,原图均放在同一目录,如JPEGImages
,标注的同名xml文件均放在同一目录,如Annotations
,示例如下:
MyDataset/ # 目标检测数据集根目录
|--JPEGImages/ # 原图文件所在目录
| |--1.jpg
| |--2.jpg
| |--...
| |--...
|
|--Annotations/ # 标注文件所在目录
| |--1.xml
| |--2.xml
| |--...
| |--...
为了用于训练,我们需要在MyDataset
目录下准备train_list.txt
, val_list.txt
和labels.txt
三个文件,分别用于表示训练集列表,验证集列表和类别标签列表。
labels.txt用于列出所有类别,类别对应行号表示模型训练过程中类别的id(行号从0开始计数),例如labels.txt为以下内容
dog
cat
snake
表示该检测数据集中共有3个目标类别,分别为dog
,cat
和snake
,在模型训练中dog
对应的类别id为0, cat
对应1,以此类推
train_list.txt列出用于训练时的图片集合,与其对应的标注文件,示例如下
JPEGImages/1.jpg Annotations/1.xml
JPEGImages/2.jpg Annotations/2.xml
... ...
其中第一列为原图相对MyDataset
的相对路径,第二列为标注文件相对MyDataset
的相对路径
val_list列出用于验证时的图片集成,与其对应的标注文件,格式与val_list.txt一致
!git clone https://gitee.com/paddlepaddle/PaddleDetection.git
!pip install -r PaddleDetection/requirements.txt
在终端输入:
cd PaddleDetection
python setup.py install
在PaddleDetection/configs/datasets下创建orange.yml,并写入以下内容:
metric: VOC
map_type: 11point
num_classes: 1
TrainDataset:
!VOCDataSet
dataset_dir: work/train/dataset/train
anno_path: train_list.txt
label_list: labels.txt
data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']
EvalDataset:
!VOCDataSet
dataset_dir: work/train/dataset/train
anno_path: val_list.txt
label_list: labels.txt
data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']
TestDataset:
!ImageFolder
anno_path: labels.txt
这里选取了以下三个模型进行训练并比较效果
PPYOLOe
YOLOv3
Picodet
修改PaddleDetection/configs/ppyoloe/ppyoloe_crn_l_300e_coco.yml文件:
_BASE_: [
'../datasets/orange.yml',
'../runtime.yml',
'./_base_/optimizer_300e.yml',
'./_base_/ppyoloe_crn.yml',
'./_base_/ppyoloe_reader.yml',
]
log_iter: 100
snapshot_epoch: 10
weights: output/ppyoloe_crn_l_300e_coco/model_final
pretrain_weights: https://paddledet.bj.bcebos.com/models/pretrained/CSPResNetb_l_pretrained.pdparams
depth_mult: 1.0
width_mult: 1.0
根据gpu数量修改学习率:
比如我用的单gpu环境,修改PaddleDetection/configs/ppyoloe/base/optimizer_300e.yml
epoch: 300
LearningRate:
base_lr: 0.003125
schedulers:
- !CosineDecay
max_epochs: 360
- !LinearWarmup
start_factor: 0.
epochs: 5
OptimizerBuilder:
optimizer:
momentum: 0.9
type: Momentum
regularizer:
factor: 0.0005
type: L2
修改PaddleDetection/configs/yolov3/yolov3_darknet53_270e_voc.yml:
_BASE_: [
'../datasets/orange.yml',
'../runtime.yml',
'_base_/optimizer_270e.yml',
'_base_/yolov3_darknet53.yml',
'_base_/yolov3_reader.yml',
]
snapshot_epoch: 5
weights: output/yolov3_darknet53_270e_voc/model_final
# set collate_batch to false because ground-truth info is needed
# on voc dataset and should not collate data in batch when batch size
# is larger than 1.
EvalReader:
collate_batch: false
根据gpu数量修改学习率:
比如我用的单gpu环境,修改PaddleDetection/configs/yolov3/base/optimizer_270e.yml
epoch: 270
LearningRate:
base_lr: 0.000125
schedulers:
- !PiecewiseDecay
gamma: 0.1
milestones:
- 216
- 243
- !LinearWarmup
start_factor: 0.
steps: 4000
OptimizerBuilder:
optimizer:
momentum: 0.9
type: Momentum
regularizer:
factor: 0.0005
type: L2
与上面类似,不再赘述
!python -u PaddleDetection/tools/train.py -c PaddleDetection/configs/ppyoloe/ppyoloe_crn_l_300e_coco.yml \
-o pretrain_weights=https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_300e_coco.pdparams\
--use_vdl=true --eval
!python -u PaddleDetection/tools/train.py \
-c PaddleDetection/configs/yolov3/yolov3_darknet53_270e_voc.yml --use_vdl=true --eval
!python -u PaddleDetection/tools/train.py \
-c PaddleDetection/configs/picodet/picodet_l_640_coco_lcnet.yml --use_vdl=true --eval
可以利用VisualDL实时可视化训练
模型 | 训练集map | 讯飞提交map |
---|---|---|
PPYOLOe | 82.65 | 87.17 |
YOLOv3 | 83.21 | 80.12 |
Picodet | 83.14 | 85.9 |
!python PaddleDetection/tools/eval.py -c PaddleDetection/configs/ppyoloe/ppyoloe_crn_l_300e_coco.yml \
-o weights=output/ppyoloe_crn_l_300e_coco/best_model.pdparams
!python PaddleDetection/tools/eval.py -c PaddleDetection/configs/yolov3/yolov3_darknet53_270e_voc.yml \
-o weights=output/yolov3_darknet53_270e_voc/best_model.pdparams
!python PaddleDetection/tools/eval.py -c PaddleDetection/configs/picodet/picodet_l_640_coco_lcnet.yml\
-o weights=output/picodet_l_640_coco_lcnet/best_model.pdparams
#yolov3导出
!python PaddleDetection/tools/export_model.py -c PaddleDetection/configs/yolov3/yolov3_darknet53_270e_voc.yml \
--output_dir=output/inference_model \
-o weights=output/yolov3_darknet53_270e_voc/best_model.pdparams
#yoloe导出
!python PaddleDetection/tools/export_model.py -c PaddleDetection/configs/ppyoloe/ppyoloe_crn_l_300e_coco.yml \
--output_dir=output/inference_model \
-o weights=output/ppyoloe_crn_l_300e_coco/best_model.pdparams
#picodet导出
!python PaddleDetection/tools/export_model.py -c PaddleDetection/configs/picodet/picodet_l_640_coco_lcnet.yml \
--output_dir=output/inference_model \
-o weights=output/picodet_l_640_coco_lcnet/best_model.pdparams
#yolov3预测
!python PaddleDetection/deploy/python/infer.py --model_dir=output/inference_model/yolov3_darknet53_270e_voc \
--image_dir=work/train/dataset/test/JPEGImages --device=GPU\
--output_dir=output/predict/yolov3 \
--save_results=True
# yoloe预测
!python PaddleDetection/deploy/python/infer.py --model_dir=output/inference_model/ppyoloe_crn_l_300e_coco \
--image_dir=work/train/dataset/test/JPEGImages --device=GPU \
--output_dir=output/predict/yoloe \
--save_results=True
# picodet预测
!python PaddleDetection/deploy/python/infer.py --model_dir=output/inference_model/picodet_l_640_coco_lcnet \
--image_dir=work/train/dataset/test/JPEGImages --device=GPU \
--output_dir=output/predict/picodet \
--save_results=True
P.S:这些是我本地跑的代码,文件路径可能需要自己修改与添加……
import json
import os.path
for name in os.listdir(r"C:\Users\boyif\Desktop\paddle\orange\dataset\test\JPEGImages"):
fp = open("detection-results/"+name[:name.find(".")]+".txt", "a+")
fp.close()
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\yolov3\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
fp = open(filename, "a+")
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("yolov3 finish")
既然训了三个模型,那就试试能不能融合一下(结果我尝试了融合检测的结果)
还用nms合并了同类框。现在想想这就是在把大家认得都对的合在一起,把认错的留下来……
P.S:这些是我本地跑的代码,文件路径可能需要自己修改与添加……
(反正实际并没有正向的效果,无所谓了)
import json
import os.path
for name in os.listdir(r"C:\Users\boyif\Desktop\paddle\orange\dataset\test\JPEGImages"):
fp = open("detection-results/"+name[:name.find(".")]+".txt", "a+")
fp.close()
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\yolov3\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
fp = open(filename, "a+")
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("yolov3 finish")
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\ppyoloe\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
fp = open(filename, "a+")
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("yoloe finish")
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\picodet\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
fp = open(filename, "a+")
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("picodet finish")
import numpy as np
import matplotlib.pyplot as plt
import os
def py_cpu_nms(dets, thresh):
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
scores = dets[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
res = []
index = scores.argsort()[::-1]
while index.size > 0:
i = index[0]
res.append(i)
x11 = np.maximum(x1[i], x1[index[1:]])
y11 = np.maximum(y1[i], y1[index[1:]])
x22 = np.minimum(x2[i], x2[index[1:]])
y22 = np.minimum(y2[i], y2[index[1:]])
w = np.maximum(0, x22 - x11 + 1)
h = np.maximum(0, y22 - y11 + 1)
overlaps = w * h
iou = overlaps / (areas[i] + areas[index[1:]] - overlaps)
idx = np.where(iou <= thresh)[0]
index = index[idx + 1]
# print(res)
return res
def plot_boxs(box, c):
x1 = box[:, 0]
y1 = box[:, 1]
x2 = box[:, 2]
y2 = box[:, 3]
plt.plot([x1, x2], [y1, y1], c)
plt.plot([x1, x2], [y2, y2], c)
plt.plot([x1, x1], [y1, y2], c)
plt.plot([x2, x2], [y1, y2], c)
for name in os.listdir(r"C:\Users\boyif\Desktop\paddle\orange\detection-results"):
fp = open(os.path.join(r"C:\Users\boyif\Desktop\paddle\orange\detection-results", name))
result = []
for info in fp.readlines():
info = info[info.find(" ") + 1:]
score = info[:info.find(" ")]
info = info[info.find(" ")+1:]
xmin = info[:info.find(" ")]
info = info[info.find(" ") + 1:]
ymin = info[:info.find(" ")]
info = info[info.find(" ")+1:]
xmax = info[:info.find(" ")]
info = info[info.find(" ") + 1:]
ymax = info[:info.find(" ")]
# print(score,xmin,ymin,xmax,ymax)
result.append([float(xmin), float(ymin), float(xmax), float(ymax), float(score)])
result = np.array(result)
# print(result)
res = py_cpu_nms(result, 0.7)
# print(res)
# print(result[res])
fp.close()
fp = open(os.path.join(r"C:\Users\boyif\Desktop\paddle\orange\detection-results", name),"w")
for box in result[res]:
fp.write("shoot " + str(box[4]) + " " + str(box[0]) + " " + str(box[1]) + " " + str(box[2]) + " " + str(box[3]) + "\n")
print(name)
模型 | 讯飞map |
---|---|
PPYOLOe+Picodet | 84.69 |
PPYOLOe+Picodet+YOLOv3 | 84.56 |
PPYOLOe+YOLOv3 | 86.15 |
结果都没有PPYOLOe自己单独提交的高,属于是没见识,瞎忙活……
是个新人,有些很傻的问题不明白……
我直接将不同模型的结果全放在一起map明显下降
而我将放在一起的结果经过nms合并框后map与原模型表现略有下降
各自产生的原因是什么呢?
在经过 谢杰航 老师的指导后,采用了新的优化方法:
这样nms合并的时候就会优先选没加惩罚的框,可以通过添加惩罚的多少来调整融合的效果
import json
import os.path
# for name in os.listdir(r"C:\Users\boyif\Desktop\paddle\orange\dataset\test\JPEGImages"):
# fp = open("detection-results/"+name[:name.find(".")]+".txt", "w")
# fp.close()
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\yolov3\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]-0.2
if score <= 0:
continue
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp = open(filename, "a+")
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("yolov3 finish")
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\ppyoloe\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]-0.1
if score <= 0:
continue
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp = open(filename, "a+")
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("yoloe finish")
results = json.load(open(r"C:\Users\boyif\Desktop\paddle\orange\提交文件\picodet\results.json", "r"))
for result in results:
#print(result)
filename = result["image_file"]
filename = filename[filename.rfind("/")+1:filename.find(".")]+".txt"
filename = "detection-results/"+filename
#print("shoot "+str(result["score"]) + " " + str(result["bbox"][0])+" "+str(result["bbox"][1])+" "+str(result["bbox"][2])+" "+str(result["bbox"][3])+"\n")
score = result["score"]-0.1
if score <= 0:
continue
xmin = result["bbox"][0]
ymin = result["bbox"][1]
xmax = xmin + result["bbox"][2]
ymax = ymin + result["bbox"][3]
fp = open(filename, "a+")
fp.write("shoot " + str(score)+" "+str(xmin)+" "+str(ymin)+" "+str(xmax)+" "+str(ymax)+"\n")
fp.close()
print("picodet finish")
虽然结果在尝试了各种方法后并没有正向提升,但是在另外的一个目标检测比赛中却是有一定效果的。积累了可复用的代码模块(以后也许有用?),是不错的实践经验。
感谢 谢杰航
老师 的指导
零算法基础也能在数据竞赛中跑个好的名次!使用paddle套件中的先进学术模型完成各比赛中主流任务的baseline提交。
Text CSV Jupyter Notebook Python
Dear OpenI User
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.
For more agreement content, please refer to the《Openl Qizhi Community AI Collaboration Platform Usage Agreement》