{"id":2822,"date":"2023-06-03T12:44:56","date_gmt":"2023-06-03T12:44:56","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2822"},"modified":"2023-06-03T12:58:51","modified_gmt":"2023-06-03T12:58:51","slug":"visualize-neural-networks-using-mindfusion-diagram-component","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/visualize-neural-networks-using-mindfusion-diagram-component\/","title":{"rendered":"Visualize neural networks using MindFusion diagram component"},"content":{"rendered":"\n<p>In this post we&#8217;ll show how to visualize a neural network as a flow diagram. The networks will be loaded from Open Neural Network Exchange (ONNX) file format, with a sample network from the <a href=\"https:\/\/github.com\/onnx\/models\">https:\/\/github.com\/onnx\/models<\/a> collection.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>The complete sample project is available here \u2013<br><a href=\"https:\/\/mindfusion.dev\/_samples\/NeuralNet.zip\">https:\/\/mindfusion.dev\/_samples\/NeuralNet.zip<\/a><\/p>\n\n\n\n<p>Start by creating a .NET Windows Forms project, in our example we use C# \/ .NET 6 template. Add the MindFusion.Diagramming Nuget package, and double click the DiagramView and Overview controls from toolbox to add them to the form.<\/p>\n\n\n\n<p>Add the <a href=\"https:\/\/www.nuget.org\/packages\/OnnxSharp\">OnnxSharp<\/a> nuget package, which lets us parse ONNX files. Import the following namespaces into the form&#8217;s code-behind:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using Onnx;\n\nusing MindFusion.Diagramming;\nusing MindFusion.Diagramming.Layout;<\/code><\/pre>\n\n\n\n<p>Parse the ONNX file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var model = ModelProto.Parser.ParseFromFile(@\"inception-v1-12-qdq.onnx\");\nvar graph = model.Graph;<\/code><\/pre>\n\n\n\n<p>Loop over the network nodes and create respective diagram ones. We&#8217;ll use a dictionary to keep track for diagram objects corresponding to ONNX ones. The Onnx.NodeProto class contains many properties, but we&#8217;ll show just a few of them in grid format using a TableNode:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var nodeMap = new Dictionary&lt;NodeProto, DiagramNode&gt;();\n\n\/\/ create a TableNode for each graph node\nforeach (var networkNode in graph.Node)\n{\n\tvar diagramNode = diagram.Factory.CreateTableNode(0, 0, 30, 30, 2, 1);\n\tdiagramNode&#91;0, 0].Text = \"OpType:\";\n\tdiagramNode&#91;1, 0].Text = networkNode.OpType;\n\tforeach (var attribute in networkNode.Attribute)\n\t{\n\t\tdiagramNode.AddRow();\n\t\tint r = diagramNode.RowCount - 1;\n\t\tdiagramNode&#91;0, r].Text = attribute.Name;\n\t\tdiagramNode&#91;1, r].Text = attribute.Type.ToString();\n\t}\n\tdiagramNode.ResizeToFitText(false, false);\n\tdiagramNode.Caption = networkNode.Name;\n\tdiagramNode.ConnectionStyle = TableConnectionStyle.Table;\n\n\tnodeMap&#91;networkNode] = diagramNode;\n}<\/code><\/pre>\n\n\n\n<p>Style the tables a bit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>diagramNode.Caption = networkNode.Name;\ndiagramNode.CellFrameStyle = CellFrameStyle.Simple;\ndiagramNode.Brush = new MindFusion.Drawing.SolidBrush(Color.LightGray);\ndiagramNode.CaptionBackBrush = new MindFusion.Drawing.SolidBrush(Color.LightSkyBlue);<\/code><\/pre>\n\n\n\n<p>Find pairs of nodes with matching output -&gt; input identifiers to draw links between them:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ draw links when we find pairs of matching output -&gt; input identifiers\nforeach (var networkNode1 in graph.Node)\n{\n\tforeach (var output in networkNode1.Output)\n\t{\n\t\tforeach (var networkNode2 in graph.Node)\n\t\t{\n\t\t\tif (networkNode1 == networkNode2)\n\t\t\t\tcontinue;\n\n\t\t\tforeach (var input in networkNode2.Input)\n\t\t\t{\n\t\t\t\tif (output == input)\n\t\t\t\t{\n\t\t\t\t\tvar diagramNode1 = nodeMap&#91;networkNode1];\n\t\t\t\t\tvar diagramNode2 = nodeMap&#91;networkNode2];\n\t\t\t\t\tdiagram.Factory.CreateDiagramLink(diagramNode1, diagramNode2);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}<\/code><\/pre>\n\n\n\n<p>Finally arrange the diagram:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>diagram.Arrange(new LayeredLayout { EnforceLinkFlow = true, IgnoreNodeSize = false });\ndiagram.ResizeToFitItems(5);\n<\/code><\/pre>\n\n\n\n<p>The final result should look like \u2013<br><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"317\" class=\"wp-image-2823\" style=\"width: 600px;\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram.png\" alt=\"\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram.png 1892w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram-300x159.png 300w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram-1024x542.png 1024w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram-768x406.png 768w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram-1536x813.png 1536w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2023\/06\/neural_network_diagram-500x265.png 500w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n\n\n\n<p>The sample above uses MindFusion\u2019s <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/flowchartnet\/Getting_Started.htm\">Windows Forms API<\/a>. Code for other frameworks will look similar as MindFusion maintains same diagramming model for multiple platforms. You can download the trial version of any MindFusion.Diagramming component from <a href=\"https:\/\/mindfusion.dev\/downloads.html\">this page<\/a>.<\/p>\n\n\n\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we&#8217;ll show how to visualize a neural network as a flow diagram. The networks will be loaded from the Open Neural Network Exchange (ONNX) file format, with a sample network from the https:\/\/github.com\/onnx\/models collection. <a href=\"https:\/\/mindfusion.dev\/blog\/visualize-neural-networks-using-mindfusion-diagram-component\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[95,74],"tags":[],"class_list":["post-2822","post","type-post","status-publish","format-standard","hentry","category-diagramming-2","category-sample-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-Jw","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=2822"}],"version-history":[{"count":6,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2822\/revisions"}],"predecessor-version":[{"id":2831,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2822\/revisions\/2831"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}