function [map, featureMap, featureImportance] = imageLIME(varargin)
% imageLIME  Explain network predictions using LIME
%
%   map = imageLIME(net, X, labels) computes a map of the change in
%   classification score for the specified class labels using the
%   locally-interpretable model-agnostic explanation (LIME) technique.
%   net can be a SeriesNetwork object or a DAGNetwork object object. This 
%   function requires Statistics and Machine Learning Toolbox.
%
%   The function divides the input data X into features and generates
%   samples of synthetic observations as copies of X with features
%   removed at random. The synthetic data is used to fit an interpretable
%   model that approximates the behavior of the network. The
%   interpretable model is used to compute a map of the relative
%   importance of the features in X. You can use the map to identify the
%   parts of an image that most impact the classification.
%
%   map(i,j) corresponds to the importance of a feature at pixel (i,j) to
%   the interpretable model. If you provide labels as a vector of
%   categoricals, char vectors, or strings, then map(:,:,k) corresponds
%   to the map for labels(k).
%
%   map = imageLIME(net, X, channel) computes a map of the change in total
%   activation using the last compatible layer of net and the specified 
%   channel. Use this syntax for nonclassification tasks such as 
%   regression. The software computes the total activation 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 imageLIME technique to
%   nonclassification tasks. The network must be a dlnetwork, and the
%   function will automatically choose the layer to compute the saliency
%   maps. This layer can be set using net.OutputNames = "layerName".
%
%   [map, featureMap, featureImportance] = imageLIME(net, X, labels)
%   additionally returns a map of the features used to fit the
%   interpretable model and the calculated importance of each feature.
%   For each pixel (i,j) in the input image, idx = featureMap(i,j) is an
%   integer corresponding to the index of the feature containing that
%   pixel. The corresponding importance of the feature is given by
%   featureImportance(idx). If you provide labels as a vector of
%   categoricals, char vectors, or strings, then featureImportance(idx,k)
%   corresponds to the importance of feature idx for labels(k).
%
%   [...] = imageLIME(__, Name, Value) specifies additional options for the
%   computation using one or more name-value pair arguments:
%
%       'NumFeatures'  - Approximate number of features to divide the image
%                        into. The exact number of features depends on the
%                        image and value of 'Segmentation', and can be
%                        smaller than this value. A larger value gives
%                        more, smaller features, and require a larger
%                        'NumSamples' to give the best results. When
%                        'Segmentation' is 'superpixels' or 'grid', the
%                        default value is 49. When 'Segmentation' is a
%                        numeric matrix, the default value is the number of
%                        unique elements in the numeric matrix.
%       'NumSamples'   - Number of synthetic observations to randomly
%                        generate. A larger value gives better results but
%                        takes more time to compute. The default value is
%                        2048.
%       'Segmentation' - Method for dividing the image into features,
%                        specified as one of the following:
%                        - 'superpixels'. Segment image into superpixel
%                          features, using the SUPERPIXELS function.
%                          Requires Image Processing Toolbox. This is the
%                          default.
%                        - 'grid'. Segment image into a grid of
%                          approximately square features based on the image
%                          aspect ratio. Depending on the size and shape of
%                          the image, the number of grid cells can be
%                          smaller than the specified value of
%                          'NumFeatures'. If the image is square, specify
%                          NumFeatures as a square number.
%                        - numeric matrix. Segment image into custom
%                          features using the numeric matrix as a map where
%                          the integer value of each pixel specifies the
%                          feature of the corresponding pixel. 'NumFeatures'
%                          is the same as the number of unique elements in
%                          the matrix. The size of the matrix must match the
%                          size of the input image.
%       'Model'        - Interpretable model used to approximate the
%                        network classification behavior using the
%                        synthetic data, specified as one of the following:
%                        - 'tree'. Fit a regression tree using FITRTREE,
%                          then compute the importance of each feature with
%                          PREDICTORIMPORTANCE. This is the default.
%                        - 'linear'. Fit a linear model with lasso
%                          regression using FITRLINEAR, then compute the
%                          importance of each feature using the weights of
%                          the linear model.
%       'OutputUpsampling'
%                      - Method for upsampling the output map when
%                        'Segmentation' is 'grid', specified as one of the
%                        following:
%                        - '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
%                           grid of features. This is the default.
%                        - '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.
%                        - 'none'. The map is not upsampled and can be
%                           smaller than the size of the input data.
%       'MiniBatchSize' - The size of the mini-batches of synthetic data
%                         passed to the network. Larger mini-batch sizes
%                         lead to faster computation, at the cost of more
%                         memory. The default value 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.
%
%   Example:
%       % Load pretrained network
%       net = googlenet;
%
%       % Load image
%       X = imresize(imread("sherlock.jpg"),[224 224]);
%       label = "golden retriever";
%
%       % Compute LIME map
%       map = imageLIME(net,X,label);
%       imshow(X);
%       hold on;
%       colormap jet;
%       imagesc(map,'AlphaData',0.5);
%
%   See also gradCAM, occlusionSensitivity, deepDreamImage

% References:
%   Ribeiro, Marco Tulio, Sameer Singh, and Carlos Guestrin. "'Why Should I
%   Trust You?': Explaining the Predictions of Any Classifier."
%   ArXiv:1602.04938 [Cs, Stat], August 9, 2016.
%   http://arxiv.org/abs/1602.04938.

% Copyright 2019-2023 The MathWorks, Inc.

narginchk(3,Inf);

factory = deep.internal.viz.lime.factory.ImageLIMEFactory();

try
    [map, featureMap, featureImportance] = deep.internal.viz.lime.computedeepLIME(factory,varargin{:});
catch err
    throw(err);
end

end
