주요 콘텐츠

Complex-Valued Neural Networks

R2026b

Complex numbers are a useful and natural way of expressing data in many scientific and engineering domains, such as wireless communications or quantum mechanics. To model data in these domains, build and train neural networks with complex-valued inputs, outputs, and learnable parameters.

Since R2024a, the trainnet function, the dlgradient function, the automatic differentiation framework, and many layers, solvers, and metrics support complex numbers. You can build and train a complex-valued neural network in the same way you would build and train a real-valued neural network.

An alternative approach is to split the data into real and imaginary parts and treat them as two separate real-valued input channels. Use this approach in these circumstances:

  • You are using a release that is older than R2024a.

  • Your solver or network architecture does not support complex numbers.

  • The next steps in your workflow do not support complex-valued neural networks. For example, formal verification, compression, and code generation do not support complex-valued neural networks.

For more information, see Split Input Data Into Real and Imaginary Components. For an example of this approach, see Train Network with Complex-Valued Data.

Supported Layers

There are two types of layers that support complex-valued input and output data:

  • Layers that do not have learnables and use the same algorithm for both real and complex values, and that therefore support both real and complex input data; for example, additionLayer

  • Dedicated complex layers that have learnables or that require a specific, complex algorithm; for example, complexConvolution1dLayer

Since R2024a, unless otherwise indicated, these layers support complex-valued data.

Input Layers

inputLayer

An input layer inputs unformatted data or data with a custom format into a neural network.

imageInputLayer

An image input layer inputs 2-D images to a neural network and applies data normalization.

image3dInputLayer

A 3-D image input layer inputs 3-D images or volumes to a neural network and applies data normalization.

sequenceInputLayer

A sequence input layer inputs sequence data to a neural network and applies data normalization.

featureInputLayer

A feature input layer inputs feature data to a neural network and applies data normalization. Use this layer when you have a data set of numeric scalars representing features (data without spatial or time dimensions).

Convolution and Fully Connected Layers

complexFullyConnectedLayer (since R2026a)

A complex fully connected layer multiplies the input by a complex weight matrix and then adds a complex bias vector.

complexConvolution1dLayer (since R2026b)

A complex 1-D convolutional layer applies sliding complex convolutional filters to 1-D input.

complexConvolution2dLayer (since R2026b)

A complex 2-D convolutional layer applies sliding complex convolutional filters to 2-D input.

Sequence Layers

flattenLayer

A flatten layer collapses the spatial dimensions of the input into the channel dimension.

Activation Layers

tanhLayer

A hyperbolic tangent (tanh) activation layer applies the tanh function on the layer inputs.

functionLayer

A function layer applies a specified function to the layer input.

complexReluLayer (since R2025a)

A complex ReLU layer performs a threshold operation to the real and imaginary parts of the input, where any value less than zero is set to zero.

zreluLayer (since R2026a)

A zReLU layer performs a threshold operation to complex inputs, where any value with negative real or imaginary part is set to zero.

Utility Layers

dropoutLayer

A dropout layer randomly sets input elements to zero with a given probability.

scalingLayer

A scaling layer linearly scales and offsets the input data.

crop2dLayer

A 2-D crop layer applies 2-D cropping to the input.

crop3dLayer

A 3-D crop layer crops a 3-D volume to the size of the input feature map.

complexToRealLayer (since R2024b)

A complex-to-real layer converts complex-valued data to real-valued data by splitting the data in a specified dimension.

realToComplexLayer (since R2024b)

A real-to-complex layer converts real-valued data to complex-valued data by merging the data in a specified dimension.

Pooling Layers

globalAveragePooling1dLayer

A 1-D global average pooling layer performs downsampling by outputting the average of the time or spatial dimensions of the input.

globalAveragePooling2dLayer

A 2-D global average pooling layer performs downsampling by computing the mean of the height and width dimensions of the input.

globalAveragePooling3dLayer

A 3-D global average pooling layer performs downsampling by computing the mean of the height, width, and depth dimensions of the input.

Combination Layers

additionLayer

An addition layer adds inputs from multiple neural network layers element-wise.

multiplicationLayer

A multiplication layer multiplies inputs from multiple neural network layers element-wise.

concatenationLayer

A concatenation layer takes inputs and concatenates them along a specified dimension. The inputs must have the same size in all dimensions except the concatenation dimension.

depthConcatenationLayer

A depth concatenation layer takes inputs that have the same height and width and concatenates them along the channel dimension.

Supported Solvers

To choose a solver, specify the solverName argument of the trainingOptions function.

There are two types of solvers in Deep Learning Toolbox™: stochastic solvers and batch solvers. Only stochastic solvers support complex-valued gradients.

SolverDescriptionSyntax
SGDMStochastic gradient descent with momentumtrainingOptions("sgdm",...)
RMSPropRoot mean square propagationtrainingOptions("rmsprop",...)
AdamAdaptive moment estimationtrainingOptions("adam",...)

Supported Metrics and Loss Functions

Since R2026a, these built-in metrics support complex-valued network outputs:

  • "mae"/"mean-absolute-error"/"l1loss" — Mean absolute error for regression tasks

  • "mse"/"mean-squared-error"/"l2loss" — Mean squared error for regression tasks

You can also define custom metrics that support complex-valued network outputs. To learn more about defining custom metrics, see Define Custom Metric Function.

Supported Functions

Every function listed in MATLAB Functions with dlarray Support supports complex-valued dlarray inputs, provided the underlying function supports complex-valued inputs.

Additionally, these functions support complex-valued dlarray objects as inputs:

dlgradient

Compute gradients for custom training loops using automatic differentiation

fullyconnect (since R2026a)

Sum all weighted input data and apply a bias

l1loss (since R2026a)

L1 loss for regression tasks

l2loss (since R2026a)

L2 loss for regression tasks

Choose Complex Activation Layer

Choosing activation layers can affect the performance of a neural network. For an example showing how to choose an activation layer, see Compare Activation Layers.

Creating an equivalent complex-valued layer for a real-valued activation layer might not be straightforward. For example, the original layer might have more than one complex equivalent, as is the case for the ReLU layer. The algorithm of the ReLU operation cannot be applied directly to complex numbers because it assumes that the data is ordered. Instead, there are several different complex algorithms for ReLU. Deep Learning Toolbox contains two built-in complex ReLU layers:

  • zReLU — A zreluLayer object performs a threshold operation to complex inputs, where the layer sets any value with a negative real or imaginary part to zero. For example, -1 + 2i results in 0, because the real part is negative. 1 - 2i results in 0, because the imaginary part is negative. 1 + 2i results in 1 + 2i, because both the real and the imaginary part are positive.

  • Complex ReLU — A complexReluLayer object performs a threshold operation on the real and imaginary parts of the input separately, where the layer sets any negative value to zero. For example, -1 + 2i results in 0 + 2i. 1 - 2i results in 1 + 0i.

Even if you can apply a layer to complex numbers, it might still behave differently than when you apply it to real numbers. For example, the swish operation is defined as f(x)=x1+e−x. For complex numbers, this function oscillates and has poles, where the denominator is equal to zero and the function diverges.

Create Custom Complex Layer

To create a custom layer that supports complex-valued input data, follow the same process as you would to create a custom layer that supports only real-valued data, but specify only operations that support complex numbers. To learn how to create custom layers, see Define Custom Deep Learning Layers.

For example, to create a complex-valued swish activation layer that applies the swish activation function separately to the real and imaginary parts of the input, use this code.

classdef complexSwishLayer < nnet.layer.Layer & nnet.layer.Acceleratable
% complexSwishLayer   Complex-valued swish activation layer
%
%   A complex swish layer applies the swish activation function
%   separately to the real and imaginary parts of the input:
%
%       complexSwish(a + ib) = swish(a) + i*swish(b),
%
%   where swish(x) = x / (1 + exp(-x)).

    methods
        function layer = complexSwishLayer(args)
            arguments
                args.Name = "";
            end

            layer.Name = args.Name;
            layer.Description = "Complex Swish";
        end

        function Z = predict(~, X)
            Z = complex(swish(real(X)),swish(imag(X)));
        end
    end
end

function Y = swish(X)
    Y = X ./ (1 + exp(-X));
end

Define Complex Backward Function

Note

Defining the backward function is optional and rarely needed. If you do not specify a backward function, and the layer forward functions support dlarray objects, then the software determines the complex backward function using automatic differentiation. For a list of functions that support dlarray objects, see List of Functions with dlarray Support.

Define a custom backward function when you want to:

  • Use a specific algorithm to compute the derivatives.

  • Use operations in the forward functions that do not support dlarray objects.

  • Customize the backward function at points where the derivative is not defined. For example, the ReLU operation has a discontinuity at x=0. By default, the software sets the gradient to 0 at the discontinuity. To choose a different value, create a custom ReLU layer and use a custom backward function.

The definition of the gradient for the backward function is different for complex-valued layers than for real-valued layers.

When training a neural network, compute the complex gradients by using the conjugate Wirtinger derivative. This derivative points in the direction of the steepest ascent in the complex plane:

gradient(f(z))=2dfdz*=dfdℜ(z)+idfdℑ(z) .

The dlgradient function returns twice the value of the conjugate Wirtinger derivative. However, the loss must be real, so dLdz*=(dLdz)*. MATLAB® computes the nonconjugate Wirtinger derivative during backpropagation and applies a complex conjugate at the end. Therefore, to implement a custom complex backward function, implement the nonconjugate Wirtinger derivative of the loss function:

dLdx=∑jdyjdx·dLdyj+dyj*dx·(dLdyj)* .

For more information on how to implement custom backward functions, see Backward Function.

Resolve Unintended Complex Gradients

Backpropagation can cause complex gradients to flow into layers that do not support complex numbers. In that situation, you might see an error message like this: Encountered complex value when computing gradient with respect to an output of fullyConnectedLayer. Convert all outputs of fullyConnectedLayer to real.

To resolve this error, add calls to the real function before the layer that returns complex gradients.

If complex gradients propagate back into a layer from a complex layer, add a function layer before the complex layer:

layers = [
    featureInputLayer(10)
    fullyConnectedLayer(10)
    functionLayer(@real) % add function layer
    complexReluLayer
    complexToRealLayer];

If complex gradients propagate inside a custom loss function, add a call to the real function in the loss function:

function [loss,grad] = customLoss(X)
    loss = imag(sigmoid(X));
    loss = real(loss); % add call to real
    loss = sum(loss,"all")
    grad = dlgradient(loss,X);
end

Split Input Data Into Real and Imaginary Components

If you cannot use a complex-valued neural network, then an alternative approach is to split the data into real and imaginary parts and treat them as two separate real-valued input channels.

Before R2024a, split the data into real and imaginary parts before giving it to the neural network by using the real and imag functions.

In R2024a, if a network starts with one of these input layers, set the SplitComplexInputs name-value argument to true:

After R2024b, add a complexToRealLayer layer after the input layer instead.

After R2024b, if most of a neural network supports complex-valued data, and only a subsection of the network does not, then you can wrap that subsection in complexToRealLayer and realToComplexLayer objects. For example:

layers = [...
inputLayer(inputSize), ...
layerThatSupportsComplex1, ...
layerThatSupportsComplex2, ...

% more layers

complexToRealLayer, ...
layerThatDoesNotSupportComplex, ...
realToComplexLayer, ...

% more layers
];

See Also

| | | | | |

Topics