function map = occlusionSensitivity(varargin)
% occlusionSensitivity  Explain network predictions by occluding the inputs
%
%   map = occlusionSensitivity(net, X, labels) computes a map of the change
%   in classification score for the specified class labels when parts of
%   the input data X are occluded. The change in classification score is
%   relative to the score of the original data without occlusion. Areas in
%   the map with higher positive values correspond to regions of input data
%   that contribute more to the specified classification label. The network
%   must be a series network or a dag network.
%
%   The function moves an occluding mask across the input data, giving a
%   change in classification score value for each mask location. You can
%   use an occlusion map to identify the parts of an input image that most
%   impact the classification score. 
%
%   map(i,j) corresponds to the change in total activation at the specified
%   layer and channel at the spatial location (i,j). If channel is a
%   vector, then map(:,:,k) corresponds to the map for channel(k).
%
%   map = occlusionSensitivity(net, X, channel) computes a map of the change 
%   in total activation for the specified layer and channel  when parts of 
%   the input data X are occluded with a mask. The total activation is 
%   computed by summing over all spatial dimensions of the activation of
%   the specified channel. The total activation fulfills the role of the
%   class score for classification problems and generalizes the occlusion
%   sensitivity technique to nonclassification tasks. The network must be a 
%   dlnetwork. occlusionSensitivity will automatically choose the layer 
%   using the property OutputNames from dlnetwork. This layer can be
%   manually set by doing net.OutputNames = "layerName".
%
%   map = occlusionSensitivity(net, X, layerName, channel) computes a map
%   of the change in total activation for the specified layer and channel
%   when parts of the input data X are occluded with a mask. Use this
%   syntax for nonclassification tasks, such as regression, or for use with
%   a custom classification layer. The total activation is computed by
%   summing over all spatial dimensions of the activation of the specified
%   channel. The total activation fulfills the role of the class score for
%   classification problems and generalizes the occlusion sensitivity
%   technique to nonclassification tasks. The network can be a series
%   network or a dag network.
%
%   map = occlusionSensitivity(__, Name, Value) specifies additional
%   options for the computation using one or more name-value pair
%   arguments:
%
%     'MaskSize'  - Size of the occluding mask, specified as one of the
%                   following:
%                     - 'auto'. Use a mask size of 20 % of the input size 
%                       rounded to the nearest integer. Values below 1 are
%                       rounded to 1. This is the default.
%                     - A vector [h w], where h and w are the height and
%                       width of the mask, respectively.
%                     - A scalar which specifies both the height and width
%                       of the mask.
%     'Stride'    - Step size for traversing the mask across the input
%                   horizontally and vertically, specified as one of the
%                   following:
%                     - 'auto'. Use a stride of 10 % of the input size 
%                       rounded to the nearest integer. Values below 1 are 
%                       rounded to 1. This is the default.
%                     - A vector [h w], where h and w are the vertical and
%                       horizontal stride of the mask, respectively.
%                     - A scalar which specifies both the vertical and
%                       horizontal stride of the mask.
%     'MaskValue' - Value to replace occluded pixels with, specified as one
%                   of the following:
%                     - 'auto'. Replace occluded pixels with the
%                       channel-wise mean of the input data. This is the
%                       default.
%                     - A numeric scalar, a vector with a number of
%                       elements equal to C, or an array of size [1x1xC],
%                       where C is the number of channels in the input
%                       data. Every element of the mask is set to this
%                       value.
%     'OutputUpsampling'
%                  - Method for upsampling the output map, specified
%                    as one of the following:
%                     - 'bicubic'. The map is upsampled to the input data's
%                       spatial resolution with IMRESIZE using the
%                       'bicubic' method. This gives a smooth map the same
%                       size as the input data. This is the default.
%                     - 'nearest'. The map is upsampled to the input data's
%                       spatial resolution with IMRESIZE using the
%                       'nearest' method. The resulting map reflects the
%                       resolution of the occlusion computation.
%                     - 'none'. The map is not upsampled and can be smaller
%                       than the size of the input data.
%     'MaskClipping' 
%                   - Method for handling the interaction of the mask with
%                     the edge of the input data, specified as one of the
%                     following:
%                     - 'on'. The center of the first mask is placed at
%                       the top left of the input data. Masks at the edge
%                       of the data are not full size. This is the default.
%                     - 'off'. The top left corner of the first mask is
%                       aligned with the top left corner of the input data.
%                       Masks are always full size. If the values of 
%                       MaskSize and Stride mean that some masks extend 
%                       past the boundaries of the data, those masks are 
%                       excluded.
%     'MiniBatchSize'
%                   - The size of the mini-batches of occluded data passed
%                     to the network. Larger mini-batch sizes lead to faster
%                     computation, at the cost of more memory. The default
%                     is 128.
%     'ExecutionEnvironment'
%                  - Execution environment for the network. Hardware
%                    resources to use to run the computation, specified as
%                    one of the following:
%                     - 'auto'. Use a GPU if available, otherwise use
%                        the CPU. This is the default.
%                     - 'gpu'. Use the GPU. To use a GPU, you must
%                        have Parallel Computing Toolbox(TM) and a 
%                        supported GPU device. If a suitable GPU is not 
%                        available, the function returns an error.
%                     - 'cpu'. Use the CPU.
%
%   See also gradCAM, imageLIME, deepDreamImage

% References:
%   Zeiler M.D., Fergus R. (2014) Visualizing and Understanding
%   Convolutional Networks. In: Fleet D., Pajdla T., Schiele B., Tuytelaars
%   T. (eds) Computer Vision, ECCV 2014. ECCV 2014. Lecture Notes in
%   Computer Science, vol 8689. Springer, Cham

% Copyright 2019-2023 The MathWorks, Inc.

narginchk(3,Inf);

factory = deep.internal.viz.occlude.factory.Image2DOcclusionFactory();

try
    map = deep.internal.viz.occlude.computeOcclusionSensitivity(factory, varargin{:});
catch err
    throw(err);
end

end
