def __init__(self, images="cifar10", labels=None, config=None): """Initializes DeepAugment object Does following steps: 1. load and preprocess data 2. create child model 3. create controller 4. create notebook (for recording trainings) 5. do initial training 6. create objective function 7. evaluate objective function without augmentation Args: images (numpy.array/str): array with shape (n_images, dim1, dim2 , channel_size), or a string with name of keras-dataset (cifar10, fashion_mnsit) labels (numpy.array): labels of images, array with shape (n_images) where each element is an integer from 0 to number of classes config (dict): dictionary of configurations, for updating the default config which is: { "model": "basiccnn", "method": "bayesian_optimization", "train_set_size": 2000, "val_set_size": 100, "opt_samples": 3, "opt_last_n_epochs": 3, "opt_initial_points": 10, "child_epochs": 50, "child_first_train_epochs": 0, "child_batch_size": 64, "pre_aug_weights_path": "pre_aug_weights.h5", "logging": logging, "notebook_path": f"{EXPERIMENT_FOLDER_PATH}/notebook.csv" } """ self.config = DEFAULT_CONFIG if config!=None: self.config.update(config) self.iterated = 0 # keep tracks how many times optimizer iterated self._load_and_preprocess_data(images, labels) # define main objects self.child_model = ChildCNN(self.input_shape, self.num_classes, self.config) self.controller = Controller(self.config) self.notebook = Notebook(self.config) if self.config["child_first_train_epochs"] > 0: self._do_initial_training() self.child_model.save_pre_aug_weights() self.objective_func = Objective( self.data, self.child_model, self.notebook, self.config ) #self._evaluate_objective_func_without_augmentation() self.trial_hyperparams = None self.trial_no = 0
def run_model(dataset_name, num_classes, epochs, batch_size, policies_path): data, input_shape = DataOp.load(dataset_name) data = DataOp.preprocess_normal(data) wrn_28_10 = ChildCNN( model_name="wrn_28_10", input_shape=input_shape, batch_size=batch_size, num_classes=num_classes, pre_augmentation_weights_path="initial_model_weights.h5", logging=logging, ) if policies_path == "dont_augment": policy_str = "non_augmented" else: policy_str = "augmented" csv_logger = CSVLogger( f"{EXPERIMENT_FOLDER_PATH}/wrn_28_10_training_on_{dataset_name}_{policy_str}.csv" ) if policies_path == "dont_augment": history = wrn_28_10.fit_normal(data, epochs=epochs, csv_logger=csv_logger) print(f"Reached validation accuracy is {history['val_acc'][-1]}") else: datagen = deepaugment_image_generator( data["X_train"], data["y_train"], policies_path, batch_size=batch_size, augment_chance=0.8, ) print("fitting the model") history = wrn_28_10.fit_with_generator( datagen, data["X_val"], data["y_val"], train_data_size=len(data["X_train"]), epochs=epochs, csv_logger=csv_logger, ) print(f"Reached validation accuracy is {history['val_acc'][-1]}")
class DeepAugment: """Initiliazes commponents of DeepAugment (e.g. Controller, Child-model, Notebook) and optimizes image augmentation hyperparameters """ @logger(logfile_dir=EXPERIMENT_FOLDER_PATH) def __init__(self, images="cifar10", labels=None, config=None): """Initializes DeepAugment object Does following steps: 1. load and preprocess data 2. create child model 3. create controller 4. create notebook (for recording trainings) 5. do initial training 6. create objective function 7. evaluate objective function without augmentation Args: images (numpy.array/str): array with shape (n_images, dim1, dim2 , channel_size), or a string with name of keras-dataset (cifar10, fashion_mnsit) labels (numpy.array): labels of images, array with shape (n_images) where each element is an integer from 0 to number of classes config (dict): dictionary of configurations, for updating the default config which is: { "model": "basiccnn", "method": "bayesian_optimization", "train_set_size": 2000, "opt_samples": 3, "opt_last_n_epochs": 3, "opt_initial_points": 10, "child_epochs": 50, "child_first_train_epochs": 0, "child_batch_size": 64, "pre_aug_weights_path": "pre_aug_weights.h5", "logging": logging, "notebook_path": f"{EXPERIMENT_FOLDER_PATH}/notebook.csv" } """ self.config = DEFAULT_CONFIG if config!=None: self.config.update(config) self.iterated = 0 # keep tracks how many times optimizer iterated self._load_and_preprocess_data(images, labels) # define main objects self.child_model = ChildCNN(self.input_shape, self.num_classes, self.config) self.controller = Controller(self.config) self.notebook = Notebook(self.config) if self.config["child_first_train_epochs"] > 0: self._do_initial_training() self.child_model.save_pre_aug_weights() self.objective_func = Objective( self.data, self.child_model, self.notebook, self.config ) self._evaluate_objective_func_without_augmentation() def optimize(self, iterations=300): """Optimize objective function hyperparameters using controller and child model Args: iterations (int): number of optimization iterations, which the child model will be run Returns: pandas.DataFrame: top policies (with highest expected accuracy increase) """ # iteratate optimizer for trial_no in range(self.iterated + 1, self.iterated + iterations + 1): trial_hyperparams = self.controller.ask() print("trial:", trial_no, "\n", trial_hyperparams) f_val = self.objective_func.evaluate(trial_no, trial_hyperparams) self.controller.tell(trial_hyperparams, f_val) self.iterated += iterations # update number of previous iterations self.top_policies = self.notebook.get_top_policies(20) self.notebook.output_top_policies() print("\ntop policies are:\n", self.top_policies) return self.top_policies def image_generator_with_top_policies(self, images, labels, batch_size=None): """ Args: images (numpy.array): array with shape (N,dim,dim,channek-size) labels (numpy.array): array with shape (N), where each eleemnt is an integer from 0 to num_classes-1 batch_size (int): batch size of the generator on demand Returns: generator: generator for augmented images """ if batch_size is None: batch_size = self.config["child_batch_size"] top_policies_list = self.top_policies[ ['A_aug1_type', 'A_aug1_magnitude', 'A_aug2_type', 'A_aug2_magnitude', 'B_aug1_type', 'B_aug1_magnitude', 'B_aug2_type', 'B_aug2_magnitude', 'C_aug1_type', 'C_aug1_magnitude', 'C_aug2_type', 'C_aug2_magnitude', 'D_aug1_type', 'D_aug1_magnitude', 'D_aug2_type', 'D_aug2_magnitude', 'E_aug1_type', 'E_aug1_magnitude', 'E_aug2_type', 'E_aug2_magnitude'] ].to_dict(orient="records") return deepaugment_image_generator(images, labels, top_policies_list, batch_size=batch_size) def _load_and_preprocess_data(self, images, labels): """Loads and preprocesses data Records `input_shape`, `data`, and `num_classes` into `self Args: images (numpy.array/str): array with shape (n_images, dim1, dim2 , channel_size), or a string with name of keras-dataset (cifar10, fashion_mnsit) labels (numpy.array): labels of images, array with shape (n_images) where each element is an integer from 0 to number of classes """ if isinstance(images, str): X, y, self.input_shape = DataOp.load(images) else: X, y = images, labels self.input_shape = X.shape[1:] self.data = DataOp.preprocess(X, y, self.config["train_set_size"]) self.num_classes = DataOp.find_num_classes(self.data) def _do_initial_training(self): """Do the first training without augmentations Training weights will be used as based to further child model trainings """ history = self.child_model.fit( self.data, epochs=self.config["child_first_train_epochs"] ) #BUG #self.notebook.record( # -1, ["first", 0.0, "first", 0.0, "first", 0.0, 0.0], 1, None, history #) def _evaluate_objective_func_without_augmentation(self): """Find out what would be the accuracy if augmentation are not applied """ no_aug_hyperparams = ["rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0, "rotate", 0.0] f_val = self.objective_func.evaluate(0, no_aug_hyperparams) self.controller.tell(no_aug_hyperparams, f_val)
def run_full_model(images, labels, test_proportion=0.1, model="wrn_28_10", epochs=200, batch_size=64, policies_path="dont_augment"): data = {} data["X_train"], data["X_val"], data["y_train"], data[ "y_val"] = train_test_split(images, labels, test_size=test_proportion, shuffle=True) data = DataOp.preprocess_normal(data) input_shape = data["X_train"][0].shape num_classes = data["y_train"].shape[1] cnn_config = { "model": model, "weights": "imagenet", "input_shape": input_shape, "child_batch_size": batch_size, "pre_augmentation_weights_path": "initial_model_weights.h5", "logging": logging } full_model = ChildCNN(input_shape=input_shape, num_classes=num_classes, config=cnn_config) if policies_path == "dont_augment": policy_str = "non_augmented" else: policy_str = "augmented" csv_logger = CSVLogger( f"{EXPERIMENT_FOLDER_PATH}/wrn_28_10_training_on_{policy_str}.csv") if policies_path == "dont_augment": history = full_model.fit_normal(data, epochs=epochs, csv_logger=csv_logger) print(f"Reached validation accuracy is {history['val_acc'][-1]}") else: datagen = deepaugment_image_generator( data["X_train"], data["y_train"], policies_path, batch_size=batch_size, augment_chance=0.8, ) file = open('datagen.txt', 'w') file.write(datagen) file.close() print("fitting the model") history = full_model.fit_with_generator( datagen, data["X_val"], data["y_val"], train_data_size=len(data["X_train"]), epochs=epochs, csv_logger=csv_logger, ) print(f"Reached validation accuracy is {history['val_acc'][-1]}")