function net = resnetLayers(inputSize, numClasses, options)
% 

%   Copyright 2021-2023 The MathWorks, Inc.

arguments
    inputSize {mustBeNumeric,mustBeInteger,mustBePositive,iMustBeValidInputSize(inputSize)}
    numClasses (1,1) {mustBeNumeric,mustBeInteger,mustBePositive}
    options.InitialFilterSize (1,2) {mustBeNumeric,mustBeInteger,mustBePositive} = 7
    options.InitialNumFilters(1,1) {mustBeNumeric,mustBeInteger,mustBePositive} = 64
    options.InitialStride (1,2) {mustBeNumeric,mustBeInteger,mustBePositive} = 2
    options.InitialPoolingLayer (1,:) char = 'max'
    options.ResidualBlockType (1,:) char = 'batchnorm-before-add'
    options.BottleneckType (1,:) char = 'downsample-first-conv'
    options.StackDepth (1,:) {mustBeNumeric,mustBeInteger,mustBePositive} = [3 4 6 3]
    options.NumFilters (1,:) {mustBeNumeric,mustBeInteger,mustBePositive} = [64 128 256 512]
    options.Normalization (1,:) char = 'zerocenter'
end

try
    builder = deep.internal.util.Resnet2dBuilder;
    builder.Delimiter = '_';
    dlnet = createNetwork(builder,inputSize,numClasses,options);
    lgraph = layerGraph(dlnet);
    lgraph = addLayers(lgraph, classificationLayer('Name','output'));
    net = connectLayers(lgraph,'softmax','output');
catch ex
    throw(ex);
end
end

%% Helper functions

function iMustBeValidInputSize(inputSize)
if ~iIsRowVectorOfTwoOrThree(inputSize)
    error(message('nnet_cnn:resnetLayers:InvalidImageSize2D'));
end
end

function tf = iIsRowVectorOfTwoOrThree(x)
tf = isrow(x) && (numel(x)==2 || numel(x)==3);
end
