test_nearest_interp_op.py 14.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
#
# 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
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# 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 print_function

import unittest
import numpy as np
from op_test import OpTest
import paddle.fluid.core as core
21
import paddle.fluid as fluid
22 23


24 25 26 27
def nearest_neighbor_interp_np(X,
                               out_h,
                               out_w,
                               out_size=None,
28 29
                               actual_shape=None,
                               align_corners=True):
30 31 32 33
    """nearest neighbor interpolation implement in shape [N, C, H, W]"""
    if out_size is not None:
        out_h = out_size[0]
        out_w = out_size[1]
34 35 36
    if actual_shape is not None:
        out_h = actual_shape[0]
        out_w = actual_shape[1]
37 38 39
    n, c, in_h, in_w = X.shape

    ratio_h = ratio_w = 0.0
T
tink2123 已提交
40 41 42 43 44 45 46 47 48 49
    if (out_h > 1):
        if (align_corners):
            ratio_h = (in_h - 1.0) / (out_h - 1.0)
        else:
            ratio_h = 1.0 * in_h / out_h
    if (out_w > 1):
        if (align_corners):
            ratio_w = (in_w - 1.0) / (out_w - 1.0)
        else:
            ratio_w = 1.0 * in_w / out_w
50 51

    out = np.zeros((n, c, out_h, out_w))
52 53 54 55 56 57 58 59 60 61 62 63 64

    if align_corners:
        for i in range(out_h):
            in_i = int(ratio_h * i + 0.5)
            for j in range(out_w):
                in_j = int(ratio_w * j + 0.5)
                out[:, :, i, j] = X[:, :, in_i, in_j]
    else:
        for i in range(out_h):
            in_i = int(ratio_h * i)
            for j in range(out_w):
                in_j = int(ratio_w * j)
                out[:, :, i, j] = X[:, :, in_i, in_j]
65 66 67 68

    return out.astype(X.dtype)


69
class TestNearestInterpOp(OpTest):
70 71
    def setUp(self):
        self.out_size = None
72
        self.actual_shape = None
73
        self.init_test_case()
74
        self.op_type = "nearest_interp"
75 76
        input_np = np.random.random(self.input_shape).astype("float32")

D
dengkaipeng 已提交
77 78 79 80 81 82 83 84
        if self.scale > 0:
            out_h = int(self.input_shape[2] * self.scale)
            out_w = int(self.input_shape[3] * self.scale)
        else:
            out_h = self.out_h
            out_w = self.out_w

        output_np = nearest_neighbor_interp_np(input_np, out_h, out_w,
85 86
                                               self.out_size, self.actual_shape,
                                               self.align_corners)
87 88 89
        self.inputs = {'X': input_np}
        if self.out_size is not None:
            self.inputs['OutSize'] = self.out_size
90 91
        if self.actual_shape is not None:
            self.inputs['OutSize'] = self.actual_shape
92 93 94
        self.attrs = {
            'out_h': self.out_h,
            'out_w': self.out_w,
D
dengkaipeng 已提交
95
            'scale': self.scale,
96 97
            'interp_method': self.interp_method,
            'align_corners': self.align_corners,
98 99 100 101 102 103 104 105 106 107
        }
        self.outputs = {'Out': output_np}

    def test_check_output(self):
        self.check_output()

    def test_check_grad(self):
        self.check_grad(['X'], 'Out', in_place=True)

    def init_test_case(self):
108
        self.interp_method = 'nearest'
109 110 111
        self.input_shape = [2, 3, 4, 4]
        self.out_h = 2
        self.out_w = 2
D
dengkaipeng 已提交
112
        self.scale = 0.
113
        self.out_size = np.array([3, 3]).astype("int32")
114
        self.align_corners = True
115 116


117
class TestNearestNeighborInterpCase1(TestNearestInterpOp):
118
    def init_test_case(self):
119
        self.interp_method = 'nearest'
120 121 122
        self.input_shape = [4, 1, 7, 8]
        self.out_h = 1
        self.out_w = 1
D
dengkaipeng 已提交
123
        self.scale = 0.
T
tink2123 已提交
124
        self.align_corners = True
125 126


127
class TestNearestNeighborInterpCase2(TestNearestInterpOp):
128
    def init_test_case(self):
129
        self.interp_method = 'nearest'
130 131 132
        self.input_shape = [3, 3, 9, 6]
        self.out_h = 12
        self.out_w = 12
D
dengkaipeng 已提交
133
        self.scale = 0.
134
        self.align_corners = True
135 136


137
class TestNearestNeighborInterpCase3(TestNearestInterpOp):
138
    def init_test_case(self):
139
        self.interp_method = 'nearest'
140 141 142
        self.input_shape = [1, 1, 128, 64]
        self.out_h = 64
        self.out_w = 128
D
dengkaipeng 已提交
143
        self.scale = 0.
144
        self.align_corners = True
145 146


147
class TestNearestNeighborInterpCase4(TestNearestInterpOp):
148
    def init_test_case(self):
149
        self.interp_method = 'nearest'
150 151 152
        self.input_shape = [4, 1, 7, 8]
        self.out_h = 1
        self.out_w = 1
D
dengkaipeng 已提交
153
        self.scale = 0.
154
        self.out_size = np.array([2, 2]).astype("int32")
155
        self.align_corners = True
156 157


158
class TestNearestNeighborInterpCase5(TestNearestInterpOp):
159
    def init_test_case(self):
160
        self.interp_method = 'nearest'
161 162 163
        self.input_shape = [3, 3, 9, 6]
        self.out_h = 12
        self.out_w = 12
D
dengkaipeng 已提交
164
        self.scale = 0.
165
        self.out_size = np.array([11, 11]).astype("int32")
166
        self.align_corners = True
167 168


169
class TestNearestNeighborInterpCase6(TestNearestInterpOp):
170
    def init_test_case(self):
171
        self.interp_method = 'nearest'
172 173 174
        self.input_shape = [1, 1, 128, 64]
        self.out_h = 64
        self.out_w = 128
D
dengkaipeng 已提交
175
        self.scale = 0.
176
        self.out_size = np.array([65, 129]).astype("int32")
177
        self.align_corners = True
178 179


K
Kaipeng Deng 已提交
180 181 182 183 184 185 186 187 188 189
class TestNearestNeighborInterpSame(TestNearestInterpOp):
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [2, 3, 128, 64]
        self.out_h = 128
        self.out_w = 64
        self.scale = 0.
        self.align_corners = True


190
class TestNearestNeighborInterpActualShape(TestNearestInterpOp):
191
    def init_test_case(self):
192
        self.interp_method = 'nearest'
193 194 195
        self.input_shape = [3, 2, 32, 16]
        self.out_h = 64
        self.out_w = 32
D
dengkaipeng 已提交
196
        self.scale = 0.
197
        self.out_size = np.array([66, 40]).astype("int32")
198
        self.align_corners = True
199 200


201
class TestNearestInterpOpUint8(OpTest):
202 203
    def setUp(self):
        self.out_size = None
204
        self.actual_shape = None
205
        self.init_test_case()
206
        self.op_type = "nearest_interp"
207 208
        input_np = np.random.randint(
            low=0, high=256, size=self.input_shape).astype("uint8")
D
dengkaipeng 已提交
209 210 211 212 213 214 215 216 217

        if self.scale > 0:
            out_h = int(self.input_shape[2] * self.scale)
            out_w = int(self.input_shape[3] * self.scale)
        else:
            out_h = self.out_h
            out_w = self.out_w

        output_np = nearest_neighbor_interp_np(input_np, out_h, out_w,
218 219
                                               self.out_size, self.actual_shape,
                                               self.align_corners)
220 221 222 223 224 225
        self.inputs = {'X': input_np}
        if self.out_size is not None:
            self.inputs['OutSize'] = self.out_size
        self.attrs = {
            'out_h': self.out_h,
            'out_w': self.out_w,
D
dengkaipeng 已提交
226
            'scale': self.scale,
227 228
            'interp_method': self.interp_method,
            'align_corners': self.align_corners
229 230 231 232 233 234 235
        }
        self.outputs = {'Out': output_np}

    def test_check_output(self):
        self.check_output_with_place(place=core.CPUPlace(), atol=1)

    def init_test_case(self):
236
        self.interp_method = 'nearest'
237 238 239
        self.input_shape = [1, 3, 9, 6]
        self.out_h = 10
        self.out_w = 9
D
dengkaipeng 已提交
240
        self.scale = 0.
241
        self.align_corners = True
242 243


244
class TestNearestNeighborInterpCase1Uint8(TestNearestInterpOpUint8):
245 246 247 248 249
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [2, 3, 128, 64]
        self.out_h = 120
        self.out_w = 50
D
dengkaipeng 已提交
250
        self.scale = 0.
T
tink2123 已提交
251
        self.align_corners = True
252 253


254
class TestNearestNeighborInterpCase2Uint8(TestNearestInterpOpUint8):
255 256 257 258 259
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [4, 1, 7, 8]
        self.out_h = 5
        self.out_w = 13
D
dengkaipeng 已提交
260
        self.scale = 0.
261
        self.out_size = np.array([6, 15]).astype("int32")
262 263 264 265 266 267
        self.align_corners = True


class TestNearestInterpWithoutCorners(TestNearestInterpOp):
    def set_align_corners(self):
        self.align_corners = False
268 269


D
dengkaipeng 已提交
270 271 272
class TestNearestNeighborInterpScale1(TestNearestInterpOp):
    def init_test_case(self):
        self.interp_method = 'nearest'
273
        self.input_shape = [3, 2, 7, 5]
D
dengkaipeng 已提交
274 275 276 277 278 279 280 281 282 283
        self.out_h = 64
        self.out_w = 32
        self.scale = 2.
        self.out_size = np.array([66, 40]).astype("int32")
        self.align_corners = True


class TestNearestNeighborInterpScale2(TestNearestInterpOp):
    def init_test_case(self):
        self.interp_method = 'nearest'
284
        self.input_shape = [3, 2, 5, 7]
D
dengkaipeng 已提交
285 286 287 288 289 290 291 292 293 294
        self.out_h = 64
        self.out_w = 32
        self.scale = 1.5
        self.out_size = np.array([66, 40]).astype("int32")
        self.align_corners = True


class TestNearestNeighborInterpScale3(TestNearestInterpOp):
    def init_test_case(self):
        self.interp_method = 'nearest'
295
        self.input_shape = [3, 2, 7, 5]
D
dengkaipeng 已提交
296 297 298 299 300 301 302
        self.out_h = 64
        self.out_w = 32
        self.scale = 1.
        self.out_size = np.array([66, 40]).astype("int32")
        self.align_corners = True


303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
class TestNearestInterpOp_attr_tensor(OpTest):
    def setUp(self):
        self.out_size = None
        self.actual_shape = None
        self.init_test_case()
        self.op_type = "nearest_interp"
        self.shape_by_1Dtensor = False
        self.scale_by_1Dtensor = False
        self.attrs = {
            'interp_method': self.interp_method,
            'align_corners': self.align_corners,
        }

        input_np = np.random.random(self.input_shape).astype("float32")
        self.inputs = {'X': input_np}

        if self.scale_by_1Dtensor:
            self.inputs['Scale'] = np.array([self.scale]).astype("float32")
        elif self.scale > 0:
            out_h = int(self.input_shape[2] * self.scale)
            out_w = int(self.input_shape[3] * self.scale)
            self.attrs['scale'] = self.scale
        else:
            out_h = self.out_h
            out_w = self.out_w

        if self.shape_by_1Dtensor:
            self.inputs['OutSize'] = self.out_size
        elif self.out_size is not None:
            size_tensor = []
            for index, ele in enumerate(self.out_size):
                size_tensor.append(("x" + str(index), np.ones(
                    (1)).astype('int32') * ele))
            self.inputs['SizeTensor'] = size_tensor

        self.attrs['out_h'] = self.out_h
        self.attrs['out_w'] = self.out_w
        output_np = nearest_neighbor_interp_np(input_np, out_h, out_w,
                                               self.out_size, self.actual_shape,
                                               self.align_corners)
        self.outputs = {'Out': output_np}

    def test_check_output(self):
        self.check_output()

    def test_check_grad(self):
        self.check_grad(['X'], 'Out', in_place=True)

    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [2, 3, 4, 4]
        self.out_h = 3
        self.out_w = 3
        self.scale = 0.
        self.out_size = [3, 3]
        self.align_corners = True


# out_size is a tensor list
class TestNearestInterp_attr_tensor_Case1(TestNearestInterpOp_attr_tensor):
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [3, 3, 9, 6]
        self.out_h = 12
        self.out_w = 12
        self.scale = 0.
        self.out_size = [8, 12]
        self.align_corners = True


# out_size is a 1-D tensor
class TestNearestInterp_attr_tensor_Case2(TestNearestInterpOp_attr_tensor):
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [3, 2, 32, 16]
        self.out_h = 64
        self.out_w = 32
        self.scale = 0.
        self.out_size = np.array([66, 40]).astype("int32")
        self.align_corners = True
        self.shape_by_1Dtensor = True


# scale is a 1-D tensor
class TestNearestInterp_attr_tensor_Case3(TestNearestInterpOp_attr_tensor):
    def init_test_case(self):
        self.interp_method = 'nearest'
        self.input_shape = [3, 2, 32, 16]
        self.out_h = 64
        self.out_w = 32
        self.scale = 2.0
        self.out_size = None
        self.align_corners = True
        self.scale_by_1Dtensor = True


class TestNearestAPI(OpTest):
    def test_case(self):
        x = fluid.layers.data(name="x", shape=[3, 6, 6], dtype="float32")

        dim = fluid.layers.data(
            name="dim", shape=[1], dtype="int32", append_batch_size=False)
        shape_tensor = fluid.layers.data(
            name="shape_tensor",
            shape=[2],
            dtype="int32",
            append_batch_size=False)
        actual_size = fluid.layers.data(
            name="actual_size",
            shape=[2],
            dtype="int32",
            append_batch_size=False)
        scale_tensor = fluid.layers.data(
            name="scale_tensor",
            shape=[1],
            dtype="float32",
            append_batch_size=False)

        out1 = fluid.layers.resize_nearest(x, out_shape=[12, 12])
        out2 = fluid.layers.resize_nearest(x, out_shape=[12, dim])
        out3 = fluid.layers.resize_nearest(x, out_shape=shape_tensor)
        out4 = fluid.layers.resize_nearest(
            x, out_shape=[4, 4], actual_shape=actual_size)
        out5 = fluid.layers.resize_nearest(x, scale=scale_tensor)

        x_data = np.random.random((1, 3, 6, 6)).astype("float32")
        dim_data = np.array([12]).astype("int32")
        shape_data = np.array([12, 12]).astype("int32")
        actual_size_data = np.array([12, 12]).astype("int32")
        scale_data = np.array([2.0]).astype("float32")

        place = core.CPUPlace()
        exe = fluid.Executor(place)
        results = exe.run(fluid.default_main_program(),
                          feed={
                              "x": x_data,
                              "dim": dim_data,
                              "shape_tensor": shape_data,
                              "actual_size": actual_size_data,
                              "scale_tensor": scale_data
                          },
                          fetch_list=[out1, out2, out3, out4, out5],
                          return_numpy=True)

        expect_res = nearest_neighbor_interp_np(
            x_data, out_h=12, out_w=12, align_corners=True)
        for res in results:
            self.assertTrue(np.allclose(res, expect_res))


453 454
if __name__ == "__main__":
    unittest.main()