| @@ -610,6 +610,55 @@ static void fuse_hardsigmoid(onnx::GraphProto* mutable_graph, std::map<std::stri | |||
| } | |||
| } | |||
| static void fuse_batchnorm1d_squeeze_unsqueeze(onnx::GraphProto* mutable_graph, std::map<std::string, onnx::TensorProto>& weights, std::map<std::string, onnx::TensorProto>& binaryop_weights, std::map<std::string, int>& node_reference, std::set<std::string>& blob_names, int& reduced_node_count, std::vector<std::string>& reduced_binaryop_weights) | |||
| { | |||
| int node_count = mutable_graph->node_size(); | |||
| for (int i=0; i<node_count; i++) | |||
| { | |||
| onnx::NodeProto* node = mutable_graph->mutable_node(i); | |||
| // BatchNormalization <= Unsqueeze - BatchNormalization - Squeeze | |||
| if (node->op_type() == "Unsqueeze") | |||
| { | |||
| if (node_reference.find(node->output(0)) == node_reference.end() || node_reference[node->output(0)] != 1) | |||
| continue; | |||
| if (i+2 >= node_count) | |||
| continue; | |||
| onnx::NodeProto* node2 = mutable_graph->mutable_node(i+1); | |||
| onnx::NodeProto* node3 = mutable_graph->mutable_node(i+2); | |||
| if (node2->op_type() != "BatchNormalization" || node3->op_type() != "Squeeze") | |||
| continue; | |||
| if (node_reference.find(node2->output(0)) == node_reference.end() || node_reference[node2->output(0)] != 1) | |||
| continue; | |||
| if (node_reference.find(node3->output(0)) == node_reference.end() || node_reference[node3->output(0)] != 1) | |||
| continue; | |||
| if (node2->input(0) != node->output(0) || node3->input(0) != node2->output(0)) | |||
| continue; | |||
| // reduce | |||
| node->set_op_type("noop_reducedncnn"); | |||
| node3->set_op_type("noop_reducedncnn"); | |||
| node_reference.erase(node_reference.find(node->output(0))); | |||
| node_reference.erase(node_reference.find(node2->output(0))); | |||
| blob_names.erase(node->output(0)); | |||
| blob_names.erase(node2->output(0)); | |||
| node2->set_input(0, node->input(0)); | |||
| node2->set_output(0, node3->output(0)); | |||
| reduced_node_count += 2; | |||
| i += 2; | |||
| } | |||
| } | |||
| } | |||
| int main(int argc, char** argv) | |||
| { | |||
| const char* onnxpb = argv[1]; | |||
| @@ -802,6 +851,7 @@ int main(int argc, char** argv) | |||
| fuse_shufflechannel (mutable_graph, weights, binaryop_weights, node_reference, blob_names, reduced_node_count, reduced_binaryop_weights); | |||
| fuse_hardsigmoid (mutable_graph, weights, binaryop_weights, node_reference, blob_names, reduced_node_count, reduced_binaryop_weights); | |||
| fuse_hardswish (mutable_graph, weights, binaryop_weights, node_reference, blob_names, reduced_node_count, reduced_binaryop_weights); | |||
| fuse_batchnorm1d_squeeze_unsqueeze(mutable_graph, weights, binaryop_weights, node_reference, blob_names, reduced_node_count, reduced_binaryop_weights); | |||
| // remove node_reference entry with reference equals to one | |||
| int splitncnn_blob_count = 0; | |||