test_cross_entropy_loss.py 67.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# Copyright (c) 2020 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.

import paddle
import paddle.fluid as fluid
import numpy as np
import unittest
19 20
from test_softmax_op import stable_softmax
from test_softmax_with_cross_entropy_op import cross_entropy
R
root 已提交
21
from paddle.fluid import Program, program_guard
22
from paddle.fluid.framework import _test_eager_guard
23 24


25
def log_softmax(x, axis=-1):
26 27 28 29
    softmax_out = np.apply_along_axis(stable_softmax, axis, x)
    return np.log(softmax_out)


30 31 32
def cross_entropy_loss_1d(
    input, label, weight=None, reduction='mean', ignore_index=-100
):
33 34 35 36 37 38
    log_softmax_out = log_softmax(input)
    input_shape = log_softmax_out.shape
    N = input_shape[0]
    C = input_shape[1]
    out = np.zeros_like(label).astype(np.float64)
    total_weight = 0
39 40
    # 1. compute softmax cross_entropy (with weight)
    #    Note: only support hard labels.
41 42 43 44 45 46 47 48
    for i in range(N):
        cur_target = label[i]
        if cur_target == ignore_index:
            out[i] = 0
            continue
        cur_weight = weight[cur_target] if weight is not None else 1
        total_weight += cur_weight
        out[i] = -log_softmax_out[i][cur_target] * cur_weight
49

50
    # 2. deal with reduction
51 52 53
    if reduction == 'sum':
        return np.sum(out), np.array([total_weight]).astype('float64')
    elif reduction == 'mean':
54 55
        out = out.sum() / total_weight if total_weight != 0 else out.sum()
        return out, np.array([total_weight]).astype('float64')
56 57 58 59
    elif reduction == 'none':
        return out


60 61 62
def cross_entropy_loss_2d(
    input, label, weight=None, reduction='mean', ignore_index=-100
):
63 64 65
    log_softmax_out = log_softmax(input)
    input_shape = log_softmax_out.shape
    N = input_shape[0]
66 67 68
    H = input_shape[1]
    W = input_shape[2]

69 70 71 72 73 74 75 76 77 78 79
    out = np.zeros_like(label).astype(np.float64)
    total_weight = 0
    for i in range(N):
        for h in range(H):
            for w in range(W):
                cur_target = label[i][h][w]
                if cur_target == ignore_index:
                    out[i][h][w] = 0
                    continue
                cur_weight = weight[cur_target] if weight is not None else 1
                total_weight += cur_weight
80 81 82
                out[i][h][w] = (
                    -log_softmax_out[i][h][w][cur_target] * cur_weight
                )
83 84 85
    if reduction == 'sum':
        return np.sum(out), np.array([total_weight]).astype('float64')
    elif reduction == 'mean':
86 87
        out = out.sum() / total_weight if total_weight != 0 else out.sum()
        return out, np.array([total_weight]).astype('float64')
88 89 90 91
    elif reduction == 'none':
        return out


92 93 94 95
def cross_entropy_soft(
    softmax, label, axis, N, weight=None, reduction='mean', ignore_index=-100
):
    # 1.loss
96
    loss = cross_entropy(
97 98
        softmax, label, True, axis, ignore_index  # soft_label,
    )
99 100 101 102

    if weight is None and reduction == 'none':
        return loss

103
    # 2.weight
104
    weighted_loss = loss
105
    total_weight = N  # for weight is None
106 107 108 109 110 111 112 113 114
    if weight is not None:
        weighted_loss = np.zeros_like(loss).astype(np.float64)
        total_weight = 0
        for i in range(N):
            cur_soft_label = label[i]
            cur_weight = np.dot(weight, cur_soft_label)
            total_weight += cur_weight
            weighted_loss[i] = loss[i] * cur_weight

115
    # 3.reduce
116 117 118 119 120 121 122 123 124 125 126 127 128
    if reduction == 'none':
        return weighted_loss

    elif reduction == 'mean':
        weighted_loss_sum = np.sum(weighted_loss)
        weighted_loss_mean = weighted_loss_sum / total_weight
        return weighted_loss_mean

    else:
        weighted_loss_sum = np.sum(weighted_loss)
        return weighted_loss_sum


129 130 131 132 133 134 135 136 137 138 139 140
def cross_entropy_soft_2d(
    softmax,
    label,
    axis,
    N,
    H,
    W,
    weight=None,
    reduction='mean',
    ignore_index=-100,
):
    # 1.loss
141
    loss = cross_entropy(
142 143
        softmax, label, True, axis, ignore_index  # soft_label,
    )
144 145 146 147

    if weight is None and reduction == 'none':
        return loss

148
    # 2.weight
149
    weighted_loss = loss
150
    total_weight = N  # for weight is None
151 152 153 154 155 156 157 158 159 160 161
    if weight is not None:
        weighted_loss = np.zeros_like(loss).astype(np.float64)
        total_weight = 0
        for i in range(N):
            for h in range(H):
                for w in range(W):
                    cur_soft_label = label[i][h][w]
                    cur_weight = np.dot(weight, cur_soft_label)
                    total_weight += cur_weight
                    weighted_loss[i][h][w] = loss[i][h][w] * cur_weight

162
    # 3.reduce
163 164 165 166 167 168 169 170 171 172 173 174 175
    if reduction == 'none':
        return weighted_loss

    elif reduction == 'mean':
        weighted_loss_sum = np.sum(weighted_loss)
        weighted_loss_mean = weighted_loss_sum / total_weight
        return weighted_loss_mean

    else:
        weighted_loss_sum = np.sum(weighted_loss)
        return weighted_loss_sum


176
class CrossEntropyLoss(unittest.TestCase):
R
ronnywang 已提交
177
    def setUp(self):
178 179 180
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
181

182
    # test for deprecated softmax_with_cross_entropy
183 184 185
    def test_softmax_with_cross_entropy(self):
        self.numeric_stable_mode = False
        self.soft_label = True
186 187 188
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
189
        self.axis = -1
190
        self.ignore_index = -100  # should not be changed
191 192 193 194 195 196 197
        self.N = 4
        self.C = 3
        self.shape = [self.N, self.C]
        self.use_softmax = True
        self.reduction = 'none'
        self.weight = None
        self.logits = getattr(
198 199 200 201
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
202 203 204 205 206
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype)
        self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)

207 208 209 210 211 212 213 214 215
        expected = cross_entropy_soft(
            softmax,
            self.labels,
            self.axis,
            self.N,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
216 217 218 219 220 221 222 223

        paddle.set_device("cpu")

        paddle.disable_static()
        paddle_loss_swce = paddle.nn.functional.softmax_with_cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
224 225
            axis=self.axis,
        )
226 227 228 229 230 231 232

        paddle_loss_ce = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=fluid.dygraph.to_variable(self.weight)
233 234 235 236 237 238 239 240
            if self.weight is not None
            else None,
            reduction=self.reduction,
        )

        np.testing.assert_allclose(
            paddle_loss_swce.numpy(), expected, rtol=1e-05
        )
241
        np.testing.assert_allclose(paddle_loss_ce.numpy(), expected, rtol=1e-05)
242

243 244
    # soft_label test start
    # soft_label test 1
245 246 247
    def test_cross_entropy_loss_soft_1d(self):
        self.numeric_stable_mode = False
        self.soft_label = True
248 249 250
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
251
        self.axis = -1
252
        self.ignore_index = -100  # should not be changed
253 254 255 256 257 258 259
        self.N = 4
        self.C = 3
        self.shape = [self.N, self.C]
        self.use_softmax = True
        self.reduction = 'none'
        self.weight = None
        self.logits = getattr(
260 261 262 263
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
264 265 266 267 268
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype)
        self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)

269 270 271 272 273 274 275 276 277
        expected = cross_entropy_soft(
            softmax,
            self.labels,
            self.axis,
            self.N,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
278 279 280

        paddle.set_device("cpu")

281
        # 2. dygraph
282 283 284 285 286 287 288
        paddle.disable_static()
        paddle_loss_none_weight = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=fluid.dygraph.to_variable(self.weight)
289 290 291 292
            if self.weight is not None
            else None,
            reduction=self.reduction,
        )
293 294
        dy_ret_value = paddle_loss_none_weight.numpy()

295
        # 3. static
296 297 298
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
299 300 301 302 303
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
304
        with fluid.program_guard(prog, startup_prog):
305 306 307 308 309 310
            input = fluid.data(
                name='input', shape=[self.N, self.C], dtype=self.dtype
            )
            label = fluid.data(
                name='label', shape=[self.N, self.C], dtype=self.dtype
            )
311 312

            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
313 314
                reduction=self.reduction, soft_label=True
            )
315 316 317
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
318 319 320 321 322 323 324 325
            static_ret = exe.run(
                prog,
                feed={
                    'input': self.logits,
                    'label': self.labels,
                },
                fetch_list=[ret],
            )
326 327 328
            self.assertIsNotNone(static_ret)
        paddle.disable_static()

329 330
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
331

332
    # soft_label test 2
333 334 335
    def test_cross_entropy_loss_soft_1d_weight(self):
        self.numeric_stable_mode = False
        self.soft_label = True
336 337 338
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
339
        self.axis = -1
340
        self.ignore_index = -100  # should not be changed
341 342 343 344 345 346 347
        self.N = 4
        self.C = 3
        self.shape = [self.N, self.C]
        self.use_softmax = True
        self.reduction = 'none'
        self.weight = np.random.uniform(0.1, 1.0, self.C).astype(self.dtype)
        self.logits = getattr(
348 349 350 351
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
352 353 354
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        if self.soft_label:
355 356 357
            self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(
                self.dtype
            )
358 359 360 361
            self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)
        else:
            axis_dim = self.shape[self.axis]
            self.shape[self.axis] = 1
362 363 364 365 366 367 368 369 370 371 372 373 374 375
            self.labels = np.random.randint(
                0, axis_dim, self.shape, dtype="int64"
            )

        # 1. numpy
        expected = cross_entropy_soft(
            softmax,
            self.labels,
            self.axis,
            self.N,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
376 377 378

        paddle.set_device("cpu")

379
        # 2. dygraph
380 381 382 383 384 385 386
        paddle.disable_static()
        paddle_loss_none_weight = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=fluid.dygraph.to_variable(self.weight),
387 388
            reduction=self.reduction,
        )
389 390 391 392 393 394
        dy_ret_value = paddle_loss_none_weight.numpy()

        # 3.static
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
395 396 397 398 399
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
400
        with fluid.program_guard(prog, startup_prog):
401 402 403 404 405 406
            input = fluid.data(
                name='input', shape=[self.N, self.C], dtype=self.dtype
            )
            label = fluid.data(
                name='label', shape=[self.N, self.C], dtype=self.dtype
            )
R
ronnywang 已提交
407
            weight = fluid.data(name='weight', shape=[self.C], dtype=self.dtype)
408 409

            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
410 411
                weight=weight, reduction=self.reduction, soft_label=True
            )
412 413 414
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
415 416 417 418 419 420 421 422 423
            static_ret = exe.run(
                prog,
                feed={
                    'input': self.logits,
                    'label': self.labels,
                    "weight": self.weight,
                },
                fetch_list=[ret],
            )
424 425 426
            self.assertIsNotNone(static_ret)
        paddle.disable_static()

427 428
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
429

430
    # soft_label test 3
431 432 433
    def test_cross_entropy_loss_soft_1d_mean(self):
        self.numeric_stable_mode = False
        self.soft_label = True
434 435 436
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
437
        self.axis = -1
438
        self.ignore_index = -100  # should not be changed
439 440 441 442 443 444 445
        self.N = 4
        self.C = 3
        self.shape = [self.N, self.C]
        self.use_softmax = True
        self.reduction = 'mean'
        self.weight = None
        self.logits = getattr(
446 447 448 449
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
450 451 452 453 454
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype)
        self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)

455 456 457 458 459 460 461 462 463 464
        # 1. numpy
        expected = cross_entropy_soft(
            softmax,
            self.labels,
            self.axis,
            self.N,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
465 466 467

        paddle.set_device("cpu")

468
        # 2 dygraph
469 470 471 472 473 474 475
        paddle.disable_static()
        paddle_loss_mean = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=self.weight,
476 477
            reduction=self.reduction,
        )
478 479
        dy_ret_value = paddle_loss_mean.numpy()

480
        # 3. static
481 482 483
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
484 485 486 487 488
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
489
        with fluid.program_guard(prog, startup_prog):
490 491 492 493 494 495
            input = fluid.data(
                name='input', shape=[self.N, self.C], dtype=self.dtype
            )
            label = fluid.data(
                name='label', shape=[self.N, self.C], dtype=self.dtype
            )
496 497

            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
498 499
                reduction=self.reduction, soft_label=True
            )
500 501 502
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
503 504 505 506 507
            static_ret = exe.run(
                prog,
                feed={'input': self.logits, 'label': self.labels},
                fetch_list=[ret],
            )
508 509 510
            self.assertIsNotNone(static_ret)
        paddle.disable_static()

511 512
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
513

514
    # soft_label test 4
515 516 517
    def test_cross_entropy_loss_soft_1d_weight_mean(self):
        self.numeric_stable_mode = False
        self.soft_label = True
518 519 520
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
521
        self.axis = -1
522
        self.ignore_index = -100  # should not be changed
523 524 525 526 527 528 529
        self.N = 4
        self.C = 3
        self.shape = [self.N, self.C]
        self.use_softmax = True
        self.reduction = 'mean'
        self.weight = np.random.uniform(0.1, 1.0, self.C).astype(self.dtype)
        self.logits = getattr(
530 531 532 533
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
534 535 536 537 538
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype)
        self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)

539 540 541 542 543 544 545 546 547 548
        # 1. numpy
        expected = cross_entropy_soft(
            softmax,
            self.labels,
            self.axis,
            self.N,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
549 550 551 552

        paddle.set_device("cpu")
        paddle.disable_static()

553
        # 2. dygraph
554 555 556 557 558 559
        paddle_loss_none_weight = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=fluid.dygraph.to_variable(self.weight),
560 561
            reduction=self.reduction,
        )
562 563
        dy_ret_value = paddle_loss_none_weight.numpy()

564
        # 3. static
565 566 567
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
568 569 570 571 572
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
573
        with fluid.program_guard(prog, startup_prog):
574 575 576 577 578 579
            input = fluid.data(
                name='input', shape=[self.N, self.C], dtype=self.dtype
            )
            label = fluid.data(
                name='label', shape=[self.N, self.C], dtype=self.dtype
            )
R
ronnywang 已提交
580
            weight = fluid.data(name='weight', shape=[self.C], dtype=self.dtype)
581 582

            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
583 584
                weight=weight, reduction=self.reduction, soft_label=True
            )
585 586
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
587 588 589 590 591 592 593 594 595
            static_ret = exe.run(
                prog,
                feed={
                    'input': self.logits,
                    'label': self.labels,
                    "weight": self.weight,
                },
                fetch_list=[ret],
            )
596 597 598
            self.assertIsNotNone(static_ret)
        paddle.disable_static()

599 600
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
601

602
    # soft_label test 5
603
    def test_cross_entropy_loss_soft_2d(self):
H
hong 已提交
604 605 606
        def inner_cross_entropy_loss_soft_2d(soft_label):
            self.numeric_stable_mode = False
            self.soft_label = soft_label
607 608 609
            self.dtype = (
                'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
            )
H
hong 已提交
610
            self.axis = -1
611
            self.ignore_index = -100  # should not be changed
H
hong 已提交
612 613 614 615 616 617 618 619 620
            self.N = 3
            self.H = 2
            self.W = 2
            self.C = 5
            self.shape = [self.N, self.H, self.W, self.C]
            self.use_softmax = True
            self.reduction = 'none'
            self.weight = None
            self.logits = getattr(
621 622 623 624 625 626 627
                self,
                "logits",
                np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
            )
            softmax = np.apply_along_axis(
                stable_softmax, self.axis, self.logits
            )
628

629 630 631
            self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(
                self.dtype
            )
H
hong 已提交
632
            self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)
633

634 635 636 637 638 639 640 641 642 643 644 645
            # 1. numpy
            expected = cross_entropy_soft_2d(
                softmax,
                self.labels,
                self.axis,
                self.N,
                self.H,
                self.W,
                weight=self.weight,
                reduction=self.reduction,
                ignore_index=self.ignore_index,
            )
H
hong 已提交
646 647 648 649

            paddle.set_device("cpu")
            paddle.disable_static()

650
            # 2. dygraph
H
hong 已提交
651 652 653 654 655 656
            paddle_loss_none_weight = paddle.nn.functional.cross_entropy(
                fluid.dygraph.to_variable(self.logits),
                fluid.dygraph.to_variable(self.labels),
                soft_label=True,
                axis=self.axis,
                weight=fluid.dygraph.to_variable(self.weight)
657 658 659 660
                if self.weight is not None
                else None,
                reduction=self.reduction,
            )
H
hong 已提交
661 662
            dy_ret_value = paddle_loss_none_weight.numpy()

663
            # 3. static
H
hong 已提交
664 665 666
            paddle.enable_static()
            prog = fluid.Program()
            startup_prog = fluid.Program()
667 668 669 670 671
            place = (
                fluid.CUDAPlace(0)
                if fluid.core.is_compiled_with_cuda()
                else fluid.CPUPlace()
            )
H
hong 已提交
672
            with fluid.program_guard(prog, startup_prog):
673 674 675 676 677 678 679 680 681 682
                input = fluid.data(
                    name='input',
                    shape=[self.N, self.H, self.W, self.C],
                    dtype=self.dtype,
                )
                label = fluid.data(
                    name='label',
                    shape=[self.N, self.H, self.W, self.C],
                    dtype=self.dtype,
                )
H
hong 已提交
683 684

                cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
685 686
                    reduction=self.reduction, soft_label=True
                )
H
hong 已提交
687 688
                ret = cross_entropy_loss(input, label)
                exe = fluid.Executor(place)
689 690 691 692 693 694 695 696
                static_ret = exe.run(
                    prog,
                    feed={
                        'input': self.logits,
                        'label': self.labels,
                    },
                    fetch_list=[ret],
                )
H
hong 已提交
697 698 699 700 701 702 703 704 705
                self.assertIsNotNone(static_ret)
            paddle.disable_static()

            np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
            np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
            np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)

        inner_cross_entropy_loss_soft_2d(True)
        inner_cross_entropy_loss_soft_2d(False)
706

707
    # soft_label test 6
708 709 710
    def test_cross_entropy_loss_soft_2d_weight_mean(self):
        self.numeric_stable_mode = False
        self.soft_label = True
711 712 713
        self.dtype = (
            'float32' if fluid.core.is_compiled_with_rocm() else 'float64'
        )
714
        self.axis = -1
715
        self.ignore_index = -100  # should not be changed
716 717 718 719 720 721 722 723 724
        self.N = 3
        self.H = 2
        self.W = 2
        self.C = 5
        self.shape = [self.N, self.H, self.W, self.C]
        self.use_softmax = True
        self.reduction = 'mean'
        self.weight = np.random.uniform(0.1, 1.0, self.C).astype(self.dtype)
        self.logits = getattr(
725 726 727 728
            self,
            "logits",
            np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype),
        )
729 730 731 732 733
        softmax = np.apply_along_axis(stable_softmax, self.axis, self.logits)

        self.labels = np.random.uniform(0.1, 1.0, self.shape).astype(self.dtype)
        self.labels /= np.sum(self.labels, axis=self.axis, keepdims=True)

734 735 736 737 738 739 740 741 742 743 744 745
        # 1. numpy
        expected = cross_entropy_soft_2d(
            softmax,
            self.labels,
            self.axis,
            self.N,
            self.H,
            self.W,
            weight=self.weight,
            reduction=self.reduction,
            ignore_index=self.ignore_index,
        )
746 747 748 749

        paddle.set_device("cpu")
        paddle.disable_static()

750
        # 2. dygraph
751 752 753 754 755 756
        paddle_loss_none_weight = paddle.nn.functional.cross_entropy(
            fluid.dygraph.to_variable(self.logits),
            fluid.dygraph.to_variable(self.labels),
            soft_label=True,
            axis=self.axis,
            weight=fluid.dygraph.to_variable(self.weight),
757 758
            reduction=self.reduction,
        )
759 760
        dy_ret_value = paddle_loss_none_weight.numpy()

761
        # 3. static
762 763 764
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
765 766 767 768 769
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
770
        with fluid.program_guard(prog, startup_prog):
771 772 773 774 775 776 777 778 779 780
            input = fluid.data(
                name='input',
                shape=[self.N, self.H, self.W, self.C],
                dtype=self.dtype,
            )
            label = fluid.data(
                name='label',
                shape=[self.N, self.H, self.W, self.C],
                dtype=self.dtype,
            )
R
ronnywang 已提交
781
            weight = fluid.data(name='weight', shape=[self.C], dtype=self.dtype)
782 783

            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
784 785
                weight=weight, reduction=self.reduction, soft_label=True
            )
786 787
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
788 789 790 791 792 793 794 795 796
            static_ret = exe.run(
                prog,
                feed={
                    'input': self.logits,
                    'label': self.labels,
                    "weight": self.weight,
                },
                fetch_list=[ret],
            )
797 798 799
            self.assertIsNotNone(static_ret)
        paddle.disable_static()

800 801 802
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
803

804
    # soft_label test end
805

806
    def test_cross_entropy_loss_1d_with_mean_ignore(self):
R
ronnywang 已提交
807
        input_np = np.random.random([2, 4]).astype(self.dtype)
808 809 810 811
        label_np = np.random.randint(0, 4, size=(2)).astype(np.int64)
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
812 813 814 815 816
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
817
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
818
            input = fluid.data(name='input', shape=[2, 4], dtype=self.dtype)
819 820 821 822 823
            label = fluid.data(name='label', shape=[2], dtype='int64')
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(ignore_index=0)
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
824 825 826 827 828 829 830 831
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                },
                fetch_list=[ret],
            )
832 833 834 835
            self.assertIsNotNone(static_ret)
        expected = cross_entropy_loss_1d(input_np, label_np)[0]

        with fluid.dygraph.guard():
836 837 838 839 840 841 842
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
                axis=1, ignore_index=0
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
843 844 845
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_1d(input_np, label_np, ignore_index=0)[0]
846 847 848
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
849

850 851 852 853 854 855 856 857
    def test_cross_entropy_loss_1d_with_mean_ignore_negative(self):
        N = 100
        C = 200
        input_np = np.random.random([N, C]).astype(self.dtype)
        label_np = -np.ones((N)).astype(np.int64)
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
858 859 860 861 862
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
863 864 865 866
        with fluid.program_guard(prog, startup_prog):
            input = fluid.data(name='input', shape=[N, C], dtype=self.dtype)
            label = fluid.data(name='label', shape=[N], dtype='int64')
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
867 868
                ignore_index=-1
            )
869 870
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
871 872 873 874 875 876 877 878
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                },
                fetch_list=[ret],
            )
879 880 881 882
            self.assertIsNotNone(static_ret)

        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
883 884 885 886 887 888
                axis=1, ignore_index=-1
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
889 890 891 892
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_1d(input_np, label_np, ignore_index=-1)[0]

893 894 895
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
896

897
    def test_cross_entropy_loss_1d_with_weight_mean_ignore(self):
898 899
        N = 100
        C = 200
R
ronnywang 已提交
900
        input_np = np.random.random([N, C]).astype(self.dtype)
901
        label_np = np.random.randint(0, C, size=(N)).astype(np.int64)
R
ronnywang 已提交
902
        weight_np = np.random.random([C]).astype(self.dtype)
903 904 905
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
906 907 908 909 910
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
911
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
912
            input = fluid.data(name='input', shape=[N, C], dtype=self.dtype)
913
            label = fluid.data(name='label', shape=[N], dtype='int64')
914 915 916 917 918 919
            weight = fluid.data(
                name='weight', shape=[C], dtype=self.dtype
            )  # weight for each class
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
                weight=weight, ignore_index=0
            )
920 921 922
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
923 924 925 926 927 928 929 930 931
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
932 933 934 935 936 937
            self.assertIsNotNone(static_ret)

        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
                weight=fluid.dygraph.to_variable(weight_np),
                axis=1,
938 939 940 941 942 943
                ignore_index=0,
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
944 945
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
946 947 948
        expected = cross_entropy_loss_1d(
            input_np, label_np, weight=weight_np, ignore_index=0
        )[0]
949

950 951 952
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
953

H
HydrogenSulfate 已提交
954 955 956 957 958 959 960 961 962 963
    def test_cross_entropy_loss_1d_with_weight_mean_ignore_exceedlabel(self):
        N = 100
        C = 200
        input_np = np.random.random([N, C]).astype(self.dtype)
        label_np = np.random.randint(0, C, size=(N)).astype(np.int64)
        label_np[0] = 255
        weight_np = np.random.random([C]).astype(self.dtype)

        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
964 965 966 967 968 969
                weight=fluid.dygraph.to_variable(weight_np), ignore_index=255
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
H
HydrogenSulfate 已提交
970 971
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
972 973 974
        expected = cross_entropy_loss_1d(
            input_np, label_np, weight=weight_np, ignore_index=255
        )[0]
H
HydrogenSulfate 已提交
975

976
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
H
HydrogenSulfate 已提交
977

978
    def test_cross_entropy_loss_1d_with_weight_mean(self):
R
ronnywang 已提交
979
        input_np = np.random.random([2, 4]).astype(self.dtype)
980
        label_np = np.random.randint(0, 4, size=(2)).astype(np.int64)
981
        weight_np = np.random.random([4]).astype(self.dtype)  # shape:C
982
        paddle.enable_static()
983 984
        prog = fluid.Program()
        startup_prog = fluid.Program()
985 986 987 988 989
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
990
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
991
            input = fluid.data(name='input', shape=[2, 4], dtype=self.dtype)
992
            label = fluid.data(name='label', shape=[2], dtype='int64')
993 994 995
            weight = fluid.data(
                name='weight', shape=[4], dtype=self.dtype
            )  # weight for each class
996 997 998 999
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(weight=weight)
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1000 1001 1002 1003 1004 1005 1006 1007 1008
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1009
            self.assertIsNotNone(static_ret)
1010 1011 1012
        expected = cross_entropy_loss_1d(input_np, label_np, weight=weight_np)[
            0
        ]
1013

1014 1015
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1016 1017 1018 1019 1020 1021
                weight=fluid.dygraph.to_variable(weight_np), axis=1
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1022 1023
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1024 1025 1026
        expected = cross_entropy_loss_1d(input_np, label_np, weight=weight_np)[
            0
        ]
1027 1028 1029
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1030

1031
    def test_cross_entropy_loss_1d_with_weight_sum(self):
1032 1033 1034
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N,1
        weight_np = np.random.random([200]).astype(self.dtype)  # C
1035
        paddle.enable_static()
1036 1037
        prog = fluid.Program()
        startup_prog = fluid.Program()
1038 1039 1040 1041 1042
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1043
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1044
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1045
            label = fluid.data(name='label', shape=[100], dtype='int64')
R
ronnywang 已提交
1046
            weight = fluid.data(name='weight', shape=[200], dtype=self.dtype)
1047
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1048 1049
                weight=weight, reduction='sum'
            )
1050 1051 1052
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1053 1054 1055 1056 1057 1058 1059 1060 1061
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1062 1063 1064
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1065 1066 1067 1068 1069 1070
                weight=fluid.dygraph.to_variable(weight_np), reduction='sum'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1071 1072
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1073 1074 1075
        expected = cross_entropy_loss_1d(
            input_np, label_np, weight=weight_np, reduction='sum'
        )[0]
1076 1077 1078
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1079

1080
    def test_cross_entropy_loss_1d_with_weight_none(self):
1081 1082 1083
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N,1
        weight_np = np.random.random([200]).astype(self.dtype)  # C
1084

1085
        paddle.enable_static()
1086 1087
        prog = fluid.Program()
        startup_prog = fluid.Program()
1088 1089 1090 1091 1092
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1093
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1094
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1095
            label = fluid.data(name='label', shape=[100], dtype='int64')
R
ronnywang 已提交
1096
            weight = fluid.data(name='weight', shape=[200], dtype=self.dtype)
1097

1098
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1099 1100
                weight=weight, reduction='none'
            )
1101 1102 1103
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1104 1105 1106 1107 1108 1109 1110 1111 1112
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1113
            static_ret = np.squeeze(static_ret)
1114 1115 1116
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1117 1118 1119 1120 1121 1122
                weight=fluid.dygraph.to_variable(weight_np), reduction='none'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1123
            dy_ret_value = dy_ret.numpy()
1124
            dy_ret_value = np.squeeze(dy_ret_value)
1125
            self.assertIsNotNone(dy_ret_value)
1126 1127 1128
        expected = cross_entropy_loss_1d(
            input_np, label_np, weight=weight_np, reduction='none'
        )
1129 1130 1131
        np.testing.assert_allclose(static_ret, dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret, expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1132 1133

    def test_cross_entropy_loss_1d_with_weight_none_func(self):
1134 1135 1136
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N
        weight_np = np.random.random([200]).astype(self.dtype)  # C
1137 1138 1139
        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
1140 1141 1142 1143 1144
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1145
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1146
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1147
            label = fluid.data(name='label', shape=[100], dtype='int64')
R
ronnywang 已提交
1148
            weight = fluid.data(name='weight', shape=[200], dtype=self.dtype)
1149 1150 1151
            ret = paddle.nn.functional.cross_entropy(
                input, label, weight=weight, reduction='none'
            )
1152 1153

            exe = fluid.Executor(place)
1154 1155 1156 1157 1158 1159 1160 1161 1162
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1163 1164 1165 1166 1167 1168 1169
            static_ret = np.squeeze(static_ret)
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            dy_ret = paddle.nn.functional.cross_entropy(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
                weight=fluid.dygraph.to_variable(weight_np),
1170 1171
                reduction='none',
            )
1172 1173 1174
            dy_ret_value = dy_ret.numpy()
            dy_ret_value = np.squeeze(dy_ret_value)
            self.assertIsNotNone(dy_ret_value)
1175 1176 1177
        expected = cross_entropy_loss_1d(
            input_np, label_np, weight=weight_np, reduction='none'
        )
1178 1179 1180
        np.testing.assert_allclose(static_ret, dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret, expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1181 1182

    def test_cross_entropy_loss_1d_mean(self):
1183 1184
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N,1
1185
        paddle.enable_static()
1186 1187
        prog = fluid.Program()
        startup_prog = fluid.Program()
1188 1189 1190 1191 1192
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1193
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1194
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1195 1196 1197 1198
            label = fluid.data(name='label', shape=[100], dtype='int64')
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss()
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
1199 1200 1201 1202 1203
            static_ret = exe.run(
                prog,
                feed={'input': input_np, 'label': label_np},
                fetch_list=[ret],
            )
1204 1205 1206
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss()
1207 1208 1209 1210
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1211 1212 1213
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_1d(input_np, label_np)[0]
1214 1215 1216
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1217 1218

    def test_cross_entropy_loss_1d_sum(self):
1219 1220
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N,1
1221
        paddle.enable_static()
1222 1223
        prog = fluid.Program()
        startup_prog = fluid.Program()
1224 1225 1226 1227 1228
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1229
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1230
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1231 1232
            label = fluid.data(name='label', shape=[100], dtype='int64')
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1233 1234
                reduction='sum'
            )
1235 1236
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
1237 1238 1239 1240 1241
            static_ret = exe.run(
                prog,
                feed={'input': input_np, 'label': label_np},
                fetch_list=[ret],
            )
1242 1243 1244
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1245 1246 1247 1248 1249 1250
                reduction='sum'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1251 1252 1253
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_1d(input_np, label_np, reduction='sum')[0]
1254 1255 1256
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1257 1258

    def test_cross_entropy_loss_1d_none(self):
1259 1260
        input_np = np.random.random([100, 200]).astype(self.dtype)  # N,C
        label_np = np.random.randint(0, 100, size=(100)).astype(np.int64)  # N,1
1261
        paddle.enable_static()
1262 1263
        prog = fluid.Program()
        startup_prog = fluid.Program()
1264 1265 1266 1267 1268
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1269
        with fluid.program_guard(prog, startup_prog):
R
ronnywang 已提交
1270
            input = fluid.data(name='input', shape=[100, 200], dtype=self.dtype)
1271 1272
            label = fluid.data(name='label', shape=[100], dtype='int64')
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1273 1274
                reduction='none'
            )
1275 1276
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
1277 1278 1279 1280 1281
            static_ret = exe.run(
                prog,
                feed={'input': input_np, 'label': label_np},
                fetch_list=[ret],
            )
1282
            static_ret = np.squeeze(static_ret)
1283 1284 1285
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1286 1287 1288 1289 1290 1291
                reduction='none'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1292
            dy_ret_value = dy_ret.numpy()
1293
            dy_ret_value = np.squeeze(dy_ret_value)
1294 1295
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_1d(input_np, label_np, reduction='none')
1296 1297 1298
        np.testing.assert_allclose(static_ret, dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret, expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1299 1300

    def test_cross_entropy_loss_2d_with_weight_none(self):
1301 1302 1303 1304 1305 1306 1307
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW1
        weight_np = np.random.random(size=(3,)).astype(self.dtype)  # C
1308 1309

        paddle.enable_static()
1310 1311
        prog = fluid.Program()
        startup_prog = fluid.Program()
1312 1313 1314 1315 1316
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1317
        with fluid.program_guard(prog, startup_prog):
1318 1319 1320
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1321
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
R
ronnywang 已提交
1322
            weight = fluid.data(name='weight', shape=[3], dtype=self.dtype)
1323
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1324 1325
                weight=weight, reduction='none'
            )
1326 1327 1328
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1329 1330 1331 1332 1333 1334 1335 1336 1337
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1338
            static_ret = np.squeeze(static_ret)
1339 1340 1341
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1342 1343 1344 1345 1346 1347
                weight=fluid.dygraph.to_variable(weight_np), reduction='none'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1348
            dy_ret_value = dy_ret.numpy()
1349
            dy_ret_value = np.squeeze(dy_ret_value)
1350
            self.assertIsNotNone(dy_ret_value)
1351 1352 1353
        expected = cross_entropy_loss_2d(
            input_np, label_np, weight=weight_np, reduction='none'
        )
1354 1355 1356
        np.testing.assert_allclose(static_ret, dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret, expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1357 1358

    def test_cross_entropy_loss_2d_with_weight_axis_change_mean(self):
1359 1360 1361 1362 1363 1364 1365
        input_np = np.random.random(size=(2, 3, 2, 2)).astype(
            self.dtype
        )  # NCHW
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
        weight_np = np.random.random(size=(3,)).astype(self.dtype)  # C
1366 1367 1368 1369

        paddle.enable_static()
        prog = fluid.Program()
        startup_prog = fluid.Program()
1370 1371 1372 1373 1374
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1375
        with fluid.program_guard(prog, startup_prog):
1376 1377 1378
            input = fluid.data(
                name='input', shape=[2, 3, 2, 2], dtype=self.dtype
            )
1379 1380 1381
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
            weight = fluid.data(name='weight', shape=[3], dtype=self.dtype)
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1382 1383
                weight=weight, reduction='mean', axis=1
            )
1384 1385 1386 1387
            # specify the class channels to axis 1
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1388 1389 1390 1391 1392 1393 1394 1395 1396
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1397 1398 1399 1400

            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1401 1402
                weight=fluid.dygraph.to_variable(weight_np),
                reduction='mean',
1403 1404 1405 1406 1407 1408
                axis=1,
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1409 1410
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1411 1412 1413 1414 1415 1416
        expected = cross_entropy_loss_2d(
            np.transpose(input_np, [0, 2, 3, 1]),
            label_np,
            weight=weight_np,
            reduction='mean',
        )[0]
1417 1418 1419
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1420

H
HydrogenSulfate 已提交
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
    def test_cross_entropy_loss_2d_with_weight_mean_ignore_exceedlabel(self):
        N = 4
        C = 3
        H = 512
        W = 512
        input_np = np.random.random([N, H, W, C]).astype(self.dtype)
        label_np = np.random.randint(0, C, size=(N, H, W)).astype(np.int64)
        label_np[0, 0, 0] = 255
        weight_np = np.random.random([C]).astype(self.dtype)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1432 1433 1434 1435 1436 1437
                weight=fluid.dygraph.to_variable(weight_np), ignore_index=255
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
H
HydrogenSulfate 已提交
1438 1439
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1440 1441 1442
        expected = cross_entropy_loss_2d(
            input_np, label_np, weight=weight_np, ignore_index=255
        )[0]
1443
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
H
HydrogenSulfate 已提交
1444

1445
    def test_cross_entropy_loss_2d_with_weight_mean(self):
1446 1447 1448 1449 1450 1451 1452
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
        weight_np = np.random.random(size=(3,)).astype(self.dtype)  # C
1453
        paddle.enable_static()
1454 1455
        prog = fluid.Program()
        startup_prog = fluid.Program()
1456 1457 1458 1459 1460
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1461
        with fluid.program_guard(prog, startup_prog):
1462 1463 1464
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1465
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
R
ronnywang 已提交
1466
            weight = fluid.data(name='weight', shape=[3], dtype=self.dtype)
1467
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1468 1469
                weight=weight, reduction='mean'
            )
1470 1471 1472
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1473 1474 1475 1476 1477 1478 1479 1480 1481
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1482 1483 1484
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1485 1486 1487 1488 1489 1490
                weight=fluid.dygraph.to_variable(weight_np), reduction='mean'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1491 1492
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1493 1494 1495
        expected = cross_entropy_loss_2d(
            input_np, label_np, weight=weight_np, reduction='mean'
        )[0]
1496 1497 1498
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1499 1500

    def test_cross_entropy_loss_2d_with_weight_sum(self):
1501 1502 1503 1504 1505 1506 1507
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
        weight_np = np.random.random(size=(3,)).astype(self.dtype)  # C
1508 1509
        paddle.enable_static()

1510 1511
        prog = fluid.Program()
        startup_prog = fluid.Program()
1512 1513 1514 1515 1516
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1517
        with fluid.program_guard(prog, startup_prog):
1518 1519 1520
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1521
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
R
ronnywang 已提交
1522
            weight = fluid.data(name='weight', shape=[3], dtype=self.dtype)
1523
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1524 1525
                weight=weight, reduction='sum'
            )
1526 1527 1528
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1529 1530 1531 1532 1533 1534 1535 1536 1537
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                    "weight": weight_np,
                },
                fetch_list=[ret],
            )
1538 1539 1540
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1541 1542 1543 1544 1545 1546
                weight=fluid.dygraph.to_variable(weight_np), reduction='sum'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1547 1548
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1549 1550 1551
        expected = cross_entropy_loss_2d(
            input_np, label_np, weight=weight_np, reduction='sum'
        )[0]
1552 1553 1554
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1555 1556

    def test_cross_entropy_loss_2d_none(self):
1557 1558 1559 1560 1561 1562
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
1563
        paddle.enable_static()
1564 1565
        prog = fluid.Program()
        startup_prog = fluid.Program()
1566 1567 1568 1569 1570
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1571
        with fluid.program_guard(prog, startup_prog):
1572 1573 1574
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1575
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
1576
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1577 1578
                reduction='none'
            )
1579 1580
            ret = cross_entropy_loss(input, label)
            exe = fluid.Executor(place)
1581 1582 1583 1584 1585 1586 1587 1588
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                },
                fetch_list=[ret],
            )
1589
            static_ret = np.squeeze(static_ret)
1590 1591 1592
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1593 1594 1595 1596 1597 1598
                reduction='none'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1599
            dy_ret_value = dy_ret.numpy()
1600
            dy_ret_value = np.squeeze(dy_ret_value)
1601 1602
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_2d(input_np, label_np, reduction='none')
1603 1604 1605
        np.testing.assert_allclose(static_ret, dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret, expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1606 1607

    def test_cross_entropy_loss_2d_mean(self):
1608 1609 1610 1611 1612 1613
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
1614
        paddle.enable_static()
1615 1616
        prog = fluid.Program()
        startup_prog = fluid.Program()
1617 1618 1619 1620 1621
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1622
        with fluid.program_guard(prog, startup_prog):
1623 1624 1625
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1626
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
1627
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1628 1629
                reduction='mean'
            )
1630 1631 1632
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1633 1634 1635 1636 1637 1638 1639 1640
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                },
                fetch_list=[ret],
            )
1641 1642 1643
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1644 1645 1646 1647 1648 1649
                reduction='mean'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1650 1651
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
1652 1653 1654
        expected = cross_entropy_loss_2d(input_np, label_np, reduction='mean')[
            0
        ]
1655 1656 1657
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1658 1659

    def test_cross_entropy_loss_2d_sum(self):
1660 1661 1662 1663 1664 1665
        input_np = np.random.random(size=(2, 2, 2, 3)).astype(
            self.dtype
        )  # NHWC
        label_np = np.random.randint(0, 3, size=(2, 2, 2)).astype(
            np.int64
        )  # NHW
1666
        paddle.enable_static()
1667 1668
        prog = fluid.Program()
        startup_prog = fluid.Program()
1669 1670 1671 1672 1673
        place = (
            fluid.CUDAPlace(0)
            if fluid.core.is_compiled_with_cuda()
            else fluid.CPUPlace()
        )
1674
        with fluid.program_guard(prog, startup_prog):
1675 1676 1677
            input = fluid.data(
                name='input', shape=[2, 2, 2, 3], dtype=self.dtype
            )
1678
            label = fluid.data(name='label', shape=[2, 2, 2], dtype='int64')
1679
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1680 1681
                reduction='sum'
            )
1682 1683 1684
            ret = cross_entropy_loss(input, label)

            exe = fluid.Executor(place)
1685 1686 1687 1688 1689 1690 1691 1692
            static_ret = exe.run(
                prog,
                feed={
                    'input': input_np,
                    'label': label_np,
                },
                fetch_list=[ret],
            )
1693 1694 1695
            self.assertIsNotNone(static_ret)
        with fluid.dygraph.guard():
            cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1696 1697 1698 1699 1700 1701
                reduction='sum'
            )
            dy_ret = cross_entropy_loss(
                fluid.dygraph.to_variable(input_np),
                fluid.dygraph.to_variable(label_np),
            )
1702 1703 1704
            dy_ret_value = dy_ret.numpy()
            self.assertIsNotNone(dy_ret_value)
        expected = cross_entropy_loss_2d(input_np, label_np, reduction='sum')[0]
1705 1706 1707
        np.testing.assert_allclose(static_ret[0], dy_ret_value, rtol=1e-05)
        np.testing.assert_allclose(static_ret[0], expected, rtol=1e-05)
        np.testing.assert_allclose(dy_ret_value, expected, rtol=1e-05)
1708

1709
    def test_soft_1d_dygraph_api(self):
1710 1711 1712 1713 1714 1715 1716
        with _test_eager_guard():
            self.test_cross_entropy_loss_soft_1d()
            self.test_cross_entropy_loss_soft_1d_weight()
            self.test_cross_entropy_loss_soft_1d_mean()
            self.test_cross_entropy_loss_soft_1d_weight_mean()

    # put all testcases in one test will be failed
1717
    def test_soft_2d_dygraph_api(self):
1718 1719 1720 1721
        with _test_eager_guard():
            self.test_cross_entropy_loss_soft_2d()
            self.test_cross_entropy_loss_soft_2d_weight_mean()

1722
    def test_other_dygraph_api(self):
1723 1724 1725 1726
        with _test_eager_guard():
            self.test_cross_entropy_loss_1d_with_mean_ignore()
            self.test_cross_entropy_loss_1d_with_mean_ignore_negative()
            self.test_cross_entropy_loss_1d_with_weight_mean_ignore()
1727
            self.test_cross_entropy_loss_1d_with_weight_mean_ignore_exceedlabel()
1728 1729 1730 1731 1732 1733 1734 1735 1736
            self.test_cross_entropy_loss_1d_with_weight_mean()
            self.test_cross_entropy_loss_1d_with_weight_sum()
            self.test_cross_entropy_loss_1d_with_weight_none()
            self.test_cross_entropy_loss_1d_with_weight_none_func()
            self.test_cross_entropy_loss_1d_mean()
            self.test_cross_entropy_loss_1d_sum()
            self.test_cross_entropy_loss_1d_none()
            self.test_cross_entropy_loss_2d_with_weight_none()
            self.test_cross_entropy_loss_2d_with_weight_axis_change_mean()
1737
            self.test_cross_entropy_loss_2d_with_weight_mean_ignore_exceedlabel()
1738 1739 1740 1741 1742 1743
            self.test_cross_entropy_loss_2d_with_weight_mean()
            self.test_cross_entropy_loss_2d_with_weight_sum()
            self.test_cross_entropy_loss_2d_none()
            self.test_cross_entropy_loss_2d_mean()
            self.test_cross_entropy_loss_2d_sum()

1744

1745 1746 1747 1748
class TestCrossEntropyFAPIError(unittest.TestCase):
    def test_errors(self):
        with program_guard(Program(), Program()):

H
HydrogenSulfate 已提交
1749
            def test_WeightLength_NotEqual():
1750
                input_data = paddle.rand(shape=[20, 100])
1751 1752 1753
                label_data = paddle.randint(
                    0, 100, shape=[20, 1], dtype="int64"
                )
H
HydrogenSulfate 已提交
1754
                weight_data = paddle.rand([100 + 1])
1755 1756 1757 1758 1759 1760
                paddle.nn.functional.cross_entropy(
                    input=input_data,
                    label=label_data,
                    weight=weight_data,
                    ignore_index=-100,
                )
H
HydrogenSulfate 已提交
1761

H
HydrogenSulfate 已提交
1762
            self.assertRaises(ValueError, test_WeightLength_NotEqual)
H
HydrogenSulfate 已提交
1763

H
HydrogenSulfate 已提交
1764 1765
            def test_LabelValue_ExceedMax():
                input_data = paddle.rand(shape=[20, 100])
1766 1767 1768
                label_data = paddle.randint(
                    0, 100, shape=[20, 1], dtype="int64"
                )
H
HydrogenSulfate 已提交
1769 1770
                label_data[0] = 100
                weight_data = paddle.rand([100])
1771 1772 1773 1774 1775 1776
                paddle.nn.functional.cross_entropy(
                    input=input_data,
                    label=label_data,
                    weight=weight_data,
                    ignore_index=-100,
                )
H
HydrogenSulfate 已提交
1777 1778 1779 1780 1781

            self.assertRaises(ValueError, test_LabelValue_ExceedMax)

            def test_LabelValue_ExceedMin():
                input_data = paddle.rand(shape=[20, 100])
1782 1783 1784
                label_data = paddle.randint(
                    0, 100, shape=[20, 1], dtype="int64"
                )
H
HydrogenSulfate 已提交
1785 1786
                label_data[0] = -1
                weight_data = paddle.rand([100])
1787 1788 1789 1790 1791 1792
                paddle.nn.functional.cross_entropy(
                    input=input_data,
                    label=label_data,
                    weight=weight_data,
                    ignore_index=-100,
                )
H
HydrogenSulfate 已提交
1793 1794 1795

            self.assertRaises(ValueError, test_LabelValue_ExceedMin)

H
HydrogenSulfate 已提交
1796
            def static_test_WeightLength_NotEqual():
1797
                input_np = np.random.random([2, 4]).astype('float32')
H
HydrogenSulfate 已提交
1798
                label_np = np.random.randint(0, 4, size=(2)).astype(np.int64)
1799
                weight_np = np.random.random([3]).astype('float32')
H
HydrogenSulfate 已提交
1800 1801 1802
                paddle.enable_static()
                prog = fluid.Program()
                startup_prog = fluid.Program()
1803 1804 1805 1806 1807
                place = (
                    fluid.CUDAPlace(0)
                    if fluid.core.is_compiled_with_cuda()
                    else fluid.CPUPlace()
                )
H
HydrogenSulfate 已提交
1808
                with fluid.program_guard(prog, startup_prog):
1809 1810 1811
                    input = fluid.data(
                        name='input', shape=[2, 4], dtype='float32'
                    )
H
HydrogenSulfate 已提交
1812
                    label = fluid.data(name='label', shape=[2], dtype='int64')
1813 1814 1815
                    weight = fluid.data(
                        name='weight', shape=[3], dtype='float32'
                    )  # weight for each class
H
HydrogenSulfate 已提交
1816
                    cross_entropy_loss = paddle.nn.loss.CrossEntropyLoss(
1817 1818
                        weight=weight
                    )
H
HydrogenSulfate 已提交
1819 1820 1821
                    ret = cross_entropy_loss(input, label)

                    exe = fluid.Executor(place)
1822 1823 1824 1825 1826 1827 1828 1829 1830
                    static_ret = exe.run(
                        prog,
                        feed={
                            'input': input_np,
                            'label': label_np,
                            "weight": weight_np,
                        },
                        fetch_list=[ret],
                    )
H
HydrogenSulfate 已提交
1831 1832 1833 1834
                    self.assertIsNotNone(static_ret)

            self.assertRaises(ValueError, static_test_WeightLength_NotEqual)

1835

1836 1837
if __name__ == "__main__":
    unittest.main()