Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
码农StayUp
yolov7-obb
提交
16c84698
Y
yolov7-obb
项目概览
码农StayUp
/
yolov7-obb
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
yolov7-obb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
16c84698
编写于
7月 08, 2022
作者:
Bubbliiiing
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update loss
上级
2c470c77
变更
6
展开全部
隐藏空白更改
内联
并排
Showing
6 changed file
with
355 addition
and
467 deletion
+355
-467
README.md
README.md
+1
-1
nets/yolo.py
nets/yolo.py
+1
-1
nets/yolo_training.py
nets/yolo_training.py
+335
-324
train.py
train.py
+1
-1
utils/dataloader.py
utils/dataloader.py
+13
-119
utils/utils_fit.py
utils/utils_fit.py
+4
-21
未找到文件。
README.md
浏览文件 @
16c84698
...
...
@@ -31,7 +31,7 @@ YoloV7 | https://github.com/bubbliiiing/yolov7-pytorch
## 性能情况
| 训练数据集 | 权值文件名称 | 测试数据集 | 输入图片大小 | mAP 0.5:0.95 | mAP 0.5 |
| :-----: | :-----: | :------: | :------: | :------: | :-----: |
| COCO-Train2017 |
[
yolov7_weights.pth
](
https://github.com/bubbliiiing/yolov7-pytorch/releases/download/v1.0/yolov7_weights.pth
)
| COCO-Val2017 | 640x640 |
27.6 | 45.0
| COCO-Train2017 |
[
yolov7_weights.pth
](
https://github.com/bubbliiiing/yolov7-pytorch/releases/download/v1.0/yolov7_weights.pth
)
| COCO-Val2017 | 640x640 |
50.7 | 69.2
## 所需环境
torch==1.2.0
...
...
nets/yolo.py
浏览文件 @
16c84698
...
...
@@ -305,5 +305,5 @@ class YoloBody(nn.Module):
# y1=(batch_size, 75, 20, 20)
#---------------------------------------------------#
out0
=
self
.
yolo_head_P5
(
P5
)
return
out0
,
out1
,
out2
return
[
out0
,
out1
,
out2
]
\ No newline at end of file
nets/yolo_training.py
浏览文件 @
16c84698
此差异已折叠。
点击以展开。
train.py
浏览文件 @
16c84698
...
...
@@ -311,7 +311,7 @@ if __name__ == "__main__":
#----------------------#
# 获得损失函数
#----------------------#
yolo_loss
=
YOLOLoss
(
anchors
,
num_classes
,
input_shape
,
Cuda
,
anchors_mask
,
label_smoothing
)
yolo_loss
=
YOLOLoss
(
anchors
,
num_classes
,
input_shape
,
anchors_mask
,
label_smoothing
)
#----------------------#
# 记录Loss
#----------------------#
...
...
utils/dataloader.py
浏览文件 @
16c84698
...
...
@@ -30,7 +30,6 @@ class YoloDataset(Dataset):
self
.
length
=
len
(
self
.
annotation_lines
)
self
.
bbox_attrs
=
5
+
num_classes
self
.
threshold
=
4
def
__len__
(
self
):
return
self
.
length
...
...
@@ -57,7 +56,10 @@ class YoloDataset(Dataset):
image
=
np
.
transpose
(
preprocess_input
(
np
.
array
(
image
,
dtype
=
np
.
float32
)),
(
2
,
0
,
1
))
box
=
np
.
array
(
box
,
dtype
=
np
.
float32
)
if
len
(
box
)
!=
0
:
nL
=
len
(
box
)
# number of labels
labels_out
=
np
.
zeros
((
nL
,
6
))
if
nL
:
#---------------------------------------------------#
# 对真实框进行归一化,调整到0-1之间
#---------------------------------------------------#
...
...
@@ -70,8 +72,11 @@ class YoloDataset(Dataset):
#---------------------------------------------------#
box
[:,
2
:
4
]
=
box
[:,
2
:
4
]
-
box
[:,
0
:
2
]
box
[:,
0
:
2
]
=
box
[:,
0
:
2
]
+
box
[:,
2
:
4
]
/
2
y_true
=
self
.
get_target
(
box
)
return
image
,
box
,
y_true
labels_out
[:,
1
]
=
box
[:,
-
1
]
labels_out
[:,
2
:]
=
box
[:,
:
4
]
return
image
,
labels_out
def
rand
(
self
,
a
=
0
,
b
=
1
):
return
np
.
random
.
rand
()
*
(
b
-
a
)
+
a
...
...
@@ -378,127 +383,16 @@ class YoloDataset(Dataset):
new_boxes
=
np
.
concatenate
([
box_1
,
box_2
],
axis
=
0
)
return
new_image
,
new_boxes
def
get_near_points
(
self
,
x
,
y
,
i
,
j
):
sub_x
=
x
-
i
sub_y
=
y
-
j
if
sub_x
>
0.5
and
sub_y
>
0.5
:
return
[[
0
,
0
],
[
1
,
0
],
[
0
,
1
]]
elif
sub_x
<
0.5
and
sub_y
>
0.5
:
return
[[
0
,
0
],
[
-
1
,
0
],
[
0
,
1
]]
elif
sub_x
<
0.5
and
sub_y
<
0.5
:
return
[[
0
,
0
],
[
-
1
,
0
],
[
0
,
-
1
]]
else
:
return
[[
0
,
0
],
[
1
,
0
],
[
0
,
-
1
]]
def
get_target
(
self
,
targets
):
#-----------------------------------------------------------#
# 一共有三个特征层数
#-----------------------------------------------------------#
num_layers
=
len
(
self
.
anchors_mask
)
input_shape
=
np
.
array
(
self
.
input_shape
,
dtype
=
'int32'
)
grid_shapes
=
[
input_shape
//
{
0
:
32
,
1
:
16
,
2
:
8
,
3
:
4
}[
l
]
for
l
in
range
(
num_layers
)]
y_true
=
[
np
.
zeros
((
len
(
self
.
anchors_mask
[
l
]),
grid_shapes
[
l
][
0
],
grid_shapes
[
l
][
1
],
self
.
bbox_attrs
),
dtype
=
'float32'
)
for
l
in
range
(
num_layers
)]
box_best_ratio
=
[
np
.
zeros
((
len
(
self
.
anchors_mask
[
l
]),
grid_shapes
[
l
][
0
],
grid_shapes
[
l
][
1
]),
dtype
=
'float32'
)
for
l
in
range
(
num_layers
)]
if
len
(
targets
)
==
0
:
return
y_true
for
l
in
range
(
num_layers
):
in_h
,
in_w
=
grid_shapes
[
l
]
anchors
=
np
.
array
(
self
.
anchors
)
/
{
0
:
32
,
1
:
16
,
2
:
8
,
3
:
4
}[
l
]
batch_target
=
np
.
zeros_like
(
targets
)
#-------------------------------------------------------#
# 计算出正样本在特征层上的中心点
#-------------------------------------------------------#
batch_target
[:,
[
0
,
2
]]
=
targets
[:,
[
0
,
2
]]
*
in_w
batch_target
[:,
[
1
,
3
]]
=
targets
[:,
[
1
,
3
]]
*
in_h
batch_target
[:,
4
]
=
targets
[:,
4
]
#-------------------------------------------------------#
# wh : num_true_box, 2
# np.expand_dims(wh, 1) : num_true_box, 1, 2
# anchors : 9, 2
# np.expand_dims(anchors, 0) : 1, 9, 2
#
# ratios_of_gt_anchors代表每一个真实框和每一个先验框的宽高的比值
# ratios_of_gt_anchors : num_true_box, 9, 2
# ratios_of_anchors_gt代表每一个先验框和每一个真实框的宽高的比值
# ratios_of_anchors_gt : num_true_box, 9, 2
#
# ratios : num_true_box, 9, 4
# max_ratios代表每一个真实框和每一个先验框的宽高的比值的最大值
# max_ratios : num_true_box, 9
#-------------------------------------------------------#
ratios_of_gt_anchors
=
np
.
expand_dims
(
batch_target
[:,
2
:
4
],
1
)
/
np
.
expand_dims
(
anchors
,
0
)
ratios_of_anchors_gt
=
np
.
expand_dims
(
anchors
,
0
)
/
np
.
expand_dims
(
batch_target
[:,
2
:
4
],
1
)
ratios
=
np
.
concatenate
([
ratios_of_gt_anchors
,
ratios_of_anchors_gt
],
axis
=
-
1
)
max_ratios
=
np
.
max
(
ratios
,
axis
=
-
1
)
for
t
,
ratio
in
enumerate
(
max_ratios
):
#-------------------------------------------------------#
# ratio : 9
#-------------------------------------------------------#
over_threshold
=
ratio
<
self
.
threshold
over_threshold
[
np
.
argmin
(
ratio
)]
=
True
for
k
,
mask
in
enumerate
(
self
.
anchors_mask
[
l
]):
if
not
over_threshold
[
mask
]:
continue
#----------------------------------------#
# 获得真实框属于哪个网格点
# x 1.25 => 1
# y 3.75 => 3
#----------------------------------------#
i
=
int
(
np
.
floor
(
batch_target
[
t
,
0
]))
j
=
int
(
np
.
floor
(
batch_target
[
t
,
1
]))
offsets
=
self
.
get_near_points
(
batch_target
[
t
,
0
],
batch_target
[
t
,
1
],
i
,
j
)
for
offset
in
offsets
:
local_i
=
i
+
offset
[
0
]
local_j
=
j
+
offset
[
1
]
if
local_i
>=
in_w
or
local_i
<
0
or
local_j
>=
in_h
or
local_j
<
0
:
continue
if
box_best_ratio
[
l
][
k
,
local_j
,
local_i
]
!=
0
:
if
box_best_ratio
[
l
][
k
,
local_j
,
local_i
]
>
ratio
[
mask
]:
y_true
[
l
][
k
,
local_j
,
local_i
,
:]
=
0
else
:
continue
#----------------------------------------#
# 取出真实框的种类
#----------------------------------------#
c
=
int
(
batch_target
[
t
,
4
])
#----------------------------------------#
# tx、ty代表中心调整参数的真实值
#----------------------------------------#
y_true
[
l
][
k
,
local_j
,
local_i
,
0
]
=
batch_target
[
t
,
0
]
y_true
[
l
][
k
,
local_j
,
local_i
,
1
]
=
batch_target
[
t
,
1
]
y_true
[
l
][
k
,
local_j
,
local_i
,
2
]
=
batch_target
[
t
,
2
]
y_true
[
l
][
k
,
local_j
,
local_i
,
3
]
=
batch_target
[
t
,
3
]
y_true
[
l
][
k
,
local_j
,
local_i
,
4
]
=
1
y_true
[
l
][
k
,
local_j
,
local_i
,
c
+
5
]
=
1
#----------------------------------------#
# 获得当前先验框最好的比例
#----------------------------------------#
box_best_ratio
[
l
][
k
,
local_j
,
local_i
]
=
ratio
[
mask
]
return
y_true
# DataLoader中collate_fn使用
def
yolo_dataset_collate
(
batch
):
images
=
[]
bboxes
=
[]
y_trues
=
[[]
for
_
in
batch
[
0
][
2
]]
for
img
,
box
,
y_true
in
batch
:
for
i
,
(
img
,
box
)
in
enumerate
(
batch
):
images
.
append
(
img
)
box
[:,
0
]
=
i
bboxes
.
append
(
box
)
for
i
,
sub_y_true
in
enumerate
(
y_true
):
y_trues
[
i
].
append
(
sub_y_true
)
images
=
torch
.
from_numpy
(
np
.
array
(
images
)).
type
(
torch
.
FloatTensor
)
bboxes
=
[
torch
.
from_numpy
(
ann
).
type
(
torch
.
FloatTensor
)
for
ann
in
bboxes
]
y_trues
=
[
torch
.
from_numpy
(
np
.
array
(
ann
,
np
.
float32
)).
type
(
torch
.
FloatTensor
)
for
ann
in
y_trues
]
return
images
,
bboxes
,
y_trues
bboxes
=
torch
.
from_numpy
(
np
.
concatenate
(
bboxes
,
0
)).
type
(
torch
.
FloatTensor
)
return
images
,
bboxes
utils/utils_fit.py
浏览文件 @
16c84698
...
...
@@ -17,12 +17,11 @@ def fit_one_epoch(model_train, model, ema, yolo_loss, loss_history, eval_callbac
if
iteration
>=
epoch_step
:
break
images
,
targets
,
y_trues
=
batch
[
0
],
batch
[
1
],
batch
[
2
]
images
,
targets
=
batch
[
0
],
batch
[
1
]
with
torch
.
no_grad
():
if
cuda
:
images
=
images
.
cuda
(
local_rank
)
targets
=
[
ann
.
cuda
(
local_rank
)
for
ann
in
targets
]
y_trues
=
[
ann
.
cuda
(
local_rank
)
for
ann
in
y_trues
]
targets
=
targets
.
cuda
(
local_rank
)
#----------------------#
# 清零梯度
#----------------------#
...
...
@@ -32,15 +31,7 @@ def fit_one_epoch(model_train, model, ema, yolo_loss, loss_history, eval_callbac
# 前向传播
#----------------------#
outputs
=
model_train
(
images
)
loss_value_all
=
0
#----------------------#
# 计算损失
#----------------------#
for
l
in
range
(
len
(
outputs
)):
loss_item
=
yolo_loss
(
l
,
outputs
[
l
],
targets
,
y_trues
[
l
])
loss_value_all
+=
loss_item
loss_value
=
loss_value_all
loss_value
=
yolo_loss
(
outputs
,
targets
,
images
)
#----------------------#
# 反向传播
...
...
@@ -54,15 +45,7 @@ def fit_one_epoch(model_train, model, ema, yolo_loss, loss_history, eval_callbac
# 前向传播
#----------------------#
outputs
=
model_train
(
images
)
loss_value_all
=
0
#----------------------#
# 计算损失
#----------------------#
for
l
in
range
(
len
(
outputs
)):
loss_item
=
yolo_loss
(
l
,
outputs
[
l
],
targets
,
y_trues
[
l
])
loss_value_all
+=
loss_item
loss_value
=
loss_value_all
loss_value
=
yolo_loss
(
outputs
,
targets
,
images
)
#----------------------#
# 反向传播
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录