test_losses.py 6.06 KB
Newer Older
dingchang's avatar
dingchang committed
1
# Copyright (c) OpenMMLab. All rights reserved.
wuyuefeng's avatar
Votenet  
wuyuefeng committed
2
3
import pytest
import torch
4
from torch import nn as nn
wuyuefeng's avatar
Votenet  
wuyuefeng committed
5

6
7
from mmdet.models import build_loss

wuyuefeng's avatar
Votenet  
wuyuefeng committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

def test_chamfer_disrance():
    from mmdet3d.models.losses import ChamferDistance, chamfer_distance

    with pytest.raises(AssertionError):
        # test invalid mode
        ChamferDistance(mode='smoothl1')
        # test invalid type of reduction
        ChamferDistance(mode='l2', reduction=None)

    self = ChamferDistance(
        mode='l2', reduction='sum', loss_src_weight=1.0, loss_dst_weight=1.0)
    source = torch.tensor([[[-0.9888, 0.9683, -0.8494],
                            [-6.4536, 4.5146,
                             1.6861], [2.0482, 5.6936, -1.4701],
                            [-0.5173, 5.6472, 2.1748],
                            [-2.8010, 5.4423, -1.2158],
                            [2.4018, 2.4389, -0.2403],
                            [-2.8811, 3.8486, 1.4750],
                            [-0.2031, 3.8969,
                             -1.5245], [1.3827, 4.9295, 1.1537],
                            [-2.6961, 2.2621, -1.0976]],
                           [[0.3692, 1.8409,
                             -1.4983], [1.9995, 6.3602, 0.1798],
                            [-2.1317, 4.6011,
                             -0.7028], [2.4158, 3.1482, 0.3169],
                            [-0.5836, 3.6250, -1.2650],
                            [-1.9862, 1.6182, -1.4901],
                            [2.5992, 1.2847, -0.8471],
                            [-0.3467, 5.3681, -1.4755],
                            [-0.8576, 3.3400, -1.7399],
                            [2.7447, 4.6349, 0.1994]]])

    target = torch.tensor([[[-0.4758, 1.0094, -0.8645],
                            [-0.3130, 0.8564, -0.9061],
                            [-0.1560, 2.0394, -0.8936],
                            [-0.3685, 1.6467, -0.8271],
                            [-0.2740, 2.2212, -0.7980]],
                           [[1.4856, 2.5299,
                             -1.0047], [2.3262, 3.3065, -0.9475],
                            [2.4593, 2.5870,
                             -0.9423], [0.0000, 0.0000, 0.0000],
                            [0.0000, 0.0000, 0.0000]]])

    loss_source, loss_target, indices1, indices2 = self(
        source, target, return_indices=True)

    assert torch.allclose(loss_source, torch.tensor(219.5936))
    assert torch.allclose(loss_target, torch.tensor(22.3705))
Wenwei Zhang's avatar
Wenwei Zhang committed
57
58
59
60
61
62
63
64
65

    expected_inds1 = [[0, 4, 4, 4, 4, 2, 4, 4, 4, 3],
                      [0, 1, 0, 1, 0, 4, 2, 0, 0, 1]]
    expected_inds2 = [[0, 4, 4, 4, 4, 2, 4, 4, 4, 3],
                      [0, 1, 0, 1, 0, 3, 2, 0, 0, 1]]
    assert (torch.equal(indices1, indices1.new_tensor(expected_inds1))
            or torch.equal(indices1, indices1.new_tensor(expected_inds2)))
    assert torch.equal(indices2,
                       indices2.new_tensor([[0, 0, 0, 0, 0], [0, 3, 6, 0, 0]]))
wuyuefeng's avatar
Votenet  
wuyuefeng committed
66
67
68
69
70
71

    loss_source, loss_target, indices1, indices2 = chamfer_distance(
        source, target, reduction='sum')

    assert torch.allclose(loss_source, torch.tensor(219.5936))
    assert torch.allclose(loss_target, torch.tensor(22.3705))
Wenwei Zhang's avatar
Wenwei Zhang committed
72
73
    assert (torch.equal(indices1, indices1.new_tensor(expected_inds1))
            or torch.equal(indices1, indices1.new_tensor(expected_inds2)))
wuyuefeng's avatar
Votenet  
wuyuefeng committed
74
75
    assert (indices2 == indices2.new_tensor([[0, 0, 0, 0, 0], [0, 3, 6, 0,
                                                               0]])).all()
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


def test_paconv_regularization_loss():
    from mmdet3d.models.losses import PAConvRegularizationLoss
    from mmdet3d.ops import PAConv, PAConvCUDA
    from mmdet.apis import set_random_seed

    class ToyModel(nn.Module):

        def __init__(self):
            super(ToyModel, self).__init__()

            self.paconvs = nn.ModuleList()
            self.paconvs.append(PAConv(8, 16, 8))
            self.paconvs.append(PAConv(8, 16, 8, kernel_input='identity'))
            self.paconvs.append(PAConvCUDA(8, 16, 8))

            self.conv1 = nn.Conv1d(3, 8, 1)

    set_random_seed(0, True)
    model = ToyModel()

    # reduction shoule be in ['none', 'mean', 'sum']
    with pytest.raises(AssertionError):
        paconv_corr_loss = PAConvRegularizationLoss(reduction='l2')

    paconv_corr_loss = PAConvRegularizationLoss(reduction='mean')
    mean_corr_loss = paconv_corr_loss(model.modules())
    assert mean_corr_loss >= 0
    assert mean_corr_loss.requires_grad

    sum_corr_loss = paconv_corr_loss(model.modules(), reduction_override='sum')
    assert torch.allclose(sum_corr_loss, mean_corr_loss * 3)

    none_corr_loss = paconv_corr_loss(
        model.modules(), reduction_override='none')
    assert none_corr_loss.shape[0] == 3
    assert torch.allclose(none_corr_loss.mean(), mean_corr_loss)
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148


def test_uncertain_smooth_l1_loss():
    from mmdet3d.models.losses import UncertainL1Loss, UncertainSmoothL1Loss

    # reduction shoule be in ['none', 'mean', 'sum']
    with pytest.raises(AssertionError):
        uncertain_l1_loss = UncertainL1Loss(reduction='l2')
    with pytest.raises(AssertionError):
        uncertain_smooth_l1_loss = UncertainSmoothL1Loss(reduction='l2')

    pred = torch.tensor([1.5783, 0.5972, 1.4821, 0.9488])
    target = torch.tensor([1.0813, -0.3466, -1.1404, -0.9665])
    sigma = torch.tensor([-1.0053, 0.4710, -1.7784, -0.8603])

    # test uncertain l1 loss
    uncertain_l1_loss_cfg = dict(
        type='UncertainL1Loss', alpha=1.0, reduction='mean', loss_weight=1.0)
    uncertain_l1_loss = build_loss(uncertain_l1_loss_cfg)
    mean_l1_loss = uncertain_l1_loss(pred, target, sigma)
    expected_l1_loss = torch.tensor(4.7069)
    assert torch.allclose(mean_l1_loss, expected_l1_loss, atol=1e-4)

    # test uncertain smooth l1 loss
    uncertain_smooth_l1_loss_cfg = dict(
        type='UncertainSmoothL1Loss',
        alpha=1.0,
        beta=0.5,
        reduction='mean',
        loss_weight=1.0)
    uncertain_smooth_l1_loss = build_loss(uncertain_smooth_l1_loss_cfg)
    mean_smooth_l1_loss = uncertain_smooth_l1_loss(pred, target, sigma)
    expected_smooth_l1_loss = torch.tensor(3.9795)
    assert torch.allclose(
        mean_smooth_l1_loss, expected_smooth_l1_loss, atol=1e-4)