def __init__(
        self,
        classifiers: "CLASSIFIER_NEURALNETWORK_TYPE" | list["CLASSIFIER_NEURALNETWORK_TYPE"],
        hash_function: Callable | None = None,
        ensemble_size: int = 50,
        channels_first: bool = False,
        clip_values: "CLIP_VALUES_TYPE" | None = None,
        preprocessing_defences: "Preprocessor" | list["Preprocessor"] | None = None,
        postprocessing_defences: "Postprocessor" | list["Postprocessor"] | None = None,
        preprocessing: "PREPROCESSING_TYPE" = (0.0, 1.0),
    ) -> None:
        """
        :param classifiers: The base model definition to use for defining the ensemble.
               If a list, the list must be the same size as the ensemble size.
        :param hash_function: The function used to partition the training data. If empty, the hash function
               will use the sum of the input values modulo the ensemble size for partitioning.
        :param ensemble_size: The number of models in the ensemble.
        :param channels_first: Set channels first or last.
        :param clip_values: Tuple of the form `(min, max)` of floats or `np.ndarray` representing the minimum and
               maximum values allowed for features. If floats are provided, these will be used as the range of all
               features. If arrays are provided, each value will be considered the bound for a feature, thus
               the shape of clip values needs to match the total number of features.
        :param preprocessing_defences: Preprocessing defence(s) to be applied by the classifier. Not applicable
               in this classifier.
        :param postprocessing_defences: Postprocessing defence(s) to be applied by the classifier.
        :param preprocessing: Tuple of the form `(subtrahend, divisor)` of floats or `np.ndarray` of values to be
               used for data preprocessing. The first value will be subtracted from the input. The input will then
               be divided by the second one. Not applicable in this classifier.
        """
        self.can_fit = False  # self.fit() cannot be used with models loaded from disk
        if not isinstance(classifiers, list):
            warnings.warn(
                "If a single classifier is passed, it should not have been loaded \
                from disk due to cloning errors with models loaded from disk. If you are \
                using pre-trained model(s), create a list of Estimator objects the same \
                length as the ensemble size"
            )
            self.can_fit = True

            if hasattr(classifiers, "clone_for_refitting"):
                # Initialize the ensemble based on the provided architecture
                # Use ART's cloning if possible
                try:
                    classifiers = [classifiers.clone_for_refitting() for _ in range(ensemble_size)]  # type: ignore
                except ValueError as error:
                    warnings.warn("Switching to deepcopy due to ART Cloning Error: " + str(error))
                    classifiers = [copy.deepcopy(classifiers) for _ in range(ensemble_size)]  # type: ignore
            else:
                classifiers = [copy.deepcopy(classifiers) for _ in range(ensemble_size)]
        elif isinstance(classifiers, list) and len(classifiers) != ensemble_size:
            raise ValueError("The length of the classifier list must be the same as the ensemble size")

        super().__init__(
            classifiers=classifiers,
            clip_values=clip_values,
            channels_first=channels_first,
            preprocessing_defences=preprocessing_defences,
            postprocessing_defences=postprocessing_defences,
            preprocessing=preprocessing,
        )

        if hash_function is None:

            def default_hash(x):
                return int(np.sum(x)) % ensemble_size

            self.hash_function = default_hash
        else:
            self.hash_function = hash_function

        self.ensemble_size = ensemble_size

        :param classifiers: The base model definition to use for defining the ensemble.
               If a list, the list must be the same size as the ensemble size.
        :param hash_function: The function used to partition the training data. If empty, the hash function
               will use the sum of the input values modulo the ensemble size for partitioning.
        :param ensemble_size: The number of models in the ensemble.
        :param channels_first: Set channels first or last.
        :param clip_values: Tuple of the form `(min, max)` of floats or `np.ndarray` representing the minimum and
               maximum values allowed for features. If floats are provided, these will be used as the range of all
               features. If arrays are provided, each value will be considered the bound for a feature, thus
               the shape of clip values needs to match the total number of features.
        :param preprocessing_defences: Preprocessing defence(s) to be applied by the classifier. Not applicable
               in this classifier.
        :param postprocessing_defences: Postprocessing defence(s) to be applied by the classifier.
        :param preprocessing: Tuple of the form `(subtrahend, divisor)` of floats or `np.ndarray` of values to be
               used for data preprocessing. The first value will be subtracted from the input. The input will then
               be divided by the second one. Not applicable in this classifier.
        
art/estimators/classification/deep_partition_ensemble.py