def image_predict_proba(self, X):
        """
        Predicts class probabilities for the entire image.

        Parameters:
        -----------

        X: array, shape = [n_samples, n_pixels_x, n_pixels_y, n_bands]
            Array of training images

        y: array, shape = [n_samples] or [n_samples, n_pixels_x, n_pixels_y, n_classes]
            Target probabilities
        """
        self._check_image(X)

        probabilities = self.pixel_classifier.image_predict_proba(X)

        patches, _ = self._to_patches(probabilities)

        row_steps = self._image_size[0] // self.patch_size[0]
        col_steps = self._image_size[1] // self.patch_size[1]

        ps = self.patch_size[0] * self.patch_size[1]

        # how can this be optimised?
        for i, j, k in itertools.product(range(row_steps), range(col_steps), range(self._samples)):
            patches[k, i, j, 0] = np.sum(patches[k, i, j, 0]) / ps
            patches[k, i, j, 1] = np.sum(patches[k, i, j, 1]) / ps

        return probabilities