{"id":148,"date":"2018-02-14T14:43:21","date_gmt":"2018-02-14T14:43:21","guid":{"rendered":"https:\/\/blogs.mathworks.com\/deep-learning\/?p=148"},"modified":"2021-04-06T15:52:24","modified_gmt":"2021-04-06T19:52:24","slug":"create-a-simple-dag-network","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/deep-learning\/2018\/02\/14\/create-a-simple-dag-network\/","title":{"rendered":"Create a Simple DAG Network"},"content":{"rendered":"<div class=\"content\"><h3>Creating a Simple DAG Network<\/h3><p>Today I want to show the basic tools needed to build your own DAG (directed acyclic graph) network for deep learning. I'm going to build this network and train it on our digits dataset.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/simple-dag-network.png\" alt=\"\"> <\/p><p>As the first step, I'll create the main branch, which follows the left path shown above. The <tt>layerGraph<\/tt> function will save a bunch of connection steps; it creates a graph network from a simple array of layers, connecting the layers together in order.<\/p><pre class=\"codeinput\">layers = [\r\n    imageInputLayer([28 28 1],<span class=\"string\">'Name'<\/span>,<span class=\"string\">'input'<\/span>)\r\n\r\n    convolution2dLayer(5,16,<span class=\"string\">'Padding'<\/span>,<span class=\"string\">'same'<\/span>,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'conv_1'<\/span>)\r\n    batchNormalizationLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'BN_1'<\/span>)\r\n    reluLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'relu_1'<\/span>)\r\n\r\n    convolution2dLayer(3,32,<span class=\"string\">'Padding'<\/span>,<span class=\"string\">'same'<\/span>,<span class=\"string\">'Stride'<\/span>,2,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'conv_2'<\/span>)\r\n    batchNormalizationLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'BN_2'<\/span>)\r\n    reluLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'relu_2'<\/span>)\r\n    convolution2dLayer(3,32,<span class=\"string\">'Padding'<\/span>,<span class=\"string\">'same'<\/span>,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'conv_3'<\/span>)\r\n    batchNormalizationLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'BN_3'<\/span>)\r\n    reluLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'relu_3'<\/span>)\r\n\r\n    additionLayer(2,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'add'<\/span>)\r\n\r\n    averagePooling2dLayer(2,<span class=\"string\">'Stride'<\/span>,2,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'avpool'<\/span>)\r\n    fullyConnectedLayer(10,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'fc'<\/span>)\r\n    softmaxLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'softmax'<\/span>)\r\n    classificationLayer(<span class=\"string\">'Name'<\/span>,<span class=\"string\">'classOutput'<\/span>)];\r\n<\/pre><p>Connect the layers using <tt>layerGraph<\/tt>.<\/p><pre class=\"codeinput\">lgraph = layerGraph(layers)\r\n<\/pre><pre class=\"codeoutput\">\r\nlgraph = \r\n\r\n  LayerGraph with properties:\r\n\r\n         Layers: [15&times;1 nnet.cnn.layer.Layer]\r\n    Connections: [14&times;2 table]\r\n\r\n<\/pre><p>The <tt>plot<\/tt> function knows how to visualize a DAG network.<\/p><pre class=\"codeinput\">plot(lgraph)\r\naxis <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/CreateSimpleDAGNetworkExample_01.png\" alt=\"\"> <p>Next, I need to create the single layer that will be on the other branch. It is a 1-by-1 convolutional layer. Its parameters (number of filters and stride) are set to match the activation size of the <tt>'relu_3'<\/tt> layer. Once the layer is created, <tt>addLayers<\/tt> adds it to <tt>lgraph<\/tt>.<\/p><pre class=\"codeinput\">skip_conv_layer = convolution2dLayer(1,32,<span class=\"string\">'Stride'<\/span>,2,<span class=\"string\">'Name'<\/span>,<span class=\"string\">'skipConv'<\/span>);\r\nlgraph = addLayers(lgraph,skip_conv_layer);\r\nplot(lgraph)\r\naxis <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/CreateSimpleDAGNetworkExample_02.png\" alt=\"\"> <p>You can see the new layer there, but it's looking a little lonely off to the side. I need to connect it to the other layers using <tt>connectLayers<\/tt>.<\/p><pre class=\"codeinput\">lgraph = connectLayers(lgraph,<span class=\"string\">'relu_1'<\/span>,<span class=\"string\">'skipConv'<\/span>);\r\nlgraph = connectLayers(lgraph,<span class=\"string\">'skipConv'<\/span>,<span class=\"string\">'add\/in2'<\/span>);\r\nplot(lgraph);\r\naxis <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/CreateSimpleDAGNetworkExample_03.png\" alt=\"\"> <p>Now that I've constructed the network, here are the steps for training it using our digits dataset.<\/p><pre class=\"codeinput\">[trainImages,trainLabels] = digitTrain4DArrayData;\r\n[valImages,valLabels] = digitTest4DArrayData;\r\n<\/pre><p>Specify training options and train the network.<\/p><pre class=\"codeinput\">options = trainingOptions(<span class=\"string\">'sgdm'<\/span>,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'MaxEpochs'<\/span>,6,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'Shuffle'<\/span>,<span class=\"string\">'every-epoch'<\/span>,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'ValidationData'<\/span>,{valImages,valLabels},<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'ValidationFrequency'<\/span>,20,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'VerboseFrequency'<\/span>,20);\r\nnet = trainNetwork(trainImages,trainLabels,lgraph,options)\r\n<\/pre><pre class=\"codeoutput\">Training on single GPU.\r\nInitializing image normalization.\r\n|=======================================================================================================================|\r\n|     Epoch    |   Iteration  | Time Elapsed |  Mini-batch  |  Validation  |  Mini-batch  |  Validation  | Base Learning|\r\n|              |              |  (seconds)   |     Loss     |     Loss     |   Accuracy   |   Accuracy   |     Rate     |\r\n|=======================================================================================================================|\r\n|            1 |            1 |         0.03 |       2.3317 |       2.2729 |       11.72% |       14.38% |       0.0100 |\r\n|            1 |           20 |         0.81 |       0.9775 |       0.9119 |       71.88% |       72.24% |       0.0100 |\r\n|            2 |           40 |         1.61 |       0.3783 |       0.4352 |       92.19% |       88.86% |       0.0100 |\r\n|            2 |           60 |         2.38 |       0.3752 |       0.3111 |       89.06% |       92.06% |       0.0100 |\r\n|            3 |           80 |         3.21 |       0.1935 |       0.1945 |       96.88% |       96.18% |       0.0100 |\r\n|            3 |          100 |         4.04 |       0.1777 |       0.1454 |       97.66% |       97.32% |       0.0100 |\r\n|            4 |          120 |         4.89 |       0.0662 |       0.0956 |      100.00% |       98.50% |       0.0100 |\r\n|            4 |          140 |         5.77 |       0.0764 |       0.0694 |       99.22% |       99.30% |       0.0100 |\r\n|            5 |          160 |         6.58 |       0.0466 |       0.0540 |      100.00% |       99.52% |       0.0100 |\r\n|            5 |          180 |         7.36 |       0.0459 |       0.0459 |       99.22% |       99.60% |       0.0100 |\r\n|            6 |          200 |         8.12 |       0.0276 |       0.0390 |      100.00% |       99.56% |       0.0100 |\r\n|            6 |          220 |         9.01 |       0.0242 |       0.0354 |      100.00% |       99.62% |       0.0100 |\r\n|            6 |          234 |         9.84 |       0.0160 |              |      100.00% |              |       0.0100 |\r\n|=======================================================================================================================|\r\n\r\nnet = \r\n\r\n  DAGNetwork with properties:\r\n\r\n         Layers: [16&times;1 nnet.cnn.layer.Layer]\r\n    Connections: [16&times;2 table]\r\n\r\n<\/pre><p>The output of <tt>trainNetwork<\/tt> is a <tt>DAGNetwork<\/tt> object. The <tt>Connections<\/tt> property records how the individual layers are connected to each other.<\/p><pre class=\"codeinput\">net.Connections\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n  16&times;2 table\r\n\r\n      Source       Destination \r\n    __________    _____________\r\n\r\n    'input'       'conv_1'     \r\n    'conv_1'      'BN_1'       \r\n    'BN_1'        'relu_1'     \r\n    'relu_1'      'conv_2'     \r\n    'relu_1'      'skipConv'   \r\n    'conv_2'      'BN_2'       \r\n    'BN_2'        'relu_2'     \r\n    'relu_2'      'conv_3'     \r\n    'conv_3'      'BN_3'       \r\n    'BN_3'        'relu_3'     \r\n    'relu_3'      'add\/in1'    \r\n    'add'         'avpool'     \r\n    'avpool'      'fc'         \r\n    'fc'          'softmax'    \r\n    'softmax'     'classOutput'\r\n    'skipConv'    'add\/in2'    \r\n\r\n<\/pre><p>Classify the validation images and calculate the accuracy.<\/p><pre class=\"codeinput\">predictedLabels = classify(net,valImages);\r\naccuracy = mean(predictedLabels == valLabels)\r\n<\/pre><pre class=\"codeoutput\">\r\naccuracy =\r\n\r\n    0.9974\r\n\r\n<\/pre><p>Those are the basics. Create layers using the various layer functions and join them up using <tt>layerGraph<\/tt> and <tt>connectLayers<\/tt>. Then you can train and use the network in the same way you would train and use other networks.<\/p><p>Reference: <a href=\"https:\/\/www.mathworks.com\/help\/nnet\/examples\/create-and-train-dag-network.html\">Create and Train a DAG Network for Deep Learning<\/a><\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_7c523d9bcc8a4f1bba3561dcc820214e() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='7c523d9bcc8a4f1bba3561dcc820214e ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 7c523d9bcc8a4f1bba3561dcc820214e';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2018 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_7c523d9bcc8a4f1bba3561dcc820214e()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2017b<br><\/p><\/div><!--\r\n7c523d9bcc8a4f1bba3561dcc820214e ##### SOURCE BEGIN #####\r\n%% Creating a Simple DAG Network\r\n% Today I want to show the basic tools needed to build your own DAG\r\n% (directed acyclic graph) network for deep learning. I'm going to build\r\n% this network and train it on our digits dataset.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/simple-dag-network.png>>\r\n%\r\n% As the first step, I'll create the main branch, which follows the left\r\n% path shown above. The |layerGraph| function will save a bunch of\r\n% connection steps; it creates a graph network from a simple array of\r\n% layers, connecting the layers together in order.\r\n\r\nlayers = [\r\n    imageInputLayer([28 28 1],'Name','input')\r\n    \r\n    convolution2dLayer(5,16,'Padding','same','Name','conv_1')\r\n    batchNormalizationLayer('Name','BN_1')\r\n    reluLayer('Name','relu_1')\r\n    \r\n    convolution2dLayer(3,32,'Padding','same','Stride',2,'Name','conv_2')\r\n    batchNormalizationLayer('Name','BN_2')\r\n    reluLayer('Name','relu_2')\r\n    convolution2dLayer(3,32,'Padding','same','Name','conv_3')\r\n    batchNormalizationLayer('Name','BN_3')\r\n    reluLayer('Name','relu_3')\r\n    \r\n    additionLayer(2,'Name','add')\r\n    \r\n    averagePooling2dLayer(2,'Stride',2,'Name','avpool')\r\n    fullyConnectedLayer(10,'Name','fc')\r\n    softmaxLayer('Name','softmax')\r\n    classificationLayer('Name','classOutput')];\r\n%% \r\n% Connect the layers using |layerGraph|.\r\n\r\nlgraph = layerGraph(layers)\r\n\r\n%%\r\n% The |plot| function knows how to visualize a DAG network.\r\n\r\nplot(lgraph)\r\naxis off\r\n\r\n%% \r\n% Next, I need to create the single layer that will be on the other branch.\r\n% It is a 1-by-1 convolutional layer. Its parameters (number of filters and stride)\r\n% are set to match the activation size of the |'relu_3'| layer. Once the layer is created,\r\n% |addLayers| adds it to |lgraph|.\r\n\r\nskip_conv_layer = convolution2dLayer(1,32,'Stride',2,'Name','skipConv');\r\nlgraph = addLayers(lgraph,skip_conv_layer);\r\nplot(lgraph)\r\naxis off\r\n\r\n%% \r\n% You can see the new layer there, but it's looking a little lonely off to\r\n% the side. I need to connect it to the other layers using |connectLayers|.\r\n\r\nlgraph = connectLayers(lgraph,'relu_1','skipConv');\r\nlgraph = connectLayers(lgraph,'skipConv','add\/in2');\r\nplot(lgraph);\r\naxis off\r\n\r\n%% \r\n% Now that I've constructed the network, here are the steps for training it\r\n% using our digits dataset.\r\n\r\n[trainImages,trainLabels] = digitTrain4DArrayData;\r\n[valImages,valLabels] = digitTest4DArrayData;\r\n\r\n%% \r\n% Specify training options and train the network.\r\n\r\noptions = trainingOptions('sgdm',...\r\n    'MaxEpochs',6,...\r\n    'Shuffle','every-epoch',...\r\n    'ValidationData',{valImages,valLabels},...\r\n    'ValidationFrequency',20,...\r\n    'VerboseFrequency',20);\r\nnet = trainNetwork(trainImages,trainLabels,lgraph,options)\r\n\r\n%%\r\n% The output of |trainNetwork| is a |DAGNetwork| object. The |Connections|\r\n% property records how the individual layers are connected to each other.\r\n\r\nnet.Connections\r\n\r\n%% \r\n% Classify the validation images and calculate the accuracy.\r\n\r\npredictedLabels = classify(net,valImages);\r\naccuracy = mean(predictedLabels == valLabels)\r\n\r\n%%\r\n% Those are the basics. Create layers using the various layer functions and\r\n% join them up using |layerGraph| and |connectLayers|. Then you can train\r\n% and use the network in the same way you would train and use other\r\n% networks.\r\n%\r\n% Reference:\r\n% <https:\/\/www.mathworks.com\/help\/nnet\/examples\/create-and-train-dag-network.html\r\n% Create and Train a DAG Network for Deep Learning>\r\n##### SOURCE END ##### 7c523d9bcc8a4f1bba3561dcc820214e\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/deep-learning\/files\/2018\/02\/simple-dag-network.png\" onError=\"this.style.display ='none';\" \/><\/div><p>Creating a Simple DAG NetworkToday I want to show the basic tools needed to build your own DAG (directed acyclic graph) network for deep learning. I'm going to build this network and train it on our... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/deep-learning\/2018\/02\/14\/create-a-simple-dag-network\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/posts\/148"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/comments?post=148"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/posts\/148\/revisions"}],"predecessor-version":[{"id":164,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/posts\/148\/revisions\/164"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/media?parent=148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/categories?post=148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/deep-learning\/wp-json\/wp\/v2\/tags?post=148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}