test_mean_op.py 12.3 KB
Newer Older
1
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
D
dzhwinter 已提交
2
#
D
dzhwinter 已提交
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
D
dzhwinter 已提交
6
#
D
dzhwinter 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
D
dzhwinter 已提交
8
#
D
dzhwinter 已提交
9 10 11 12 13 14
# 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.

15 16
from __future__ import print_function

L
liaogang 已提交
17 18
import unittest
import numpy as np
A
arlesniak 已提交
19
from op_test import OpTest, OpTestTool
20
import paddle
C
chengduo 已提交
21
import paddle.fluid.core as core
22 23
import paddle.fluid as fluid
from paddle.fluid import Program, program_guard
24
from paddle.fluid.framework import _test_eager_guard
25

26 27
np.random.seed(10)

L
liaogang 已提交
28

29 30 31 32 33 34 35 36 37 38 39 40
def mean_wrapper(x, axis=None, keepdim=False, reduce_all=False):
    if reduce_all == True:
        return paddle.mean(x, range(len(x.shape)), keepdim)
    return paddle.mean(x, axis, keepdim)


def reduce_mean_wrapper(x, axis=0, keepdim=False, reduce_all=False):
    if reduce_all == True:
        return paddle.mean(x, range(len(x.shape)), keepdim)
    return paddle.mean(x, axis, keepdim)


Q
qijun 已提交
41
class TestMeanOp(OpTest):
42

L
liaogang 已提交
43
    def setUp(self):
Q
qijun 已提交
44
        self.op_type = "mean"
45
        self.python_api = paddle.mean
46
        self.dtype = np.float64
C
chengduo 已提交
47 48
        self.init_dtype_type()
        self.inputs = {'X': np.random.random((10, 10)).astype(self.dtype)}
Q
qijun 已提交
49
        self.outputs = {'Out': np.mean(self.inputs["X"])}
L
liaogang 已提交
50

C
chengduo 已提交
51 52 53
    def init_dtype_type(self):
        pass

Q
qijun 已提交
54
    def test_check_output(self):
55
        self.check_output(check_eager=True)
L
liaogang 已提交
56

Q
qijun 已提交
57
    def test_checkout_grad(self):
58
        self.check_grad(['X'], 'Out', check_eager=True)
59 60


61
class TestMeanOpError(unittest.TestCase):
62

63 64 65 66
    def test_errors(self):
        with program_guard(Program(), Program()):
            # The input type of mean_op must be Variable.
            input1 = 12
67
            self.assertRaises(TypeError, paddle.mean, input1)
68
            # The input dtype of mean_op must be float16, float32, float64.
69 70 71
            input2 = fluid.layers.data(name='input2',
                                       shape=[12, 10],
                                       dtype="int32")
72
            self.assertRaises(TypeError, paddle.mean, input2)
73 74 75
            input3 = fluid.layers.data(name='input3',
                                       shape=[4],
                                       dtype="float16")
76 77 78
            fluid.layers.softmax(input3)


C
chengduo 已提交
79 80 81
@unittest.skipIf(not core.is_compiled_with_cuda(),
                 "core is not compiled with CUDA")
class TestFP16MeanOp(TestMeanOp):
82

C
chengduo 已提交
83 84
    def init_dtype_type(self):
        self.dtype = np.float16
S
sneaxiy 已提交
85
        self.__class__.no_need_check_grad = True
C
chengduo 已提交
86 87 88 89

    def test_check_output(self):
        place = core.CUDAPlace(0)
        if core.is_float16_supported(place):
90
            self.check_output_with_place(place, check_eager=True)
C
chengduo 已提交
91 92 93 94

    def test_checkout_grad(self):
        place = core.CUDAPlace(0)
        if core.is_float16_supported(place):
S
sneaxiy 已提交
95 96 97 98
            with fluid.dygraph.guard():
                x_np = np.random.random((10, 10)).astype(self.dtype)
                x = paddle.to_tensor(x_np)
                x.stop_gradient = False
99
                y = paddle.mean(x)
S
sneaxiy 已提交
100 101 102 103
                dx = paddle.grad(y, x)[0].numpy()
                dx_expected = self.dtype(1.0 / np.prod(x_np.shape)) * np.ones(
                    x_np.shape).astype(self.dtype)
                self.assertTrue(np.array_equal(dx, dx_expected))
C
chengduo 已提交
104 105


A
arlesniak 已提交
106 107
@OpTestTool.skip_if_not_cpu_bf16()
class TestBF16MeanOp(TestMeanOp):
108

A
arlesniak 已提交
109 110 111 112 113
    def init_dtype_type(self):
        self.dtype = np.uint16

    def test_check_output(self):
        paddle.enable_static()
114
        self.check_output_with_place(core.CPUPlace(), check_eager=True)
A
arlesniak 已提交
115 116 117

    def test_checkout_grad(self):
        place = core.CPUPlace()
118
        self.check_grad_with_place(place, ['X'], 'Out', check_eager=True)
A
arlesniak 已提交
119 120


121 122 123 124 125 126 127 128
def ref_reduce_mean(x, axis=None, keepdim=False, reduce_all=False):
    if isinstance(axis, list):
        axis = tuple(axis)
    if reduce_all:
        axis = None
    return np.mean(x, axis=axis, keepdims=keepdim)


S
sneaxiy 已提交
129 130 131 132 133 134 135 136
def ref_reduce_mean_grad(x, axis, dtype):
    if reduce_all:
        axis = list(range(x.ndim))

    shape = [x.shape[i] for i in axis]
    return (1.0 / np.prod(shape) * np.ones(shape)).astype(dtype)


137
class TestReduceMeanOp(OpTest):
138

139 140
    def setUp(self):
        self.op_type = 'reduce_mean'
141
        self.python_api = reduce_mean_wrapper
142 143 144 145 146 147 148 149
        self.dtype = 'float64'
        self.shape = [2, 3, 4, 5]
        self.axis = [0]
        self.keepdim = False
        self.set_attrs()

        np.random.seed(10)
        x_np = np.random.uniform(-1, 1, self.shape).astype(self.dtype)
S
sneaxiy 已提交
150 151 152
        if not hasattr(self, "reduce_all"):
            self.reduce_all = (not self.axis) or len(self.axis) == len(x_np)

153 154 155 156 157 158 159 160 161
        out_np = ref_reduce_mean(x_np, self.axis, self.keepdim, self.reduce_all)
        self.inputs = {'X': x_np}
        self.outputs = {'Out': out_np}
        self.attrs = {
            'dim': self.axis,
            'keep_dim': self.keepdim,
            'reduce_all': self.reduce_all
        }

S
sneaxiy 已提交
162 163 164
        if self.dtype == 'float16':
            self.__class__.no_need_check_grad = True

165 166 167 168
    def set_attrs(self):
        pass

    def test_check_output(self):
S
sneaxiy 已提交
169
        if self.dtype != 'float16':
170
            self.check_output(check_eager=True)
S
sneaxiy 已提交
171 172 173 174 175
        else:
            if not core.is_compiled_with_cuda():
                return
            place = paddle.CUDAPlace(0)
            self.check_output_with_place(place=place)
176 177

    def test_check_grad(self):
S
sneaxiy 已提交
178
        if self.dtype != 'float16':
179
            self.check_grad(['X'], ['Out'], check_eager=True)
S
sneaxiy 已提交
180 181 182 183 184 185 186 187 188
        else:
            return
            if not core.is_compiled_with_cuda():
                return
            place = paddle.CUDAPlace(0)
            if core.is_float16_supported(place):
                return
            with fluid.dygraph.guard(place=place):
                x = paddle.tensor(self.inputs['X'])
189 190 191
                y = paddle.mean(x,
                                axis=self.attrs['dim'],
                                keepdim=self.attrs['keep_dim'])
S
sneaxiy 已提交
192
                dx = paddle.grad(y, x)[0].numpy()
193 194 195
                dx_expected = ref_reduce_mean_grad(self.inputs['X'],
                                                   self.attrs['dim'],
                                                   self.dtype)
S
sneaxiy 已提交
196
                self.assertTrue(np.array_equal(dx, dx_expected))
197 198 199


class TestReduceMeanOpDefaultAttrs(TestReduceMeanOp):
200

201 202
    def setUp(self):
        self.op_type = 'reduce_mean'
203
        self.python_api = reduce_mean_wrapper
204 205 206 207 208 209 210 211 212 213
        self.dtype = 'float64'
        self.shape = [2, 3, 4, 5]

        x_np = np.random.uniform(-1, 1, self.shape).astype(self.dtype)
        out_np = np.mean(x_np, axis=0)
        self.inputs = {'X': x_np}
        self.outputs = {'Out': out_np}


class TestReduceMeanOpFloat32(TestReduceMeanOp):
214

215 216 217 218
    def set_attrs(self):
        self.dtype = 'float32'


S
sneaxiy 已提交
219
class TestReduceMeanOpFloat16(TestReduceMeanOp):
220

S
sneaxiy 已提交
221 222 223 224
    def set_attrs(self):
        self.dtype = 'float16'


225
class TestReduceMeanOpShape1D(TestReduceMeanOp):
226

227 228 229 230
    def set_attrs(self):
        self.shape = [100]


S
sneaxiy 已提交
231
class TestReduceMeanOpShape1DFP16(TestReduceMeanOp):
232

S
sneaxiy 已提交
233 234 235 236 237
    def set_attrs(self):
        self.shape = [100]
        self.dtype = 'float16'


238
class TestReduceMeanOpShape6D(TestReduceMeanOp):
239

240 241 242 243
    def set_attrs(self):
        self.shape = [2, 3, 4, 5, 6, 7]


S
sneaxiy 已提交
244
class TestReduceMeanOpShape6DFP16(TestReduceMeanOp):
245

S
sneaxiy 已提交
246 247 248 249 250
    def set_attrs(self):
        self.shape = [2, 3, 4, 5, 6, 7]
        self.dtype = 'float16'


251
class TestReduceMeanOpAxisAll(TestReduceMeanOp):
252

253 254 255 256
    def set_attrs(self):
        self.axis = [0, 1, 2, 3]


S
sneaxiy 已提交
257
class TestReduceMeanOpAxisAllFP16(TestReduceMeanOp):
258

S
sneaxiy 已提交
259 260 261 262 263
    def set_attrs(self):
        self.axis = [0, 1, 2, 3]
        self.dtype = 'float16'


264
class TestReduceMeanOpAxisTuple(TestReduceMeanOp):
265

266 267 268 269
    def set_attrs(self):
        self.axis = (0, 1, 2)


S
sneaxiy 已提交
270
class TestReduceMeanOpAxisTupleFP16(TestReduceMeanOp):
271

S
sneaxiy 已提交
272 273 274 275 276
    def set_attrs(self):
        self.axis = (0, 1, 2)
        self.dtype = 'float16'


277
class TestReduceMeanOpAxisNegative(TestReduceMeanOp):
278

279 280 281 282
    def set_attrs(self):
        self.axis = [-2, -1]


S
sneaxiy 已提交
283
class TestReduceMeanOpAxisNegativeFP16(TestReduceMeanOp):
284

S
sneaxiy 已提交
285 286 287 288 289
    def set_attrs(self):
        self.axis = [-2, -1]
        self.dtype = 'float16'


290
class TestReduceMeanOpKeepdimTrue1(TestReduceMeanOp):
291

292 293 294 295
    def set_attrs(self):
        self.keepdim = True


S
sneaxiy 已提交
296
class TestReduceMeanOpKeepdimTrue1FP16(TestReduceMeanOp):
297

S
sneaxiy 已提交
298 299 300 301 302
    def set_attrs(self):
        self.keepdim = True
        self.dtype = 'float16'


303
class TestReduceMeanOpKeepdimTrue2(TestReduceMeanOp):
304

305 306 307 308 309
    def set_attrs(self):
        self.axis = [0, 1, 2, 3]
        self.keepdim = True


S
sneaxiy 已提交
310
class TestReduceMeanOpKeepdimTrue2FP16(TestReduceMeanOp):
311

S
sneaxiy 已提交
312 313 314 315 316 317
    def set_attrs(self):
        self.axis = [0, 1, 2, 3]
        self.keepdim = True
        self.dtype = 'float16'


318
class TestReduceMeanOpReduceAllTrue(TestReduceMeanOp):
319

320 321 322 323
    def set_attrs(self):
        self.reduce_all = True


S
sneaxiy 已提交
324
class TestReduceMeanOpReduceAllTrueFP16(TestReduceMeanOp):
325

S
sneaxiy 已提交
326 327 328 329 330
    def set_attrs(self):
        self.reduce_all = True
        self.dtype = 'float16'


331
class TestMeanAPI(unittest.TestCase):
332
    # test paddle.tensor.stat.mean
333 334 335 336 337 338 339 340

    def setUp(self):
        self.x_shape = [2, 3, 4, 5]
        self.x = np.random.uniform(-1, 1, self.x_shape).astype(np.float32)
        self.place = paddle.CUDAPlace(0) if core.is_compiled_with_cuda() \
            else paddle.CPUPlace()

    def test_api_static(self):
Z
Fix  
zhupengyang 已提交
341
        paddle.enable_static()
342
        with paddle.static.program_guard(paddle.static.Program()):
343
            x = paddle.fluid.data('X', self.x_shape)
344 345 346 347 348 349 350 351 352 353 354 355
            out1 = paddle.mean(x)
            out2 = paddle.tensor.mean(x)
            out3 = paddle.tensor.stat.mean(x)
            axis = np.arange(len(self.x_shape)).tolist()
            out4 = paddle.mean(x, axis)
            out5 = paddle.mean(x, tuple(axis))

            exe = paddle.static.Executor(self.place)
            res = exe.run(feed={'X': self.x},
                          fetch_list=[out1, out2, out3, out4, out5])
        out_ref = np.mean(self.x)
        for out in res:
356
            self.assertEqual(np.allclose(out, out_ref, rtol=1e-04), True)
357

Z
Fix  
zhupengyang 已提交
358 359 360
    def test_api_dygraph(self):
        paddle.disable_static(self.place)

361
        def test_case(x, axis=None, keepdim=False):
Z
Zhou Wei 已提交
362
            x_tensor = paddle.to_tensor(x)
363 364 365 366 367 368
            out = paddle.mean(x_tensor, axis, keepdim)
            if isinstance(axis, list):
                axis = tuple(axis)
                if len(axis) == 0:
                    axis = None
            out_ref = np.mean(x, axis, keepdims=keepdim)
369 370
            self.assertEqual(np.allclose(out.numpy(), out_ref, rtol=1e-04),
                             True)
371 372 373 374 375 376 377 378 379 380 381

        test_case(self.x)
        test_case(self.x, [])
        test_case(self.x, -1)
        test_case(self.x, keepdim=True)
        test_case(self.x, 2, keepdim=True)
        test_case(self.x, [0, 2])
        test_case(self.x, (0, 2))
        test_case(self.x, [0, 1, 2, 3])
        paddle.enable_static()

382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    def test_fluid_api(self):
        with fluid.program_guard(fluid.Program(), fluid.Program()):
            x = fluid.data("x", shape=[10, 10], dtype="float32")
            out = fluid.layers.reduce_mean(input=x, dim=1)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            x_np = np.random.rand(10, 10).astype(np.float32)
            res = exe.run(feed={"x": x_np}, fetch_list=[out])
        self.assertEqual(np.allclose(res[0], np.mean(x_np, axis=1)), True)

        with fluid.dygraph.guard():
            x_np = np.random.rand(10, 10).astype(np.float32)
            x = fluid.dygraph.to_variable(x_np)
            out = fluid.layers.reduce_mean(input=x, dim=1)
        self.assertEqual(np.allclose(out.numpy(), np.mean(x_np, axis=1)), True)

398
    def test_errors(self):
399 400 401 402 403
        paddle.disable_static()
        x = np.random.uniform(-1, 1, [10, 12]).astype('float32')
        x = paddle.to_tensor(x)
        self.assertRaises(Exception, paddle.mean, x, -3)
        self.assertRaises(Exception, paddle.mean, x, 2)
Z
Fix  
zhupengyang 已提交
404
        paddle.enable_static()
405
        with paddle.static.program_guard(paddle.static.Program()):
406
            x = paddle.fluid.data('X', [10, 12], 'int32')
407 408 409
            self.assertRaises(TypeError, paddle.mean, x)


Q
qijun 已提交
410
if __name__ == "__main__":
411
    paddle.enable_static()
L
liaogang 已提交
412
    unittest.main()