Main Content

verifyNetworkRobustness

Verify adversarial robustness of MATLAB, ONNX, and PyTorch networks

Since R2022b

    Description

    Add-On Required: This feature requires the AI Verification Library for Deep Learning Toolbox add-on.

    dlnetwork robustness

    result = verifyNetworkRobustness(net,XLower,XUpper,label) verifies whether the network net is adversarially robust with respect to the class label when the input is between XLower and XUpper. For more information, see Adversarial Examples.

    A network is robust to adversarial examples for a specific input if the predicted class does not change when the input takes any value between XLower and XUpper. For more information, see Algorithms.

    example

    [result,detailedResult] = verifyNetworkRobustness(net,XLower,XUpper,label) also returns details of the verification results for each class. (since R2026a)

    result = verifyNetworkRobustness(___,Name=Value) verifies the adversarial robustness with additional options specified by one or more name-value arguments.

    ONNX and PyTorch network robustness

    Since R2026a

    This syntax requires the Deep Learning Toolbox Interface for alpha-beta-CROWN Verifier add-on.

    result = verifyNetworkRobustness(modelfile,XLower,XUpper,label,numClasses) verifies whether the pretrained ONNX™ or PyTorch® network in modelfile is adversarially robust with respect to the class label when the input is between XLower and XUpper and the network has numClasses. For more information, see Adversarial Examples.

    A network is robust to adversarial examples for a specific input if the predicted class does not change when the input takes any value between XLower and XUpper.

    result = verifyNetworkRobustness(___,Name=Value) verifies the adversarial robustness with additional options specified by one or more name-value arguments.

    example

    Examples

    collapse all

    Verify the adversarial robustness of an image classification network.

    Load a pretrained classification network. This network is a dlnetwork object that has been trained to predict the class label of images of handwritten digits.

    load("digitsRobustClassificationConvolutionNet.mat")

    Load the test data.

    [XTest,TTest] = digitTest4DArrayData;

    Select the first ten images.

    X = XTest(:,:,:,1:10);
    label = TTest(1:10);

    Convert the test data to a dlarray object.

    X = dlarray(X,"SSCB");

    Verify the network robustness to an input perturbation between –0.01 and 0.01 for each pixel. Create lower and upper bounds for the input.

    perturbation = 0.01;
    XLower = X - perturbation;
    XUpper = X + perturbation;

    Verify the network robustness for each test image.

    result = verifyNetworkRobustness(netRobust,XLower,XUpper,label);
    summary(result,Statistics="counts")
    result: 10×1 categorical
    
         verified      10 
         violated       0 
         unproven       0 
    

    Since R2026a

    Load a pretrained classification network. This network is a dlnetwork object that has been trained to predict the class label of images of handwritten digits.

    load("digitsRobustClassificationConvolutionNet.mat")

    Load the test data.

    [XTest,TTest] = digitTest4DArrayData;

    Randomly select images to test.

    idx = randi(numel(TTest),500,1);
    
    X = XTest(:,:,:,idx);
    labels = TTest(idx);

    Convert the test data to a dlarray object.

    X = dlarray(X,"SSCB");

    Verify the network robustness to an input perturbation between –0.01 and 0.01 for each pixel. Create lower and upper bounds for the input.

    perturbation = 0.1;
    XLower = X - perturbation;
    XUpper = X + perturbation;

    Verify the network robustness for each test image. For each observation, if the software is unable to guarantee that an adversarial example does not exists for any class or the other than the true class, then the result is "unproven" or "violated".

    [verificationResults,classVerificationResults] = verifyNetworkRobustness(netRobust,XLower,XUpper,labels,MiniBatchSize=32);
    summary(verificationResults,Statistics="counts")
    verificationResults: 500×1 categorical
    
         verified       38 
         violated        0 
         unproven      462 
    

    You can also see more detailed results of when an adversarial examples exists for each class. Visualize the detailed verification results for status "verified" using the helper function verificationMatrix.

    verificationMatrix(classVerificationResults,"verified");

    Figure contains an object of type heatmap. The chart of type heatmap has title Class-by-class verified results.

    Visualize the detailed verification results for status "violated" or "unproven" using the helper function verificationMatrix.

    verificationMatrix(classVerificationResults,["violated","unproven"]);

    Figure contains an object of type heatmap. The chart of type heatmap has title Class-by-class violated or unproven results.

    Helper Function

    Use the verificationMatrix to visualize the detailed results output of the verifyNetworkRobustness function.

    function verificationMatrix(detailedResults,verifiedStatus)
    
    % Initialize the verification matrix
    numClasses = size(detailedResults,2);
    vMat = zeros(numClasses);
    
    %  Calculate the verification matrix entries
    for ii = 1:numClasses
        missingIdx = ismissing(detailedResults(:, ii));
        v = 1:numClasses;
        v(ii) = [];
        classMatrix = detailedResults(missingIdx, v);
        tf = ismember(classMatrix, verifiedStatus);
        tfSum = sum(tf, 1);
        vMat(ii,v) = tfSum;
    end
    
    titleStatus = strjoin(verifiedStatus," or ");
    
    % Create a heatmap
    figure
    heatmap(vMat,Title="Class-by-class " + titleStatus + " results", ...
        XLabel="Adversarial Class", ...
        YLabel="True Class", ...
        ColorbarVisible="on");
    end
    

    Since R2026a

    Load a pretrained classification network.

    load("digitsRobustClassificationConvolutionNet.mat")

    Load the test data.

    [XTest,TTest] = digitTest4DArrayData;

    Randomly select images to test.

    idx = randi(numel(TTest),500,1);
    
    X = XTest(:,:,:,idx);
    labels = TTest(idx);

    Convert the test data to a dlarray object.

    X = dlarray(X,"SSCB");

    Verify the network robustness to an input perturbation between –0.01 and 0.01 for each pixel. Create lower and upper bounds for the input.

    perturbation = 0.01;
    XLower = X - perturbation;
    XUpper = X + perturbation;

    Create an AlphaCROWN options object. Optimize the interval and optimize over the average objective.

    opts = alphaCROWNOptions(InitialLearnRate=0.9,MaxEpochs=20, ...
        Objective="interval", ...
        ObjectiveMode="average", ...
        Verbose=true);

    Verify the network robustness for each test image.

    result = verifyNetworkRobustness(netRobust,XLower,XUpper,labels,Algorithm=opts);
    Number of mini-batches to process: 4
    .... (4 mini-batches)
    Total time = 242.6 seconds.
    
    summary(result,Statistics="counts")
    result: 500×1 categorical
    
         verified      493 
         violated        2 
         unproven        5 
    

    Since R2026a

    Load a pretrained classification network. This network is a PyTorch® model that has been trained to predict the class label of images of handwritten digits.

    modelfile = "digitsClassificationConvolutionNet.pt";

    Load the test data and select the first 20 images.

    [XTest,TTest] = digitTest4DArrayData;
    X = XTest(:,:,:,1:20);
    labels = TTest(1:20);

    Verify the network robustness to an input perturbation between –0.01 and 0.01 for each pixel. Create lower and upper bounds for the input.

    perturbation = 0.01;
    XLower = X - perturbation;
    XUpper = X + perturbation;

    Create a custom network verification options object to use the "crown" algorithm with 100 projected gradient descent (PGD) restarts.

    options = networkVerificationOptions(GeneralCompleteVerifier="skip",...
        SolverBoundPropMethod="crown",...
        AttackPgdRestarts=100);

    Verify the network robustness for each test image with the created network verification options. Specify the input data permutation from MATLAB to Python® dimension ordering as [4 3 1 2] and number of classes as 10.

    numClasses = 10;
    result = verifyNetworkRobustness(modelfile,XLower,XUpper,labels,numClasses, ...
            Algorithm=options, ...
            InputDataPermutation=[4 3 1 2]);
    Warning: Starting and configuring the Python interpreter for the alpha-beta-CROWN verifier. This may take a few minutes.
    
    summary(result)
    result: 20×1 categorical
    
         verified          4 
         violated         13 
         unproven          3 
         <undefined>       0 
    

    Find the maximum adversarial perturbation that you can apply to an input without changing the predicted class.

    Load a pretrained classification network. This network is a dlnetwork object that has been trained to predict the class of images of handwritten digits.

    load("digitsRobustClassificationConvolutionNet.mat")

    Load the test data.

    [XTest,TTest] = digitTest4DArrayData;

    Select a test image.

    idx = 3;
    X = XTest(:,:,:,idx);
    label = TTest(idx);

    Create lower and upper bounds for a range of perturbation values.

    perturbationRange = 0:0.005:0.1;
    
    for i = 1:numel(perturbationRange)
    XLower(:,:,:,i) = X - perturbationRange(i);
    XUpper(:,:,:,i) = X + perturbationRange(i);
    end

    Repeat the class label for each set of bounds.

    label = repmat(label,numel(perturbationRange),1);

    Convert the bounds to dlarray objects.

    XLower = dlarray(XLower,"SSCB");
    XUpper = dlarray(XUpper,"SSCB");

    Verify the adversarial robustness for each perturbation.

    result = verifyNetworkRobustness(netRobust,XLower,XUpper,label);
    plot(perturbationRange,result,"*")
    xlabel("Perturbation")

    Figure contains an axes object. The axes object with xlabel Perturbation contains a line object which displays its values using only markers.

    Find the maximum perturbation value for which the function returns verified.

    maxIdx = find(result=="verified",1,"last");
    maxPerturbation = perturbationRange(maxIdx)
    maxPerturbation = 
    0.0600
    

    Input Arguments

    collapse all

    Input lower bound, specified as a dlarray object or a numeric array.

    • If you provide a dlnetwork object as input, XLower must be a formatted dlarray object. For more information about dlarray formats, see the fmt input argument of dlarray.

    • If you provide an ONNX or PyTorch modelfile as input, XLower can be a numeric array or a dlarray object. See Input Dimension Ordering for more information.

    The lower and upper bounds, XLower and XUpper, must have the same size and format. The function computes the results across the batch ("B") dimension of the input lower and upper bounds.

    For ONNX and PyTorch networks, the batch dimension is the first dimension of the data after it is permuted to Python® dimension ordering.

    Input upper bound, specified as a formatted dlarray object or a numeric array.

    • If you provide a dlnetwork object as input, XUpper must be a formatted dlarray object. For more information about dlarray formats, see the fmt input argument of dlarray.

    • If you provide an ONNX or PyTorch modelfile as input, XUpper must be a numeric array.

    The lower and upper bounds, XLower and XUpper, must have the same size and format. The function computes the results across the batch ("B") dimension of the input lower and upper bounds.

    For ONNX and PyTorch networks, the batch dimension is the first dimension of the data after it is permuted to Python dimension ordering.

    Class label, specified as a numeric index or a categorical, or a vector of these values. The length of label must match the size of the batch ("B") dimension of the lower and upper bounds.

    The function verifies that the predicted class that the network returns matches label for any input in the range defined by the lower and upper bounds.

    Note

    If you specify label as a categorical, then the order of the categories must match the order of the outputs in the network.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | categorical

    dlnetwork only

    Network, specified as an initialized dlnetwork object. To initialize a dlnetwork object, use the initialize function.

    The function supports these layers:

    LayerNotes and Limitations

    additionLayer (since R2024b)

     

    averagePooling2dLayer (since R2023a)

    Supported when PaddingValue is set to 0.

    batchNormalizationLayer (since R2023a)

     

    clippedReluLayer (since R2026a)

     

    convolution2dLayer (since R2023a)

    Supported when Dilation is set to [1 1] or 1 and PaddingValue is set to 0.

    depthConcatenationLayer (since R2026a)

     

    dropoutLayer (since R2023a)

     

    featureInputLayer

    Supported when Normalization is set to "none" (since R2022b) or "zerocenter", "zscore", "rescale-symmetric", "rescale-zero-one" (since R2023a). Custom normalization functions are not supported.

    flattenLayer (since R2026a)

     

    fullyConnectedLayer

     

    globalAveragePooling2dLayer (since R2023a)

     

    globalMaxPooling2dLayer (since R2023a)

     

    identityLayer (since R2026a)

     

    imageInputLayer

    Supported when Normalization is set to "none" (since R2022b) or "zerocenter", "zscore", "rescale-symmetric", "rescale-zero-one" (since R2023a). Custom normalization functions are not supported.

    leakyReluLayer (since R2026a)

    You can optimize this layer using the α-CROWN algorithm.

    maxPooling2dLayer (since R2023a)

     

    nnet.onnx.layer.CustomOutputLayer (built-in ONNX layer) (since R2025a)

    Supported when DataFormat is set to "CB" or "SSCB". The data format is commonly set by the InputDataFormats and OutputDataFormats options of the importNetworkFromONNX function.

    nnet.onnx.layer.ElementwiseAffineLayer (built-in ONNX layer) (since R2023a)

     

    nnet.onnx.layer.FlattenInto2dLayer (built-in ONNX layer) (since R2025a)

     

    reluLayer

    You can optimize this layer using the α-CROWN algorithm.

    sigmoidLayer (since R2023a)

     

    tanhLayer

     

    The function does not support networks with multiple inputs and multiple outputs.

    The function verifies the network using the final layer. If your final layer is a softmax layer, then the function uses the penultimate layer instead as this provides better verification results. (since R2026a)

    Before R2026a: If your final layer is a softmax layer, then remove this layer before calling the function.

    ONNX or PyTorch only

    Since R2026a

    ONNX or PyTorch model file name specified as a character vector or a string scalar. The modelfile must be a full PyTorch model (saved using torch.save()) or an ONNX model with the .onnx extension.

    Note

    The Python classification network must be saved without a softmaxLayer in the output.

    Number of output classes specified as a numeric integer. This is the number of output classes in the pretrained ONNX or PyTorch network.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    Name-Value Arguments

    expand all

    Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

    Example: verifyNetworkRobustness(net,XLower,XUpper,label,MiniBatchSize=32,ExecutionEnvironment="multi-gpu") verifies the network robustness using a mini-batch size of 32 and using multiple GPUs.

    All Model Types

    expand all

    Since R2026a

    Verification algorithm, specified as one of these values:

    • "crown" — Use the CROWN algorithm [4]. This option is the same as using a NetworkVerificationOptions object with the default values if used with a ONNX or PyTorch network.

    • "alpha-crown" — Use the α-CROWN algorithm [6] with default options. This option is the same as using an AlphaCROWNOptions object with the default values if used with a dlnetwork.

    • "alpha-beta-crown" — Use the α-β-CROWN algorithm with default options. This option is only available with ONNX or PyTorch networks.

    • AlphaCROWNOptions object — Use the α-CROWN algorithm with custom options. Create an AlphaCROWNOptions object using the alphaCROWNOptions function. This option is only available with dlnetwork.

    • NetworkVerificationOptions object — Use the α-β-CROWN algorithm with custom options. Create a NetworkVerificationOptions object using the networkVerificationOptions function. This option is only available with ONNX or PyTorch networks.

    For more information, see CROWN, α-CROWN, and α,β-CROWN.

    The α-CROWN algorithm produces tighter bounds at the cost of longer computation times and higher memory requirements.

    Since R2024a

    Hardware resource, specified as one of these values:

    • "auto" – Use a local GPU if one is available. Otherwise, use the local CPU.

    • "cpu" – Use the local CPU.

    • "gpu" – Use the local GPU.

    • "multi-gpu" – Use multiple GPUs on one machine, using a local parallel pool based on your default cluster profile. If there is no current parallel pool, the software starts a parallel pool with pool size equal to the number of available GPUs. Only available when input is a dlnetwork object.

    • "parallel-auto" – Use a local or remote parallel pool. If there is no current parallel pool, the software starts one using the default cluster profile. If the pool has access to GPUs, then only workers with a unique GPU perform the computations and excess workers become idle. If the pool does not have GPUs, then the computations take place on all available CPU workers instead. Only available when input is a dlnetwork object.

    • "parallel-cpu" – Use CPU resources in a local or remote parallel pool, ignoring any GPUs. If there is no current parallel pool, the software starts one using the default cluster profile. Only available when input is a dlnetwork object.

    • "parallel-gpu" – Use GPUs in a local or remote parallel pool. Excess workers become idle. If there is no current parallel pool, the software starts one using the default cluster profile. Only available when input is a dlnetwork object.

    The "gpu", "multi-gpu", "parallel-auto", "parallel-cpu", and "parallel-gpu" options require Parallel Computing Toolbox™. To use a GPU for deep learning, you must also have a supported GPU device. For information on supported devices, see GPU Computing Requirements (Parallel Computing Toolbox). If you choose one of these options and Parallel Computing Toolbox or a suitable GPU is not available, then the software returns an error.

    For more information on when to use the different execution environments, see Scale Up Deep Learning in Parallel, on GPUs, and in the Cloud.

    Dependency

    If you specify Algorithm as an AlphaCROWNOptions object, then the execution environment specified in the options object takes precedence.

    dlnetwork only

    expand all

    Since R2023b

    Size of the mini-batch, specified as a positive integer.

    Larger mini-batch sizes require more memory, but can lead to faster computations.

    Dependency

    If you specify Algorithm as an AlphaCROWNOptions object, then the value of the mini-batch size in the options object takes precedence.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    Since R2026a

    Adversarial class label for verification, specified as a categorical scalar, numeric scalar, or [].

    The function verifies that the network is robust to adversarial inputs with the specified adversarial class label, between the specified lower and upper bounds. If AdversarialLabel is [], then the function verifies if the network is robust to adversarial inputs from each of the classes.

    Note

    If you specify the adversarial label as a categorical scalar, then the order of the categories must match the order of the outputs in the network.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | categorical

    Since R2026a

    Option to enable verbose output, specified as a numeric or logical 1 (true) or 0 (false). When you set this input to 1 (true), the function returns the progress of the algorithm by indicating which mini-batch the function is processing and the total number of mini-batches.

    Dependency

    If you specify Algorithm as an AlphaCROWNOptions object, then the verbose value specified in the options object takes precedence.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical

    ONNX or PyTorch only

    Since R2026a

    expand all

    Input dimension ordering specified as a numeric row vector. The ordering is the desired permutation of data in XLower and XUpper from MATLAB to Python dimension ordering. See Input Dimension Ordering for more information.

    Example: [4 3 1 2]

    Number of dimensions in input data specified as a positive integer.

    Example: 4

    Output Arguments

    collapse all

    Verification result, returned as an N-by-1 categorical array, where N is the number of observations. For each set of input lower and upper bounds, the function returns the corresponding element of this array as one of these values:

    • "verified" — The network is robust to adversarial inputs between the specified bounds.

    • "violated" — The network is not robust to adversarial inputs between the specified bounds.

    • "unproven" — Unable to prove whether the network is robust to adversarial inputs between the specified bounds.

    The function computes the results across the batch ("B") dimension of the input lower and upper bounds. If you supply k upper bounds, lower bounds, and labels, then result(k) corresponds to the verification result for the kth input lower and upper bounds. For more information, see Network Robustness.

    For an observation to return "verified", for each class different from the target class, there must not exist an adversarial example. To get a more granular result showing the verification status for each observation for each class, return detailedResult.

    Since R2026a

    Detailed verification result, returned as an N-by-C categorical array, where N is the number of observations and C is the number of classes.

    For each observation, the detailed results show the verification result for each observation, for each class. For example, detailedResult(i,j) indicates if there exists an adversarial example within the specified input bounds that causes the model to classify observation i as class j.

    Each element of detailedResultcan be one of these values:

    • "verified" — The network is robust to adversarial inputs between the specified bounds.

    • "violated" — The network is not robust to adversarial inputs between the specified bounds.

    • "unproven" — Unable to prove whether the network is robust to adversarial inputs between the specified bounds.

    • "<undefined>" — The adversarial class label is the same as the true class label, so the property to verify is invalid.

    For more information, see Network Robustness.

    Note

    This output is not available for ONNX or PyTorch networks.

    More About

    collapse all

    Algorithms

    collapse all

    References

    [1] Goodfellow, Ian J., Jonathon Shlens, and Christian Szegedy. “Explaining and Harnessing Adversarial Examples.” Preprint, submitted March 20, 2015. https://arxiv.org/abs/1412.6572.

    [2] Singh, Gagandeep, Timon Gehr, Markus Püschel, and Martin Vechev. “An Abstract Domain for Certifying Neural Networks”. Proceedings of the ACM on Programming Languages 3, no. POPL (January 2, 2019): 1–30. https://dl.acm.org/doi/10.1145/3290354.

    [3] Singh, Gagandeep, Timon Gehr, Markus Püschel, and Martin Vechev. “An Abstract Domain for Certifying Neural Networks.” Proceedings of the ACM on Programming Languages 3, no. POPL (January 2, 2019): 1–30. https://doi.org/10.1145/3290354.

    [4] Zhang, Huan, Tsui-Wei Weng, Pin-Yu Chen, Cho-Jui Hsieh, and Luca Daniel. “Efficient Neural Network Robustness Certification with General Activation Functions.” arXiv, 2018. https://doi.org/10.48550/ARXIV.1811.00866.

    [5] Xu, Kaidi, Zhouxing Shi, Huan Zhang, Yihan Wang, Kai-Wei Chang, Minlie Huang, Bhavya Kailkhura, Xue Lin, and Cho-Jui Hsieh. “Automatic Perturbation Analysis for Scalable Certified Robustness and Beyond.” arXiv, 2020. https://doi.org/10.48550/ARXIV.2002.12920.

    [6] Xu, Kaidi, Huan Zhang, Shiqi Wang, Yihan Wang, Suman Jana, Xue Lin, and Cho-Jui Hsieh. “Fast and Complete: Enabling Complete Neural Network Verification with Rapid and Massively Parallel Incomplete Verifiers.” arXiv, 2020. https://doi.org/10.48550/ARXIV.2011.13824.

    [7] Wang, Shiqi, Huan Zhang, Kaidi Xu, Xue Lin, Suman Jana, Cho-Jui Hsieh, and J. Zico Kolter. "Beta-crown: Efficient bound propagation with per-neuron split constraints for neural network robustness verification." Advances in neural information processing systems 34 (2021)

    Extended Capabilities

    expand all

    Version History

    Introduced in R2022b

    expand all