pytorch

Форк
0
/
c2_ref_test.py 
869 строк · 30.8 Кб
1
# @package onnx
2
# Module caffe2.python.onnx.tests.c2_ref_test
3

4

5

6

7

8

9
import os
10
import unittest
11

12
from caffe2.python import core
13
from caffe2.proto import caffe2_pb2
14

15
import onnx
16
from onnx.helper import make_node, make_graph, make_tensor, make_tensor_value_info, make_model
17
from caffe2.python.onnx.helper import c2_native_run_net, c2_native_run_op
18

19
from onnx import mapping
20
import caffe2.python.onnx.frontend as c2_onnx
21
import caffe2.python.onnx.backend as c2
22

23
import numpy as np
24
from caffe2.python.models.download import ModelDownloader
25

26
from caffe2.python.onnx.tests.test_utils import TestCase
27

28
import caffe2.python._import_c_extension as C
29

30

31
class TestCaffe2Basic(TestCase):
32
    def test_dummy_name(self):
33
        g = C.DummyName()
34
        n1 = g.new_dummy_name()
35
        n2 = g.new_dummy_name()
36
        assert n1 != n2, "Got same names in different calls: {}".format(n1)
37

38
    def test_check_arguments(self):
39
        b2 = C.Caffe2Backend()
40

41
        node_def = make_node("Add", inputs=["X", "Y"], outputs=["Z"])
42
        b2.convert_node(node_def.SerializeToString())
43

44
        bad_node_def = make_node("Add", inputs=["X", "Y"], outputs=["Z"], foo=42, bar=56)
45
        with self.assertRaisesRegex(RuntimeError,
46
                                    "Don't know how to map unexpected argument (foo|bar)"):
47
            b2.convert_node(bad_node_def.SerializeToString())
48

49
    def test_dynamicslice_3inputs_graph(self):
50
        node_def = make_node(
51
            "DynamicSlice", ["X1", "X2", "X3"], ["Y"])
52

53
        graph_def = make_graph(
54
            [node_def],
55
            name="test",
56
            inputs=[make_tensor_value_info("X1", onnx.TensorProto.FLOAT, (2, 4)),
57
             make_tensor_value_info("X2", onnx.TensorProto.INT32, (1, 2)),
58
             make_tensor_value_info("X3", onnx.TensorProto.INT32, (1, 2))],
59
            outputs=[make_tensor_value_info("Y", onnx.TensorProto.FLOAT, (1, 2))])
60
        model_def = make_model(graph_def, producer_name='caffe2-ref-test')
61

62
        x = [[1,2,3,4],[5,6,7,8]]
63
        start = [0, 0]
64
        end = [-1, 4]
65
        prepared = c2.prepare(model_def)
66
        output = prepared.run(inputs=[np.array(x), np.array(start), np.array(end)])
67
        self.assertSameOutputs(output[0], np.array(x)[0:-1, 0:4])
68

69
    def test_dynamicslice_4inputs_graph(self):
70
        node_def = make_node(
71
            "DynamicSlice", ["X1", "X2", "X3", "axes"], ["Y"])
72
        graph_def = make_graph(
73
            [node_def],
74
            name="test",
75
            inputs=[make_tensor_value_info("X1", onnx.TensorProto.FLOAT, (2, 4)),
76
             make_tensor_value_info("X2", onnx.TensorProto.INT32, (1, 2)),
77
             make_tensor_value_info("X3", onnx.TensorProto.INT32, (1, 2)),
78
             make_tensor_value_info("axes", onnx.TensorProto.INT32, (1, 2))],
79
            outputs=[make_tensor_value_info("Y", onnx.TensorProto.FLOAT, (1, 2))])
80
        model_def = make_model(graph_def, producer_name='caffe2-ref-test')
81
        x = [[1,2,3,4],[5,6,7,8]]
82
        start = [0, 1]
83
        end = [4, 5]
84
        axes = [1, 0]
85
        prepared = c2.prepare(model_def)
86
        output = prepared.run(inputs=[np.array(x), np.array(start), np.array(end), np.array(axes)])
87
        self.assertSameOutputs(output[0], np.array(x)[1:5, 0:4])
88

89
    def test_relu_graph(self):
90
        X = np.random.randn(3, 2).astype(np.float32)
91
        Y_ref = np.clip(X, 0, np.inf)
92

93
        node_def = make_node(
94
            "Relu", ["X"], ["Y"])
95
        output = c2.run_node(
96
            node_def, {"X": X})
97
        np.testing.assert_almost_equal(output.Y, Y_ref)
98

99
        graph_def = make_graph(
100
            [node_def],
101
            name="test",
102
            inputs=[make_tensor_value_info("X", onnx.TensorProto.FLOAT, [3, 2])],
103
            outputs=[make_tensor_value_info("Y", onnx.TensorProto.FLOAT, [3, 2])])
104
        c2_rep = c2.prepare(make_model(graph_def, producer_name='caffe2-ref-test'))
105
        output = c2_rep.run(X)
106
        np.testing.assert_almost_equal(output.Y, Y_ref)
107

108
    def test_elementwiselinear(self):
109
        X = np.random.randn(4, 2, 5, 7, 3).astype(np.float32)
110
        W = np.random.randn(21).astype(np.float32)
111
        B = np.random.randn(21).astype(np.float32)
112

113
        predict_net = caffe2_pb2.NetDef()
114
        predict_net.name = 'test-elementwiselinear-net'
115
        predict_net.external_input[:] = ['X', 'W', 'B']
116
        predict_net.external_output[:] = ['Y']
117
        predict_net.op.extend([
118
            core.CreateOperator(
119
                'ElementwiseLinear',
120
                inputs=['X', 'W', 'B'],
121
                outputs=['Y'],
122
                axis=3,
123
            ),
124
        ])
125
        ws, c2_outputs = c2_native_run_net(
126
            init_net=None,
127
            predict_net=predict_net,
128
            inputs=[X, W, B])
129

130
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
131
            predict_net=predict_net,
132
            value_info={
133
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape),
134
                'W': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[W.dtype], W.shape),
135
                'B': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[B.dtype], B.shape),
136
            })
137
        onnx_outputs = c2.run_model(onnx_model, inputs=[X, W, B])
138
        self.assertSameOutputs(c2_outputs, onnx_outputs)
139

140
    def test_initializer(self):
141
        X = np.array([[1, 2], [3, 4]]).astype(np.float32)
142
        Y = np.array([[1, 2], [3, 4]]).astype(np.float32)
143
        weight = np.array([[1, 0], [0, 1]])
144
        graph_def = make_graph(
145
            [make_node("Add", ["X", "Y"], ["Z0"]),
146
             make_node("Cast", ["Z0"], ["Z"], to=onnx.TensorProto.FLOAT),
147
             make_node("Mul", ["Z", "weight"], ["W0"]),
148
             make_node("Tanh", ["W0"], ["W1"]),
149
             make_node("Sigmoid", ["W1"], ["W2"]),
150
             make_node("Scale", ["W2"], ["W3"], scale=-1.0)],
151
            name="test_initializer",
152
            inputs=[
153
                make_tensor_value_info("X", onnx.TensorProto.FLOAT, (2, 2)),
154
                make_tensor_value_info("Y", onnx.TensorProto.FLOAT, (2, 2)),
155
                make_tensor_value_info("weight", onnx.TensorProto.FLOAT, (2, 2)),
156
            ],
157
            outputs=[
158
                make_tensor_value_info("W3", onnx.TensorProto.FLOAT, (2, 2))
159
            ],
160
            initializer=[make_tensor("weight",
161
                                     onnx.TensorProto.FLOAT,
162
                                     [2, 2],
163
                                     weight.flatten().astype(float))]
164
        )
165

166
        def sigmoid(x):
167
            return 1 / (1 + np.exp(-x))
168

169
        W_ref = -sigmoid(np.tanh((X + Y) * weight))
170
        c2_rep = c2.prepare(make_model(graph_def, producer_name='caffe2-ref-test'))
171
        output = c2_rep.run({"X": X, "Y": Y})
172
        np.testing.assert_almost_equal(output["W3"], W_ref)
173

174
    def test_reducemean(self):
175
        X = np.random.randn(4, 6, 10, 5, 3).astype(np.float32)
176

177
        predict_net = caffe2_pb2.NetDef()
178
        predict_net.name = 'test-reducemean-net'
179
        predict_net.external_input[:] = ['X']
180
        predict_net.external_output[:] = [
181
                'reduce_front_mean',
182
                'reduce_back_mean',
183
                'reduce_mean_0',
184
                'reduce_mean_1',
185
            ]
186
        predict_net.op.extend([
187
            core.CreateOperator(
188
                'ReduceFrontMean',
189
                inputs=['X'],
190
                outputs=['reduce_front_mean'],
191
                num_reduce_dim=2,
192
            ),
193
            core.CreateOperator(
194
                'ReduceBackMean',
195
                inputs=['X'],
196
                outputs=['reduce_back_mean'],
197
                num_reduce_dim=2,
198
            ),
199
            core.CreateOperator(
200
                'ReduceMean',
201
                inputs=['X'],
202
                outputs=['reduce_mean_0'],
203
                axes=[1, 3],
204
                keepdims=0,
205
            ),
206
            core.CreateOperator(
207
                'ReduceMean',
208
                inputs=['X'],
209
                outputs=['reduce_mean_1'],
210
                axes=[1, 3],
211
                keepdims=1,
212
            ),
213
        ])
214
        ws, c2_outputs = c2_native_run_net(
215
            init_net=None,
216
            predict_net=predict_net,
217
            inputs=[X])
218

219
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
220
            predict_net=predict_net,
221
            value_info={
222
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape)
223
            })
224
        onnx_outputs = c2.run_model(onnx_model, inputs=[X])
225
        self.assertSameOutputs(c2_outputs, onnx_outputs)
226

227
    def test_upsample(self):
228
        X = np.random.randn(1, 1, 2, 2).astype(np.float32)
229
        width_scale = 2.0
230
        height_scale = 2.0
231

232
        predict_net = caffe2_pb2.NetDef()
233
        predict_net.name = 'test-upsample-net'
234
        predict_net.external_input[:] = ['X']
235
        predict_net.external_output[:] = ['Y']
236
        predict_net.op.extend([
237
            core.CreateOperator(
238
                'ResizeNearest',
239
                inputs=['X'],
240
                outputs=['Y'],
241
                width_scale=width_scale,
242
                height_scale=height_scale,
243
            ),
244
        ])
245
        ws, c2_outputs = c2_native_run_net(
246
            init_net=None,
247
            predict_net=predict_net,
248
            inputs=[X])
249

250
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
251
            predict_net=predict_net,
252
            value_info={
253
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape)
254
            })
255
        onnx_outputs = c2.run_model(onnx_model, inputs=[X])
256
        self.assertSameOutputs(c2_outputs, onnx_outputs)
257

258
    def test_fc(self):
259
        X_fake = np.zeros((3, 1, 3, 1, 7), dtype=np.float32)
260
        X = np.random.randn(5, 2, 3, 1, 7).astype(np.float32)
261
        W = np.random.randn(11, 21).astype(np.float32)
262
        B = np.random.randn(11).astype(np.float32)
263

264
        predict_net = caffe2_pb2.NetDef()
265
        predict_net.name = 'test-fc-net'
266
        predict_net.external_input[:] = ['X', 'W', 'B']
267
        predict_net.external_output[:] = ['Y']
268
        predict_net.op.extend([
269
            core.CreateOperator(
270
                'FC',
271
                inputs=['X', 'W', 'B'],
272
                outputs=['Y'],
273
                axis=2,
274
            ),
275
        ])
276
        ws, c2_outputs = c2_native_run_net(
277
            init_net=None,
278
            predict_net=predict_net,
279
            inputs=[X, W, B])
280

281
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
282
            predict_net=predict_net,
283
            value_info={
284
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X_fake.shape),
285
                'W': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[W.dtype], W.shape),
286
                'B': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[B.dtype], B.shape),
287
            })
288
        onnx_outputs = c2.run_model(onnx_model, inputs=[X, W, B])
289
        self.assertSameOutputs(c2_outputs, onnx_outputs)
290

291
    def test_gemm(self):
292
        # simple
293
        A = np.random.randn(3, 2).astype(np.float32)
294
        B = np.random.randn(2, 4).astype(np.float32)
295
        C = np.random.randn(3, 4).astype(np.float32)
296
        node_def = make_node(
297
            'Gemm',
298
            ['A', 'B', 'C'],
299
            ["Y"])
300
        output = c2.run_node(node_def, [A, B, C])
301
        np.testing.assert_almost_equal(output["Y"], np.dot(A, B) + C)
302

303
        # transA
304
        A = np.transpose(A)
305
        node_def = make_node(
306
            'Gemm',
307
            ['A', 'B', 'C'],
308
            ["Y"],
309
            transA=1)
310
        output = c2.run_node(node_def, [A, B, C])
311
        np.testing.assert_almost_equal(
312
            output["Y"],
313
            np.dot(np.transpose(A), B) + C)
314
        # revert A
315
        A = np.transpose(A)
316

317
        # transB
318
        B = np.transpose(B)
319
        node_def = make_node(
320
            'Gemm',
321
            ['A', 'B', 'C'],
322
            ["Y"],
323
            transB=1)
324
        output = c2.run_node(node_def, [A, B, C])
325
        np.testing.assert_almost_equal(
326
            output["Y"],
327
            np.dot(A, np.transpose(B)) + C)
328
        # revert B
329
        B = np.transpose(B)
330

331
        # scale
332
        alpha = np.random.random()
333
        beta = np.random.random()
334
        node_def = make_node(
335
            'Gemm',
336
            ['A', 'B', 'C'],
337
            ["Y"],
338
            alpha=alpha,
339
            beta=beta)
340
        output = c2.run_node(node_def, [A, B, C])
341
        np.testing.assert_almost_equal(
342
            output["Y"],
343
            alpha * np.dot(A, B) + beta * C)
344

345
        # setup broadcastable C
346
        C = np.random.randn(4).astype(np.float32)
347

348
        # broadcast for opset7
349
        node_def = make_node(
350
            'Gemm',
351
            ['A', 'B', 'C'],
352
            ["Y"],
353
            alpha=alpha,
354
            beta=beta)
355
        output = c2.run_node(node_def, [A, B, C], opset_version=7)
356
        np.testing.assert_almost_equal(
357
            output["Y"],
358
            alpha * np.dot(A, B) + beta * C)
359
        # broadcast for opset3 and 6
360
        node_def = make_node(
361
            'Gemm',
362
            ['A', 'B', 'C'],
363
            ["Y"],
364
            alpha=alpha,
365
            beta=beta,
366
            broadcast=1)
367
        output = c2.run_node(node_def, [A, B, C], opset_version=6)
368
        np.testing.assert_almost_equal(
369
            output["Y"],
370
            alpha * np.dot(A, B) + beta * C)
371

372
        # transB
373
        B = np.transpose(B)
374

375
        # transB and broadcast for opset7
376
        node_def = make_node(
377
            'Gemm',
378
            ['A', 'B', 'C'],
379
            ["Y"],
380
            alpha=alpha,
381
            beta=beta,
382
            transB=1)
383
        output = c2.run_node(node_def, [A, B, C], opset_version=7)
384
        np.testing.assert_almost_equal(
385
            output["Y"],
386
            alpha * np.dot(A, np.transpose(B)) + beta * C)
387
        # transB and broadcast for opset3 and 6
388
        node_def = make_node(
389
            'Gemm',
390
            ['A', 'B', 'C'],
391
            ["Y"],
392
            alpha=alpha,
393
            beta=beta,
394
            broadcast=1,
395
            transB=1)
396
        output = c2.run_node(node_def, [A, B, C], opset_version=6)
397
        np.testing.assert_almost_equal(
398
            output["Y"],
399
            alpha * np.dot(A, np.transpose(B)) + beta * C)
400

401
        # revert B
402
        B = np.transpose(B)
403
        # set a scalar to C
404
        C = np.random.randn(1).astype(np.float32)
405

406
        # scalar broadcast for opset7
407
        node_def = make_node(
408
            'Gemm',
409
            ['A', 'B', 'C'],
410
            ["Y"],
411
            alpha=alpha,
412
            beta=beta)
413
        output = c2.run_node(node_def, [A, B, C], opset_version=7)
414
        np.testing.assert_almost_equal(
415
            output["Y"],
416
            alpha * np.dot(A, B) + beta * C)
417
        # scalar broadcast for opset3 and 6
418
        node_def = make_node(
419
            'Gemm',
420
            ['A', 'B', 'C'],
421
            ["Y"],
422
            alpha=alpha,
423
            beta=beta,
424
            broadcast=1)
425
        output = c2.run_node(node_def, [A, B, C], opset_version=6)
426
        np.testing.assert_almost_equal(
427
            output["Y"],
428
            alpha * np.dot(A, B) + beta * C)
429

430
    def test_gemm_conversion(self):
431
        node_def = make_node(
432
            'Gemm',
433
            ['A', 'B', 'C'],
434
            ["Y"],
435
            alpha=2.,
436
            beta=3.)
437
        node_def_broadcast = make_node(
438
            'Gemm',
439
            ['A', 'B', 'C'],
440
            ["Y"],
441
            alpha=2.,
442
            beta=3.,
443
            broadcast=1)
444
        node_def_transpose_b = make_node(
445
            'Gemm',
446
            ['A', 'B', 'C'],
447
            ["Y"],
448
            alpha=2.,
449
            beta=3.,
450
            transB=1)
451

452
        node_def_transpose_b_broadcast = make_node(
453
            'Gemm',
454
            ['A', 'B', 'C'],
455
            ["Y"],
456
            alpha=2.,
457
            beta=3.,
458
            transB=1,
459
            broadcast=1)
460

461
        backend = C.Caffe2Backend()
462

463
        # without broadcast and without shape info, gemm will be
464
        # converted to matmul + add
465
        _, op_strs = backend.convert_node(node_def.SerializeToString())
466
        op_names = []
467
        for s in op_strs:
468
            op = caffe2_pb2.OperatorDef()
469
            op.ParseFromString(s)
470
            op_names.append(op.type)
471
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
472

473
        # opset7
474
        # If C is a 1d tensor, gemm will be converted to FC/FCTransposed
475
        _, op_strs = backend.convert_node(node_def_transpose_b.SerializeToString(
476
        ), [make_tensor_value_info("C", onnx.TensorProto.FLOAT, (3,)).SerializeToString()],
477
        7)
478
        op_names = []
479
        for s in op_strs:
480
            op = caffe2_pb2.OperatorDef()
481
            op.ParseFromString(s)
482
            op_names.append(op.type)
483
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])
484

485
        _, op_strs = backend.convert_node(node_def.SerializeToString(
486
        ), [make_tensor_value_info("C", onnx.TensorProto.FLOAT, (3,)).SerializeToString()],
487
        7)
488
        op_names = []
489
        for s in op_strs:
490
            op = caffe2_pb2.OperatorDef()
491
            op.ParseFromString(s)
492
            op_names.append(op.type)
493
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])
494

495
        # opset6 without broadcast(C should match A*B's dim)
496
        # The gemm will be converted to matmul + add, since the FC requires c
497
        # to be 1d tensor.
498
        _, op_strs = backend.convert_node(node_def.SerializeToString(
499
        ), [make_tensor_value_info("A", onnx.TensorProto.FLOAT, (3,2)).SerializeToString(),
500
            make_tensor_value_info("B", onnx.TensorProto.FLOAT, (2,3)).SerializeToString(),
501
            make_tensor_value_info("C", onnx.TensorProto.FLOAT, (3,3)).SerializeToString()],
502
        6)
503
        op_names = []
504
        for s in op_strs:
505
            op = caffe2_pb2.OperatorDef()
506
            op.ParseFromString(s)
507
            op_names.append(op.type)
508
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
509

510
        # opset6 with broadcast
511
        # If C is a 1d tensor, gemm will be converted to FC/FCTransposed
512
        _, op_strs = backend.convert_node(node_def_transpose_b_broadcast.SerializeToString(
513
        ), [make_tensor_value_info("C", onnx.TensorProto.FLOAT, (3,)).SerializeToString()],
514
        6)
515
        op_names = []
516
        for s in op_strs:
517
            op = caffe2_pb2.OperatorDef()
518
            op.ParseFromString(s)
519
            op_names.append(op.type)
520
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])
521

522
        _, op_strs = backend.convert_node(node_def_broadcast.SerializeToString(
523
        ), [make_tensor_value_info("C", onnx.TensorProto.FLOAT, (3,)).SerializeToString()],
524
        6)
525
        op_names = []
526
        for s in op_strs:
527
            op = caffe2_pb2.OperatorDef()
528
            op.ParseFromString(s)
529
            op_names.append(op.type)
530
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])
531

532
        # opset7
533
        # If C is a scalar and B's last dim is 1, gemm will be converted to FC/FCTransposed
534
        _, op_strs = backend.convert_node(node_def_transpose_b.SerializeToString(
535
        ), [make_tensor_value_info("B", onnx.TensorProto.FLOAT, (1,2)).SerializeToString(),
536
            make_tensor_value_info("C", onnx.TensorProto.FLOAT, (1,)).SerializeToString()],
537
        7)
538
        op_names = []
539
        for s in op_strs:
540
            op = caffe2_pb2.OperatorDef()
541
            op.ParseFromString(s)
542
            op_names.append(op.type)
543
        self.assertEqual(op_names, ['Scale', 'Scale', 'FC'])
544

545
        _, op_strs = backend.convert_node(node_def.SerializeToString(
546
        ), [make_tensor_value_info("B", onnx.TensorProto.FLOAT, (2,1)).SerializeToString(),
547
            make_tensor_value_info("C", onnx.TensorProto.FLOAT, (1,)).SerializeToString()],
548
        7)
549
        op_names = []
550
        for s in op_strs:
551
            op = caffe2_pb2.OperatorDef()
552
            op.ParseFromString(s)
553
            op_names.append(op.type)
554
        self.assertEqual(op_names, ['Scale', 'Scale', 'FCTransposed'])
555
        # If C is a scalar and B's last dim is not 1, gemm will be converted
556
        # to matmul + add.
557
        _, op_strs = backend.convert_node(node_def_transpose_b.SerializeToString(
558
        ), [make_tensor_value_info("B", onnx.TensorProto.FLOAT, (2,2)).SerializeToString(),
559
            make_tensor_value_info("C", onnx.TensorProto.FLOAT, (1,)).SerializeToString()],
560
        7)
561
        op_names = []
562
        for s in op_strs:
563
            op = caffe2_pb2.OperatorDef()
564
            op.ParseFromString(s)
565
            op_names.append(op.type)
566
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
567
        # If C is a scalar and B's shape info is not available,
568
        # gemm will be converted to matmul + add.
569
        _, op_strs = backend.convert_node(node_def_transpose_b.SerializeToString(
570
        ), [make_tensor_value_info("C", onnx.TensorProto.FLOAT, (1,)).SerializeToString()],
571
        7)
572
        op_names = []
573
        for s in op_strs:
574
            op = caffe2_pb2.OperatorDef()
575
            op.ParseFromString(s)
576
            op_names.append(op.type)
577
        self.assertEqual(op_names, ['Scale', 'Scale', 'MatMul', 'Add'])
578

579
    def test_mergedim(self):
580
        X = np.random.randn(2, 3, 1, 5).astype(np.float32)
581

582
        predict_net = caffe2_pb2.NetDef()
583
        predict_net.name = 'test-mergedim-net'
584
        predict_net.external_input[:] = ['X']
585
        predict_net.external_output[:] = ['Y']
586
        predict_net.op.extend([
587
            core.CreateOperator(
588
                'MergeDim',
589
                inputs=['X'],
590
                outputs=['Y'],
591
            ),
592
        ])
593
        ws, c2_outputs = c2_native_run_net(
594
            init_net=None,
595
            predict_net=predict_net,
596
            inputs=[X])
597

598
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
599
            predict_net=predict_net,
600
            value_info={
601
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape),
602
            })
603
        onnx_outputs = c2.run_model(onnx_model, inputs=[X])
604
        self.assertSameOutputs(c2_outputs, onnx_outputs)
605

606
    def test_tensor_filling_ops(self):
607
        for dtype in [
608
                onnx.TensorProto.FLOAT,
609
                onnx.TensorProto.DOUBLE,
610
                onnx.TensorProto.BOOL,
611
                onnx.TensorProto.INT8,
612
                onnx.TensorProto.INT16,
613
                onnx.TensorProto.INT32,
614
                onnx.TensorProto.INT64,
615
                onnx.TensorProto.UINT8,
616
                onnx.TensorProto.UINT16,
617
                onnx.TensorProto.UINT32,
618
        ]:
619
            shape = (1, 2, 3)
620
            vals = np.random.randn(*shape)
621
            if dtype != onnx.TensorProto.BOOL:
622
                vals *= 5
623
            vals = vals.astype(
624
                mapping.TENSOR_TYPE_TO_NP_TYPE[dtype])
625
            tensor = make_tensor(
626
                name='test-tensor-{}'.format(dtype),
627
                data_type=dtype,
628
                dims=[1, 2, 3],
629
                vals=vals.flatten().tolist(),
630
            )
631
            op = c2.Caffe2Backend._create_tensor_filling_op(tensor)
632
            self.assertEqual(len(op.input), 0)
633
            self.assertEqual(op.output, [tensor.name])
634
            ws, output = c2_native_run_op(op, inputs=[])
635
            self.assertEqual(len(output), 1)
636
            np.testing.assert_almost_equal(output[0], vals)
637
            np.testing.assert_almost_equal(ws.FetchBlob(op.output[0]), vals)
638

639
    def test_tensor_filling_ops_c_backend(self):
640
        for dtype in [
641
                onnx.TensorProto.FLOAT,
642
                onnx.TensorProto.DOUBLE,
643
                onnx.TensorProto.BOOL,
644
                onnx.TensorProto.INT8,
645
                onnx.TensorProto.INT16,
646
                onnx.TensorProto.INT32,
647
                onnx.TensorProto.INT64,
648
                onnx.TensorProto.UINT8,
649
                onnx.TensorProto.UINT16,
650
                onnx.TensorProto.UINT32,
651
        ]:
652
            shape = (1, 2, 3)
653
            vals = np.random.randn(*shape)
654
            if dtype != onnx.TensorProto.BOOL:
655
                vals *= 5
656
            vals = vals.astype(
657
                mapping.TENSOR_TYPE_TO_NP_TYPE[dtype])
658
            tensor = make_tensor(
659
                name='test-tensor-{}'.format(dtype),
660
                data_type=dtype,
661
                dims=[1, 2, 3],
662
                vals=vals.flatten().tolist(),
663
            )
664
            b = C.Caffe2Backend()
665
            op = caffe2_pb2.OperatorDef()
666
            op.ParseFromString(b._build_tensor_filling_op(tensor.SerializeToString(), ''))
667
            self.assertEqual(len(op.input), 0)
668
            self.assertEqual(op.output, [tensor.name])
669
            ws, output = c2_native_run_op(op, inputs=[])
670
            self.assertEqual(len(output), 1)
671
            np.testing.assert_almost_equal(output[0], vals)
672
            np.testing.assert_almost_equal(ws.FetchBlob(op.output[0]), vals)
673

674
    def test_concat(self):
675
        I0 = np.random.randn(20, 4).astype(np.float32)
676
        I1 = np.random.randn(20, 4).astype(np.float32)
677
        for i in range(2):
678
            predict_net = caffe2_pb2.NetDef()
679
            predict_net.name = 'test-concat-net'
680
            predict_net.external_input[:] = ['I0', 'I1']
681
            predict_net.external_output[:] = ['Y', 'output_dim']
682
            predict_net.op.extend([
683
                core.CreateOperator(
684
                    'Concat',
685
                    inputs=['I0', 'I1'],
686
                    outputs=['Y', 'output_dim'],
687
                    axis=1,
688
                    add_axis=(1 if i == 0 else 0),
689
                ),
690
            ])
691
            ws, c2_outputs = c2_native_run_net(
692
                init_net=None,
693
                predict_net=predict_net,
694
                inputs=[I0, I1])
695
            onnx_model = c2_onnx.caffe2_net_to_onnx_model(
696
                predict_net=predict_net,
697
                value_info={
698
                    'I0': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[I0.dtype], I0.shape),
699
                    'I1': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[I1.dtype], I1.shape),
700
                })
701
            onnx_outputs = c2.run_model(onnx_model, inputs=[I0, I1])
702
            self.assertSameOutputs(c2_outputs, onnx_outputs)
703

704
    def test_slice(self):
705
        X = np.random.randn(1, 2, 3).astype(np.float32)
706
        starts = np.array([0, 1, 0], dtype=np.int32)
707
        ends = np.array([-1, 2, 3], dtype=np.int32)
708

709
        predict_net = caffe2_pb2.NetDef()
710
        predict_net.name = 'test-slice-net'
711
        predict_net.external_input[:] = ['X']
712
        predict_net.external_output[:] = ['Y']
713
        predict_net.op.extend([
714
            core.CreateOperator(
715
                'Slice',
716
                inputs=['X'],
717
                outputs=['Y'],
718
                starts=starts,
719
                ends=ends,
720
            ),
721
        ])
722
        ws, c2_outputs = c2_native_run_net(
723
            init_net=None,
724
            predict_net=predict_net,
725
            inputs=[X])
726

727
        onnx_model = c2_onnx.caffe2_net_to_onnx_model(
728
            predict_net=predict_net,
729
            value_info={
730
                'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape)
731
            })
732
        onnx_outputs = c2.run_model(onnx_model, inputs=[X])
733
        self.assertSameOutputs(c2_outputs, onnx_outputs)
734

735
    def test_cast(self):
736
        X = np.random.randn(1, 2, 3).astype(np.float32)
737

738
        for to_type in ['INT8', caffe2_pb2.TensorProto.INT8,
739
                        'DOUBLE', caffe2_pb2.TensorProto.DOUBLE]:
740
            predict_net = caffe2_pb2.NetDef()
741
            predict_net.name = 'test-cast-net'
742
            predict_net.external_input[:] = ['X']
743
            predict_net.external_output[:] = ['Y']
744
            predict_net.op.extend([
745
                core.CreateOperator(
746
                    'Cast',
747
                    inputs=['X'],
748
                    outputs=['Y'],
749
                    to=to_type,
750
                ),
751
            ])
752
            ws, c2_outputs = c2_native_run_net(
753
                init_net=None,
754
                predict_net=predict_net,
755
                inputs=[X])
756

757
            onnx_model = c2_onnx.caffe2_net_to_onnx_model(
758
                predict_net=predict_net,
759
                value_info={
760
                    'X': (onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[X.dtype], X.shape)
761
                })
762
            onnx_outputs = c2.run_model(onnx_model, inputs=[X])
763
            self.assertSameOutputs(c2_outputs, onnx_outputs)
764

765

766
class TestCaffe2End2End(TestCase):
767
    def setUp(self):
768
        self.model_downloader = ModelDownloader('ONNX_MODELS')
769

770
    def _test_net(self,
771
                  net_name,
772
                  input_blob_dims=(1, 3, 224, 224),
773
                  decimal=7):
774
        np.random.seed(seed=0)
775
        try:
776
            c2_init_net, c2_predict_net, value_info, debug_str = self.model_downloader.get_c2_model_dbg(net_name)
777
        except Exception as e:
778
            # catch IOError/OSError that is caused by FileNotFoundError and PermissionError
779
            # This is helpful because sometimes we get errors due to gfs not available
780
            # get_c2_model_dbg wraps URLError/HTTPErrors into generic Exception
781
            # Skip the tests if model can not be downloaded due to the any of the above
782
            print("\n_test_net exception: ", e)
783
            self.skipTest(str(e))
784

785
        # start to run the model and compare outputs
786
        n, c, h, w = input_blob_dims
787
        data = np.random.randn(n, c, h, w).astype(np.float32)
788
        inputs = [data]
789
        _, c2_outputs = c2_native_run_net(c2_init_net, c2_predict_net, inputs, debug_str)
790
        del _
791

792
        model = c2_onnx.caffe2_net_to_onnx_model(
793
            predict_net=c2_predict_net,
794
            init_net=c2_init_net,
795
            value_info=value_info,
796
        )
797
        c2_ir = c2.prepare(model)
798
        onnx_outputs = c2_ir.run(inputs)
799
        self.assertSameOutputs(c2_outputs, onnx_outputs, decimal=decimal)
800

801
    @unittest.skipIf(
802
        os.environ.get('SKIP_IN_FB'),
803
        'Skip internally!')
804
    def test_alexnet(self):
805
        self._test_net('bvlc_alexnet', decimal=4)
806

807
    @unittest.skipIf(
808
        os.environ.get('SKIP_IN_FB'),
809
        'Skip internally!')
810
    def test_resnet50(self):
811
        self._test_net('resnet50')
812

813
    @unittest.skipIf(
814
        os.environ.get('JENKINS_URL') or os.environ.get('SKIP_IN_FB'),
815
        'Taking too long to download!')
816
    def test_vgg16(self):
817
        self._test_net('vgg16')
818

819
    @unittest.skipIf(
820
        os.environ.get('JENKINS_URL') or os.environ.get('SKIP_IN_FB'),
821
        'Taking too long to download!')
822
    def test_zfnet(self):
823
        self._test_net('zfnet')
824

825
    @unittest.skipIf(
826
        os.environ.get('SKIP_IN_FB'),
827
        'Skip internally!')
828
    def test_inception_v1(self):
829
        self._test_net('inception_v1', decimal=2)
830

831
    @unittest.skipIf(
832
        os.environ.get('SKIP_IN_FB'),
833
        'Skip internally!')
834
    def test_inception_v2(self):
835
        self._test_net('inception_v2')
836

837
    @unittest.skipIf(
838
        os.environ.get('SKIP_IN_FB'),
839
        'Skip internally!')
840
    def test_squeezenet(self):
841
        self._test_net('squeezenet')
842

843
    @unittest.skipIf(
844
        os.environ.get('SKIP_IN_FB'),
845
        'Skip internally!')
846
    def test_densenet121(self):
847
        self._test_net('densenet121')
848

849
    @unittest.skipIf(
850
        os.environ.get('SKIP_IN_FB'),
851
        'Skip internally!')
852
    def test_bvlc_googlenet(self):
853
        self._test_net('bvlc_googlenet')
854

855
    @unittest.skipIf(
856
        os.environ.get('SKIP_IN_FB'),
857
        'Skip internally!')
858
    def test_bvlc_reference_caffenet(self):
859
        self._test_net('bvlc_reference_caffenet')
860

861
    @unittest.skipIf(
862
        os.environ.get('SKIP_IN_FB'),
863
        'Skip internally!')
864
    def test_bvlc_reference_rcnn_ilsvrc13(self):
865
        self._test_net('bvlc_reference_rcnn_ilsvrc13')
866

867

868
if __name__ == '__main__':
869
    unittest.main()
870

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.