1+ #! /usr/bin/python
2+ # -*- coding: utf-8 -*-
3+ import numpy as np
4+ import onnx
5+ from onnx import helper , numpy_helper
6+ from collections import OrderedDict
7+ import tensorlayerx as tlx
8+ from tlx2onnx .op_mapper .datatype_mapping import NP_TYPE_TO_TENSOR_TYPE
9+ from tlx2onnx .op_mapper .op_mapper import OpMapper
10+ from tlx2onnx .common import make_node
11+ from tlx2onnx .common import make_shape_channels_first , get_channels_first_permutation ,get_channels_last_permutation
12+
13+ @OpMapper (["SubpixelConv2d" ])
14+ class SubpixelConv ():
15+
16+ @classmethod
17+ def version_1 (cls , node , ** kwargs ):
18+ onnx_node = []
19+ onnx_value = []
20+ onnx_init = []
21+
22+ op_type = "DepthToSpace"
23+ attr_dict = OrderedDict ()
24+ # get in_node_name out_node_nmae
25+ x_name = node ['in_nodes_name' ][0 ]
26+ out_name = node ['out_nodes_name' ][0 ]
27+ x_shape = node ['in_tensors' ][0 ]
28+ out_shape = node ['out_tensors' ][0 ]
29+
30+ # get data_type
31+ data_type = node ['dtype' ]
32+ tensor_type = NP_TYPE_TO_TENSOR_TYPE [data_type ]
33+
34+ # get cur_node_layer node_index
35+ layer = node ['node' ].layer
36+ layer_name = layer .__class__ .__name__
37+ spatial = int (layer_name [- 2 ])
38+
39+ # get layer attr
40+ scale = layer .scale
41+ data_format = layer .data_format
42+ attr_dict ["blocksize" ] = scale
43+
44+ if data_format == "channels_last" :
45+ permutation = get_channels_first_permutation (spatial )
46+ x_shape_t = make_shape_channels_first (x_shape )
47+ transpose_value = helper .make_tensor_value_info (x_name + '_t' , tensor_type , shape = x_shape_t )
48+ onnx_value .append (transpose_value )
49+ transpose_node , out = make_node ('Transpose' , inputs = [x_name ], outputs = [x_name + '_t' ], perm = permutation )
50+ onnx_node .append (transpose_node )
51+ depth_to_space , out = make_node (op_type , inputs = [out ], outputs = [out + '_t' ], ** attr_dict )
52+ onnx_node .append (depth_to_space )
53+ permutation = get_channels_last_permutation (spatial )
54+ transpose_node , out = make_node ('Transpose' , inputs = [out ], outputs = [out_name ], perm = permutation )
55+ onnx_node .append (transpose_node )
56+ return onnx_node , onnx_value , onnx_init
57+
58+ elif data_format == 'channels_first' :
59+
60+ depth_to_space , out = make_node (op_type , inputs = [x_name ], outputs = [out_name ], ** attr_dict )
61+ onnx_node .append (depth_to_space )
62+ return onnx_node , onnx_value , onnx_init
63+ else :
64+ raise ValueError (
65+ "Only support 'channels_first' or 'channels_last' data_format mode, but got {}." .format (data_format ))
66+
67+ @classmethod
68+ def version_11 (cls , node , ** kwargs ):
69+ onnx_node = []
70+ onnx_value = []
71+ onnx_init = []
72+
73+ op_type = "DepthToSpace"
74+ attr_dict = OrderedDict ()
75+ # get in_node_name out_node_nmae
76+ x_name = node ['in_nodes_name' ][0 ]
77+ out_name = node ['out_nodes_name' ][0 ]
78+ x_shape = node ['in_tensors' ][0 ]
79+ out_shape = node ['out_tensors' ][0 ]
80+
81+ # get data_type
82+ data_type = node ['dtype' ]
83+ tensor_type = NP_TYPE_TO_TENSOR_TYPE [data_type ]
84+
85+ # get cur_node_layer node_index
86+ layer = node ['node' ].layer
87+ layer_name = layer .__class__ .__name__
88+ spatial = int (layer_name [- 2 ])
89+
90+ # get layer attr
91+ scale = layer .scale
92+ data_format = layer .data_format
93+ attr_dict ["blocksize" ] = scale
94+ if tlx .BACKEND in ["tensorflow" , "mindspore" ]:
95+ attr_dict ["mode" ] = "DCR"
96+ elif tlx .BACKEND in ["torch" , "paddle" ]:
97+ attr_dict ["mode" ] = "CRD"
98+
99+ if data_format == "channels_last" :
100+ permutation = get_channels_first_permutation (spatial )
101+ x_shape_t = make_shape_channels_first (x_shape )
102+ transpose_value = helper .make_tensor_value_info (x_name + '_t' , tensor_type , shape = x_shape_t )
103+ onnx_value .append (transpose_value )
104+ transpose_node , out = make_node ('Transpose' , inputs = [x_name ], outputs = [x_name + '_t' ], perm = permutation )
105+ onnx_node .append (transpose_node )
106+ depth_to_space , out = make_node (op_type , inputs = [out ], outputs = [out + '_t' ], ** attr_dict )
107+ onnx_node .append (depth_to_space )
108+ permutation = get_channels_last_permutation (spatial )
109+ transpose_node , out = make_node ('Transpose' , inputs = [out ], outputs = [out_name ], perm = permutation )
110+ onnx_node .append (transpose_node )
111+ return onnx_node , onnx_value , onnx_init
112+
113+ elif data_format == 'channels_first' :
114+
115+ depth_to_space , out = make_node (op_type , inputs = [x_name ], outputs = [out_name ], ** attr_dict )
116+ onnx_node .append (depth_to_space )
117+ return onnx_node , onnx_value , onnx_init
118+ else :
119+ raise ValueError (
120+ "Only support 'channels_first' or 'channels_last' data_format mode, but got {}." .format (data_format ))
0 commit comments