Commit 8590ec24 authored by yaoht's avatar yaoht
Browse files

init commit

parent 38a732e1
import src.c2oObject as Node
##-----------------------------------------------------Gemm层-------------------------------------------------------##
#获取超参数
def getGemmAttri(layer):
#超参数字典
dict = {"alpha": 1.0,
"beta": 1.0,
"transA": 0,
"transB": 1}
return dict
#计算输出维度
def getGemmOutShape(input_shape,num_output):
output_shape = [[input_shape[0][0], num_output]]
return output_shape
#构建节点
def createGemm(layer, nodename, inname, outname, input_shape, num_output):
dict = getGemmAttri(layer)
output_shape = getGemmOutShape(input_shape,num_output)
#构建node
node = Node.c2oNode(layer, nodename, "Gemm", inname, outname, input_shape, output_shape, dict)
return node
import src.c2oObject as Node
import numpy as np
def get_InstanceNorm_param(layer, input_shape):
scale = []
bias = []
for i in range(input_shape[0][1]):
scale.append(1)
bias.append(0)
return scale, bias
def create_InstanceNorm_attributes(layer):
epsilon: float = layer.mvn_param.eps
if not epsilon:
epsilon = 1e-05
attributes = {"epsilon": epsilon}
return attributes
def get_InstanceNorm_output_shape(input_shape):
output_shape = input_shape
return output_shape
def create_InstanceNorm_op(layer, node_name, input_name, output_name, input_shape):
output_shape = get_InstanceNorm_output_shape(input_shape)
attributes = create_InstanceNorm_attributes(layer)
node = Node.c2oNode(layer, node_name, "InstanceNormalization",
input_name, output_name,
input_shape,output_shape,attributes)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
import numpy as np
def get_interp_attri(layer, input_shape):
# scale = layer.upsample_param.scale
# scales = [1.0,1.0,scale,scale]
# dict = {"scales":scales,"mode":"nearest"}#Upsample将scales放入参数里面了
# dict = {"width_scale": scale,"height_scale":scale, "mode": "nearest"}#在OpenVINO读onnx的时候要求用width_scale和height_scale
height = layer.interp_param.height
width = layer.interp_param.width
zoom_factor = layer.interp_param.zoom_factor
shrink_factor = layer.interp_param.shrink_factor
pad_beg = layer.interp_param.pad_beg
pad_end = layer.interp_param.pad_end
H, W = input_shape[0][2], input_shape[0][3]
sacles = [1.0, 1.0, 1.0, 1.0]
if height > H and width > W:
if height / H == width / W:
scale = float(height / H)
scales = [1.0, 1.0, scale, scale]
attributes = {"mode": "linear",
'scales': scales}
return attributes
if height == 0 and width == 0:
if zoom_factor > 1 and shrink_factor == 1:
height_in_eff = height + pad_beg + pad_end
width_in_eff = width + pad_beg + pad_end
height_out = height_in_eff + (height_in_eff - 1) * (zoom_factor -1)
width_out = width_in_eff + (width_in_eff - 1) * (zoom_factor -1)
scale_height = float(height_out /height_in_eff)
scale_width = float(width_out /width_in_eff)
scales = [1.0, 1.0, scale_height, scale_width]
attributes = {"mode": "linear",
'scales': scales}
return attributes
else:
print("do not support interp type")
exit(-1)
def get_interp_output_shape(layer, input_shape, attributes):
scales = attributes.get("scales")
output_shape = [np.multiply(np.array(scales, dtype=np.int), np.array(input_shape[0])).tolist()]
return output_shape
# TODO interp 只支持放大的情况,后期会将 onnx 升级到 1.6.0 , 并使用 resize 替换
def create_interp_node(layer, node_name, input_name, output_name, input_shape):
attributes = get_interp_attri(layer, input_shape)
output_shape = get_interp_output_shape(layer, input_shape, attributes)
# print(output_shape)
node = Node.c2oNode(layer, node_name, "Upsample", input_name, output_name, input_shape, output_shape, attributes)
return node
import src.c2oObject as Node
##-------------------------------------------------LRN层-------------------------------------------------------------##
#获取超参数
def getLRNAttri(layer):
# 获取超参数
##尺寸
size = layer.lrn_param.local_size
##alpha
alpha = layer.lrn_param.alpha
##beta
beta = layer.lrn_param.beta
# 超参数字典
dict = {"alpha":alpha,
"beta":beta,
"bias":1.0,
"size": size}
return dict
#计算输出维度
def getLRNOutShape(input_shape):
# 计算输出维度output_shape
output_shape = input_shape # 与输入维度一样
return output_shape
#构建节点
def createLRN(layer,nodename, inname,outname,input_shape):
dict = getLRNAttri(layer)
output_shape = getLRNOutShape(input_shape)
#构建node
node = Node.c2oNode(layer, nodename, "LRN", inname, outname, input_shape, output_shape, dict)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# Message that stores parameters used by LogLayer
# message LogParameter {
# // LogLayer computes outputs y = log_base(shift + scale * x), for base > 0.
# // Or if base is set to the default (-1), base is set to e,
# // so y = ln(shift + scale * x) = log_e(shift + scale * x)
# optional float base = 1 [default = -1.0];
# optional float scale = 2 [default = 1.0];
# optional float shift = 3 [default = 0.0];
# }
import src.c2oObject as Node
def get_log_output_shape(input_shape):
output_shape = input_shape
return output_shape
def create_log_node(layer, node_name, input_name, output_name, input_shape):
output_shape = get_log_output_shape(layer)
node = Node.c2oNode(layer, node_name, 'Log', input_name, output_name, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
from typing import Dict
def create_attribute(layer):
attribute: Dict = {
'axis': 1,
'p': 2
}
return attribute
def get_node_output(input_shape):
output_shape = input_shape
return output_shape
def create_Lp_Normalization(layer, node_name, input_name, output_name, input_shape):
attribute = create_attribute(layer)
output_shape = get_node_output(input_shape)
node = Node.c2oNode(layer, node_name, "LpNormalization", input_name, output_name, input_shape, output_shape,
attribute)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
def get_min_output_shape(input_shape):
output_shape = input_shape
return output_shape
def create_min_op(layer, node_name, input_name, output_name, input_shape):
output_shape = get_min_output_shape(input_shape)
node = Node.c2oNode(layer, node_name, "Min", input_name, output_name, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
import numpy as np
from typing import *
from onnx import TensorProto
import copy
def need_add_reshape(input_shape: List[List]) -> bool:
return len(input_shape[0]) != len(input_shape[1])
def get_param_shape(input_shape: List[List]) -> List:
input = input_shape[0]
scale = copy.deepcopy(input_shape[1])
if len(input) > len(scale):
for i in range(len(input) - len(scale)):
scale.append(1)
return scale
def broadcast_scale(input_shape: List[List]) -> List[List]:
input = input_shape[0]
scale = input_shape[1]
if len(input) > len(scale):
for i in range(len(input) - len(scale)):
scale.append(1)
broadcast_shape = [input, scale]
elif len(input) < len(scale):
print("the scale should be less than input")
exit(-1)
else:
broadcast_shape = [input, scale]
return broadcast_shape
def get_mul_output_shape(input_shape: List[List]) -> List[List]:
output_shape = input_shape[0]
return [output_shape]
def create_mul_node(layer, node_name, input_name, output_name, input_shape):
output_shape = get_mul_output_shape(input_shape)
node = Node.c2oNode(layer, node_name, 'Mul', input_name, output_name, input_shape, output_shape)
return node
import src.c2oObject as Node
def getPReluOutShape(input_shape):
output_shape = input_shape
return output_shape
def createPRelu(layer, nodename, inname, outname, input_shape):
output_shape = getPReluOutShape(input_shape)
node = Node.c2oNode(layer, nodename, "PRelu", inname, outname, input_shape, output_shape)
return node
import numpy as np
import src.c2oObject as Node
import math
import copy
def get_pool_pads(layer):
pad = layer.pooling_param.pad
if pad != 0:
pad_h = pad_w = pad
else:
if layer.pooling_param.pad_h != 0 and layer.pooling_param.pad_w != 0:
pad_h = layer.pooling_param.pad_h
pad_w = layer.pooling_param.pad_w
else:
pad_h = pad_w = 0
pads = [0, 0, pad_h, pad_w, 0, 0, pad_h, pad_w]
return pads
def calculate_pad_output_shape(input_shape, pads):
pad_h = pads[2]
pad_w = pads[3]
output_shape = copy.deepcopy(input_shape[0])
output_shape[2] = output_shape[2] + 2 * pad_h
output_shape[3] = output_shape[3] + 2 * pad_w
return [output_shape]
def create_pad_node(layer, node_name, input_name, output_name, input_shape):
pads = get_pool_pads(layer)
attributes = {"mode": "constant"}
pad_input_name = input_name
pad_output_name = output_name
pad_output_shape = calculate_pad_output_shape(input_shape, pads)
node = Node.c2oNode(layer, node_name, 'Pad', pad_input_name, pad_output_name, input_shape, pad_output_shape,
attributes)
return node
def get_pool_attributes(layer, pool_type, input_shape):
number = input_shape[0][0]
channel = input_shape[0][1]
height = input_shape[0][2]
weight = input_shape[0][3]
kernel_size = layer.pooling_param.kernel_size
pad = layer.pooling_param.pad
stride = layer.pooling_param.stride
if pool_type == 'GlobalMaxPool' or pool_type == 'GlobalAveragePool':
global_pooling = True
else:
global_pooling = False
# pass kernel_shape
if global_pooling:
kernel_h = height
kernel_w = weight
else:
if kernel_size != 0:
kernel_h = kernel_w = kernel_size
elif layer.pooling_param.kernel_h != 0 and layer.pooling_param.kernel_w != 0:
kernel_h = layer.pooling_param.kernel_h
kernel_w = layer.pooling_param.kernel_w
else:
kernel_h = 1
kernel_w = 1
kernel_shape = [kernel_h, kernel_w]
# pass pad
if pad != 0:
pad_h = pad_w = pad
else:
if layer.pooling_param.pad_h != 0 and layer.pooling_param.pad_w != 0:
pad_h = layer.pooling_param.pad_h
pad_w = layer.pooling_param.pad_w
else:
pad_h = pad_w = 0
pads = [pad_h, pad_w, pad_h, pad_w]
# 由于 caffe 与 onnx 的 pad 的计算的原因,将 pad 属性,单独创建一个节点
pads = [0, 0, 0, 0]
# pass strides
stride_h = stride_w = 1
if stride != 1:
stride_h = stride_w = stride
else:
if layer.pooling_param.stride_h != 0 and layer.pooling_param.stride_w != 0:
stride_h = layer.pooling_param.stride_h
stride_w = layer.pooling_param.stride_w
else:
stride_h = stride_w = 1
strides = [stride_h, stride_w]
# pass round_mode
# caffe 上默认是使用 ceil 的,但是在 onnx 默认使用 floor
# caffe definition
# enum RoundMode {
# CEIL = 0;
# FLOOR = 1;
# }
# default Ceil = 0
# onnx ceil_mode floor = 0, ceil = 1, default: floor = 0
round_mode_ceil = 0
round_mode_floor = 1
round_mode = 0
if layer.pooling_param.round_mode == 0:
round_mode = round_mode_ceil
elif layer.pooling_param.round_mode == 1:
round_mode = round_mode_floor
else:
# wrong condition
exit(-1)
if round_mode == round_mode_ceil:
ceil_mode = 1
else:
ceil_mode = 0
attributes = {"kernel_shape": kernel_shape,
"strides": strides,
"pads": pads,
"ceil_mode": ceil_mode
}
return attributes
# 计算输出维度
def get_pooling_output_shape(input_shape, layer, attributes, with_indices=False):
number = input_shape[0][0]
channel = input_shape[0][1]
kernel_shape = attributes["kernel_shape"]
kernel_h = kernel_shape[0]
kernel_w = kernel_shape[1]
pads = attributes["pads"]
strides = attributes["strides"]
stride_h = strides[0]
stride_w = strides[1]
ceil_mode = attributes["ceil_mode"]
pad_h = pads[2]
pad_w = pads[3]
height = input_shape[0][2]
width = input_shape[0][3]
if ceil_mode == 1:
# ceil
pooled_height = int(math.ceil((height + 2 * pad_h - kernel_h) / stride_h)) + 1
pooled_width = int(math.ceil((width + 2 * pad_h - kernel_w) / stride_w)) + 1
else:
# floor
pooled_height = int(math.floor((height + 2 * pad_h - kernel_h) / stride_h)) + 1
pooled_width = int(math.floor((width + 2 * pad_h - kernel_w) / stride_w)) + 1
if pad_h != 0 or pad_w != 0:
if ((pooled_height - 1) * stride_h) >= (height + pad_h):
pooled_height = pooled_height - 1
if ((pooled_width - 1) * stride_w) >= (width + pad_w):
pooled_width = pooled_width - 1
if kernel_h == 0:
kernel_h = kernel_w = 1
if with_indices:
output_shape = [[number, channel, pooled_height, pooled_width],
[number, channel, pooled_height, pooled_width]]
else:
output_shape = [[number, channel, pooled_height, pooled_width]]
return output_shape
def pooling_type(layer):
pool_value = layer.pooling_param.pool
global_value = layer.pooling_param.global_pooling
if pool_value == 0 and global_value is True:
return 'GlobalMaxPool'
elif pool_value == 1 and global_value is True:
return 'GlobalAveragePool'
elif pool_value == 0 and global_value is False:
return 'MaxPool'
elif pool_value == 1 and global_value is False:
return 'AveragePool'
else:
print("unsupport pooling!")
exit(-1)
# 构建节点
def create_pooling_node(layer, nodename, inname, outname, input_shape):
pool_type = pooling_type(layer)
node = None
attributes = get_pool_attributes(layer, pool_type, input_shape)
with_indices = True if len(outname) == 2 else False
output_shape = get_pooling_output_shape(input_shape, layer, attributes, with_indices=with_indices)
# 判断是池化种类,最大池化、平均池化
if pool_type == 'GlobalMaxPool':
node = Node.c2oNode(layer, nodename, "GlobalMaxPool", inname, outname, input_shape, output_shape, dict={})
elif pool_type == 'MaxPool':
node = Node.c2oNode(layer, nodename, "MaxPool", inname, outname, input_shape, output_shape, dict=attributes)
elif pool_type == 'GlobalAveragePool':
node = Node.c2oNode(layer, nodename, "GlobalAveragePool", inname, outname, input_shape, output_shape,
dict={})
elif pool_type == 'AveragePool':
node = Node.c2oNode(layer, nodename, "AveragePool", inname, outname, input_shape, output_shape,
dict=attributes)
# Layers[i].pooling_param.pool==2为随机池化
assert (node is not None)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
import numpy as np
def get_power_param(layer):
power: int = layer.power_param.power
scale: int = layer.power_param.scale
shift: int = layer.power_param.shift
return np.array([power]), np.array([scale]), np.array([shift])
def get_power_output_shape(input_shape):
return [input_shape[0]]
def create_power_node(layer, node_name, input_name, output_name, input_shape):
output_shape = get_power_output_shape(input_shape)
node = Node.c2oNode(layer, node_name, "Pow", input_name, output_name, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import onnx
from typing import *
from onnx import helper
from typing import *
import ctypes
import src.c2oObject as Node
import math
def create_custom_node(type_name: Text,
inputs: Sequence[Text],
outputs: Sequence[Text],
attributes: Dict) -> onnx.NodeProto:
node = helper.make_node(type_name, inputs, outputs, **attributes)
print(format(node))
return node
def create_priorbox_attributes(layer) -> Dict:
min_sizes = layer.prior_box_param.min_size
max_sizes = layer.prior_box_param.max_size
# onnx attributes does not support bool type
flip = 1 if layer.prior_box_param.flip else 0
clip = 1 if layer.prior_box_param.clip else 0
aspect_ratio_tmp = layer.prior_box_param.aspect_ratio
# get aspect ratio
aspect_ratios = [1.0]
for item in aspect_ratio_tmp:
already_exist = False
for i in range(len(aspect_ratios)):
if math.fabs(item - aspect_ratios[i]) < 1e-6:
already_exist = True
if already_exist is False:
aspect_ratios.append(item)
if flip == 1:
aspect_ratios.append(1. / item)
# get variances variances_tmp: List[float]
variances = []
if len(layer.prior_box_param.variance) > 1:
assert len(layer.prior_box_param.variance) == 4
variances = layer.prior_box_param.variance
elif len(layer.prior_box_param.variance) == 1:
variances = layer.prior_box_param.variance
else:
# set default to 0.1
variances.append(0.1)
# get image size
img_sizes = [0, 0]
if layer.prior_box_param.img_size != 0:
img_sizes = [layer.prior_box_param.img_size, layer.prior_box_param.img_size]
elif (layer.prior_box_param.img_h != 0) and (layer.prior_box_param.img_w != 0):
# be careful the order: [img_w, img_h]
img_sizes = [layer.prior_box_param.img_w, layer.prior_box_param.img_h]
# get step
steps = [0.0, 0.0]
if layer.prior_box_param.step != 0:
steps = [layer.prior_box_param.step, layer.prior_box_param.step]
elif (layer.prior_box_param.step_h != 0) and (layer.prior_box_param.step_w != 0):
# be careful the order: [step_w, step_h]
steps = [layer.prior_box_param.step_w, layer.prior_box_param.step_h]
offset = layer.prior_box_param.offset
attributes = {
'min_sizes': min_sizes,
'max_sizes': max_sizes,
'clip': clip,
'flip': flip,
'variances': variances,
'aspect_ratios': aspect_ratios,
'img_sizes': img_sizes,
'steps': steps,
'offset': offset
}
return attributes
def caculate_output_shape(layer, input_shape: List, attributes: Dict) -> List:
width = input_shape[0][2]
height = input_shape[0][3]
aspect_ratios = attributes.get('aspect_ratios')
min_sizes = attributes.get('min_sizes')
num_priors = len(aspect_ratios) * len(min_sizes)
max_sizes = attributes.get('max_sizes')
for max_size in max_sizes:
if max_size > 0:
num_priors = num_priors + 1
return [[1, 2, width * height * num_priors * 4]]
def create_priorbox_node(layer,
node_name: str,
inputs_name: List[str],
outputs_name: List[str],
inputs_shape: List, ) -> onnx.NodeProto:
attributes = create_priorbox_attributes(layer)
outputs_shape = caculate_output_shape(layer, inputs_shape, attributes)
node = Node.c2oNode(layer, node_name, "PriorBox",
inputs_name, outputs_name,
inputs_shape, outputs_shape,
attributes)
return node
import src.c2oObject as Node
# 获取超参数
def getReluAttri(layer):
attributes = {}
if layer.relu_param.negative_slope != 0:
attributes = {"alpha": layer.relu_param.negative_slope}
return attributes
# 计算输出维度
def getReluOutShape(input_shape):
# 获取output_shape
output_shape = input_shape
return output_shape
# 构建节点
def createRelu(layer, nodename, inname, outname, input_shape):
attributes = getReluAttri(layer)
output_shape = getReluOutShape(input_shape)
if attributes == {}:
node = Node.c2oNode(layer, nodename, "Relu", inname, outname, input_shape, output_shape)
else:
node = Node.c2oNode(layer, nodename, "LeakyRelu", inname, outname, input_shape, output_shape, dict=attributes)
return node
import src.c2oObject as Node
import numpy as np
from typing import *
from operator import mul
from functools import reduce
# 计算输出维度
def getReshapeOutShape(layer, input_shape: List) -> List:
if layer.type == 'InnerProduct':
dims = input_shape[0]
in_prod = 1
for i in range(1, len(dims)):
in_prod = in_prod * dims[i]
output_shape = [dims[0], in_prod]
return [output_shape]
elif layer.type == 'ShuffleChannel':
## change [N, C, H, W] -> [N, G, C', H, W] tensor
group = layer.shuffle_channel_param.group
n, g, c, h, w = input_shape[0][0], group, int(input_shape[0][1] / group), input_shape[0][2], input_shape[0][3]
out_shape = [[n, g, c, h, w]]
return out_shape
elif layer.type == 'DeReshape':
n, c, h, w = input_shape[0][0], input_shape[0][1] * input_shape[0][2], input_shape[0][3], input_shape[0][4]
out_shape = [[n, c, h, w]]
return out_shape
elif layer.type == 'Flatten':
axis = layer.flatten_param.axis
assert axis == 1, "Flatten: not support axis not equal 1"
# return [[0, -1]]
shape = input_shape[0]
input_prod = 1
for i in range(axis, len(shape)):
input_prod = input_prod * shape[i]
output_shape = [shape[0:axis] + [input_prod]]
return output_shape
elif layer.type == 'Scale':
return input_shape
elif layer.type == 'Reshape':
shape = input_shape[0]
re_shape = layer.reshape_param.shape.dim
new_shape_list = []
for j in range(len(re_shape)):
if re_shape[j] == 0:
# if value = 0 ; then use original
new_shape_list.append(shape[j])
else:
new_shape_list.append(re_shape[j])
if -1 in new_shape_list:
index = new_shape_list.index(-1)
if index == 0:
prod = reduce(mul, new_shape_list[1:], 1)
elif index == (len(new_shape_list) -1):
prod = reduce(mul, new_shape_list[0:index])
else:
prod = reduce(mul, new_shape_list[0:index]) * reduce(mul, new_shape_list[index+1:], 1)
new_shape_list[index] = int(reduce(mul, shape, 1) / prod)
output_shape = [new_shape_list]
return output_shape
def get_reshape_param(layer, input_shape: List[int]) -> List[int]:
re_shape = layer.reshape_param.shape.dim
return re_shape
# 构建节点
def createReshape(layer, node_name, input_name, output_name, input_shape, output_shape={}):
# 获取output_shape
if layer.type == 'Scale' and output_shape != {}:
node = Node.c2oNode(layer, node_name, "Reshape", input_name, output_name, input_shape, output_shape)
return node
else:
output_shape = getReshapeOutShape(layer, input_shape)
# 构建node
node = Node.c2oNode(layer, node_name, "Reshape", input_name, output_name, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import onnx
from typing import *
from onnx import helper
from typing import *
import ctypes
import src.c2oObject as Node
import numpy as np
def create_attributes(layer) -> Dict:
coordinate_transformation_mode = 'half_pixel'
cubic_coeff_a = -0.75
exclude_outside = 0
extrapolation_value = 0.0
mode = 'nearest'
nearest_mode = 'round_prefer_floor'
attributes = {
"coordinate_transformation_mode": coordinate_transformation_mode,
"cubic_coeff_a": cubic_coeff_a,
"exclude_outside": exclude_outside,
"extrapolation_value": extrapolation_value,
"mode": mode,
"nearest_mode" :nearest_mode
}
return attributes
def caculate_output_shape(layer, input_shape) -> List:
scale = layer.upsample_param.scale
scales = [1.0,1.0,scale,scale]
output_shape = [np.multiply(np.array(scales,dtype=np.int),np.array(input_shape[0])).tolist()]
return output_shape
def create_resize_node(layer,
node_name: str,
inputs_name: List[str],
outputs_name: List[str],
inputs_shape: List, ) -> onnx.NodeProto:
attributes = create_attributes(layer)
outputs_shape = caculate_output_shape(layer, inputs_shape)
node = Node.c2oNode(layer, node_name, "Resize",
inputs_name, outputs_name,
inputs_shape, outputs_shape,
attributes)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
# 计算输出维度
def getReshapeOutShape(layer, input_shape):
try:
# 获取layer的reshape param
re_shape = layer.reshape_param.shape.dim
except Exception as e:
re_shape = []
# 计算input shape所有维度之积
in_prod = 1
for dim in input_shape[0]:
in_prod = in_prod * dim
if re_shape == []:
output_shape = [[1, in_prod]]
else:
output_shape = re_shape
for i in range(len(re_shape)):
if re_shape[i] == 0:
output_shape[i] = input_shape[0][i]
for j in range(len(output_shape)):
if output_shape[j] == -1:
for d in output_shape:
in_prod = in_prod / d
output_shape[j] = int(in_prod * -1)
output_shape = [output_shape]
return output_shape
# 构建节点
def createShuffle(layer, nodename, inname, outname, input_shape):
# 获取output_shape
output_shape = getReshapeOutShape(layer, input_shape)
# 构建node
node = Node.c2oNode(layer, nodename, "Reshape", inname, outname, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
def getOutShape(input_shape):
# 获取output_shape
output_shape = input_shape
return output_shape
# 构建节点
def createSigmoid(layer, nodename, inname, outname, input_shape):
output_shape = getOutShape(input_shape)
node = Node.c2oNode(layer, nodename, "Sigmoid", inname, outname, input_shape, output_shape)
return node
# Tencent is pleased to support the open source community by making TNN available.
#
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
#
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
import src.c2oObject as Node
def analyzeLayer(layer, input_shape):
# 获取到 slice_point
axis = layer.slice_param.axis
starts = [0]
axes = [axis]
for step in layer.slice_param.slice_point:
starts.append(step)
axes.append(axis)
# 获取需要进行操作的轴
ends = []
for step in layer.slice_param.slice_point:
ends.append(step)
# 这个地方搞了一个小 trick, 使用输入的 axis 作为最后一个
ends.append(input_shape[0][axis])
return starts, ends, axes
# 计算输出维度
# def getSliceOutShape(layer, input_shape, output_name):
# # TODO:
# steps = []
# for step in layer.slice_param.slice_point:
# steps.append(step)
# # slice point
# assert len(steps) == len(output_name) - 1
# # 轴
# axis = layer.concat_param.axis
# start = 0
# n, c, w, h = input_shape[0][0], 0, input_shape[0][2], input_shape[0][3]
# # 计算总体的值
# output_shape = [[]]
# sum = input_shape[0][1]
# if (axis == 1):
# for step in steps:
# # update start
# c = step - start
# output_shape.append([n, c, w, h])
# start = step
# output_shape.append([n, sum - start, w, h])
# return output_shape[1:]
# def getSliceAttri(layer, start, end, axes):
# attributs = {
# 'starts': [start],
# 'ends': [end],
# 'axes': [axes],
# }
# return attributs
def getSliceOutShape(input_shape, start, end):
if len(input_shape[0]) == 4:
output_shape = [[input_shape[0][0], end - start, input_shape[0][2], input_shape[0][3]]]
elif len(input_shape[0]) == 2:
output_shape = [[input_shape[0][0], end - start]]
else:
print("Unsupport slice shape")
exit(-1)
return output_shape
# 构建节点
def createSlice(layer, node_name, input_name, output_name, input_shape, start, end):
output_shape = getSliceOutShape(input_shape, start, end)
node = Node.c2oNode(layer, node_name, "Slice", input_name, output_name, input_shape, output_shape, Flag=True)
return node
import src.c2oObject as Node
##---------------------------------------------softmax层--------------------------------------------------------------##
#获取超参数
def getSoftmaxAttri(layer):
##轴
axis = layer.softmax_param.axis
#超参数字典
dict = {"axis": axis}
return dict
#计算输出维度
def getSoftmaxOutShape(input_shape):
#计算输出维度output_shape
output_shape = input_shape#与输入维度一样
return output_shape
#构建节点
def createSoftmax(layer, nodename, inname, outname, input_shape):
dict = getSoftmaxAttri(layer)
output_shape = getSoftmaxOutShape(input_shape)
#构建node
node = Node.c2oNode(layer, nodename, "Softmax", inname, outname, input_shape, output_shape, dict)
return node
#coding:utf-8
import src.c2oObject as Node
def getOutShape(input_shape):
# 获取output_shape
return input_shape
# 构建节点
def createTanh(layer, nodename, inname, outname, input_shape):
output_shape = getOutShape(input_shape)
node = Node.c2oNode(layer, nodename, "Tanh", inname,
outname, input_shape, output_shape)
return node
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment