Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiments/kyle models #3

Merged
merged 6 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ logs/
/**/*.png
*.tif
*.tiff
*.tfrecord.gz

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
27 changes: 17 additions & 10 deletions fao_models/dataloader.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
import tensorflow as tf
import os


def _parse_function(proto):
# Define the parsing schema
feature_description = {
'image': tf.io.FixedLenFeature([], tf.string),
'label': tf.io.FixedLenFeature([], tf.string),
"image": tf.io.FixedLenFeature([], tf.string),
"label": tf.io.FixedLenFeature([], tf.string),
}
# Parse the input `tf.train.Example` proto using the schema
example = tf.io.parse_single_example(proto, feature_description)
image = tf.io.parse_tensor(example['image'], out_type=tf.float32)
label = tf.io.parse_tensor(example['label'], out_type=tf.int64)
image = tf.io.parse_tensor(example["image"], out_type=tf.float32)
label = tf.io.parse_tensor(example["label"], out_type=tf.int64)
image.set_shape([32, 32, 4]) # Set the shape explicitly if not already defined
label.set_shape([]) # For scalar labels
return image, label


def load_dataset_from_tfrecords(tfrecord_dir, batch_size=32):

pattern = tfrecord_dir + "/*.tfrecord.gz"
files = tf.data.Dataset.list_files(pattern)
dataset = files.interleave(
lambda x: tf.data.TFRecordDataset(x, compression_type="GZIP"),
cycle_length=tf.data.AUTOTUNE,
block_length=1
block_length=1,
)
dataset = dataset.map(_parse_function, num_parallel_calls=tf.data.AUTOTUNE).batch(
batch_size, drop_remainder=True
)
dataset = dataset.map(_parse_function, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.shuffle(buffer_size=1000)
dataset = dataset.shuffle(buffer_size=100_000, seed=42)
return dataset


def split_dataset(dataset, total_examples, test_split=0.2, batch_size=32):
test_size = int(total_examples * test_split)
train_size = total_examples - test_size
Expand All @@ -36,7 +41,9 @@ def split_dataset(dataset, total_examples, test_split=0.2, batch_size=32):
train_batches = train_size // batch_size
test_batches = test_size // batch_size

train_dataset = dataset.take(train_batches).batch(batch_size).prefetch(tf.data.AUTOTUNE)
test_dataset = dataset.skip(train_batches).take(test_batches).batch(batch_size).prefetch(tf.data.AUTOTUNE)
train_dataset = dataset.take(train_batches).prefetch(tf.data.AUTOTUNE)
test_dataset = (
dataset.skip(train_batches).take(test_batches).prefetch(tf.data.AUTOTUNE)
)

return train_dataset, test_dataset
return train_dataset, test_dataset
17 changes: 17 additions & 0 deletions fao_models/graveyard/model_graveyard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
def model1(optimizer, loss_fn, metrics=[]):

model = models.Sequential(
[
layers.Input(shape=(32, 32, 4)),
layers.Flatten(),
layers.Dense(64, activation="relu"),
layers.Dense(1, activation="softmax"),
]
)

model.compile(optimizer=optimizer, loss=loss_fn, metrics=metrics)

return model



# Define your TensorFlow models here
def cnn_v1_softmax_onehot(optimizer,loss_fn,metrics=['accuracy']):
def conv_block(input_tensor, num_filters):
Expand Down
190 changes: 106 additions & 84 deletions fao_models/model_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
import yaml
from pprint import pformat
from functools import partial
import argparse

# TODO: make this single CLI arg input
config_file = r"runc3.yml"
# # TODO: make this single CLI arg input
# config_file = r"runc3.yml"

# setup logging
logging.basicConfig(
Expand All @@ -26,94 +27,115 @@
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

with open(config_file, "r") as file:
config_data = yaml.safe_load(file)

# retrieve parameters
experiment_name = config_data["experiment_name"]
model_name = config_data["model_name"]
total_examples = config_data["total_examples"]
data_dir = config_data["data_dir"]
data_split = config_data["data_split"]
epochs = config_data["epochs"]
learning_rate = config_data["learning_rate"]
batch_size = config_data["batch_size"]
buffer_size = config_data["buffer_size"]
optimizer = config_data["optimizer"]
optimizer_use_lr_schedular = config_data["optimizer_use_lr_schedular"]
loss_function = config_data["loss_function"]
early_stopping_patience = config_data["early_stopping_patience"]

# hyperbolically decrease the learning rate to 1/2 of the base rate at 1,000 epochs, 1/3 at 2,000 epochs, and so on.
if optimizer == "adam":
if optimizer_use_lr_schedular:
steps_per_epoch = total_examples * data_split // batch_size
lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
initial_learning_rate=learning_rate,
decay_steps=steps_per_epoch * epochs,
decay_rate=1,
staircase=False,
)
logger.info(
f"Using a learning rate schedule of InverseTimeDecay, decay_steps={steps_per_epoch*epochs}"
)
optimizer = tf.keras.optimizers.Adam(lr_schedule)
else:
optimizer = tf.keras.optimizers.Adam()

# pull model from config
model = get_model(model_name, optimizer=optimizer, loss_fn=loss_function)
print(model.summary())

logger.info("Config file: %s", config_file)
logger.info("Parameters:")
logger.info(pformat(config_data))
def main():

# Load the dataset without batching
dataset = dl.load_dataset_from_tfrecords(data_dir)
# initalize new cli parser
parser = argparse.ArgumentParser(description="Train a model with a .yml file.")

# Split the dataset into training and testing
train_dataset, test_dataset = dl.split_dataset(
dataset, total_examples, test_split=data_split, batch_size=batch_size
)
train_dataset = train_dataset.shuffle(buffer_size, reshuffle_each_iteration=True)
parser.add_argument(
"-c",
"--config",
type=str,
help="path to .yml file",
)

args = parser.parse_args()

config_file = args.config

with open(config_file, "r") as file:
config_data = yaml.safe_load(file)

# retrieve parameters
experiment_name = config_data["experiment_name"]
model_name = config_data["model_name"]
total_examples = config_data["total_examples"]
data_dir = config_data["data_dir"]
data_split = config_data["data_split"]
epochs = config_data["epochs"]
learning_rate = config_data["learning_rate"]
batch_size = config_data["batch_size"]
buffer_size = config_data["buffer_size"]
optimizer = config_data["optimizer"]
optimizer_use_lr_schedular = config_data["optimizer_use_lr_schedular"]
loss_function = config_data["loss_function"]
early_stopping_patience = config_data["early_stopping_patience"]

# hyperbolically decrease the learning rate to 1/2 of the base rate at 1,000 epochs, 1/3 at 2,000 epochs, and so on.
if optimizer == "adam":
if optimizer_use_lr_schedular:
steps_per_epoch = total_examples * data_split // batch_size
lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
initial_learning_rate=learning_rate,
decay_steps=steps_per_epoch * epochs,
decay_rate=1,
staircase=False,
)
logger.info(
f"Using a learning rate schedule of InverseTimeDecay, decay_steps={steps_per_epoch*epochs}"
)
optimizer = tf.keras.optimizers.Adam(lr_schedule)
else:
optimizer = tf.keras.optimizers.Adam()

# pull model from config
model = get_model(model_name, optimizer=optimizer, loss_fn=loss_function)
print(model.summary())

logger.info("Config file: %s", config_file)
logger.info("Parameters:")
logger.info(pformat(config_data))

# Load the dataset without batching
dataset = dl.load_dataset_from_tfrecords(data_dir, batch_size=batch_size)

# Split the dataset into training and testing
train_dataset, test_dataset = dl.split_dataset(
dataset, total_examples, test_split=data_split, batch_size=batch_size
)
train_dataset = train_dataset.shuffle(buffer_size, reshuffle_each_iteration=True)

logger.info("Starting model training...")
LOGS_DIR = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "logs", experiment_name
)
if not os.path.exists(LOGS_DIR):
os.makedirs(LOGS_DIR)

# setup for confusion matrix callback
tb_samples = train_dataset.take(1)
x = list(map(lambda x: x[0], tb_samples))[0]
y = list(map(lambda x: x[1], tb_samples))[0]
class_names = ["nonforest", "forest"]

# initialize and add tb callbacks
callbacks = []
file_writer = tf.summary.create_file_writer(LOGS_DIR)
cm_callback = CmCallback(y, x, class_names, file_writer)

if early_stopping_patience is not None:
logger.info(f"Using early stopping. Patience: {early_stopping_patience}")
early_stop = tf.keras.callbacks.EarlyStopping(
monitor="val_loss", patience=early_stopping_patience, restore_best_weights=True
logger.info("Starting model training...")
LOGS_DIR = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "logs", experiment_name
)
if not os.path.exists(LOGS_DIR):
os.makedirs(LOGS_DIR)

# setup for confusion matrix callback
tb_samples = train_dataset.take(1)
x = list(map(lambda x: x[0], tb_samples))[0]
y = list(map(lambda x: x[1], tb_samples))[0]
class_names = ["nonforest", "forest"]

# initialize and add tb callbacks
callbacks = []
file_writer = tf.summary.create_file_writer(LOGS_DIR)
cm_callback = CmCallback(y, x, class_names, file_writer)

if early_stopping_patience is not None:
logger.info(f"Using early stopping. Patience: {early_stopping_patience}")
early_stop = tf.keras.callbacks.EarlyStopping(
monitor="val_loss",
patience=early_stopping_patience,
restore_best_weights=True,
)
callbacks.append(early_stop)
callbacks.append(cm_callback)
callbacks.append(tf.keras.callbacks.TensorBoard(LOGS_DIR))

history = model.fit(
train_dataset,
epochs=epochs,
validation_data=test_dataset,
callbacks=callbacks,
)
callbacks.append(early_stop)
callbacks.append(cm_callback)
callbacks.append(tf.keras.callbacks.TensorBoard(LOGS_DIR))

logger.info("Model training complete")
logger.info("Training history:")
logger.info(pformat(history.history))

history = model.fit(
train_dataset,
epochs=epochs,
validation_data=test_dataset,
callbacks=callbacks,
)

logger.info("Model training complete")
logger.info("Training history:")
logger.info(pformat(history.history))
if __name__ == "__main__":
main()
Loading
Loading