Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
s920243400
PaddleDetection
提交
dcf97ccd
P
PaddleDetection
项目概览
s920243400
/
PaddleDetection
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleDetection
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
dcf97ccd
编写于
11月 25, 2020
作者:
G
Guanghua Yu
提交者:
GitHub
11月 25, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
adapt new im_shape im Mask R-CNN-FPN (#1760)
* adapt new im_shape im Mask R-CNN-FPN * fix training
上级
50599e26
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
94 addition
and
72 deletion
+94
-72
configs/_base_/readers/mask_reader.yml
configs/_base_/readers/mask_reader.yml
+6
-6
ppdet/data/transform/operator.py
ppdet/data/transform/operator.py
+10
-10
ppdet/modeling/architecture/mask_rcnn.py
ppdet/modeling/architecture/mask_rcnn.py
+4
-2
ppdet/modeling/bbox.py
ppdet/modeling/bbox.py
+6
-1
ppdet/modeling/head/mask_head.py
ppdet/modeling/head/mask_head.py
+9
-7
ppdet/modeling/layers.py
ppdet/modeling/layers.py
+43
-29
ppdet/modeling/post_process.py
ppdet/modeling/post_process.py
+4
-11
ppdet/py_op/post_process.py
ppdet/py_op/post_process.py
+12
-6
未找到文件。
configs/_base_/readers/mask_reader.yml
浏览文件 @
dcf97ccd
...
...
@@ -17,14 +17,14 @@ TrainReader:
EvalReader
:
inputs_def
:
fields
:
[
'
image'
,
'
im_
info
'
,
'
im_id'
]
fields
:
[
'
image'
,
'
im_
shape'
,
'
scale_factor
'
,
'
im_id'
]
sample_transforms
:
-
Decode
Image
:
{
to_rgb
:
true
}
-
NormalizeImage
:
{
is_channel_first
:
false
,
is_scale
:
true
,
mean
:
[
0.485
,
0.456
,
0.406
],
std
:
[
0.229
,
0.224
,
0.225
]}
-
Resize
Image
:
{
interp
:
1
,
max_size
:
1333
,
target_size
:
800
,
use_cv2
:
true
}
-
Permute
:
{
channel_first
:
true
,
to_bgr
:
false
}
-
Decode
Op
:
{
}
-
NormalizeImage
Op
:
{
is_scale
:
true
,
mean
:
[
0.485
,
0.456
,
0.406
],
std
:
[
0.229
,
0.224
,
0.225
]}
-
Resize
Op
:
{
interp
:
1
,
target_size
:
[
800
,
1333
]
}
-
Permute
Op
:
{
}
batch_transforms
:
-
PadBatch
:
{
pad_to_stride
:
32
,
use_padded_im_info
:
false
,
pad_gt
:
false
}
-
PadBatch
Op
:
{
pad_to_stride
:
32
,
pad_gt
:
false
}
batch_size
:
1
shuffle
:
false
drop_last
:
false
...
...
ppdet/data/transform/operator.py
浏览文件 @
dcf97ccd
...
...
@@ -141,7 +141,7 @@ class DecodeOp(BaseOperator):
"image width."
.
format
(
im
.
shape
[
1
],
sample
[
'w'
]))
sample
[
'w'
]
=
im
.
shape
[
1
]
sample
[
'im_shape'
]
=
np
.
array
(
im
.
shape
[:
2
],
dtype
=
np
.
in
t32
)
sample
[
'im_shape'
]
=
np
.
array
(
im
.
shape
[:
2
],
dtype
=
np
.
floa
t32
)
sample
[
'scale_factor'
]
=
np
.
array
([
1.
,
1.
],
dtype
=
np
.
float32
)
return
sample
...
...
@@ -666,8 +666,8 @@ class ResizeOp(BaseOperator):
im_scale
=
min
(
target_size_min
/
im_size_min
,
target_size_max
/
im_size_max
)
resize_h
=
i
nt
(
im_scale
*
im_shape
[
0
])
resize_w
=
i
nt
(
im_scale
*
im_shape
[
1
])
resize_h
=
i
m_scale
*
float
(
im_shape
[
0
])
resize_w
=
i
m_scale
*
float
(
im_shape
[
1
])
im_scale_x
=
im_scale
im_scale_y
=
im_scale
...
...
@@ -678,14 +678,14 @@ class ResizeOp(BaseOperator):
im
=
self
.
apply_image
(
sample
[
'image'
],
[
im_scale_x
,
im_scale_y
])
sample
[
'image'
]
=
im
sample
[
'im_shape'
]
=
np
.
a
rray
([
resize_h
,
resize_w
],
dtype
=
np
.
in
t32
)
sample
[
'im_shape'
]
=
np
.
a
sarray
([
resize_h
,
resize_w
],
dtype
=
np
.
floa
t32
)
if
'scale_factor'
in
sample
:
scale_factor
=
sample
[
'scale_factor'
]
sample
[
'scale_factor'
]
=
np
.
array
(
sample
[
'scale_factor'
]
=
np
.
a
sa
rray
(
[
scale_factor
[
0
]
*
im_scale_y
,
scale_factor
[
1
]
*
im_scale_x
],
dtype
=
np
.
float32
)
else
:
sample
[
'scale_factor'
]
=
np
.
array
(
sample
[
'scale_factor'
]
=
np
.
a
sa
rray
(
[
im_scale_y
,
im_scale_x
],
dtype
=
np
.
float32
)
# apply bbox
...
...
@@ -1397,8 +1397,8 @@ class RandomScaledCropOp(BaseOperator):
random_dim
=
int
(
dim
*
random_scale
)
dim_max
=
max
(
h
,
w
)
scale
=
random_dim
/
dim_max
resize_w
=
int
(
round
(
w
*
scale
))
resize_h
=
int
(
round
(
h
*
scale
))
resize_w
=
w
*
scale
resize_h
=
h
*
scale
offset_x
=
int
(
max
(
0
,
np
.
random
.
uniform
(
0.
,
resize_w
-
dim
)))
offset_y
=
int
(
max
(
0
,
np
.
random
.
uniform
(
0.
,
resize_h
-
dim
)))
...
...
@@ -1408,9 +1408,9 @@ class RandomScaledCropOp(BaseOperator):
canvas
[:
min
(
dim
,
resize_h
),
:
min
(
dim
,
resize_w
),
:]
=
img
[
offset_y
:
offset_y
+
dim
,
offset_x
:
offset_x
+
dim
,
:]
sample
[
'image'
]
=
canvas
sample
[
'im_shape'
]
=
np
.
a
rray
([
resize_h
,
resize_w
],
dtype
=
np
.
in
t32
)
sample
[
'im_shape'
]
=
np
.
a
sarray
([
resize_h
,
resize_w
],
dtype
=
np
.
floa
t32
)
scale_factor
=
sample
[
'sacle_factor'
]
sample
[
'scale_factor'
]
=
np
.
array
(
sample
[
'scale_factor'
]
=
np
.
a
sa
rray
(
[
scale_factor
[
0
]
*
scale
,
scale_factor
[
1
]
*
scale
],
dtype
=
np
.
float32
)
...
...
ppdet/modeling/architecture/mask_rcnn.py
浏览文件 @
dcf97ccd
...
...
@@ -96,7 +96,8 @@ class MaskRCNN(BaseArch):
self
.
bbox_head_out
,
rois
)
# Refine bbox by the output from bbox_head at test stage
self
.
bboxes
=
self
.
bbox_post_process
(
bbox_pred
,
bboxes
,
self
.
inputs
[
'im_info'
])
self
.
inputs
[
'im_shape'
],
self
.
inputs
[
'scale_factor'
])
else
:
# Proposal RoI for Mask branch
# bboxes update at training stage only
...
...
@@ -134,7 +135,8 @@ class MaskRCNN(BaseArch):
def
get_pred
(
self
,
):
mask
=
self
.
mask_post_process
(
self
.
bboxes
,
self
.
mask_head_out
,
self
.
inputs
[
'im_info'
])
self
.
inputs
[
'im_shape'
],
self
.
inputs
[
'scale_factor'
])
bbox
,
bbox_num
=
self
.
bboxes
output
=
{
'bbox'
:
bbox
.
numpy
(),
...
...
ppdet/modeling/bbox.py
浏览文件 @
dcf97ccd
...
...
@@ -93,6 +93,11 @@ class Proposal(object):
self
.
proposal_target_generator
=
proposal_target_generator
def
generate_proposal
(
self
,
inputs
,
rpn_head_out
,
anchor_out
):
# TODO: delete im_info
try
:
im_shape
=
inputs
[
'im_info'
]
except
:
im_shape
=
inputs
[
'im_shape'
]
rpn_rois_list
=
[]
rpn_prob_list
=
[]
rpn_rois_num_list
=
[]
...
...
@@ -104,7 +109,7 @@ class Proposal(object):
bbox_deltas
=
rpn_delta
,
anchors
=
anchor
,
variances
=
var
,
im_
info
=
inputs
[
'im_info'
]
,
im_
shape
=
im_shape
,
mode
=
inputs
[
'mode'
])
if
len
(
rpn_head_out
)
==
1
:
return
rpn_rois
,
rpn_rois_num
...
...
ppdet/modeling/head/mask_head.py
浏览文件 @
dcf97ccd
...
...
@@ -138,7 +138,7 @@ class MaskHead(Layer):
return
mask_head_out
def
forward_test
(
self
,
im_info
,
scale_factor
,
body_feats
,
bboxes
,
bbox_feat
,
...
...
@@ -149,12 +149,14 @@ class MaskHead(Layer):
if
bbox
.
shape
[
0
]
==
0
:
mask_head_out
=
bbox
else
:
im_info_expand
=
[]
scale_factor_list
=
[]
for
idx
,
num
in
enumerate
(
bbox_num
):
for
n
in
range
(
num
):
im_info_expand
.
append
(
im_info
[
idx
,
-
1
])
im_info_expand
=
paddle
.
concat
(
im_info_expand
)
scaled_bbox
=
paddle
.
multiply
(
bbox
[:,
2
:],
im_info_expand
,
axis
=
0
)
scale_factor_list
.
append
(
scale_factor
[
idx
,
0
])
scale_factor_list
=
paddle
.
cast
(
paddle
.
concat
(
scale_factor_list
),
'float32'
)
scaled_bbox
=
paddle
.
multiply
(
bbox
[:,
2
:],
scale_factor_list
,
axis
=
0
)
scaled_bboxes
=
(
scaled_bbox
,
bbox_num
)
mask_feat
=
self
.
mask_feat
(
body_feats
,
scaled_bboxes
,
bbox_feat
,
mask_index
,
spatial_scale
,
stage
)
...
...
@@ -174,8 +176,8 @@ class MaskHead(Layer):
mask_head_out
=
self
.
forward_train
(
body_feats
,
bboxes
,
bbox_feat
,
mask_index
,
spatial_scale
,
stage
)
else
:
im_info
=
inputs
[
'im_info
'
]
mask_head_out
=
self
.
forward_test
(
im_info
,
body_feats
,
bboxes
,
scale_factor
=
inputs
[
'scale_factor
'
]
mask_head_out
=
self
.
forward_test
(
scale_factor
,
body_feats
,
bboxes
,
bbox_feat
,
mask_index
,
spatial_scale
,
stage
)
return
mask_head_out
...
...
ppdet/modeling/layers.py
浏览文件 @
dcf97ccd
...
...
@@ -16,8 +16,7 @@ import numpy as np
from
numbers
import
Integral
import
paddle
import
paddle.fluid
as
fluid
from
paddle.fluid.dygraph.base
import
to_variable
from
paddle
import
to_tensor
from
ppdet.core.workspace
import
register
,
serializable
from
ppdet.py_op.target
import
generate_rpn_anchor_target
,
generate_proposal_target
,
generate_mask_target
from
ppdet.py_op.post_process
import
bbox_post_process
...
...
@@ -86,20 +85,20 @@ class AnchorTargetGeneratorRPN(object):
self
.
batch_size_per_im
,
self
.
positive_overlap
,
self
.
negative_overlap
,
self
.
fg_fraction
,
self
.
use_random
)
loc_indexes
=
to_
variable
(
loc_indexes
)
score_indexes
=
to_
variable
(
score_indexes
)
tgt_labels
=
to_
variable
(
tgt_labels
)
tgt_bboxes
=
to_
variable
(
tgt_bboxes
)
bbox_inside_weights
=
to_
variable
(
bbox_inside_weights
)
loc_indexes
=
to_
tensor
(
loc_indexes
)
score_indexes
=
to_
tensor
(
score_indexes
)
tgt_labels
=
to_
tensor
(
tgt_labels
)
tgt_bboxes
=
to_
tensor
(
tgt_bboxes
)
bbox_inside_weights
=
to_
tensor
(
bbox_inside_weights
)
loc_indexes
.
stop_gradient
=
True
score_indexes
.
stop_gradient
=
True
tgt_labels
.
stop_gradient
=
True
cls_logits
=
fluid
.
layers
.
reshape
(
x
=
cls_logits
,
shape
=
(
-
1
,
))
bbox_pred
=
fluid
.
layers
.
reshape
(
x
=
bbox_pred
,
shape
=
(
-
1
,
4
))
pred_cls_logits
=
fluid
.
layers
.
gather
(
cls_logits
,
score_indexes
)
pred_bbox_pred
=
fluid
.
layers
.
gather
(
bbox_pred
,
loc_indexes
)
cls_logits
=
paddle
.
reshape
(
x
=
cls_logits
,
shape
=
(
-
1
,
))
bbox_pred
=
paddle
.
reshape
(
x
=
bbox_pred
,
shape
=
(
-
1
,
4
))
pred_cls_logits
=
paddle
.
gather
(
cls_logits
,
score_indexes
)
pred_bbox_pred
=
paddle
.
gather
(
bbox_pred
,
loc_indexes
)
return
pred_cls_logits
,
pred_bbox_pred
,
tgt_labels
,
tgt_bboxes
,
bbox_inside_weights
...
...
@@ -131,22 +130,38 @@ class ProposalGenerator(object):
bbox_deltas
,
anchors
,
variances
,
im_
info
,
im_
shape
,
mode
=
'train'
):
pre_nms_top_n
=
self
.
train_pre_nms_top_n
if
mode
==
'train'
else
self
.
infer_pre_nms_top_n
post_nms_top_n
=
self
.
train_post_nms_top_n
if
mode
==
'train'
else
self
.
infer_post_nms_top_n
rpn_rois
,
rpn_rois_prob
,
rpn_rois_num
=
fluid
.
layers
.
generate_proposals
(
scores
,
bbox_deltas
,
im_info
,
anchors
,
variances
,
pre_nms_top_n
=
pre_nms_top_n
,
post_nms_top_n
=
post_nms_top_n
,
nms_thresh
=
self
.
nms_thresh
,
min_size
=
self
.
min_size
,
eta
=
self
.
eta
,
return_rois_num
=
True
)
# TODO delete im_info
if
im_shape
.
shape
[
1
]
>
2
:
import
paddle.fluid
as
fluid
rpn_rois
,
rpn_rois_prob
,
rpn_rois_num
=
fluid
.
layers
.
generate_proposals
(
scores
,
bbox_deltas
,
im_shape
,
anchors
,
variances
,
pre_nms_top_n
=
pre_nms_top_n
,
post_nms_top_n
=
post_nms_top_n
,
nms_thresh
=
self
.
nms_thresh
,
min_size
=
self
.
min_size
,
eta
=
self
.
eta
,
return_rois_num
=
True
)
else
:
rpn_rois
,
rpn_rois_prob
,
rpn_rois_num
=
ops
.
generate_proposals
(
scores
,
bbox_deltas
,
im_shape
,
anchors
,
variances
,
pre_nms_top_n
=
pre_nms_top_n
,
post_nms_top_n
=
post_nms_top_n
,
nms_thresh
=
self
.
nms_thresh
,
min_size
=
self
.
min_size
,
eta
=
self
.
eta
,
return_rois_num
=
True
)
return
rpn_rois
,
rpn_rois_prob
,
rpn_rois_num
,
post_nms_top_n
...
...
@@ -198,7 +213,7 @@ class ProposalTargetGenerator(object):
self
.
bg_thresh_hi
[
stage
],
self
.
bg_thresh_lo
[
stage
],
self
.
bbox_reg_weights
[
stage
],
self
.
num_classes
,
self
.
use_random
,
self
.
is_cls_agnostic
,
self
.
is_cascade_rcnn
)
outs
=
[
to_
variable
(
v
)
for
v
in
outs
]
outs
=
[
to_
tensor
(
v
)
for
v
in
outs
]
for
v
in
outs
:
v
.
stop_gradient
=
True
return
outs
...
...
@@ -227,7 +242,7 @@ class MaskTargetGenerator(object):
rois
,
rois_num
,
labels_int32
,
self
.
num_classes
,
self
.
mask_resolution
)
outs
=
[
to_
variable
(
v
)
for
v
in
outs
]
outs
=
[
to_
tensor
(
v
)
for
v
in
outs
]
for
v
in
outs
:
v
.
stop_gradient
=
True
return
outs
...
...
@@ -260,7 +275,7 @@ class RCNNBox(object):
scale_list
=
[]
origin_shape_list
=
[]
for
idx
in
range
(
self
.
batch_size
):
scale
=
scale_factor
[
idx
,
:]
scale
=
scale_factor
[
idx
,
:]
[
0
]
rois_num_per_im
=
rois_num
[
idx
]
expand_scale
=
paddle
.
expand
(
scale
,
[
rois_num_per_im
,
1
])
scale_list
.
append
(
expand_scale
)
...
...
@@ -327,7 +342,7 @@ class DecodeClipNms(object):
im_info
.
numpy
(),
self
.
keep_top_k
,
self
.
score_threshold
,
self
.
nms_threshold
,
self
.
num_classes
)
outs
=
[
to_
variable
(
v
)
for
v
in
outs
]
outs
=
[
to_
tensor
(
v
)
for
v
in
outs
]
for
v
in
outs
:
v
.
stop_gradient
=
True
return
outs
...
...
@@ -407,7 +422,6 @@ class YOLOBox(object):
def
__call__
(
self
,
yolo_head_out
,
anchors
,
im_shape
,
scale_factor
=
None
):
boxes_list
=
[]
scores_list
=
[]
im_shape
=
paddle
.
cast
(
im_shape
,
'float32'
)
if
scale_factor
is
not
None
:
origin_shape
=
im_shape
/
scale_factor
else
:
...
...
ppdet/modeling/post_process.py
浏览文件 @
dcf97ccd
...
...
@@ -17,14 +17,7 @@ class BBoxPostProcess(object):
self
.
nms
=
nms
def
__call__
(
self
,
head_out
,
rois
,
im_shape
,
scale_factor
=
None
):
# TODO: compatible for im_info
# remove after unify the im_shape. scale_factor
if
im_shape
.
shape
[
1
]
>
2
:
origin_shape
=
im_shape
[:,
:
2
]
scale_factor
=
im_shape
[:,
2
:]
else
:
origin_shape
=
im_shape
bboxes
,
score
=
self
.
decode
(
head_out
,
rois
,
origin_shape
,
scale_factor
)
bboxes
,
score
=
self
.
decode
(
head_out
,
rois
,
im_shape
,
scale_factor
)
bbox_pred
,
bbox_num
=
self
.
nms
(
bboxes
,
score
)
return
bbox_pred
,
bbox_num
...
...
@@ -38,12 +31,12 @@ class MaskPostProcess(object):
self
.
mask_resolution
=
mask_resolution
self
.
binary_thresh
=
binary_thresh
def
__call__
(
self
,
bboxes
,
mask_head_out
,
im_
info
):
def
__call__
(
self
,
bboxes
,
mask_head_out
,
im_
shape
,
scale_factor
=
None
):
# TODO: modify related ops for deploying
bboxes_np
=
(
i
.
numpy
()
for
i
in
bboxes
)
mask
=
mask_post_process
(
bboxes_np
,
mask_head_out
.
numpy
(),
im_
info
.
numpy
(),
self
.
mask_resolution
,
self
.
binary_thresh
)
im_
shape
.
numpy
(),
scale_factor
[:,
0
].
numpy
()
,
self
.
mask_resolution
,
self
.
binary_thresh
)
mask
=
{
'mask'
:
mask
}
return
mask
ppdet/py_op/post_process.py
浏览文件 @
dcf97ccd
...
...
@@ -10,7 +10,8 @@ import cv2
def
bbox_post_process
(
bboxes
,
bbox_prob
,
bbox_deltas
,
im_info
,
im_shape
,
scale_factor
,
keep_top_k
=
100
,
score_thresh
=
0.05
,
nms_thresh
=
0.5
,
...
...
@@ -27,14 +28,14 @@ def bbox_post_process(bboxes,
end_num
+=
box_num
boxes
=
bbox
[
st_num
:
end_num
,
:]
# bbox
boxes
=
boxes
/
im_info
[
i
][
2
]
# scale
boxes
=
boxes
/
scale_factor
[
i
]
# scale
bbox_delta
=
bbox_deltas
[
st_num
:
end_num
,
:,
:]
# bbox delta
bbox_delta
=
np
.
reshape
(
bbox_delta
,
(
box_num
,
-
1
))
# step1: decode
boxes
=
delta2bbox
(
bbox_delta
,
boxes
,
bbox_reg_weights
)
# step2: clip
boxes
=
clip_bbox
(
boxes
,
im_
info
[
i
][:
2
]
/
im_info
[
i
][
2
])
boxes
=
clip_bbox
(
boxes
,
im_
shape
[
i
][:
2
]
/
scale_factor
[
i
])
# step3: nms
cls_boxes
=
[[]
for
_
in
range
(
class_nums
)]
scores_n
=
bbox_prob
[
st_num
:
end_num
,
:]
...
...
@@ -72,7 +73,12 @@ def bbox_post_process(bboxes,
@
jit
def
mask_post_process
(
bboxes
,
masks
,
im_info
,
resolution
=
14
,
binary_thresh
=
0.5
):
def
mask_post_process
(
bboxes
,
masks
,
im_shape
,
scale_factor
,
resolution
=
14
,
binary_thresh
=
0.5
):
if
masks
.
shape
[
0
]
==
0
:
return
masks
bbox
,
bbox_nums
=
bboxes
...
...
@@ -93,8 +99,8 @@ def mask_post_process(bboxes, masks, im_info, resolution=14, binary_thresh=0.5):
labels_n
=
labels
[
st_num
:
end_num
]
masks_n
=
masks
[
st_num
:
end_num
]
im_h
=
int
(
round
(
im_
info
[
i
][
0
]
/
im_info
[
i
][
2
]))
im_w
=
int
(
round
(
im_
info
[
i
][
1
]
/
im_info
[
i
][
2
]))
im_h
=
int
(
round
(
im_
shape
[
i
][
0
]
/
scale_factor
[
i
]))
im_w
=
int
(
round
(
im_
shape
[
i
][
1
]
/
scale_factor
[
i
]))
boxes_n
=
expand_bbox
(
boxes_n
,
scale
)
boxes_n
=
boxes_n
.
astype
(
np
.
int32
)
padded_mask
=
np
.
zeros
((
M
+
2
,
M
+
2
),
dtype
=
np
.
float32
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录