({{, (RefLink[NetGraph, paclet:ref/NetGraph])[{(Subscript[layer, 1]),(Subscript[layer, 2]),…},{(Subscript[m, 1])->(Subscript[n, 1]),(Subscript[m, 2])->(Subscript[n, 2]),…}] 
specifies a neural net defined by a graph in which the output of layer (Subscript[m, i]) is given as input to layer (Subscript[n, i]).}, {, (RefLink[NetGraph, paclet:ref/NetGraph])[\[LeftAssociation]"(Subscript[name, 1])"->(Subscript[layer, 1]),"(Subscript[name, 2])"->(Subscript[layer, 2]),…\[RightAssociation],{"(Subscript[name, m1])"->"(Subscript[name, n1])",…}]
specifies a net with explicitly named layers.}})

OpenersNotesSection(Spacer1)Details

For a net with a single input port, (RefLink[NetGraph, paclet:ref/NetGraph])[…][data] gives the result of applying the net to data.

For a net with multiple input ports, (RefLink[NetGraph, paclet:ref/NetGraph])[…][<|(Subscript[port, 1])->(Subscript[data, 1]),…|>] provides data to each port.

For a net with a single output port, (RefLink[NetGraph, paclet:ref/NetGraph])[…][data] gives the output for that port.

For a net with multiple output ports, (RefLink[NetGraph, paclet:ref/NetGraph])[…][data,oport] gives the output for the output port named oport. (RefLink[NetGraph, paclet:ref/NetGraph])[…][data] or (RefLink[NetGraph, paclet:ref/NetGraph])[…][data,(RefLink[All, paclet:ref/All])] gives an association of the outputs for all ports.

(RefLink[NetGraph, paclet:ref/NetGraph])[…][data,(RefLink[NetPortGradient, paclet:ref/NetPortGradient])[iport]] gives the gradient of the output with respect to the value of the input port iport.

(RefLink[Normal, paclet:ref/Normal])[NetGraph[…]] will return a list or association of the layers used to construct the graph.

If one or more input or output ports of any layers are left unconnected, these will become ports of the entire (RefLink[NetGraph, paclet:ref/NetGraph]).

If multiple output ports of layers are left unconnected and share the same name, they will become separate ports of the entire (RefLink[NetGraph, paclet:ref/NetGraph]) with names "Port1", "Port2", etc.

Input or output ports for the entire (RefLink[NetGraph, paclet:ref/NetGraph]) can be created by specifying (RefLink[NetPort, paclet:ref/NetPort])["input"]->… or …->(RefLink[NetPort, paclet:ref/NetPort])["output"] in the list of connections.

If the n(^th) layer has more than one input port or more than one output port, these can be disambiguated by writing (RefLink[NetPort, paclet:ref/NetPort])[{n,"port"}] or (RefLink[NetPort, paclet:ref/NetPort])[n,port].

If a layer has a port that accepts multiple inputs, such as (RefLink[CatenateLayer, paclet:ref/CatenateLayer]) or (RefLink[SummationLayer, paclet:ref/SummationLayer]), multiple connections can be made simultaneously by writing {(Subscript[m, 1]),(Subscript[m, 2]),…}->n, which is equivalent to …,(Subscript[m, 1])->n,…,(Subscript[m, 2])->n,…. The inputs (Subscript[m, i]) are always passed to n in the order (Subscript[m, 1]),(Subscript[m, 2]),….

A linear chain of connections within the graph can be specified as (Subscript[layer, 1])->(Subscript[layer, 2])->…->(Subscript[layer, n]), which will cause each (Subscript[layer, i]) to be connected to (Subscript[layer, i+1]).

When ambiguous, the array shapes of input and output ports of the entire graph can be specified with options of the form "port"->shape. Valid shapes include:

(RefLink[NetGraph, paclet:ref/NetGraph]) supports the following special layer specifications when giving individual layers:

The (RefLink[StandardForm, paclet:ref/StandardForm]) of (RefLink[NetGraph, paclet:ref/NetGraph]) shows the connectivity of layers in the graph and annotates edges with the dimensions of the array that the edge represents. Clicking a layer in the graph shows more information about that layer.

(RefLink[NetGraph, paclet:ref/NetGraph])[…][data,opts] specifies that options should be used in applying the net to data. Possible options include:

Possible settings for (RefLink[WorkingPrecision, paclet:ref/WorkingPrecision]) include:

(RefLink[WorkingPrecision, paclet:ref/WorkingPrecision])->"Mixed" is only supported for (RefLink[TargetDevice, paclet:ref/TargetDevice])->"GPU", where it can result in significant performance increases on certain devices.

When given a (RefLink[NumericArray, paclet:ref/NumericArray]) as input, the output will be a (RefLink[NumericArray, paclet:ref/NumericArray]). In this case, its numeric type is derived from (RefLink[WorkingPrecision, paclet:ref/WorkingPrecision]).

With the setting (RefLink[NetEvaluationMode, paclet:ref/NetEvaluationMode])->"Training", layers such as (RefLink[DropoutLayer, paclet:ref/DropoutLayer]) will behave as they do for training rather than ordinary evaluation.

(RefLink[NetGraph, paclet:ref/NetGraph])[…][[spec]] extracts the layer specified by spec from the net.

(RefLink[NetTake, paclet:ref/NetTake])[NetGraph[…],{start,end}] returns a subgraph of the given (RefLink[NetGraph, paclet:ref/NetGraph]) that contains only the layers that connect start and end.

(RefLink[NetDelete, paclet:ref/NetDelete])[NetGraph[…],layer] deletes one or more layers from a (RefLink[NetGraph, paclet:ref/NetGraph]), returning a new graph.

(RefLink[NetFlatten, paclet:ref/NetFlatten])[NetGraph[…]] will flatten away any nested graphs that appear as layers of a (RefLink[NetGraph, paclet:ref/NetGraph]).

(RefLink[NetReplacePart, paclet:ref/NetReplacePart])[NetGraph[…],pos->layer] can be used to replace an existing layer of a (RefLink[NetGraph, paclet:ref/NetGraph]) with a new layer.

(RefLink[NetReplace, paclet:ref/NetReplace])[NetGraph[…],patt->layer] can be used to replace layers matching patt within a (RefLink[NetGraph, paclet:ref/NetGraph]) with a new layer.

(RefLink[NetRename, paclet:ref/NetRename])[NetGraph[…],"old"->"new"] can be used to rename layers of a (RefLink[NetGraph, paclet:ref/NetGraph]).

OpenersPrimaryExamplesSection(Spacer1)Examples  (17)

OpenersExampleSection0(Spacer1)Basic Examples  (2)

Create a net with one layer:

net=NetGraph[{ElementwiseLayer[Ramp]},{}]

Apply the net to an input:

net[{-1,0,1}]

Create a net with two layers:

net=NetGraph[{LinearLayer[3],LinearLayer[5]},{1->2},"Input"->2]

Initialize all arrays in the net:

net=NetInitialize[net];

Apply the net to an input:

net[{1.0,2.0}]

OpenersExampleSection1(Spacer1)Scope  (9)

Construct a net with explicitly named layers:

net=NetGraph[<|"linear1"->LinearLayer[3],"linear2"->LinearLayer[4]|>,{"linear1"->"linear2"}]

Extract the second layer by name:

NetExtract[net,"linear2"]

Use (RefLink[Part, paclet:ref/Part]) syntax to extract the first layer:

Part[net,"linear1"]

Use special syntax for (RefLink[ElementwiseLayer, paclet:ref/ElementwiseLayer]) and (RefLink[ThreadingLayer, paclet:ref/ThreadingLayer]):

net=NetGraph[{Ramp,Tanh,Times,Plus},{1->2->3,1->3->4,2->4}]

Apply the net to an input:

net[{-2,-1,0,1,2}]

Construct a net consisting of a linear chain:

net=NetGraph[{2,Ramp,4,Ramp,8},{1->2->3->4->5}]

This is equivalent to a (RefLink[NetChain, paclet:ref/NetChain]):

NetChain[{2,Ramp,4,Ramp,8}]

Create a net with two outputs:

net=NetGraph[{Ramp,LogisticSigmoid},{1->2,1->NetPort["Output1"],2->NetPort["Output2"]}]

Apply the net to an input:

net[{-1,0,1}]

Get the output from a specific port:

net[{-1,0,1},"Output1"]

Use (RefLink[NetTake, paclet:ref/NetTake]) to obtain a subnet that computes only one of the outputs:

subnet=NetTake[net,{NetPort["Input"],NetPort["Output2"]}]

subnet[{-1,0,1}]

Create a net that concatenates the output from intermediate layers:

net=NetGraph[{Ramp,LogisticSigmoid,CatenateLayer[]},{1->2,{1,2}->3}]

Apply the net to an input:

net[{-1,0,1}]

Create a net with multiple explicitly named inputs:

net=NetGraph[{Ramp,LogisticSigmoid,TotalLayer[]},{NetPort["Input1"]->1,NetPort["Input2"]->2,{1,2}->3}]

Apply the net to an input:

net[<|"Input1"->{-1,0,1},"Input2"->{1,2,3}|>]

Construct a net that explicitly computes a loss:

net=NetGraph[{LinearLayer[2],SoftmaxLayer[],MeanSquaredLossLayer[]},{1->2->3},"Input"->"Scalar"]

Initialize the net and evaluate it on an input:

net=NetInitialize[net];

net[<|"Input"->1,"Target"->{2,3}|>]

Create a net with a class decoder:

net=NetGraph[{Ramp,SoftmaxLayer[]},{1->2},"Output"-> NetDecoder[{"Class",{a,b}}]]

Evaluate the net:

net[{0.2,0.8}]

net[{0.8,0.2}]

Retrieve a property of the decoder by specifying a second argument:

net[{0.8,0.2},"Probabilities"]

net[{0.8,0.2},{"Probability",a}]

net[{0.8,0.2},"Entropy"]

Create a net with multiple layers:

net=NetGraph[{2,4,8,Tanh},{1->2->3->4}]

Create a new network consisting of the last two layers:

NetTake[net,{3,4}]

OpenersExampleSection3(Spacer1)Applications  (1)

Perform multitask learning by creating a net that produces two separate classifications. First, obtain training data:

obj=ResourceObject["CIFAR-100"]

The training data consists of an image and the corresponding high-level and low-level labels:

trainingData=ResourceData[obj,"TrainingDataset"];
RandomSample[trainingData,5]

Extract the unique labels from the "Label" and "SubLabel" columns:

labels=Union@Normal@trainingData[All,"Label"]

sublabels=Union@Normal@trainingData[All,"SubLabel"]

Create a base convolutional net that will produce a vector of 500 features:

convnet=NetChain[{
ConvolutionLayer[20,5],Ramp,PoolingLayer[2,2],
ConvolutionLayer[50,5],Ramp,PoolingLayer[2,2],
500,Ramp
},"Input"->NetEncoder[{"Image",{32,32}}]]

Create a (RefLink[NetGraph, paclet:ref/NetGraph]) that will produce separate classifications for the high-level and low-level labels:

net=NetGraph[{convnet,100,SoftmaxLayer[],20,SoftmaxLayer[]},{NetPort["Image"]->1->2->3->NetPort["SubLabel"],2->4->5->NetPort["Label"]},
"Label"->NetDecoder[{"Class",labels}],"SubLabel"->NetDecoder[{"Class",sublabels}]]

Train the network:

trained=NetTrain[net,trainingData,MaxTrainingRounds->10];

Evaluate the trained network on some example images:

trained[{,,,,,,,,,}]

Get probabilities for a single image:

trained[,"Label"->"Probabilities"]

From a random sample, select the images for which the net produces highest and lowest entropy predictions for "Label":

images=RandomSample[Normal[trainingData][[All,"Image"]],5000];
entropies=trained[images,"Label"->"Entropy"];

Labeled[images[[Ordering[entropies,-10]]],"high entropy"]
Labeled[images[[Ordering[entropies,10]]],"low entropy"]

Use (RefLink[NetTake, paclet:ref/NetTake]) to produce a sub-network that computes only "SubLabel" predictions:

subnet=NetTake[trained,{NetPort["Image"],NetPort["SubLabel"]}]

Make a prediction on a single image:

subnet[]

OpenersExampleSection4(Spacer1)Properties & Relations  (4)

(RefLink[NetChain, paclet:ref/NetChain]) objects can be used as layers in a (RefLink[NetGraph, paclet:ref/NetGraph]):

chain=NetChain[{Ramp,LogisticSigmoid}];
NetGraph[{chain, LinearLayer[3]},{1-> 2}]

(RefLink[NetGraph, paclet:ref/NetGraph]) objects with one input and one output can be used as layers inside (RefLink[NetChain, paclet:ref/NetChain]) objects:

net=NetGraph[{Ramp,LogisticSigmoid,CatenateLayer[]},{1->2,{1,2}->3}];
NetChain[{ElementwiseLayer[Ramp], net}]

The layers used to construct a (RefLink[NetGraph, paclet:ref/NetGraph]) can be extracted using (RefLink[Normal, paclet:ref/Normal]):

net=NetGraph[{1,Ramp,2,Tanh},{1->2->3->4}]

Normal[net]

Use (RefLink[NetInformation, paclet:ref/NetInformation])[graph,"SummaryGraphic"] to get a (RefLink[Graphics, paclet:ref/Graphics])[…] expression that shows the underlying connectivity of a graph:

net=NetGraph[{LinearLayer[2],Ramp,LinearLayer[3],SoftmaxLayer[],MeanSquaredLossLayer[]},{1->2->3->4->5},"Input"->"Scalar"]

NetInformation[net,"SummaryGraphic"]

OpenersExampleSection5(Spacer1)Possible Issues  (1)

The order in which edges are defined in a (RefLink[NetGraph, paclet:ref/NetGraph]) can matter. Create a (RefLink[NetGraph, paclet:ref/NetGraph]) that computes a matrix-vector dot product:

edges={NetPort["matrix"]->1,NetPort["vector"]->1}

NetGraph[{DotLayer[]},edges,"vector"->{2},"matrix"->{3,2}]

Reversing the order in which the edges are defined causes a failure, as a vector-matrix product with incompatible dimensions is now computed:

NetGraph[{DotLayer[]},Reverse[edges],"vector"->{2},"matrix"->{3,2}]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[NetModel, paclet:ref/NetModel])  ▪  (RefLink[NetPort, paclet:ref/NetPort])  ▪  (RefLink[NetTake, paclet:ref/NetTake])  ▪  (RefLink[NetFlatten, paclet:ref/NetFlatten])  ▪  (RefLink[NetChain, paclet:ref/NetChain])  ▪  (RefLink[NetInitialize, paclet:ref/NetInitialize])  ▪  (RefLink[NetTrain, paclet:ref/NetTrain])  ▪  (RefLink[NetExtract, paclet:ref/NetExtract])  ▪  (RefLink[NetEncoder, paclet:ref/NetEncoder])  ▪  (RefLink[NetDecoder, paclet:ref/NetDecoder])  ▪  (RefLink[LinearLayer, paclet:ref/LinearLayer])  ▪  (RefLink[ElementwiseLayer, paclet:ref/ElementwiseLayer])  ▪  (RefLink[NetInformation, paclet:ref/NetInformation])  ▪  (RefLink[ClassifierMeasurements, paclet:ref/ClassifierMeasurements])}})}})

({{DocumentationFooterIconsRelatedTutorial.png, ({{Tutorials}, {▪(RefLinkPlain[Neural Networks in the Wolfram Language, paclet:tutorial/NeuralNetworksOverview])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Machine Learning, paclet:guide/MachineLearning])}, {▪(RefLinkPlain[Neural Networks, paclet:guide/NeuralNetworks])}, {▪(RefLinkPlain[Image Computation for Microscopy, paclet:guide/ImageComputationForMicroscopy])}, {▪(RefLinkPlain[Audio Processing, paclet:guide/AudioProcessing])}})}})