From 25bed7e14d3cea9c9ffc5ac62ae8d1377ffb32b5 Mon Sep 17 00:00:00 2001 From: Darius Couchard Date: Wed, 19 Jun 2024 12:51:24 +0200 Subject: [PATCH 1/4] Now writing GeoTiff and having two bands: binary mask and probabilities --- scripts/inference/cropland_mapping.py | 2 +- src/worldcereal/openeo/inference.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/inference/cropland_mapping.py b/scripts/inference/cropland_mapping.py index 03eb7d6c..0b39a6a9 100644 --- a/scripts/inference/cropland_mapping.py +++ b/scripts/inference/cropland_mapping.py @@ -107,7 +107,7 @@ classes.execute_batch( outputfile=args.output_path, - out_format="NetCDF", + out_format="GTiff", job_options={ "driver-memory": "4g", "executor-memoryOverhead": "12g", diff --git a/src/worldcereal/openeo/inference.py b/src/worldcereal/openeo/inference.py index e1adf289..73ffde86 100644 --- a/src/worldcereal/openeo/inference.py +++ b/src/worldcereal/openeo/inference.py @@ -50,7 +50,7 @@ def predict(self, features: np.ndarray) -> np.ndarray: binary_labels = np.array(prediction_values) >= threshold binary_labels = binary_labels.astype(int) - return binary_labels + return np.stack([binary_labels, prediction_values], axis=0).astype(np.float32) def execute(self, inarr: xr.DataArray) -> xr.DataArray: classifier_url = self._parameters.get("classifier_url", self.CATBOOST_PATH) @@ -67,9 +67,13 @@ def execute(self, inarr: xr.DataArray) -> xr.DataArray: self.logger.info(f"Classification done with shape: {classification.shape}") classification = xr.DataArray( - classification.reshape((1, len(x_coords), len(y_coords))), + classification.reshape((2, len(x_coords), len(y_coords))), dims=["bands", "x", "y"], - coords={"bands": ["classification"], "x": x_coords, "y": y_coords}, + coords={ + "bands": ["classification", "probability"], + "x": x_coords, + "y": y_coords, + }, ) return classification From ea4317af3720e300eacdb3003d0ac290755f0ca6 Mon Sep 17 00:00:00 2001 From: Darius Couchard Date: Wed, 19 Jun 2024 14:28:49 +0200 Subject: [PATCH 2/4] Missing label in output_labels --- src/worldcereal/openeo/inference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/worldcereal/openeo/inference.py b/src/worldcereal/openeo/inference.py index 73ffde86..32fbf323 100644 --- a/src/worldcereal/openeo/inference.py +++ b/src/worldcereal/openeo/inference.py @@ -28,7 +28,7 @@ def dependencies(self) -> list: return [] # Disable the dependencies from PIP install def output_labels(self) -> list: - return ["classification"] + return ["classification", "probability"] def predict(self, features: np.ndarray) -> np.ndarray: """ From 1166fa01209f26d880e13ce0a386843f89bb9b9d Mon Sep 17 00:00:00 2001 From: Darius Couchard Date: Thu, 20 Jun 2024 11:57:44 +0200 Subject: [PATCH 3/4] Now saves uint16 values with 0-1 for crop/no-crop and 0-100 for probabilities --- scripts/inference/cropland_mapping.py | 4 ++++ src/worldcereal/openeo/inference.py | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/inference/cropland_mapping.py b/scripts/inference/cropland_mapping.py index 0b39a6a9..3ff07e67 100644 --- a/scripts/inference/cropland_mapping.py +++ b/scripts/inference/cropland_mapping.py @@ -8,6 +8,7 @@ from openeo_gfmap.backend import Backend, BackendContext from openeo_gfmap.features.feature_extractor import apply_feature_extractor from openeo_gfmap.inference.model_inference import apply_model_inference +from openeo_gfmap.preprocessing.scaling import compress_uint16 from worldcereal.openeo.feature_extractor import PrestoFeatureExtractor from worldcereal.openeo.inference import CroplandClassifier @@ -105,6 +106,9 @@ ], ) + # Cast to uint16 + classes = compress_uint16(classes) + classes.execute_batch( outputfile=args.output_path, out_format="GTiff", diff --git a/src/worldcereal/openeo/inference.py b/src/worldcereal/openeo/inference.py index 32fbf323..cdfd2bf5 100644 --- a/src/worldcereal/openeo/inference.py +++ b/src/worldcereal/openeo/inference.py @@ -48,9 +48,12 @@ def predict(self, features: np.ndarray) -> np.ndarray: # Extract all prediction values and convert them to binary labels prediction_values = [sublist["True"] for sublist in outputs[1]] binary_labels = np.array(prediction_values) >= threshold - binary_labels = binary_labels.astype(int) + binary_labels = binary_labels.astype("uint8") - return np.stack([binary_labels, prediction_values], axis=0).astype(np.float32) + prediction_values = np.array(prediction_values) * 100.0 + prediction_values = np.round(prediction_values).astype("uint8") + + return np.stack([binary_labels, prediction_values], axis=0) def execute(self, inarr: xr.DataArray) -> xr.DataArray: classifier_url = self._parameters.get("classifier_url", self.CATBOOST_PATH) @@ -62,9 +65,9 @@ def execute(self, inarr: xr.DataArray) -> xr.DataArray: self.onnx_session = self.load_ort_session(classifier_url) # Run catboost classification - self.logger.info(f"Catboost classification with input shape: {inarr.shape}") + self.logger.info("Catboost classification with input shape: %s", inarr.shape) classification = self.predict(inarr.values) - self.logger.info(f"Classification done with shape: {classification.shape}") + self.logger.info("Classification done with shape: %s", inarr.shape) classification = xr.DataArray( classification.reshape((2, len(x_coords), len(y_coords))), From c14db9106187a0211e539cbad1bdaa5774a212a5 Mon Sep 17 00:00:00 2001 From: Darius Couchard Date: Thu, 20 Jun 2024 13:01:27 +0200 Subject: [PATCH 4/4] Went to uint8 --- scripts/inference/cropland_mapping.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/inference/cropland_mapping.py b/scripts/inference/cropland_mapping.py index 3ff07e67..48f7c1ba 100644 --- a/scripts/inference/cropland_mapping.py +++ b/scripts/inference/cropland_mapping.py @@ -8,7 +8,7 @@ from openeo_gfmap.backend import Backend, BackendContext from openeo_gfmap.features.feature_extractor import apply_feature_extractor from openeo_gfmap.inference.model_inference import apply_model_inference -from openeo_gfmap.preprocessing.scaling import compress_uint16 +from openeo_gfmap.preprocessing.scaling import compress_uint8 from worldcereal.openeo.feature_extractor import PrestoFeatureExtractor from worldcereal.openeo.inference import CroplandClassifier @@ -106,8 +106,8 @@ ], ) - # Cast to uint16 - classes = compress_uint16(classes) + # Cast to uint8 + classes = compress_uint8(classes) classes.execute_batch( outputfile=args.output_path,