({{, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,s]
represents a trainable convolutional net layer having n output channels and using kernels of size s to compute the convolution.}, {, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,{s}]
represents a layer performing one-dimensional convolutions with kernels of size s.}, {, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,{h,w}]
represents a layer performing two-dimensional convolutions with kernels of size h×w.}, {, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,{h,w,d}]
represents a three-dimensional convolutions with kernels of size h×w×d.}, {, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,kernel,opts]
includes options for padding and other parameters.}})

OpenersNotesSection(Spacer1)Details and Options

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,…] represents a layer that, applied to an input array with m input channels and one or more spatial dimensions, effectively performs n×m distinct convolutions across the spatial dimensions to produce an output array with n channels.

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[…][input] explicitly computes the output from applying the layer to input.

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[…][{(Subscript[input, 1]),(Subscript[input, 2]),…}] explicitly computes outputs for each of the (Subscript[input, i]).

In (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[n,s], the dimensionality of the convolution layer will be inferred when the layer is connected in a (RefLink[NetChain, paclet:ref/NetChain]), (RefLink[NetGraph, paclet:ref/NetGraph]), etc.

The following optional parameters can be included:

The setting for "PaddingSize" can be of the following forms:

The settings for "Dilation" and "Stride" can be of the following forms:

With (RefLink[Automatic, paclet:ref/Automatic]) settings, weights and biases are added automatically when (RefLink[NetInitialize, paclet:ref/NetInitialize]) or (RefLink[NetTrain, paclet:ref/NetTrain]) is used.

The setting "Biases"->(RefLink[None, paclet:ref/None]) specifies that no biases should be used.

With the setting "Interleaving"->(RefLink[False, paclet:ref/False]), the channel dimension is taken to be the first dimension of the input and output arrays.

With the setting "Interleaving"->(RefLink[True, paclet:ref/True]), the channel dimension is taken to be the last dimension of the input and output arrays.

If weights and biases have been added, (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[…][input] explicitly computes the output from applying the layer.

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer])[…][{(Subscript[input, 1]),(Subscript[input, 2]),…}] explicitly computes outputs for each of the (Subscript[input, i]).

(RefLink[NetExtract, paclet:ref/NetExtract]) can be used to extract weights and biases from a (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) object.

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) is typically used inside (RefLink[NetChain, paclet:ref/NetChain]), (RefLink[NetGraph, paclet:ref/NetGraph]), etc.

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) exposes the following ports for use in (RefLink[NetGraph, paclet:ref/NetGraph]) etc.:

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) can operate on arrays that contain "Varying" dimensions.

When it cannot be inferred from other layers in a larger net, the option "Input"->{(Subscript[d, 1]),…,(Subscript[d, n])} can be used to fix the input dimensions of (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]).

Given an input array of dimensions (Subscript[d, 1])×…×(Subscript[d, i])×…, the output array will be of dimensions (Underscript[(OverTilde[d]), 1])×…×(Underscript[(OverTilde[d]), i])×…, where the channel dimension (Underscript[(OverTilde[d]), 1])=n and the sizes (Subscript[d, i]) are transformed according to (OverTilde[(Subscript[d, i])])=⌊((Subscript[d, i])+(Subscript[p, b])+(Subscript[p, e])-df×(k-1)-1)/s+1⌋, where (Subscript[p, b])/(Subscript[p, e]) are the padding sizes at the beginning/end of the axis, k is the kernel size, s is the stride size, and df is the dilation factor for each dimension.

OpenersPrimaryExamplesSection(Spacer1)Examples  (27)

OpenersExampleSection0(Spacer1)Basic Examples  (2)

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with 2 output channels and a kernel size of 4:

ConvolutionLayer[2,{4}]

Create an initialized one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]):

conv=NetInitialize@ConvolutionLayer[1,{2},"Input"->{1,3}]

Apply the layer to an input matrix:

conv[{{1,1,2}}]

OpenersExampleSection1(Spacer1)Scope  (3)

Create an initialized two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]):

conv=NetInitialize@ConvolutionLayer[1,2,"Input"-> {1,4,4}]

Apply the layer to an input array:

conv[RandomInteger[1,{1,4,4}]]

The output is also a rank-3 array:

Dimensions[%]

Create an initialized three-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with kernel size 2:

conv=NetInitialize@ConvolutionLayer[1,2,"Input"-> {1,3,3}]

Apply the layer to an input array:

conv[{{{1,1,0},{0,0,1},{1,1,0}}}]

Create an initialized two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) that takes an RGB image and returns an RGB image:

conv=NetInitialize@ConvolutionLayer[3,10,"Dilation"->3,"Input"-> NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) automatically threads over batches of inputs:

conv[{,}]

OpenersExampleSection2(Spacer1)Options  (17)

OpenersExampleSubsection0(Spacer1)"Biases"  (3)

Create a two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) without biases:

conv=ConvolutionLayer[2,{4,4},"Biases"-> None,"Input"->{1,40,40}]

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with an identity kernel that applies a bias to the only channel:

conv=ConvolutionLayer["Weights"->{{{1}}},"Biases"->{0.5}]

Apply the layer to an input:

conv[{{1,2,3,4,5}}]

Create a two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with an identity kernel that applies a bias to each channel:

kernel=ArrayReshape[IdentityMatrix[3],{3,3,1,1}];
conv=ConvolutionLayer["Weights"->kernel,"Biases"->{0.5,-0.5,0.},"Input"->NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

OpenersExampleSubsection1(Spacer1)"Dilation"  (2)

A dilation factor of size n on a given dimension effectively applies the kernel to elements from the input arrays that are distance n apart.

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with a dilation factor of 2:

conv=ConvolutionLayer["Weights"->{{{0.5,0.5}}},"Biases"->None,"Dilation"->2]

Apply the layer to an input:

conv[{{0,0,0,0,0,1,0,0,0,0,0}}] // Normal

Create a random two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with a dilation factor of 5:

conv=NetInitialize@ConvolutionLayer[3,{3,3},"Dilation"->5,"Input"->NetEncoder[ "Image"],"Output"->NetDecoder["Image"]]

Apply the dilated convolution layer to an image:

conv[]

OpenersExampleSubsection2(Spacer1)"Interleaving"  (1)

Create a (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with "Interleaving"->(RefLink[False, paclet:ref/False]) and one input channel:

ConvolutionLayer[1,5,"Input"-> {1,25,25},"Interleaving"->False ]

Create a (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with "Interleaving"->(RefLink[True, paclet:ref/True]) and one input channel:

ConvolutionLayer[1,5,"Input"-> {25,25,1},"Interleaving"->True ]

OpenersExampleSubsection3(Spacer1)"PaddingSize"  (4)

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) that averages neighboring elements and pads with 4 zeros on each side:

conv=ConvolutionLayer["Weights"->{{{0.5,0.5}}},"Biases"->None,"PaddingSize"->4]

Apply the layer to an input:

conv[{{1,2,3,4,5}}] // Normal

Create a random two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) that pads the first dimension with 10 zeros on each side and the second dimension with 25 zeros on each side:

conv=NetInitialize[ConvolutionLayer[3,{3,3},"PaddingSize"-> {10,25},"Input"-> NetEncoder["Image"],"Output"->NetDecoder["Image"]], RandomSeeding->Automatic]

conv[]

Create a random two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) that pads the first dimension with 10 zeros at the beginning and 20 zeros at the end:

conv=NetInitialize[ConvolutionLayer[3,{3,3},"PaddingSize"-> {{10,20},{0,0}},"Input"-> NetEncoder["Image"],"Output"->NetDecoder["Image"]], RandomSeeding->Automatic]

conv[]

Use padding to make the output dimensions equivalent to the input dimensions:

conv=ConvolutionLayer[1,5,"Input"-> {1,25,25},"PaddingSize"->2 ]

This allows for deep networks to be defined with an arbitrary number of convolutions without the height and width of the input tending to 1.

OpenersExampleSubsection4(Spacer1)"Stride"  (3)

A stride of size n on a given dimension effectively controls the step size with which the kernel is moved across the input array to produce the output array.

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with a kernel that takes the average of neighboring pairs:

kernel={{{0.5,0.5}}};
conv=ConvolutionLayer["Weights"->kernel,"Biases"->None]

Apply the layer to an input:

conv[{{1,2,3,4,5,6,7,8,9,10}}] // Normal

Using a stride of 2 applies the kernel to non-overlapping pairs:

conv=ConvolutionLayer["Weights"->kernel,"Biases"->None,"Stride"->2];
conv[{{1,2,3,4,5,6,7,8,9,10}}] // Normal

Using a stride of 4 applies the kernel to every other pair:

conv=ConvolutionLayer["Weights"->kernel,"Biases"->None,"Stride"->4];
conv[{{1,2,3,4,5,6,7,8,9,10}}] // Normal

Create a random two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with an asymmetric stride:

conv=ConvolutionLayer["Weights"->RandomReal[0.1,{3,3,4,4}],"Biases"->None,"Stride"->{3,1},"Input"->NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

Use a larger stride to reduce the dimension of the output:

conv1=ConvolutionLayer[30,7,"Input"-> {3,500,500},"Stride"->1 ]

conv2=ConvolutionLayer[30,7,"Input"-> {3,500,500},"Stride"->7 ]

A larger stride can also reduce computation time:

data=RandomReal[1,{3,500,500}];
conv1=NetInitialize@conv1;
conv2=NetInitialize@conv2;
conv1[data];//AbsoluteTiming
conv2[data];//AbsoluteTiming

OpenersExampleSubsection5(Spacer1)"Weights"  (4)

Create a one-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with a kernel that averages pairs from the input array:

conv=ConvolutionLayer["Weights"->{{{0.5,0.5}}},"Biases"->None]

Apply the layer to an input:

conv[{{1,2,3,4,5,6,7,8,9,10}}] // Normal

Create a two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with 3 input channels and 1 output channel that applies a Gaussian blur:

kernel=Table[GaussianMatrix[5],1,3];
conv=ConvolutionLayer["Weights"->kernel,"Biases"-> None,"Input"->NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

Create a two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) composed of per-channel Gaussian kernels. First create the kernels:

zero=ConstantArray[0,{19,19}];
kernel=Table[If[i==j,GaussianMatrix[{9,6-3i}],zero],{i,0,2},{j,0,2}];

Visualize the kernels:

Map[ArrayPlot[#,ImageSize->30]&,kernel,{2}]//GraphicsGrid

Initialize a net using the kernels:

conv=ConvolutionLayer["Weights"->kernel,"Biases"->None,"Input"->NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

Create a two-dimensional (RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) with a random kernel:

kernel=RandomVariate[NormalDistribution[],{3,3,5,5}];
conv=ConvolutionLayer["Weights"->kernel,"Biases"-> None,"Input"->NetEncoder["Image"],"Output"->NetDecoder["Image"]]

Apply the layer to an image:

conv[]

OpenersExampleSection3(Spacer1)Properties & Relations  (2)

The following function computes the size of the non-channel dimensions, given the input size and parameters:

outputSize[inputSize_List,kernSize_,stride_,pad_,dilate_]:=Floor[(inputSize+2*pad-(dilate*(kernSize-1)+1))/stride]+1

The output size of an input of size {256,252}, a kernel size of {2,3}, a stride of 2, a dilation factor of {3,4}, and a padding size of {1,2}:

outputSize[{256,252},{2,3},2,{1,2},{3,4}]

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) can be used to compute two-dimensional convolutions:

kernel={{10,1},{1,3}};
data={{1,2,3},{4,5,6},{7,8,9}};
ConvolutionLayer[1,"Weights"->{{kernel}},"Biases"-> {0}][{data}]//First // Normal

This is equivalent to (RefLink[ListConvolve, paclet:ref/ListConvolve]) after reversing the kernel:

ListConvolve[Reverse[kernel,{1,2}],data]

OpenersExampleSection4(Spacer1)Possible Issues  (3)

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) cannot be initialized until all its input and output dimensions are known:

NetInitialize@ConvolutionLayer[3,{2,2}]

NetInitialize@ConvolutionLayer[3,2,"Input"->{5,23,25}]

(RefLink[ConvolutionLayer, paclet:ref/ConvolutionLayer]) cannot accept symbolic inputs:

conv=NetInitialize@ConvolutionLayer[1,{1,1},"Input"-> {1,1,1}];
conv[{{{1}}}]

conv[{{{x}}}]

The kernel size cannot be larger than the input dimensions:

ConvolutionLayer[3,{15,15},"Input"->{3,10,10}]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[DeconvolutionLayer, paclet:ref/DeconvolutionLayer])  ▪  (RefLink[PoolingLayer, paclet:ref/PoolingLayer])  ▪  (RefLink[BatchNormalizationLayer, paclet:ref/BatchNormalizationLayer])  ▪  (RefLink[LocalResponseNormalizationLayer, paclet:ref/LocalResponseNormalizationLayer])  ▪  (RefLink[NetChain, paclet:ref/NetChain])  ▪  (RefLink[NetGraph, paclet:ref/NetGraph])  ▪  (RefLink[NetInitialize, paclet:ref/NetInitialize])  ▪  (RefLink[NetTrain, paclet:ref/NetTrain])  ▪  (RefLink[NetExtract, paclet:ref/NetExtract])  ▪  (RefLink[Ramp, paclet:ref/Ramp])  ▪  (RefLink[SpatialTransformationLayer, paclet:ref/SpatialTransformationLayer])  ▪  (RefLink[NetEncoder, paclet:ref/NetEncoder])}, {Related Net Encoders:  (RefLink[Image, paclet:ref/netencoder/Image])  ▪  (RefLink[Image3D, paclet:ref/netencoder/Image3D])  ▪  (RefLink[Audio, paclet:ref/netencoder/Audio])}})}})

({{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])}})}})