diff --git a/tools/onnx/onnx2ncnn.cpp b/tools/onnx/onnx2ncnn.cpp index a1c005267..4a47d7b64 100644 --- a/tools/onnx/onnx2ncnn.cpp +++ b/tools/onnx/onnx2ncnn.cpp @@ -478,6 +478,15 @@ int main(int argc, char** argv) fprintf(pp, "%-16s", "Convolution"); } } + else if (op == "ConvTranspose") + { + int group = get_node_attr_i(node, "group", 1); + if (group > 1) { + fprintf(pp, "%-16s", "DeconvolutionDepthWise"); + } else { + fprintf(pp, "%-16s", "Deconvolution"); + } + } else if (op == "Dropout") { fprintf(pp, "%-16s", "Dropout"); @@ -514,6 +523,10 @@ int main(int argc, char** argv) { fprintf(pp, "%-16s", "Scale"); } + else if (op == "InstanceNormalization") + { + fprintf(pp, "%-16s", "InstanceNorm"); + } else if (op == "LeakyRelu") { fprintf(pp, "%-16s", "ReLU"); @@ -782,6 +795,85 @@ int main(int argc, char** argv) fwrite_tensor_proto_data(B, bp); } } + else if (op == "ConvTranspose") + { + const onnx::TensorProto& W = weights[node.input(1)]; + + int num_filter = W.dims(0); + int has_bias = node.input_size() == 3 ? 1 : 0; + + std::string auto_pad = get_node_attr_s(node, "auto_pad");//TODO + std::vector kernel_shape = get_node_attr_ai(node, "kernel_shape"); + std::vector dilations = get_node_attr_ai(node, "dilations"); + std::vector strides = get_node_attr_ai(node, "strides"); + std::vector output_padding = get_node_attr_ai(node, "output_padding");//TODO implement adj + std::vector output_shape = get_node_attr_ai(node, "output_shape");//TODO + std::vector pads = get_node_attr_ai(node, "pads"); + int group = get_node_attr_i(node, "group", 1); + + fprintf(pp, " 0=%d", num_filter); + + if (kernel_shape.size() == 1) { + fprintf(pp, " 1=%d", kernel_shape[0]); + } else if (kernel_shape.size() == 2) { + fprintf(pp, " 1=%d", kernel_shape[1]); + fprintf(pp, " 11=%d", kernel_shape[0]); + } + + if (dilations.size() == 1) { + fprintf(pp, " 2=%d", dilations[0]); + } else if (dilations.size() == 2) { + fprintf(pp, " 2=%d", dilations[1]); + fprintf(pp, " 12=%d", dilations[0]); + } + + if (strides.size() == 1) { + fprintf(pp, " 3=%d", strides[0]); + } else if (strides.size() == 2) { + fprintf(pp, " 3=%d", strides[1]); + fprintf(pp, " 13=%d", strides[0]); + } + + if (auto_pad == "SAME_LOWER" || auto_pad == "SAME_UPPER") + { + // TODO + fprintf(pp, " 4=-233"); + } + else + { + + if (pads.size() == 1) { + fprintf(pp, " 4=%d", pads[0]); + } else if (pads.size() == 2) { + fprintf(pp, " 4=%d", pads[1]); + fprintf(pp, " 14=%d", pads[0]); + } else if (pads.size() == 4) { + fprintf(pp, " 4=%d", pads[1]); + fprintf(pp, " 14=%d", pads[0]); + // TODO hpad2=pads[2] wpad2=pads[3] + } + + } + + fprintf(pp, " 5=%d", has_bias); + + fprintf(pp, " 6=%d", get_tensor_proto_data_size(W)); + + if (group > 1) { + fprintf(pp, " 7=%d", group); + } + + int quantize_tag = 0; + fwrite(&quantize_tag, sizeof(int), 1, bp); + + fwrite_tensor_proto_data(W, bp); + + if (has_bias) + { + const onnx::TensorProto& B = weights[node.input(2)]; + fwrite_tensor_proto_data(B, bp); + } + } else if (op == "Dropout") { // no-op @@ -846,6 +938,18 @@ int main(int argc, char** argv) } fwrite(&bias[0], sizeof(float), channels, bp); } + else if (op == "InstanceNormalization") + { + float eps = get_node_attr_f(node, "epsilon", 1e-5f); + std::vector scale = get_node_attr_af(node, "scale"); + std::vector bias = get_node_attr_af(node, "B"); + + fprintf(pp, " 0=%d", (int)scale.size()); + fprintf(pp, " 1=%f", eps); + + fwrite(scale.data(), sizeof(float), scale.size(), bp); + fwrite(bias.data(), sizeof(float), bias.size(), bp); + } else if (op == "LeakyRelu") { float alpha = get_node_attr_f(node, "alpha", 0.01f);