Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
convert_onnx
Commits
8590ec24
Commit
8590ec24
authored
May 24, 2024
by
yaoht
Browse files
init commit
parent
38a732e1
Changes
58
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1075 additions
and
0 deletions
+1075
-0
caffe/caffe2onnx/src/OPs/Gemm.py
caffe/caffe2onnx/src/OPs/Gemm.py
+21
-0
caffe/caffe2onnx/src/OPs/InstanceNorm.py
caffe/caffe2onnx/src/OPs/InstanceNorm.py
+34
-0
caffe/caffe2onnx/src/OPs/Interp.py
caffe/caffe2onnx/src/OPs/Interp.py
+68
-0
caffe/caffe2onnx/src/OPs/LRN.py
caffe/caffe2onnx/src/OPs/LRN.py
+31
-0
caffe/caffe2onnx/src/OPs/Log.py
caffe/caffe2onnx/src/OPs/Log.py
+38
-0
caffe/caffe2onnx/src/OPs/LpNormalization.py
caffe/caffe2onnx/src/OPs/LpNormalization.py
+38
-0
caffe/caffe2onnx/src/OPs/Min.py
caffe/caffe2onnx/src/OPs/Min.py
+26
-0
caffe/caffe2onnx/src/OPs/Mul.py
caffe/caffe2onnx/src/OPs/Mul.py
+60
-0
caffe/caffe2onnx/src/OPs/PRelu.py
caffe/caffe2onnx/src/OPs/PRelu.py
+12
-0
caffe/caffe2onnx/src/OPs/Pooling.py
caffe/caffe2onnx/src/OPs/Pooling.py
+206
-0
caffe/caffe2onnx/src/OPs/Power.py
caffe/caffe2onnx/src/OPs/Power.py
+32
-0
caffe/caffe2onnx/src/OPs/PriroBox.py
caffe/caffe2onnx/src/OPs/PriroBox.py
+123
-0
caffe/caffe2onnx/src/OPs/ReLU.py
caffe/caffe2onnx/src/OPs/ReLU.py
+29
-0
caffe/caffe2onnx/src/OPs/Reshape.py
caffe/caffe2onnx/src/OPs/Reshape.py
+83
-0
caffe/caffe2onnx/src/OPs/Resize.py
caffe/caffe2onnx/src/OPs/Resize.py
+63
-0
caffe/caffe2onnx/src/OPs/Shuffle.py
caffe/caffe2onnx/src/OPs/Shuffle.py
+55
-0
caffe/caffe2onnx/src/OPs/Sigmoid.py
caffe/caffe2onnx/src/OPs/Sigmoid.py
+30
-0
caffe/caffe2onnx/src/OPs/Slice.py
caffe/caffe2onnx/src/OPs/Slice.py
+89
-0
caffe/caffe2onnx/src/OPs/Softmax.py
caffe/caffe2onnx/src/OPs/Softmax.py
+21
-0
caffe/caffe2onnx/src/OPs/Tanh.py
caffe/caffe2onnx/src/OPs/Tanh.py
+16
-0
No files found.
caffe/caffe2onnx/src/OPs/Gemm.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/InstanceNorm.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Interp.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/LRN.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Log.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/LpNormalization.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Min.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Mul.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/PRelu.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Pooling.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Power.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/PriroBox.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/ReLU.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Reshape.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Resize.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Shuffle.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Sigmoid.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Slice.py
0 → 100644
View file @
8590ec24
# 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
caffe/caffe2onnx/src/OPs/Softmax.py
0 → 100644
View file @
8590ec24
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
caffe/caffe2onnx/src/OPs/Tanh.py
0 → 100644
View file @
8590ec24
#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
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment