Publishing 2019 R1 content
[platform/upstream/dldt.git] / tools / accuracy_checker / tests / test_regression_metrics.py
1 """
2 Copyright (c) 2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 """
16
17 import pytest
18 from accuracy_checker.metrics import MetricsExecutor
19 from accuracy_checker.representation import RegressionPrediction, RegressionAnnotation
20 from accuracy_checker.presenters import EvaluationResult
21
22
23 class TestRegressionMetric:
24     def setup_method(self):
25         self.module = 'accuracy_checker.metrics.metric_evaluator'
26
27     def test_mae_with_zero_diff_between_annotation_and_prediction(self):
28         annotations = [RegressionAnnotation('identifier', 3)]
29         predictions = [RegressionPrediction('identifier', 3)]
30         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae'}]}
31         expected = EvaluationResult(
32             pytest.approx([0.0, 0.0]),
33             None,
34             'mae',
35             None,
36             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
37         )
38         dispatcher = MetricsExecutor(config, None)
39
40         dispatcher.update_metrics_on_batch(annotations, predictions)
41
42         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
43             assert evaluation_result == expected
44
45     def test_mae_with_negative_diff_between_annotation_and_prediction(self):
46         annotations = [RegressionAnnotation('identifier', 3), RegressionAnnotation('identifier2', 1)]
47         predictions = [RegressionPrediction('identifier', 5), RegressionPrediction('identifier2', 5)]
48         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae'}]}
49         expected = EvaluationResult(
50             pytest.approx([3.0, 1.0]),
51             None,
52             'mae',
53             None,
54             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
55         )
56         dispatcher = MetricsExecutor(config, None)
57
58         dispatcher.update_metrics_on_batch(annotations, predictions)
59
60         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
61             assert evaluation_result == expected
62
63     def test_mae_with_positive_diff_between_annotation_and_prediction(self):
64         annotations = [RegressionAnnotation('identifier', 3), RegressionAnnotation('identifier2', 1)]
65         predictions = [RegressionPrediction('identifier', 1), RegressionPrediction('identifier2', -3)]
66         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae'}]}
67         expected = EvaluationResult(
68             pytest.approx([3.0, 1.0]),
69             None,
70             'mae',
71             None,
72             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
73         )
74         dispatcher = MetricsExecutor(config, None)
75
76         dispatcher.update_metrics_on_batch(annotations, predictions)
77
78         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
79             assert evaluation_result == expected
80
81     def test_mse_with_zero_diff_between_annotation_and_prediction(self):
82         annotations = [RegressionAnnotation('identifier', 3)]
83         predictions = [RegressionPrediction('identifier', 3)]
84         config = {'annotation': 'mocked', 'metrics': [{'type': 'mse'}]}
85         expected = EvaluationResult(
86             pytest.approx([0.0, 0.0]),
87             None,
88             'mse',
89             None,
90             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
91         )
92         dispatcher = MetricsExecutor(config, None)
93
94         dispatcher.update_metrics_on_batch(annotations, predictions)
95
96         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
97             assert evaluation_result == expected
98
99     def test_mse_with_negative_diff_between_annotation_and_prediction(self):
100         annotations = [RegressionAnnotation('identifier', 3), RegressionAnnotation('identifier2', 1)]
101         predictions = [RegressionPrediction('identifier', 5), RegressionPrediction('identifier2', 5)]
102         config = {'annotation': 'mocked', 'metrics': [{'type': 'mse'}]}
103         expected = EvaluationResult(
104             pytest.approx([10.0, 6.0]),
105             None,
106             'mse',
107             None,
108             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
109         )
110         dispatcher = MetricsExecutor(config, None)
111
112         dispatcher.update_metrics_on_batch(annotations, predictions)
113
114         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
115             assert evaluation_result == expected
116
117     def test_mse_with_positive_diff_between_annotation_and_prediction(self):
118         annotations = [RegressionAnnotation('identifier', 3), RegressionAnnotation('identifier2', 1)]
119         predictions = [RegressionPrediction('identifier', 1), RegressionPrediction('identifier2', -3)]
120         config = {'annotation': 'mocked', 'metrics': [{'type': 'mse'}]}
121         expected = EvaluationResult(
122             pytest.approx([10.0, 6.0]),
123             None,
124             'mse',
125             None,
126             {'postfix': ' ', 'scale': 1, 'names': ['mean', 'std'], 'calculate_mean': False}
127         )
128         dispatcher = MetricsExecutor(config, None)
129
130         dispatcher.update_metrics_on_batch(annotations, predictions)
131
132         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
133             assert evaluation_result == expected
134
135     def test_missed_interval(self):
136         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae_on_interval'}]}
137         with pytest.raises(ValueError):
138             MetricsExecutor(config, None)
139
140     def test_mae_on_interval_default_all_missed(self):
141         annotations = [RegressionAnnotation('identifier', -2)]
142         predictions = [RegressionPrediction('identifier', 1)]
143         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae_on_interval', 'end': 1}]}
144         expected = EvaluationResult(
145             pytest.approx([0.0]),
146             None,
147             'mae_on_interval',
148             None,
149             {'postfix': ' ', 'scale': 1, 'names': [], 'calculate_mean': False}
150         )
151         dispatcher = MetricsExecutor(config, None)
152
153         dispatcher.update_metrics_on_batch(annotations, predictions)
154
155         with pytest.warns(UserWarning) as warnings:
156             for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
157                 assert len(warnings) == 1
158                 assert evaluation_result == expected
159
160     def test_mae_on_interval_default_all_not_in_range_not_ignore_out_of_range(self):
161         annotations = [RegressionAnnotation('identifier', -1), RegressionAnnotation('identifier', 2)]
162         predictions = [RegressionPrediction('identifier', 1), RegressionPrediction('identifier', 2)]
163         expected = EvaluationResult(
164             pytest.approx([2.0, 0.0, 0.0, 0.0]),
165             None,
166             'mae_on_interval',
167             None,
168             {
169                 'postfix': ' ',
170                 'scale': 1,
171                 'names': ['mean: < 0.0', 'std: < 0.0', 'mean: > 1.0', 'std: > 1.0'],
172                 'calculate_mean': False
173             }
174         )
175         config = {
176             'annotation': 'mocked',
177             'metrics': [{'type': 'mae_on_interval', 'end': 1, 'ignore_values_not_in_interval': False}]
178         }
179         dispatcher = MetricsExecutor(config, None)
180
181         dispatcher.update_metrics_on_batch(annotations, predictions)
182
183         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
184             assert evaluation_result == expected
185
186     def test_mae_on_interval_values_in_range(self):
187         annotations = [RegressionAnnotation('identifier', 0.5), RegressionAnnotation('identifier', 0.5)]
188         predictions = [RegressionPrediction('identifier', 1), RegressionPrediction('identifier', 0.25)]
189         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae_on_interval', 'end': 1}]}
190         expected = EvaluationResult(
191             pytest.approx([0.375, 0.125]),
192             None,
193             'mae_on_interval',
194             None,
195             {'postfix': ' ', 'scale': 1, 'names': ['mean: <= 0.0 < 1.0', 'std: <= 0.0 < 1.0'], 'calculate_mean': False}
196         )
197         dispatcher = MetricsExecutor(config, None)
198
199         dispatcher.update_metrics_on_batch(annotations, predictions)
200
201         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
202             assert evaluation_result == expected
203
204     def test_mae_on_interval_default_not_ignore_out_of_range(self):
205         annotations = [
206             RegressionAnnotation('identifier', -1),
207             RegressionAnnotation('identifier',  2),
208             RegressionAnnotation('identifier', 0.5)
209         ]
210         predictions = [
211             RegressionPrediction('identifier', 1),
212             RegressionPrediction('identifier', 2),
213             RegressionPrediction('identifier', 1)
214         ]
215         config = {
216             'annotation': 'mocked',
217             'metrics': [{'type': 'mae_on_interval', 'end': 1, 'ignore_values_not_in_interval': False}]
218         }
219         expected = EvaluationResult(
220             pytest.approx([2.0, 0.0, 0.5, 0.0,  0.0, 0.0]),
221             None,
222             'mae_on_interval',
223             None,
224             {
225                 'postfix': ' ',
226                 'scale': 1,
227                 'names': [
228                     'mean: < 0.0',
229                     'std: < 0.0',
230                     'mean: <= 0.0 < 1.0',
231                     'std: <= 0.0 < 1.0',
232                     'mean: > 1.0',
233                     'std: > 1.0'
234                 ],
235                 'calculate_mean': False
236             }
237         )
238         dispatcher = MetricsExecutor(config, None)
239
240         dispatcher.update_metrics_on_batch(annotations, predictions)
241
242         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
243             assert evaluation_result == expected
244
245     def test_mae_on_interval_with_given_interval(self):
246         annotations = [
247             RegressionAnnotation('identifier', -1),
248             RegressionAnnotation('identifier',  2),
249             RegressionAnnotation('identifier',  1)
250         ]
251         predictions = [
252             RegressionPrediction('identifier', 1),
253             RegressionPrediction('identifier', 3),
254             RegressionPrediction('identifier', 1)
255         ]
256         config = {
257             'annotation': 'mocked',
258             'metrics': [{'type': 'mae_on_interval', 'intervals': [0.0, 2.0, 4.0]}]
259         }
260         expected = EvaluationResult(
261             pytest.approx([0.0, 0.0, 1.0, 0.0]),
262             None,
263             'mae_on_interval',
264             None,
265             {
266                 'postfix': ' ',
267                 'scale': 1,
268                 'names': ['mean: <= 0.0 < 2.0', 'std: <= 0.0 < 2.0', 'mean: <= 2.0 < 4.0', 'std: <= 2.0 < 4.0'],
269                 'calculate_mean': False
270             }
271         )
272         dispatcher = MetricsExecutor(config, None)
273
274         dispatcher.update_metrics_on_batch(annotations, predictions)
275
276         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
277             assert evaluation_result == expected
278
279     def test_mae_on_interval_with_repeated_values(self):
280         annotations = [
281             RegressionAnnotation('identifier', -1),
282             RegressionAnnotation('identifier',  2),
283             RegressionAnnotation('identifier', 1)
284         ]
285         predictions = [
286             RegressionPrediction('identifier', 1),
287             RegressionPrediction('identifier', 3),
288             RegressionPrediction('identifier', 1)
289         ]
290         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae_on_interval', 'intervals': [0.0, 2.0, 2.0, 4.0]}]}
291         expected = EvaluationResult(
292             pytest.approx([0.0, 0.0, 1.0, 0.0]),
293             None,
294             'mae_on_interval',
295             None,
296             {
297                 'postfix': ' ',
298                 'scale': 1,
299                 'names': ['mean: <= 0.0 < 2.0', 'std: <= 0.0 < 2.0', 'mean: <= 2.0 < 4.0', 'std: <= 2.0 < 4.0'],
300                 'calculate_mean': False
301             }
302         )
303         dispatcher = MetricsExecutor(config, None)
304
305         dispatcher.update_metrics_on_batch(annotations, predictions)
306
307         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
308             assert evaluation_result == expected
309
310     def test_mae_on_interval_with_unsorted_values(self):
311         annotations = [
312             RegressionAnnotation('identifier', -1),
313             RegressionAnnotation('identifier',  2),
314             RegressionAnnotation('identifier',  1)
315         ]
316         predictions = [
317             RegressionPrediction('identifier', 1),
318             RegressionPrediction('identifier', 3),
319             RegressionPrediction('identifier', 1)
320         ]
321         config = {'annotation': 'mocked', 'metrics': [{'type': 'mae_on_interval', 'intervals': [2.0,  0.0, 4.0]}]}
322         expected = EvaluationResult(
323             pytest.approx([0.0, 0.0, 1.0, 0.0]),
324             None,
325             'mae_on_interval',
326             None,
327             {
328                 'postfix': ' ', 'scale': 1,
329                 'names': ['mean: <= 0.0 < 2.0', 'std: <= 0.0 < 2.0', 'mean: <= 2.0 < 4.0', 'std: <= 2.0 < 4.0'],
330                 'calculate_mean': False
331             }
332         )
333         dispatcher = MetricsExecutor(config, None)
334
335         dispatcher.update_metrics_on_batch(annotations, predictions)
336
337         for _, evaluation_result in dispatcher.iterate_metrics(annotations, predictions):
338             assert evaluation_result == expected