Skip to content

Commit

Permalink
replace logging.info with print
Browse files Browse the repository at this point in the history
add pypi version in README.md
bug fix with x_only parameter for data_processor.py
  • Loading branch information
biplovbhandari committed Apr 1, 2024
1 parent 09d5136 commit 8b53d23
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 128 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ACES (Agricultural Classification and Estimation Service)

[![image](https://img.shields.io/pypi/v/servir-aces.svg)](https://pypi.python.org/pypi/servir-aces)

ACES (Agricultural Classification and Estimation Service) is a Python module for generating training data and training machine learning models for remote sensing applications. It provides functionalities for data processing, data loading from Earth Engine, feature extraction, and model training.

## Features
Expand Down
26 changes: 11 additions & 15 deletions aces/data_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
This module provides functions for data input/output and preprocessing for the ACES project.
"""

import logging
logging.basicConfig(level=logging.INFO)

import numpy as np
import tensorflow as tf
from functools import partial
Expand Down Expand Up @@ -81,7 +78,6 @@ def calculate_n_samples(**config):
patch_size=config.get("PATCH_SHAPE_SINGLE"),
features=config.get("FEATURES"),
labels=config.get("LABELS"),
x_only=False,
depth=config.get("OUT_CLASS_NUM"))

tf_training_records = tf.data.Dataset.list_files(f"{str(config.get('TRAINING_DIR'))}/*")\
Expand Down Expand Up @@ -117,19 +113,19 @@ def print_dataset_info(dataset: tf.data.Dataset, dataset_name: str) -> None:
* dataset_name (str): The name of the dataset.
"""
logging.info(dataset_name)
print(dataset_name)
for inputs, outputs in dataset.take(1):
try:
logging.info(f"inputs: {inputs.dtype.name} {inputs.shape}")
logging.info(inputs)
logging.info(f"outputs: {outputs.dtype.name} {outputs.shape}")
logging.info(outputs)
print(f"inputs: {inputs.dtype.name} {inputs.shape}")
print(inputs)
print(f"outputs: {outputs.dtype.name} {outputs.shape}")
print(outputs)
except:
logging.info(f" > inputs:")
print(f" > inputs:")
for name, values in inputs.items():
logging.info(f" {name}: {values.dtype.name} {values.shape}")
# logging.info(f" example \n: {dataset.take(1)}")
logging.info(f" > outputs: {outputs.dtype.name} {outputs.shape}")
print(f" {name}: {values.dtype.name} {values.shape}")
# print(f" example \n: {dataset.take(1)}")
print(f" > outputs: {outputs.dtype.name} {outputs.shape}")

@staticmethod
@tf.function
Expand Down Expand Up @@ -516,7 +512,7 @@ def get_dataset(pattern: str, features: list, labels: list, patch_size: int, bat
Returns:
* tf.data.Dataset: The TFRecord dataset.
"""
logging.info(f"Loading dataset from {pattern}")
print(f"Loading dataset from {pattern}")

dataset = tf.data.Dataset.list_files(pattern).interleave(DataProcessor.create_tfrecord_from_file)

Expand Down Expand Up @@ -552,7 +548,7 @@ def get_dataset(pattern: str, features: list, labels: list, patch_size: int, bat
# dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)
if kwargs.get("training", False) and kwargs.get("TRANSFORM_DATA", True):
logging.info("randomly transforming data")
print("randomly transforming data")
if kwargs.get("USE_AI_PLATFORM", False):
dataset = dataset.map(RandomTransform(), num_parallel_calls=tf.data.AUTOTUNE)
else:
Expand Down
15 changes: 6 additions & 9 deletions aces/ee_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-

import logging
logging.basicConfig(level=logging.INFO)

import re, warnings
import ee
import numpy as np
Expand Down Expand Up @@ -105,7 +102,7 @@ def export_collection_data(collection: ee.FeatureCollection, export_type: Union[

@staticmethod
def _export_collection_to_drive(collection, start_training, **kwargs) -> None:
logging.info("Exporting training data to Google Drive..")
print("Exporting training data to Google Drive..")
training_task = ee.batch.Export.table.toDrive(
collection=collection,
description=kwargs.get("description", "myExportTableTask"),
Expand All @@ -119,7 +116,7 @@ def _export_collection_to_drive(collection, start_training, **kwargs) -> None:
@staticmethod
def _export_collection_to_asset(collection, start_training, **kwargs) -> None:
asset_id = kwargs.get("asset_id", "myAssetId")
logging.info(f"Exporting training data to {asset_id}..")
print(f"Exporting training data to {asset_id}..")
training_task = ee.batch.Export.table.toAsset(
collection=collection,
description=kwargs.get("description", "myExportTableTask"),
Expand All @@ -133,7 +130,7 @@ def _export_collection_to_cloud_storage(collection, start_training, **kwargs) ->
description = kwargs.get("description", "myExportTableTask")
bucket = kwargs.get("bucket", "myBucket")
file_prefix = kwargs.get("file_prefix") if kwargs.get("file_prefix") is not None else description
logging.info(f"Exporting training data to gs://{bucket}/{file_prefix}..")
print(f"Exporting training data to gs://{bucket}/{file_prefix}..")
training_task = ee.batch.Export.table.toCloudStorage(
collection=collection,
description=description,
Expand All @@ -157,7 +154,7 @@ def beam_export_collection_to_cloud_storage(collection_index, start_training, **
bucket = kwargs.get("bucket", "myBucket")
file_prefix = kwargs.get("file_prefix") if kwargs.get("file_prefix") is not None else description
file_prefix = f"{file_prefix}_{index}"
logging.info(f"Exporting training data to gs://{bucket}/{file_prefix}..")
print(f"Exporting training data to gs://{bucket}/{file_prefix}..")
training_task = ee.batch.Export.table.toCloudStorage(
collection=collection,
description=description,
Expand Down Expand Up @@ -197,7 +194,7 @@ def _export_image_to_cloud_storage(image, start_training, **kwargs) -> None:
else:
raise ValueError(f"region must be an ee.FeatureCollection or ee.Geometry object. Found {type(region)}")

logging.info(f"Exporting training data to gs://{bucket}/{file_name_prefix}..")
print(f"Exporting training data to gs://{bucket}/{file_name_prefix}..")

params = {
"image": image,
Expand All @@ -224,7 +221,7 @@ def _export_image_to_cloud_storage(image, start_training, **kwargs) -> None:
@staticmethod
def _export_image_to_asset(image, start_training, **kwargs) -> None:
asset_id = kwargs.get("asset_id", "")
logging.info(f"Exporting image to {asset_id}..")
print(f"Exporting image to {asset_id}..")

training_task = ee.batch.Export.image.toAsset(
image=image,
Expand Down
3 changes: 0 additions & 3 deletions aces/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
Additionally, it contains utility functions for plotting and visualizing model metrics during training.
"""

import logging
logging.basicConfig(level=logging.INFO)

import matplotlib.pyplot as plt

from tensorflow import keras
Expand Down
11 changes: 4 additions & 7 deletions aces/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
provided specifications. The class also contains utility methods for constructing custom layers and defining metrics.
"""

import logging
logging.basicConfig(level=logging.INFO)

import tensorflow as tf
from tensorflow import keras

Expand Down Expand Up @@ -104,7 +101,7 @@ def build_and_compile_dnn_model(self, **kwargs):
keras.Model: The compiled DNN model.
"""
INITIAL_BIAS = kwargs.get("INITIAL_BIAS", None)
logging.info(f"INITIAL_BIAS: {INITIAL_BIAS}")
print(f"INITIAL_BIAS: {INITIAL_BIAS}")

if INITIAL_BIAS is not None:
INITIAL_BIAS = tf.keras.initializers.Constant(INITIAL_BIAS)
Expand Down Expand Up @@ -146,7 +143,7 @@ def build_and_compile_dnn_model_for_ai_platform(self, **kwargs):
keras.Model: The compiled DNN model.
"""
INITIAL_BIAS = kwargs.get("INITIAL_BIAS", None)
logging.info(f"INITIAL_BIAS: {INITIAL_BIAS}")
print(f"INITIAL_BIAS: {INITIAL_BIAS}")
# DNN_DURING_ONLY = kwargs.get("DURING_ONLY", False)

DERIVE_FEATURES = kwargs.get("DERIVE_FEATURES", False)
Expand Down Expand Up @@ -236,7 +233,7 @@ def build_and_compile_unet_model_for_ai_platform(self, **kwargs):
with tf.distribute.MirroredStrategy().scope():
return self._build_and_compile_unet_model_for_ai_plaform(**kwargs)
else:
logging.info("No distributed strategy found.")
print("No distributed strategy found.")
return self._build_and_compile_unet_model(**kwargs)

def _build_and_compile_unet_model_for_ai_plaform(self, **kwargs):
Expand Down Expand Up @@ -276,7 +273,7 @@ def build_and_compile_unet_model(self, **kwargs):
model.compile(optimizer=self.optimizer, loss=self.loss, metrics=metrics_list)
return model
else:
logging.info("No distributed strategy found.")
print("No distributed strategy found.")
model = self._build_and_compile_unet_model(**kwargs)
metrics_list = [
Metrics.precision(),
Expand Down
80 changes: 38 additions & 42 deletions aces/model_trainer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# -*- coding: utf-8 -*-

import logging
logging.basicConfig(level=logging.INFO)
# logger = logging.getLogger(__name__)

import os
import datetime
import json
Expand Down Expand Up @@ -50,7 +46,7 @@ def __init__(self, config: Config, use_seed: bool = True, seed: int = 42):
if self.use_seed:
# producable results
import random
logging.info(f"Using seed: {self.seed}")
print(f"Using seed: {self.seed}")
tf.random.set_seed(self.seed)
np.random.seed(self.seed)
random.seed(2)
Expand Down Expand Up @@ -92,56 +88,56 @@ def train_model(self) -> None:
7. Saves training parameters, plots, and models.
"""
logging.info("****************************************************************************")
logging.info("****************************** Clear Session... ****************************")
print("****************************************************************************")
print("****************************** Clear Session... ****************************")
keras.backend.clear_session()
logging.info("****************************************************************************")
print("****************************************************************************")
print(f"****************************** Configure memory growth... ************************")
physical_devices = TFUtils.configure_memory_growth()
self.config.physical_devices = physical_devices
logging.info("****************************************************************************")
logging.info("****************************** creating datasets... ************************")
print("****************************************************************************")
print("****************************** creating datasets... ************************")
self.create_datasets(print_info=self.config.PRINT_INFO)

if self.config.USE_AI_PLATFORM:
logging.info("****************************************************************************")
logging.info("******* building and compiling model for ai platform... ********************")
print("****************************************************************************")
print("******* building and compiling model for ai platform... ********************")
self.build_and_compile_model_ai_platform()
else:
logging.info("****************************************************************************")
logging.info("************************ building and compiling model... *******************")
print("****************************************************************************")
print("************************ building and compiling model... *******************")
self.build_and_compile_model(print_model_summary=True)

logging.info("****************************************************************************")
logging.info("************************ preparing output directory... *********************")
print("****************************************************************************")
print("************************ preparing output directory... *********************")
self.prepare_output_dir()
logging.info("****************************************************************************")
logging.info("****************************** training model... ***************************")
print("****************************************************************************")
print("****************************** training model... ***************************")
self.start_training()

if self.config.USE_AI_PLATFORM:
logging.info(self.model.summary())
print(self.model.summary())

logging.info("****************************************************************************")
logging.info("****************************** evaluating model... *************************")
print("****************************************************************************")
print("****************************** evaluating model... *************************")
self.evaluate_and_print_val()
logging.info("****************************************************************************")
logging.info("****************************** saving parameters... ************************")
print("****************************************************************************")
print("****************************** saving parameters... ************************")
ModelTrainer.save_parameters(**self.config.__dict__)
logging.info("****************************************************************************")
logging.info("*************** saving model config and history object... ******************")
print("****************************************************************************")
print("*************** saving model config and history object... ******************")
self.save_history_object()
if self.config.USE_AI_PLATFORM:
ModelTrainer.save_model_config(self.config.MODEL_SAVE_DIR, **self._model.get_config())
else:
ModelTrainer.save_model_config(self.config.MODEL_SAVE_DIR, **self.model.get_config())
logging.info("****************************************************************************")
logging.info("****************************** saving plots... *****************************")
print("****************************************************************************")
print("****************************** saving plots... *****************************")
self.save_plots()
logging.info("****************************************************************************")
logging.info("****************************** saving models... ****************************")
print("****************************************************************************")
print("****************************** saving models... ****************************")
self.save_models()
logging.info("****************************************************************************")
print("****************************************************************************")

def prepare_output_dir(self) -> None:
"""
Expand All @@ -151,7 +147,7 @@ def prepare_output_dir(self) -> None:
"""
if not self.config.AUTO_MODEL_DIR_NAME:
self.config.MODEL_SAVE_DIR = self.config.OUTPUT_DIR / self.config.MODEL_DIR_NAME
logging.info(f"> Saving models and results at {self.config.MODEL_SAVE_DIR}...")
print(f"> Saving models and results at {self.config.MODEL_SAVE_DIR}...")
os.mkdir(self.config.MODEL_SAVE_DIR)
else:
today = datetime.date.today().strftime("%Y_%m_%d")
Expand All @@ -162,11 +158,11 @@ def prepare_output_dir(self) -> None:
try:
os.mkdir(self.config.MODEL_SAVE_DIR)
except FileExistsError:
logging.info(f"> {self.config.MODEL_SAVE_DIR} exists, creating another version...")
print(f"> {self.config.MODEL_SAVE_DIR} exists, creating another version...")
iterator += 1
continue
else:
logging.info(f"> Saving models and results at {self.config.MODEL_SAVE_DIR}...")
print(f"> Saving models and results at {self.config.MODEL_SAVE_DIR}...")
break

def create_datasets(self, print_info: bool = False) -> None:
Expand Down Expand Up @@ -209,7 +205,7 @@ def create_datasets(self, print_info: bool = False) -> None:
)

if print_info:
logging.info("Printing dataset info:")
print("Printing dataset info:")
DataProcessor.print_dataset_info(self.TRAINING_DATASET, "Training")
DataProcessor.print_dataset_info(self.TESTING_DATASET, "Testing")
DataProcessor.print_dataset_info(self.VALIDATION_DATASET, "Validation")
Expand All @@ -226,7 +222,7 @@ def build_and_compile_model(self, print_model_summary: bool = True) -> None:
Prints the model summary if print_model_summary is set to True.
"""
self.model = self.build_model(**self.config.__dict__)
if print_model_summary: logging.info(self.model.summary())
if print_model_summary: print(self.model.summary())

def build_and_compile_model_ai_platform(self) -> None:
"""
Expand All @@ -240,7 +236,7 @@ def build_and_compile_model_ai_platform(self) -> None:
Prints the model summary if print_model_summary is set to True.
"""
model, wrapped_model = self.build_model(**self.config.__dict__)
logging.info(model.summary())
print(model.summary())
self._model = model
self.model = wrapped_model

Expand Down Expand Up @@ -309,16 +305,16 @@ def evaluate_and_print_val(self) -> None:
Evaluates the model on the validation dataset and prints the metrics.
"""
logging.info("************************************************")
logging.info("************************************************")
logging.info("Validation")
print("************************************************")
print("************************************************")
print("Validation")
# Tip: You can remove steps=self.config.TEST_SIZE and match the TEST_SIZE from the env
evaluate_results = self.model.evaluate(self.TESTING_DATASET) # , steps=self.config.TEST_SIZE
with open(f"{self.config.MODEL_SAVE_DIR}/evaluation.txt", "w") as evaluate:
evaluate.write(json.dumps(dict(zip(self.model.metrics_names, evaluate_results))))
for name, value in zip(self.model.metrics_names, evaluate_results):
logging.info(f"{name}: {value}")
logging.info("\n")
print(f"{name}: {value}")
print("\n")

@staticmethod
def save_parameters(**config) -> None:
Expand Down Expand Up @@ -368,7 +364,7 @@ def save_plots(self) -> None:
Saves the model architecture plot, training history plot, and model object.
"""
logging.info(f"Saving plots and model visualization at {self.config.MODEL_SAVE_DIR}...")
print(f"Saving plots and model visualization at {self.config.MODEL_SAVE_DIR}...")
if self.config.USE_AI_PLATFORM:
keras.utils.plot_model(self._model, f"{self.config.MODEL_SAVE_DIR}/model.png", show_shapes=True, rankdir="TB")
keras.utils.plot_model(self.model, f"{self.config.MODEL_SAVE_DIR}/wrapped_model.png", show_shapes=True, rankdir="LR") # rankdir='TB'
Expand Down
Loading

0 comments on commit 8b53d23

Please sign in to comment.