• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15
16import numpy as np
17import pytest
18
19import mindspore.context as context
20import mindspore.nn as nn
21from mindspore import Tensor
22from mindspore.ops import operations as P
23from mindspore.ops import composite as C
24from mindspore.common import dtype as mstype
25
26
27class PReLUOpNet(nn.Cell):
28    def __init__(self):
29        super(PReLUOpNet, self).__init__()
30        self.prelu = P.PReLU()
31
32    def construct(self, x, weight):
33        return self.prelu(x, weight)
34
35
36class PReLUOpGradNet(nn.Cell):
37    def __init__(self, net):
38        super(PReLUOpGradNet, self).__init__()
39        self.forward = net
40        self.grad = C.GradOperation(get_all=True, sens_param=False)
41
42    def construct(self, x, weight):
43        return self.grad(self.forward)(x, weight)
44
45
46def judge_result_correct(result, expect):
47    result = result.asnumpy()
48    expect = expect.asnumpy()
49    assert result.dtype == expect.dtype
50    assert result.shape == expect.shape
51    assert np.allclose(result, expect, rtol=1.e-2)
52
53
54def test_prelu(x, weight, expect_forward, expect_dx, expect_dw):
55    prelu_forward = PReLUOpNet()
56    prelu_backward = PReLUOpGradNet(prelu_forward)
57    forward_output = prelu_forward(x, weight)
58    judge_result_correct(forward_output, expect_forward)
59
60    backward_output = prelu_backward(x, weight)
61    assert len(backward_output) == 2
62    judge_result_correct(backward_output[0], expect_dx)
63    judge_result_correct(backward_output[1], expect_dw)
64
65
66context.set_context(device_target="GPU", mode=context.GRAPH_MODE)
67dtypes = [mstype.float16, mstype.float32]
68
69
70@pytest.mark.level0
71@pytest.mark.platform_x86_gpu_training
72@pytest.mark.env_onecard
73def test_prelu_single_weight():
74    x = np.arange(-10, 26).reshape((2, 3, 2, 3)) * 0.7
75    weight = np.array([0.6])
76    expect_forward = np.where(x >= 0, x, weight * x)
77    expect_dx = np.where(x > 0, 1, weight)
78    expect_dw = np.sum(np.where(x >= 0, 0, x)).reshape((1,))
79
80    for dtype in dtypes:
81        x = Tensor(x, dtype)
82        weight = Tensor(weight, dtype)
83        expect_forward = Tensor(expect_forward, dtype)
84        expect_dx = Tensor(expect_dx, dtype)
85        expect_dw = Tensor(expect_dw, dtype)
86        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
87
88
89@pytest.mark.level0
90@pytest.mark.platform_x86_gpu_training
91@pytest.mark.env_onecard
92def test_prelu_multiple_weight():
93    x = np.arange(-10, 26).reshape((2, 3, 2, 3)) * 0.6
94    weight = np.array([0.2, 0.3, 0.4])
95    expect_forward = np.array([[[[-1.20, -1.08, -0.96],
96                                 [-0.84, -0.72, -0.60]],
97                                [[-0.72, -0.54, -0.36],
98                                 [-0.18, 0.00, 0.60]],
99                                [[1.20, 1.80, 2.40],
100                                 [3.00, 3.60, 4.20]]],
101                               [[[4.80, 5.40, 6.00],
102                                 [6.60, 7.20, 7.80]],
103                                [[8.40, 9.00, 9.60],
104                                 [10.20, 10.80, 11.40]],
105                                [[12.00, 12.60, 13.20],
106                                 [13.80, 14.40, 15.00]]]])
107    expect_dx = np.array([[[[0.2, 0.2, 0.2],
108                            [0.2, 0.2, 0.2]],
109                           [[0.3, 0.3, 0.3],
110                            [0.3, 0.3, 1.0]],
111                           [[1.0, 1.0, 1.0],
112                            [1.0, 1.0, 1.0]]],
113                          [[[1.0, 1.0, 1.0],
114                            [1.0, 1.0, 1.0]],
115                           [[1.0, 1.0, 1.0],
116                            [1.0, 1.0, 1.0]],
117                           [[1.0, 1.0, 1.0],
118                            [1.0, 1.0, 1.0]]]])
119    expect_dw = np.array([-27.0, -6.0, 0.0])
120
121    for dtype in dtypes:
122        x = Tensor(x, dtype)
123        weight = Tensor(weight, dtype)
124        expect_forward = Tensor(expect_forward, dtype)
125        expect_dx = Tensor(expect_dx, dtype)
126        expect_dw = Tensor(expect_dw, dtype)
127        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
128
129
130@pytest.mark.level0
131@pytest.mark.platform_x86_gpu_training
132@pytest.mark.env_onecard
133def test_prelu_single_weight_0_D():
134    x = np.array(-0.8)
135    weight = np.array([0.6])
136    expect_forward = np.array(-0.48)
137    expect_dx = np.array(0.6)
138    expect_dw = np.array([-0.8])
139
140    for dtype in dtypes:
141        x = Tensor(x, dtype)
142        weight = Tensor(weight, dtype)
143        expect_forward = Tensor(expect_forward, dtype)
144        expect_dx = Tensor(expect_dx, dtype)
145        expect_dw = Tensor(expect_dw, dtype)
146        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
147
148
149@pytest.mark.level0
150@pytest.mark.platform_x86_gpu_training
151@pytest.mark.env_onecard
152def test_prelu_single_weight_1_D():
153    x = np.arange(-10, 26).reshape((36,)) * 0.7
154    weight = np.array([0.6])
155    expect_forward = np.where(x >= 0, x, weight * x)
156    expect_dx = np.where(x > 0, 1, weight)
157    expect_dw = np.sum(np.where(x >= 0, 0, x)).reshape((1,))
158
159    for dtype in dtypes:
160        x = Tensor(x, dtype)
161        weight = Tensor(weight, dtype)
162        expect_forward = Tensor(expect_forward, dtype)
163        expect_dx = Tensor(expect_dx, dtype)
164        expect_dw = Tensor(expect_dw, dtype)
165        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
166
167
168@pytest.mark.level0
169@pytest.mark.platform_x86_gpu_training
170@pytest.mark.env_onecard
171def test_prelu_single_weight_2_D():
172    x = np.arange(-10, 26).reshape((4, 9)) * 0.7
173    weight = np.array([0.6])
174    expect_forward = np.where(x >= 0, x, weight * x)
175    expect_dx = np.where(x > 0, 1, weight)
176    expect_dw = np.sum(np.where(x >= 0, 0, x)).reshape((1,))
177
178    for dtype in dtypes:
179        x = Tensor(x, dtype)
180        weight = Tensor(weight, dtype)
181        expect_forward = Tensor(expect_forward, dtype)
182        expect_dx = Tensor(expect_dx, dtype)
183        expect_dw = Tensor(expect_dw, dtype)
184        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
185
186
187@pytest.mark.level0
188@pytest.mark.platform_x86_gpu_training
189@pytest.mark.env_onecard
190def test_prelu_multiple_weight_2_D():
191    x = np.arange(-6, 6).reshape((3, 4)) * 0.6
192    weight = np.array([0.2, 0.4, 0.7, 0.9])
193    expect_forward = np.array([[-0.72, -1.20, -1.68, -1.62],
194                               [-0.24, -0.24, 0.00, 0.60],
195                               [1.20, 1.80, 2.40, 3.00]])
196    expect_dx = np.array([[0.2, 0.4, 0.7, 0.9],
197                          [0.2, 0.4, 0.7, 1.0],
198                          [1.0, 1.0, 1.0, 1.0]])
199    expect_dw = np.array([-4.8, -3.6, -2.4, -1.8])
200
201    for dtype in dtypes:
202        x = Tensor(x, dtype)
203        weight = Tensor(weight, dtype)
204        expect_forward = Tensor(expect_forward, dtype)
205        expect_dx = Tensor(expect_dx, dtype)
206        expect_dw = Tensor(expect_dw, dtype)
207        test_prelu(x, weight, expect_forward, expect_dx, expect_dw)
208