test_yolo_box_op.py 9.6 KB
Newer Older
1 2
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
# 
D
dengkaipeng 已提交
3 4 5
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
6
# 
D
dengkaipeng 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
8
# 
D
dengkaipeng 已提交
9 10 11 12 13 14 15 16 17 18
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import division
import unittest
import numpy as np
from op_test import OpTest
19
import paddle
D
dengkaipeng 已提交
20
from paddle.fluid import core
21
from paddle.fluid.framework import _test_eager_guard
D
dengkaipeng 已提交
22 23 24


def sigmoid(x):
25
    return (1.0 / (1.0 + np.exp(((-1.0) * x))))
D
dengkaipeng 已提交
26 27


28
def YoloBox(x, img_size, attrs):
29
    (n, c, h, w) = x.shape
D
dengkaipeng 已提交
30
    anchors = attrs['anchors']
31
    an_num = int((len(anchors) // 2))
D
dengkaipeng 已提交
32 33 34
    class_num = attrs['class_num']
    conf_thresh = attrs['conf_thresh']
    downsample = attrs['downsample']
35
    clip_bbox = attrs['clip_bbox']
36
    scale_x_y = attrs['scale_x_y']
37 38
    iou_aware = attrs['iou_aware']
    iou_aware_factor = attrs['iou_aware_factor']
39 40 41
    bias_x_y = ((-0.5) * (scale_x_y - 1.0))
    input_h = (downsample * h)
    input_w = (downsample * w)
42 43
    if iou_aware:
        ioup = x[:, :an_num, :, :]
44
        ioup = np.expand_dims(ioup, axis=(-1))
45
        x = x[:, an_num:, :, :]
46
    x = x.reshape((n, an_num, (5 + class_num), h, w)).transpose((0, 1, 3, 4, 2))
D
dengkaipeng 已提交
47 48 49
    pred_box = x[:, :, :, :, :4].copy()
    grid_x = np.tile(np.arange(w).reshape((1, w)), (h, 1))
    grid_y = np.tile(np.arange(h).reshape((h, 1)), (1, w))
50 51 52 53 54 55 56 57
    pred_box[:, :, :, :, 0] = ((
        (grid_x + (sigmoid(pred_box[:, :, :, :, 0]) * scale_x_y)) + bias_x_y) /
                               w)
    pred_box[:, :, :, :, 1] = ((
        (grid_y + (sigmoid(pred_box[:, :, :, :, 1]) * scale_x_y)) + bias_x_y) /
                               h)
    anchors = [(anchors[i], anchors[(i + 1)])
               for i in range(0, len(anchors), 2)]
D
dengkaipeng 已提交
58
    anchors_s = np.array(
59
        [((an_w / input_w), (an_h / input_h)) for (an_w, an_h) in anchors])
D
dengkaipeng 已提交
60 61
    anchor_w = anchors_s[:, 0:1].reshape((1, an_num, 1, 1))
    anchor_h = anchors_s[:, 1:2].reshape((1, an_num, 1, 1))
62 63
    pred_box[:, :, :, :, 2] = (np.exp(pred_box[:, :, :, :, 2]) * anchor_w)
    pred_box[:, :, :, :, 3] = (np.exp(pred_box[:, :, :, :, 3]) * anchor_h)
64
    if iou_aware:
65 66
        pred_conf = ((sigmoid(x[:, :, :, :, 4:5])**(1 - iou_aware_factor)) *
                     (sigmoid(ioup)**iou_aware_factor))
67 68
    else:
        pred_conf = sigmoid(x[:, :, :, :, 4:5])
69 70 71 72 73 74 75 76 77 78 79
    pred_conf[(pred_conf < conf_thresh)] = 0.0
    pred_score = (sigmoid(x[:, :, :, :, 5:]) * pred_conf)
    pred_box = (pred_box * (pred_conf > 0.0).astype('float32'))
    pred_box = pred_box.reshape((n, (-1), 4))
    (pred_box[:, :, :2], pred_box[:, :, 2:4]) = (
        (pred_box[:, :, :2] - (pred_box[:, :, 2:4] / 2.0)),
        (pred_box[:, :, :2] + (pred_box[:, :, 2:4] / 2.0)))
    pred_box[:, :, 0] = (pred_box[:, :, 0] * img_size[:, 1][:, np.newaxis])
    pred_box[:, :, 1] = (pred_box[:, :, 1] * img_size[:, 0][:, np.newaxis])
    pred_box[:, :, 2] = (pred_box[:, :, 2] * img_size[:, 1][:, np.newaxis])
    pred_box[:, :, 3] = (pred_box[:, :, 3] * img_size[:, 0][:, np.newaxis])
80 81 82 83
    if clip_bbox:
        for i in range(len(pred_box)):
            pred_box[i, :, 0] = np.clip(pred_box[i, :, 0], 0, np.inf)
            pred_box[i, :, 1] = np.clip(pred_box[i, :, 1], 0, np.inf)
84 85 86 87 88
            pred_box[i, :, 2] = np.clip(pred_box[i, :, 2], (-np.inf),
                                        (img_size[(i, 1)] - 1))
            pred_box[i, :, 3] = np.clip(pred_box[i, :, 3], (-np.inf),
                                        (img_size[(i, 0)] - 1))
    return (pred_box, pred_score.reshape((n, (-1), class_num)))
D
dengkaipeng 已提交
89 90 91 92 93 94 95


class TestYoloBoxOp(OpTest):
    def setUp(self):
        self.initTestCase()
        self.op_type = 'yolo_box'
        x = np.random.random(self.x_shape).astype('float32')
96
        img_size = np.random.randint(10, 20, self.imgsize_shape).astype('int32')
D
dengkaipeng 已提交
97
        self.attrs = {
98 99 100 101 102 103 104 105
            'anchors': self.anchors,
            'class_num': self.class_num,
            'conf_thresh': self.conf_thresh,
            'downsample': self.downsample,
            'clip_bbox': self.clip_bbox,
            'scale_x_y': self.scale_x_y,
            'iou_aware': self.iou_aware,
            'iou_aware_factor': self.iou_aware_factor
D
dengkaipeng 已提交
106
        }
107 108 109
        self.inputs = {'X': x, 'ImgSize': img_size}
        (boxes, scores) = YoloBox(x, img_size, self.attrs)
        self.outputs = {'Boxes': boxes, 'Scores': scores}
D
dengkaipeng 已提交
110 111

    def test_check_output(self):
112
        self.check_output(check_eager=True)
D
dengkaipeng 已提交
113 114 115

    def initTestCase(self):
        self.anchors = [10, 13, 16, 30, 33, 23]
116
        an_num = int((len(self.anchors) // 2))
117
        self.batch_size = 32
D
dengkaipeng 已提交
118 119 120
        self.class_num = 2
        self.conf_thresh = 0.5
        self.downsample = 32
121
        self.clip_bbox = True
122 123
        self.x_shape = (self.batch_size, (an_num * (5 + self.class_num)), 13,
                        13)
124
        self.imgsize_shape = (self.batch_size, 2)
125
        self.scale_x_y = 1.0
126 127
        self.iou_aware = False
        self.iou_aware_factor = 0.5
128 129 130 131 132


class TestYoloBoxOpNoClipBbox(TestYoloBoxOp):
    def initTestCase(self):
        self.anchors = [10, 13, 16, 30, 33, 23]
133
        an_num = int((len(self.anchors) // 2))
134 135 136 137 138
        self.batch_size = 32
        self.class_num = 2
        self.conf_thresh = 0.5
        self.downsample = 32
        self.clip_bbox = False
139 140
        self.x_shape = (self.batch_size, (an_num * (5 + self.class_num)), 13,
                        13)
141
        self.imgsize_shape = (self.batch_size, 2)
142
        self.scale_x_y = 1.0
143 144
        self.iou_aware = False
        self.iou_aware_factor = 0.5
145 146 147 148 149


class TestYoloBoxOpScaleXY(TestYoloBoxOp):
    def initTestCase(self):
        self.anchors = [10, 13, 16, 30, 33, 23]
150
        an_num = int((len(self.anchors) // 2))
151 152 153 154 155
        self.batch_size = 32
        self.class_num = 2
        self.conf_thresh = 0.5
        self.downsample = 32
        self.clip_bbox = True
156 157
        self.x_shape = (self.batch_size, (an_num * (5 + self.class_num)), 13,
                        13)
158 159
        self.imgsize_shape = (self.batch_size, 2)
        self.scale_x_y = 1.2
160 161 162 163 164 165 166
        self.iou_aware = False
        self.iou_aware_factor = 0.5


class TestYoloBoxOpIoUAware(TestYoloBoxOp):
    def initTestCase(self):
        self.anchors = [10, 13, 16, 30, 33, 23]
167
        an_num = int((len(self.anchors) // 2))
168 169 170 171 172
        self.batch_size = 32
        self.class_num = 2
        self.conf_thresh = 0.5
        self.downsample = 32
        self.clip_bbox = True
173 174
        self.x_shape = (self.batch_size, (an_num * (6 + self.class_num)), 13,
                        13)
175
        self.imgsize_shape = (self.batch_size, 2)
176
        self.scale_x_y = 1.0
177 178
        self.iou_aware = True
        self.iou_aware_factor = 0.5
D
dengkaipeng 已提交
179 180


181 182 183 184 185
class TestYoloBoxDygraph(unittest.TestCase):
    def test_dygraph(self):
        paddle.disable_static()
        img_size = np.ones((2, 2)).astype('int32')
        img_size = paddle.to_tensor(img_size)
186 187
        x1 = np.random.random([2, 14, 8, 8]).astype('float32')
        x1 = paddle.to_tensor(x1)
188
        (boxes, scores) = paddle.vision.ops.yolo_box(
189
            x1,
190 191 192 193 194 195
            img_size=img_size,
            anchors=[10, 13, 16, 30],
            class_num=2,
            conf_thresh=0.01,
            downsample_ratio=8,
            clip_bbox=True,
196 197
            scale_x_y=1.0)
        assert ((boxes is not None) and (scores is not None))
198 199
        x2 = np.random.random([2, 16, 8, 8]).astype('float32')
        x2 = paddle.to_tensor(x2)
200
        (boxes, scores) = paddle.vision.ops.yolo_box(
201 202 203 204 205 206 207
            x2,
            img_size=img_size,
            anchors=[10, 13, 16, 30],
            class_num=2,
            conf_thresh=0.01,
            downsample_ratio=8,
            clip_bbox=True,
208
            scale_x_y=1.0,
209 210
            iou_aware=True,
            iou_aware_factor=0.5)
211 212
        paddle.enable_static()

213 214 215 216
    def test_eager(self):
        with _test_eager_guard():
            self.test_dygraph()

217 218 219

class TestYoloBoxStatic(unittest.TestCase):
    def test_static(self):
220
        x1 = paddle.static.data('x1', [2, 14, 8, 8], 'float32')
221
        img_size = paddle.static.data('img_size', [2, 2], 'int32')
222
        (boxes, scores) = paddle.vision.ops.yolo_box(
223
            x1,
224 225 226 227 228 229
            img_size=img_size,
            anchors=[10, 13, 16, 30],
            class_num=2,
            conf_thresh=0.01,
            downsample_ratio=8,
            clip_bbox=True,
230 231
            scale_x_y=1.0)
        assert ((boxes is not None) and (scores is not None))
232
        x2 = paddle.static.data('x2', [2, 16, 8, 8], 'float32')
233
        (boxes, scores) = paddle.vision.ops.yolo_box(
234 235 236 237 238 239 240
            x2,
            img_size=img_size,
            anchors=[10, 13, 16, 30],
            class_num=2,
            conf_thresh=0.01,
            downsample_ratio=8,
            clip_bbox=True,
241
            scale_x_y=1.0,
242 243
            iou_aware=True,
            iou_aware_factor=0.5)
244
        assert ((boxes is not None) and (scores is not None))
245

246

247 248 249
class TestYoloBoxOpHW(TestYoloBoxOp):
    def initTestCase(self):
        self.anchors = [10, 13, 16, 30, 33, 23]
250
        an_num = int((len(self.anchors) // 2))
251 252 253 254 255
        self.batch_size = 32
        self.class_num = 2
        self.conf_thresh = 0.5
        self.downsample = 32
        self.clip_bbox = False
256
        self.x_shape = (self.batch_size, (an_num * (5 + self.class_num)), 13, 9)
257
        self.imgsize_shape = (self.batch_size, 2)
258
        self.scale_x_y = 1.0
259 260
        self.iou_aware = False
        self.iou_aware_factor = 0.5
261 262


263
if (__name__ == '__main__'):
D
dengkaipeng 已提交
264
    unittest.main()