/// <summary>
        /// Implementation of <see cref="ChestXRayAIClient.Analyze(SKBitmap, CancellationToken)"/> using a single model.
        /// </summary>
        public override Task <(ScoreOutput[], CAM[])> Analyze(SKBitmap inputImage, CancellationToken cancellationToken)
        {
            ValidateImageDimensions(inputImage);

            return(Task.Factory.StartNew(() =>
            {
                // We have to check for cancellation before each of the following steps

                // Pass the image to the model and run an inference on it
                cancellationToken.ThrowIfCancellationRequested();
                float[][] modelOutputs = model.Predict(inputImage);

                // Extract the score data and package it up into a convenient object array (ScoreOutput[])
                cancellationToken.ThrowIfCancellationRequested();
                float[] scoreData = modelOutputs[0];
                ScoreOutput[] scores = GenerateScoreArray(scoreData);

                // Extract the CAM data and post-process it to generate the CAM objects
                cancellationToken.ThrowIfCancellationRequested();
                float[] camData = modelOutputs[1];
                CAM[] cams = GenerateCAMArray(camData);

                // Final cancellation check
                cancellationToken.ThrowIfCancellationRequested();

                return (scores, cams);
            }, cancellationToken));
        }
        private Task <ScoreOutput[]> GetScores(SKBitmap inputImage, CancellationToken cancellationToken)
        {
            return(Task.Factory.StartNew(() =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                float[] scoreModelOutput = scoreModel.Predict(inputImage);

                cancellationToken.ThrowIfCancellationRequested();

                ScoreOutput[] scores = GenerateScoreArray(scoreModelOutput);

                cancellationToken.ThrowIfCancellationRequested();

                return scores;
            }, cancellationToken));
        }
        private Task <CAM[]> GetCAMs(SKBitmap inputImage, CancellationToken cancellationToken)
        {
            return(Task.Factory.StartNew(() =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                float[] camModelOutput = camModel.Predict(inputImage);

                cancellationToken.ThrowIfCancellationRequested();

                CAM[] cams = GenerateCAMArray(camModelOutput);

                cancellationToken.ThrowIfCancellationRequested();

                return cams;
            }, cancellationToken));
        }