Skip to content

Commit

Permalink
Merge pull request #15 from franneck94/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
franneck94 authored Nov 22, 2020
2 parents 727a7ef + bc05cef commit 268524c
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 297 deletions.
44 changes: 11 additions & 33 deletions examples/example_grid_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(
# User-definen constants
self.num_targets = 1
self.batch_size = 128
# Load the data set
# Load the dataset
x = np.random.uniform(low=-10.0, high=10.0, size=100)
y = f(x) + np.random.normal(size=100)
x = x.reshape(-1, 1).astype(np.float32)
Expand Down Expand Up @@ -50,29 +50,17 @@ def __init__(
(x_val, y_val)
)

def get_train_set(self) -> tf.data.Dataset:
return self.train_dataset

def get_test_set(self) -> tf.data.Dataset:
return self.test_dataset

def get_val_set(self) -> tf.data.Dataset:
return self.val_dataset


def build_model(
num_features: int,
num_targets: int,
optimizer: tf.keras.optimizers.Optimizer,
learning_rate: float
) -> tf.keras.models.Model:
"""Build the test model.
"""
x_input = tf.keras.layers.Input(shape=num_features)

x = tf.keras.layers.Dense(units=10)(x_input)
x = tf.keras.layers.Activation("relu")(x)
x = tf.keras.layers.Dense(units=num_targets)(x)
y_pred = tf.keras.layers.Activation("softmax")(x)

y_pred = tf.keras.layers.Dense(units=num_targets)(x_input)
model = tf.keras.models.Model(inputs=[x_input], outputs=[y_pred])

opt = optimizer(learning_rate=learning_rate)
Expand All @@ -87,37 +75,27 @@ def build_model(
if __name__ == "__main__":
data = DATA()

train_dataset = data.get_train_set()
val_dataset = data.get_val_set()

num_features = data.num_features
num_targets = data.num_targets

epochs = 1

parameter_grid = {
param_grid = {
"optimizer": [
tf.keras.optimizers.Adam,
tf.keras.optimizers.RMSprop
],
"learning_rate": [0.001, 0.0001]
}

build_model = build_model

grid_search = GridSearch(
model_fn=build_model,
parameter_grid=parameter_grid,
param_grid=param_grid,
n_iter=2,
verbose=1,
num_features=num_features,
num_targets=num_targets
num_features=data.num_features,
num_targets=data.num_targets
)

grid_search.fit(
train_dataset=train_dataset,
val_dataset=val_dataset,
epochs=3,
train_dataset=data.train_dataset,
val_dataset=data.val_dataset,
epochs=1,
verbose=1
)

Expand Down
11 changes: 4 additions & 7 deletions examples/example_random_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(
# User-definen constants
self.num_targets = 1
self.batch_size = 128
# Load the data set
# Load the dataset
x = np.random.uniform(low=-10.0, high=10.0, size=100)
y = f(x) + np.random.normal(size=100)
x = x.reshape(-1, 1).astype(np.float32)
Expand Down Expand Up @@ -67,13 +67,10 @@ def build_model(
optimizer: tf.keras.optimizers.Optimizer,
learning_rate: float
) -> tf.keras.models.Model:
"""Build the test model.
"""
x_input = tf.keras.layers.Input(shape=num_features)

x = tf.keras.layers.Dense(units=10)(x_input)
x = tf.keras.layers.Activation("relu")(x)
x = tf.keras.layers.Dense(units=num_targets)(x)
y_pred = tf.keras.layers.Activation("softmax")(x)

y_pred = tf.keras.layers.Dense(units=num_targets)(x_input)
model = tf.keras.models.Model(inputs=[x_input], outputs=[y_pred])

opt = optimizer(learning_rate=learning_rate)
Expand Down
2 changes: 0 additions & 2 deletions tensorcross/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from .model_selection import GridSearch
from .model_selection import RandomSearch
from .version import __version__
203 changes: 8 additions & 195 deletions tensorcross/model_selection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,199 +1,12 @@
from typing import Any
from typing import Callable
from typing import Dict
from typing import Mapping
from .search import GridSearch
from .search import RandomSearch

import numpy as np
import tensorflow as tf
from sklearn.model_selection import ParameterGrid
from sklearn.model_selection import ParameterSampler

# TODO: Import GridSearchCV and RandomSearchCV when finished

class BaseSearch:
"""RandomSearch for a given parameter distribution.

Args:
model_fn (Callable): Function that builds and compiles a
tf.keras.Model or tf.keras.Sequential object.
verbose (int, optional): Whether to show information in terminal.
Defaults to 0.
kwargs (Any): Keyword arguments for the model_fn function.
"""

def __init__(
self,
model_fn: Callable,
verbose: int = 0,
**kwargs: Any
) -> None:
self.model_fn = model_fn
self.verbose = verbose
self.model_fn_kwargs = kwargs
self.results_ = {
"best_score": -np.inf,
"best_params": {},
"val_scores": [],
"params": [],
}

def summary(self) -> None:
"""Prints the summary of the search to the console.
"""
best_params_str = (f"Best score: {self.results_['best_score']} "
f"using params: {self.results_['best_params']}")
dashed_line = "".join(map(lambda x: "-", best_params_str))
print(f"\n{dashed_line}\n{best_params_str}\n{dashed_line}")

scores = self.results_["val_scores"]
params = self.results_["params"]

for idx, (score, param) in enumerate(zip(scores, params)):
print(f"Idx: {idx} - Score: {score} with param: {param}")

print(f"{dashed_line}\n")


class GridSearch(BaseSearch):
def __init__(
self,
model_fn: Callable,
parameter_grid: Mapping,
n_iter: int = 10,
verbose: int = 0,
**kwargs: Any
) -> None:
"""RandomSearch for a given parameter distribution.
Args:
model_fn (Callable): Function that builds and compiles a
tf.keras.Model or tf.keras.Sequential object.
parameter_grid (Dict[str, Iterable]): Dict of str, iterable
hyperparameter, where the str is the parameter name of the.
n_iter (int, optional): Number of random models. Defaults to 10.
verbose (int, optional): Whether to show information in terminal.
Defaults to 0.
kwargs (Any): Keyword arguments for the model_fn function.
"""
super().__init__(
model_fn,
verbose,
**kwargs
)
self.parameter_grid = ParameterGrid(parameter_grid)
self.n_iter = n_iter

def fit(
self,
train_dataset: tf.data.Dataset,
val_dataset: tf.data.Dataset,
**kwargs: Any
) -> None:
"""Runs the exhaustive grid search over the parameter grid.
Args:
train_dataset (tf.data.Dataset): tf.data.Dataset object for the
training.
val_dataset (tf.data.Dataset): tf.data.Dataset object for
the validation.
kwargs (Any): Keyword arguments for the fit method of the
tf.keras.models.Model or tf.keras.models.Sequential model.
"""
for idx, grid_combination in enumerate(self.parameter_grid):
if self.verbose:
print(f"Running Comb: {idx}")
model = self.model_fn(
**grid_combination,
**self.model_fn_kwargs
)

model.fit(
train_dataset,
validation_data=val_dataset,
**kwargs,
)

val_metric = model.evaluate(
val_dataset,
verbose=0
)[1]
self.results_["val_scores"].append(val_metric)
self.results_["params"].append(grid_combination)

best_run_idx = np.argmax(self.results_["val_scores"])
self.results_["best_score"] = self.results_["val_scores"][best_run_idx]
self.results_["best_params"] = self.results_["params"][best_run_idx]


class RandomSearch(BaseSearch):
def __init__(
self,
model_fn: Callable,
param_distributions: Dict[str, Callable],
n_iter: int = 10,
verbose: int = 0,
**kwargs: Any
) -> None:
"""RandomSearch for a given parameter distribution.
Args:
model_fn (Callable): Function that builds and compiles a
tf.keras.Model or tf.keras.Sequential object.
param_distributions (Dict[str, Callable]): Dict of str, callable
pairs, where the str is the parameter name of the.
n_iter (int, optional): Number of random models. Defaults to 10.
verbose (int, optional): Whether to show information in terminal.
Defaults to 0.
kwargs (Any): Keyword arguments for the model_fn function.
"""
super().__init__(
model_fn,
verbose,
**kwargs
)
self.param_distributions = param_distributions
self.n_iter = n_iter
self.random_sampler = ParameterSampler(
self.param_distributions,
n_iter=self.n_iter
)

def fit(
self,
train_dataset: tf.data.Dataset,
val_dataset: tf.data.Dataset,
**kwargs: Any
) -> None:
"""Runs the random search over the parameter distributions.
Args:
train_dataset (tf.data.Dataset): tf.data.Dataset object for the
training.
val_dataset (tf.data.Dataset): tf.data.Dataset object for
the validation.
kwargs (Any): Keyword arguments for the fit method of the
tf.keras.models.Model or tf.keras.models.Sequential model.
"""
for idx, random_combination in enumerate(self.random_sampler):
if self.verbose:
print(f"Running Comb: {idx}")
model = self.model_fn(
**random_combination,
**self.model_fn_kwargs
)

model.fit(
train_dataset,
validation_data=val_dataset,
**kwargs,
)

val_metric = model.evaluate(
val_dataset,
verbose=0
)[1]
self.results_["val_scores"].append(val_metric)
self.results_["params"].append(random_combination)

best_run_idx = np.argmax(self.results_["val_scores"])
self.results_["best_score"] = self.results_["val_scores"][best_run_idx]
self.results_["best_params"] = self.results_["params"][best_run_idx]
__all__ = [
"GridSearch",
"RandomSearch"
# TODO: Add GridSearchCV and RandomSearchCV when finished
]
Loading

0 comments on commit 268524c

Please sign in to comment.