def build(self): model = tf.keras.Sequential() model.add(layers.Flatten(input_shape=(42, 4))) for i in range(self.layers): if self.reg: model.add( layers.Dense(self.sizes[i], activation='elu', kernel_regularizer=regularizers.l2( self.reg[i]))) else: model.add(layers.Dense(self.sizes[i], activation='elu')) if self.dropout: model.add(layers.Dropout(self.dropout[i])) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer=optimizers.Adam(learning_rate=self.lr), loss=losses.BinaryCrossentropy(), metrics=[ 'binary_accuracy', metrics.TruePositives(name='tp'), metrics.FalseNegatives(name='fn'), metrics.TrueNegatives(name='tn'), metrics.FalsePositives(name='fp'), metrics.Recall(name='recall'), metrics.Precision(name='precision') ]) return model
def eval_use_model(model_name, path_model_file, test_file, class_num): """ evaluating model by using entire model (weights, architecture, optimizers, etc.) Arguments:\n model_name --> String, Resnet50/Resnet18/VGG16/VGG19 path_model_file --> String, path which store .hdf5 of model's weight\n test_file --> String, path to which store .h5 file of test dataset class_num --> Int, number of class/label\n Returns:\n none """ # Load model weights new_model = Model() new_model = load_model(path_model_file) new_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=[ metrics.AUC(), metrics.CategoricalAccuracy(), metrics.TruePositives(), metrics.TrueNegatives(), metrics.FalsePositives(), metrics.FalseNegatives() ]) # retrieve X_test, Y_test X_test, Y_test = retrieve_test_dataset(test_file, int(class_num)) for i in range(4): hasil = new_model.evaluate(X_test, Y_test) print(new_model.metrics_names) print(hasil)
def call(self, y_true_local, y_pred_local, fp=metrics.FalsePositives(), fn=metrics.FalseNegatives(), tp=metrics.TruePositives(), tn=metrics.TrueNegatives()): return 0.5 * tn / (tn + fn) + (tp / (tp + fp))
def get_metrics(): acc = 'accuracy' auc = metrics.AUC(num_thresholds=200, curve='ROC', name='auc', thresholds=None, multi_label=False) fp = metrics.FalsePositives(thresholds=[0.001, 0.01, 0.1, 1.0], name='FP') tp = metrics.TruePositives(thresholds=[0.001, 0.01, 0.1, 1.0], name='TP') return [acc] #, auc, fp, tp]
def confusion_matrix(self, y_label, y_class): tn = metrics.TrueNegatives() tn.update_state(y_label, y_class) print('TrueNegatives result: ', tn.result().numpy()) tp =metrics.TruePositives() tp.update_state(y_label, y_class) print('TruePositives result: ', tp.result().numpy()) fn = metrics.FalseNegatives() fn.update_state(y_label, y_class) print('FalseNegatives result: ', fn.result().numpy()) fp = metrics.FalsePositives() fp.update_state(y_label, y_class) print('FalsePositives result: ', fp.result().numpy())
def __get_metric(self, metric): if metric == "auc": return m.AUC() elif metric == "accuracy": return m.Accuracy() elif metric == "binary_accuracy": return m.BinaryAccuracy() elif metric == "categorical_accuracy": return m.CategoricalAccuracy() elif metric == "binary_crossentropy": return m.BinaryCrossentropy() elif metric == "categorical_crossentropy": return m.CategoricalCrossentropy() elif metric == "sparse_categorical_crossentropy": return m.SparseCategoricalCrossentropy() elif metric == "kl_divergence": return m.KLDivergence() elif metric == "poisson": return m.Poission() elif metric == "mse": return m.MeanSquaredError() elif metric == "rmse": return m.RootMeanSquaredError() elif metric == "mae": return m.MeanAbsoluteError() elif metric == "mean_absolute_percentage_error": return m.MeanAbsolutePercentageError() elif metric == "mean_squared_logarithm_error": return m.MeanSquaredLogarithmError() elif metric == "cosine_similarity": return m.CosineSimilarity() elif metric == "log_cosh_error": return m.LogCoshError() elif metric == "precision": return m.Precision() elif metric == "recall": return m.Recall() elif metric == "true_positive": return m.TruePositives() elif metric == "true_negative": return m.TrueNegatives() elif metric == "false_positive": return m.FalsePositives() elif metric == "false_negative": return m.FalseNegatives() else: raise Exception("specified metric not defined")
def __init__(self, n_features, n_classes): print("##################### Init NN #####################") self.N_FEATURES = n_features self.N_CLASSES = n_classes self.METRICS = [ 'accuracy', tkm.TruePositives(), tkm.FalsePositives(name='fp'), tkm.TrueNegatives(name='tn'), tkm.FalseNegatives(name='fn'), #tkm.BinaryAccuracy(name='accuracy'), tkm.Precision(name='precision'), tkm.Recall(name='recall'), tkm.AUC(name='auc') ] self.DATE = datetime.now().strftime("%d-%m_%H%M%S") create_dir(self.DATE)
def experiment(self, under=False, ratio=3, plot=False): METRICS = [ metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn'), metrics.FalseNegatives(name='fn'), metrics.BinaryAccuracy(name='accuracy'), metrics.Precision(name='precision'), metrics.Recall(name='recall'), metrics.AUC(name='auc') ] data = DataLoader() model = LeNet(data.X, METRICS) augmenter = Augmenter(data.X, data.Y) if under: data.X, data.Y = augmenter.undersample(ratio=ratio) if self.augmentation.type == 1 or self.augmentation.type == 2: data.X, data.Y = augmenter.duplicate(noise=self.augmentation.noise, sigma=self.augmentation.sigma) elif self.augmentation.type == 3: data.X, data.Y = augmenter.SMOTE() #data.normalize() #print(len(data.X)) #print(len(data.valX)) data.summarize(test=False) his = model.fit(data.X, data.Y, data.valX, data.valY) RES, fpr, tpr = model.predict(data.testX, data.testY) #self.model_summary(RES) if plot: self.plot(his) self.ROC(fpr, tpr) return RES
def compile(self, model, train_generator, valid_generator): """:arg This function contain model compile and model fit process, input a model and output history and trained model """ start_time = time() print("*" * 40, "Start {} Processing".format(model._name), "*" * 40) # we use a lot of metric to evalute our binary classification result METRICS = [ metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn'), metrics.FalseNegatives(name='fn'), metrics.BinaryAccuracy(name='binary_accuracy'), #metrics.CategoricalAccuracy(name='accuracy'), metrics.Precision(name='precision'), metrics.Recall(name='recall'), metrics.AUC(name='auc'), # F1Score(num_classes = int(y_train.shape[1]), name='F1') ] # define a optimizer opt_rms = optimizers.RMSprop(lr = 1e-4, decay = 1e-5) # define compile parameters model.compile(loss = 'binary_crossentropy', optimizer = opt_rms, metrics = ['accuracy']) # start to fit history = model.fit( train_generator, steps_per_epoch=20, epochs=5, validation_data=valid_generator, validation_steps=20 ) return history
.map(TRAIN_image_augmentor) elif data_subset_mode == 'val': data = data.batch(batch_size, drop_remainder=True) \ .map(VAL_image_augmentor) elif data_subset_mode == 'test': data = data.batch(batch_size, drop_remainder=True) \ .map(TEST_image_augmentor) if infinite: data = data.repeat() return data.prefetch(AUTOTUNE) METRICS = [ # per_class_accuracy, metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn'), metrics.FalseNegatives(name='fn'), metrics.CategoricalAccuracy(name='accuracy'), metrics.Precision(name='precision'), metrics.Recall(name='recall'), metrics.TopKCategoricalAccuracy(name='top_3_categorical_accuracy', k=3), metrics.TopKCategoricalAccuracy(name='top_5_categorical_accuracy', k=5) ] ########################################################################### ########################################################################### encoder = base_dataset.LabelEncoder(data.data.family) split_data = base_dataset.preprocess_data(data, encoder, data_config)
import numpy as np from tensorflow.keras import metrics as keras_metrics from tensorflow.keras.callbacks import EarlyStopping from tensorflow.keras.layers import Dense from tensorflow.keras.models import Sequential from ProteinDataset import ProteinDataset, mask_generator EPOCHS_DEFAULT = 100 PATIENCE_DEFAULT = 10 METRICS = [ keras_metrics.TruePositives(name="tp"), keras_metrics.FalsePositives(name="fp"), keras_metrics.TrueNegatives(name="tn"), keras_metrics.FalseNegatives(name="fn"), keras_metrics.BinaryAccuracy(name="accuracy"), keras_metrics.Precision(name="precision"), keras_metrics.Recall(name="recall"), keras_metrics.AUC(name="auc"), ] parser = argparse.ArgumentParser( description="Run a Logistic Regression pipeline.") parser.add_argument("dataset_pkl", help="Dataset (in PKL format) to use.") parser.add_argument( "--name", help= "Configuration name (e.g. 'contacts' or 'topology'). This will be tagged during the MLFlow run.", default=None, ) parser.add_argument("--epochs",
def main(**kwargs): import sys for k, v in kwargs.items(): sys.argv += [k, v] from pprint import pprint import argparse import datetime import json import os parser = argparse.ArgumentParser() parser.add_argument('--neptune_project_name', default='jacobarose/sandbox', type=str, help='Neptune.ai project name to log under') parser.add_argument('--experiment_name', default='pnas_minimal_example', type=str, help='Neptune.ai experiment name to log under') parser.add_argument('--config_path', default=r'/home/jacob/projects/pyleaves/pyleaves/configs/example_configs/pnas_resnet_config.json', type=str, help='JSON config file') parser.add_argument('-gpu', '--gpu_id', default='1', type=str, help='integer number of gpu to train on', dest='gpu_id') parser.add_argument('-tags', '--add-tags', default=[], type=str, nargs='*', help='Add arbitrary list of tags to apply to this run in neptune', dest='tags') parser.add_argument('-f', default=None) args = parser.parse_args() with open(args.config_path, 'r') as config_file: PARAMS = json.load(config_file) # print(gpu) # os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"] = str(args.gpu_id) pprint(PARAMS) import tensorflow as tf import neptune # tf.debugging.set_log_device_placement(True) print(tf.__version__) import arrow import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import io from stuf import stuf from more_itertools import unzip from functools import partial # import tensorflow as tf # tf.compat.v1.enable_eager_execution() AUTOTUNE = tf.data.experimental.AUTOTUNE from pyleaves.leavesdb.tf_utils.tf_utils import set_random_seed, reset_keras_session import pyleaves from pyleaves.utils.img_utils import random_pad_image from pyleaves.utils.utils import ensure_dir_exists from pyleaves.datasets import leaves_dataset, fossil_dataset, pnas_dataset, base_dataset from pyleaves.models.vgg16 import VGG16, VGG16GrayScale from pyleaves.models import resnet, vgg16 from tensorflow.compat.v1.keras.callbacks import Callback, ModelCheckpoint, TensorBoard, LearningRateScheduler, EarlyStopping from tensorflow.keras import metrics from tensorflow.keras.preprocessing.image import load_img, img_to_array from tensorflow.keras import layers from tensorflow.keras import backend as K import tensorflow_datasets as tfds import neptune_tensorboard as neptune_tb seed = 346 # set_random_seed(seed) # reset_keras_session() def get_preprocessing_func(model_name): if model_name.startswith('resnet'): from tensorflow.keras.applications.resnet_v2 import preprocess_input elif model_name == 'vgg16': from tensorflow.keras.applications.vgg16 import preprocess_input elif model_name=='shallow': def preprocess_input(x): return x/255.0 # ((x/255.0)-0.5)*2.0 return preprocess_input #lambda x,y: (preprocess_input(x),y) def _load_img(image_path):#, img_size=(224,224)): img = tf.io.read_file(image_path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.convert_image_dtype(img, tf.float32) return img # return tf.compat.v1.image.resize_image_with_pad(img, *img_size) def _encode_label(label, num_classes=19): label = tf.cast(label, tf.int32) label = tf.one_hot(label, depth=num_classes) return label def _load_example(image_path, label, num_classes=19): img = _load_img(image_path) one_hot_label = _encode_label(label, num_classes=num_classes) return img, one_hot_label def _load_uint8_example(image_path, label, num_classes=19): img = tf.image.convert_image_dtype(_load_img(image_path)*255.0, dtype=tf.uint8) one_hot_label = _encode_label(label, num_classes=num_classes) return img, one_hot_label def rgb2gray_3channel(img, label): ''' Convert rgb image to grayscale, but keep num_channels=3 ''' img = tf.image.rgb_to_grayscale(img) img = tf.image.grayscale_to_rgb(img) return img, label def rgb2gray_1channel(img, label): ''' Convert rgb image to grayscale, num_channels from 3 to 1 ''' img = tf.image.rgb_to_grayscale(img) return img, label def log_data(logs): for k, v in logs.items(): neptune.log_metric(k, v) neptune_logger = tf.keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch, logs: log_data(logs)) def focal_loss(gamma=2.0, alpha=4.0): gamma = float(gamma) alpha = float(alpha) def focal_loss_fixed(y_true, y_pred): """Focal loss for multi-classification FL(p_t)=-alpha(1-p_t)^{gamma}ln(p_t) Notice: y_pred is probability after softmax gradient is d(Fl)/d(p_t) not d(Fl)/d(x) as described in paper d(Fl)/d(p_t) * [p_t(1-p_t)] = d(Fl)/d(x) Focal Loss for Dense Object Detection https://arxiv.org/abs/1708.02002 Arguments: y_true {tensor} -- ground truth labels, shape of [batch_size, num_cls] y_pred {tensor} -- model's output, shape of [batch_size, num_cls] Keyword Arguments: gamma {float} -- (default: {2.0}) alpha {float} -- (default: {4.0}) Returns: [tensor] -- loss. """ epsilon = 1.e-9 y_true = tf.convert_to_tensor(y_true, tf.float32) y_pred = tf.convert_to_tensor(y_pred, tf.float32) model_out = tf.add(y_pred, epsilon) ce = tf.multiply(y_true, -tf.log(model_out)) weight = tf.multiply(y_true, tf.pow(tf.subtract(1., model_out), gamma)) fl = tf.multiply(alpha, tf.multiply(weight, ce)) reduced_fl = tf.reduce_max(fl, axis=1) return tf.reduce_mean(reduced_fl) return focal_loss_fixed def per_class_accuracy(y_true, y_pred): return tf.metrics.mean_per_class_accuracy(y_true, y_pred, num_classes=PARAMS['num_classes']) def build_model(model_params, optimizer, loss, METRICS): if model_params['name']=='vgg16': model_builder = vgg16.VGG16GrayScale(model_params) elif model_params['name'].startswith('resnet'): model_builder = resnet.ResNet(model_params) base = model_builder.build_base() model = model_builder.build_head(base) model.compile(optimizer=optimizer, loss=loss, metrics=METRICS) return model def build_shallow(input_shape=(224,224,3), num_classes=10, optimizer=None, loss=None, METRICS=None): model = tf.keras.models.Sequential() model.add(layers.Conv2D(64, (7, 7), activation='relu', input_shape=input_shape, kernel_initializer=tf.initializers.GlorotNormal())) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (7, 7), activation='relu', kernel_initializer=tf.initializers.GlorotNormal())) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (7, 7), activation='relu', kernel_initializer=tf.initializers.GlorotNormal())) model.add(layers.Flatten()) model.add(layers.Dense(64*2, activation='relu', kernel_initializer=tf.initializers.GlorotNormal())) model.add(layers.Dense(num_classes,activation='softmax', kernel_initializer=tf.initializers.GlorotNormal())) model.compile(optimizer=optimizer, loss=loss, metrics=METRICS) return model class ImageLogger: '''Tensorflow 2.0 version''' def __init__(self, log_dir: str, max_images: int, name: str): self.file_writer = tf.summary.create_file_writer(log_dir) self.log_dir = log_dir self.max_images = max_images self.name = name self._counter = tf.Variable(0, dtype=tf.int64) self.filepaths = [] def add_log(self, img, counter=None, name=None): ''' Intention is to generalize this to an abstract class for logging to any experiment management platform (e.g. neptune, mlflow, etc) Currently takes a filepath pointing to an image file and logs to current neptune experiment. ''' # scaled_images = (img - tf.math.reduce_min(img))/(tf.math.reduce_max(img) - tf.math.reduce_min(img)) # keep = 0 # scaled_images = tf.image.convert_image_dtype(tf.squeeze(scaled_images[keep,:,:,:]), dtype=tf.uint8) # scaled_images = tf.expand_dims(scaled_images, 0) # tf.summary.image(name=self.name, data=scaled_images, step=self._counter, max_outputs=self.max_images) scaled_img = (img - np.min(img))/(np.max(img) - np.min(img)) * 255.0 scaled_img = scaled_img.astype(np.uint32) neptune.log_image(log_name= name or self.name, x=counter, y=scaled_img) return scaled_img def __call__(self, images, labels): with self.file_writer.as_default(): scaled_images = (images - tf.math.reduce_min(images))/(tf.math.reduce_max(images) - tf.math.reduce_min(images)) keep = 0 scaled_images = tf.image.convert_image_dtype(tf.squeeze(scaled_images[keep,:,:,:]), dtype=tf.uint8) scaled_images = tf.expand_dims(scaled_images, 0) labels = tf.argmax(labels[[keep], :],axis=1) tf.summary.image(name=self.name, data=scaled_images, step=self._counter, max_outputs=self.max_images) filepath = os.path.join(self.log_dir,'sample_images',f'{self.name}-{self._counter}.jpg') scaled_images = tf.image.encode_jpeg(tf.squeeze(scaled_images)) tf.io.write_file(filename=tf.constant(filepath), contents=scaled_images) # self.add_log(scaled_images) self._counter.assign_add(1) return images, labels def _cond_apply(x, y, func, prob): """Conditionally apply func to x and y with probability prob. Parameters ---------- x : type Input to conditionally pass through func y : type Label func : type Function to conditionally be applied to x and y prob : type Probability of applying function, within range [0.0,1.0] Returns ------- x, y """ return tf.cond((tf.random.uniform([], 0, 1) >= (1.0 - prob)), lambda: func(x,y), lambda: (x,y)) class ImageAugmentor: """Short summary. Parameters ---------- augmentations : dict Maps a sequence of named augmentations to a scalar probability, according to which they'll be conditionally applied in order. resize_w_pad : tuple, default=None Description of parameter `resize_w_pad`. random_crop : tuple, default=None Description of parameter `random_crop`. random_jitter : dict First applies resize_w_pad, then random_crop. If user desires only 1 of these, set this to None. Should be a dict with 2 keys: 'resize':(height, width) 'crop_size':(crop_height,crop_width, channels) Only 1 of these 3 kwargs should be provided to any given augmentor: {'resize_w_pad', 'random_crop', 'random_jitter'} Example values for each: resize_w_pad=(224,224) random_crop=(224,224,3) random_jitter={'resize':(338,338), 'crop_size':(224,224, 3)} seed : int, default=None Random seed to apply to all augmentations Examples ------- Examples should be written in doctest format, and should illustrate how to use the function/class. >>> Attributes ---------- augmentations """ def __init__(self, name='', augmentations={'rotate':1.0, 'flip':1.0, 'color':1.0, 'rgb2gray_3channel':1.0}, resize_w_pad=None, random_crop=None, random_jitter={'resize':(338,338), 'crop_size':(224,224,3)}, log_dir=None, seed=None): self.name = name self.augmentations = augmentations self.seed = seed if resize_w_pad: self.target_h = resize_w_pad[0] self.target_w = resize_w_pad[1] # self.resize = self.resize_w_pad elif random_crop: self.crop_size = random_crop self.target_h = self.crop_size[0] self.target_w = self.crop_size[1] # self.resize = self.random_crop elif random_jitter: # self.target_h = tf.random.uniform([], random_jitter['crop_size'][0], random_jitter['resize'][0], dtype=tf.int32, seed=self.seed) # self.target_w = tf.random.uniform([], random_jitter['crop_size'][1], random_jitter['resize'][1], dtype=tf.int32, seed=self.seed) self.crop_size = random_jitter['crop_size'] # self.resize = self.random_jitter self.target_h = random_jitter['crop_size'][0] self.target_w = random_jitter['crop_size'][1] self.resize = self.resize_w_pad self.maps = {'rotate':self.rotate, 'flip':self.flip, 'color':self.color, 'rgb2gray_3channel':self.rgb2gray_3channel, 'rgb2gray_1channel':self.rgb2gray_1channel} self.log_dir = log_dir def rotate(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: """Rotation augmentation Args: x, tf.Tensor: Image label, tf.Tensor: arbitrary tensor, passes through unchanged Returns: Augmented image, label """ # Rotate 0, 90, 180, 270 degrees return tf.image.rot90(x, tf.random.uniform(shape=[], minval=0, maxval=4, dtype=tf.int32,seed=self.seed)), label def flip(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: """Flip augmentation Args: x, tf.Tensor: Image to flip label, tf.Tensor: arbitrary tensor, passes through unchanged Returns: Augmented image, label """ x = tf.image.random_flip_left_right(x, seed=self.seed) x = tf.image.random_flip_up_down(x, seed=self.seed) return x, label def color(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: """Color augmentation Args: x, tf.Tensor: Image label, tf.Tensor: arbitrary tensor, passes through unchanged Returns: Augmented image, label """ x = tf.image.random_hue(x, 0.08, seed=self.seed) x = tf.image.random_saturation(x, 0.6, 1.6, seed=self.seed) x = tf.image.random_brightness(x, 0.05, seed=self.seed) x = tf.image.random_contrast(x, 0.7, 1.3, seed=self.seed) return x, label def rgb2gray_3channel(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: """Convert RGB image -> grayscale image, maintain number of channels = 3 Args: x, tf.Tensor: Image label, tf.Tensor: arbitrary tensor, passes through unchanged Returns: Augmented image, label """ x = tf.image.rgb_to_grayscale(x) x = tf.image.grayscale_to_rgb(x) return x, label def rgb2gray_1channel(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: """Convert RGB image -> grayscale image, reduce number of channels from 3 -> 1 Args: x, tf.Tensor: Image label, tf.Tensor: arbitrary tensor, passes through unchanged Returns: Augmented image, label """ x = tf.image.rgb_to_grayscale(x) return x, label def resize_w_pad(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: # TODO Finish this # random_pad_image(x,min_image_size=None,max_image_size=None,pad_color=None,seed=self.seed) return tf.image.resize_with_pad(x, target_height=self.target_h, target_width=self.target_w), label def random_crop(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: return tf.image.random_crop(x, size=self.crop_size), label @tf.function def random_jitter(self, x: tf.Tensor, label: tf.Tensor) -> tf.Tensor: x, label = self.resize_w_pad(x, label) x, label = self.random_crop(x, label) return x, label def apply_augmentations(self, dataset: tf.data.Dataset): """ Call this function to apply all of the augmentation in the order of specification provided to the constructor __init__() of ImageAugmentor. Args: dataset, tf.data.Dataset: must yield individual examples of form (x, y) Returns: Augmented dataset """ dataset = dataset.map(self.resize, num_parallel_calls=AUTOTUNE) for aug_name, aug_p in self.augmentations.items(): aug = self.maps[aug_name] dataset = dataset.map(lambda x,y: _cond_apply(x, y, aug, prob=aug_p), num_parallel_calls=AUTOTUNE) # dataset = dataset.map(lambda x,y: _cond_apply(x, y, func=aug, prob=aug_p), num_parallel_calls=AUTOTUNE) return dataset class ImageLoggerCallback(Callback): '''Tensorflow 2.0 version Callback that keeps track of a tf.data.Dataset and logs the correct batch to neptune based on the current batch. ''' def __init__(self, data :tf.data.Dataset, freq=1, max_images=-1, name='', encoder=None): self.data = data self.freq = freq self.max_images = max_images self.name = name self.encoder=encoder self.init_iterator() def init_iterator(self): self.data_iter = iter(self.data) self._batch = 0 self._count = 0 self.finished = False def yield_batch(self): batch_data = next(self.data_iter) self._batch += 1 self._count += batch_data[0].shape[0] return batch_data def add_log(self, img, counter=None, name=None): ''' Intention is to generalize this to an abstract class for logging to any experiment management platform (e.g. neptune, mlflow, etc) Currently takes a filepath pointing to an image file and logs to current neptune experiment. ''' scaled_img = (img - np.min(img))/(np.max(img) - np.min(img)) * 255.0 scaled_img = scaled_img.astype(np.uint32) neptune.log_image(log_name= name or self.name, x=counter, y=scaled_img) return scaled_img def on_train_batch_begin(self, batch, logs=None): if batch % self.freq or self.finished: return while batch >= self._batch: x, y = self.yield_batch() if self.max_images==-1: self.max_images=x.shape[0] if x.ndim==3: np.newaxis(x, axis=0) if x.shape[0]>self.max_images: x = x[:self.max_images,...] y = y[:self.max_images,...] x = x.numpy() y = np.argmax(y.numpy(),axis=1) if self.encoder: y = self.encoder.decode(y) for i in range(x.shape[0]): # self.add_log(x[i,...], counter=i, name = f'{self.name}-{y[i]}-batch_{str(self._batch).zfill(3)}') self.add_log(x[i,...], counter=self._count+i, name = f'{self.name}-{y[i]}') print(f'Batch {self._batch}: Logged {np.max([x.shape[0],self.max_images])} {self.name} images to neptune') def on_epoch_end(self, epoch, logs={}): self.finished = True class ConfusionMatrixCallback(Callback): '''Tensorflow 2.0 version''' def __init__(self, log_dir, imgs : dict, labels : dict, classes, freq=1, include_train=False, seed=None): self.file_writer = tf.summary.create_file_writer(log_dir) self.log_dir = log_dir self.seed = seed self._counter = 0 assert np.all(np.array(imgs.keys()) == np.array(labels.keys())) self.imgs = imgs for k,v in labels.items(): if v.ndim==2: labels[k] = tf.argmax(v,axis=-1) self.labels = labels self.num_samples = {k:l.numpy().shape[0] for k,l in labels.items()} self.classes = classes self.freq = freq self.include_train = include_train def log_confusion_matrix(self, model, imgs, labels, epoch, name='', norm_cm=False): pred_labels = model.predict_classes(imgs) # pred_labels = tf.argmax(pred_labels,axis=-1) pred_labels = pred_labels[:,None] con_mat = tf.math.confusion_matrix(labels=labels, predictions=pred_labels, num_classes=len(self.classes)).numpy() if norm_cm: con_mat = np.around(con_mat.astype('float') / con_mat.sum(axis=1)[:, np.newaxis], decimals=2) con_mat_df = pd.DataFrame(con_mat, index = self.classes, columns = self.classes) figure = plt.figure(figsize=(12, 12)) sns.heatmap(con_mat_df, annot=True, cmap=plt.cm.Blues) plt.tight_layout() plt.ylabel('True label') plt.xlabel('Predicted label') buf = io.BytesIO() plt.savefig(buf, format='png') buf.seek(0) image = tf.image.decode_png(buf.getvalue(), channels=4) image = tf.expand_dims(image, 0) with self.file_writer.as_default(): tf.summary.image(name=name+'_confusion_matrix', data=image, step=self._counter) neptune.log_image(log_name=name+'_confusion_matrix', x=self._counter, y=figure) plt.close(figure) self._counter += 1 return image def on_epoch_end(self, epoch, logs={}): if (not self.freq) or (epoch%self.freq != 0): return if self.include_train: cm_summary_image = self.log_confusion_matrix(self.model, self.imgs['train'], self.labels['train'], epoch=epoch, name='train') cm_summary_image = self.log_confusion_matrix(self.model, self.imgs['val'], self.labels['val'], epoch=epoch, name='val') #################################################################################### #################################################################################### #################################################################################### neptune.init(project_qualified_name=args.neptune_project_name) # neptune_tb.integrate_with_tensorflow() experiment_dir = '/media/data/jacob/sandbox_logs' experiment_name = args.experiment_name experiment_start_time = arrow.utcnow().format('YYYY-MM-DD_HH-mm-ss') log_dir =os.path.join(experiment_dir, experiment_name, 'log_dir',PARAMS['loss'], experiment_start_time) ensure_dir_exists(log_dir) print('Tensorboard log_dir: ', log_dir) # os.system(f'neptune tensorboard {log_dir} --project {args.neptune_project_name}') weights_best = os.path.join(log_dir, 'model_ckpt.h5') restore_best_weights=False histogram_freq=0 patience=25 num_epochs = PARAMS['num_epochs'] initial_epoch=0 src_db = pyleaves.DATABASE_PATH datasets = { 'PNAS': pnas_dataset.PNASDataset(src_db=src_db), 'Leaves': leaves_dataset.LeavesDataset(src_db=src_db), 'Fossil': fossil_dataset.FossilDataset(src_db=src_db) } # data = datasets[PARAMS['dataset_name']] data_config = stuf(threshold=PARAMS['data_threshold'], num_classes=PARAMS['num_classes'] , data_splits_meta={ 'train':PARAMS['train_size'], 'val':PARAMS['val_size'], 'test':PARAMS['test_size'] } ) preprocess_input = get_preprocessing_func(PARAMS['model_name']) preprocess_input(tf.zeros([4, 224, 224, 3])) load_example = partial(_load_uint8_example, num_classes=data_config.num_classes) # load_example = partial(_load_example, num_classes=data_config.num_classes) if PARAMS['num_channels']==3: color_aug = {'rgb2gray_3channel':1.0} elif PARAMS['num_channels']==1: color_aug = {'rgb2gray_1channel':1.0} resize_w_pad=None random_jitter=None if not PARAMS['random_jitter']['resize']: resize_w_pad = PARAMS['image_size'] else: random_jitter=PARAMS['random_jitter'] TRAIN_image_augmentor = ImageAugmentor(name='train', augmentations={**PARAMS["augmentations"], **color_aug},#'rotate':1.0,'flip':1.0,**color_aug}, resize_w_pad=resize_w_pad, random_crop=None, random_jitter=random_jitter, log_dir=log_dir, seed=None) VAL_image_augmentor = ImageAugmentor(name='val', augmentations={**color_aug}, resize_w_pad=PARAMS['image_size'], random_crop=None, random_jitter=None, log_dir=log_dir, seed=None) TEST_image_augmentor = ImageAugmentor(name='test', augmentations={**color_aug}, resize_w_pad=PARAMS['image_size'], random_crop=None, random_jitter=None, log_dir=log_dir, seed=None) def neptune_log_augmented_images(split_data, num_demo_samples=40, PARAMS=PARAMS): num_demo_samples = 40 cm_data_x = {'train':[],'val':[]} cm_data_y = {'train':[],'val':[]} cm_data_x['train'], cm_data_y['train'] = next(iter(get_data_loader(data=split_data['train'], data_subset_mode='train', batch_size=num_demo_samples, infinite=True, augment=False,seed=2836))) cm_data_x['val'], cm_data_y['val'] = next(iter(get_data_loader(data=split_data['val'], data_subset_mode='val', batch_size=num_demo_samples, infinite=True, augment=False, seed=2836))) for (k_x,v_x), (k_y, v_y) in zip(cm_data_x.items(), cm_data_y.items()): x = tf.data.Dataset.from_tensor_slices(v_x) y = tf.data.Dataset.from_tensor_slices(v_y) xy_data = tf.data.Dataset.zip((x, y)) v = xy_data.map(VAL_image_augmentor.resize, num_parallel_calls=AUTOTUNE) v_aug = TRAIN_image_augmentor.apply_augmentations(xy_data) v_x, v_y = [i.numpy() for i in next(iter(v.batch(10*num_demo_samples)))] v_x_aug, v_y_aug = [i.numpy() for i in next(iter(v_aug.batch(10*num_demo_samples)))] k = k_x for i in range(num_demo_samples): print(f'Neptune: logging {k}_{i}') print(f'{v_x[i].shape}, {v_x_aug[i].shape}') idx = np.random.randint(0,len(v_x)) if True: #'train' in k: TRAIN_image_augmentor.logger.add_log(v_x[idx],counter=i, name=k) TRAIN_image_augmentor.logger.add_log(v_x_aug[idx],counter=i, name=k+'_aug') def get_data_loader(data : tuple, data_subset_mode='train', batch_size=32, num_classes=None, infinite=True, augment=True, seed=2836): num_samples = len(data[0]) x = tf.data.Dataset.from_tensor_slices(data[0]) labels = tf.data.Dataset.from_tensor_slices(data[1]) data = tf.data.Dataset.zip((x, labels)) data = data.cache() if data_subset_mode == 'train': data = data.shuffle(buffer_size=num_samples) # data = data.map(lambda x,y: (tf.image.convert_image_dtype(load_img(x)*255.0,dtype=tf.uint8),y), num_parallel_calls=-1) # data = data.map(load_example, num_parallel_calls=AUTOTUNE) data = data.map(load_example, num_parallel_calls=AUTOTUNE) data = data.map(lambda x,y: (preprocess_input(x), y), num_parallel_calls=AUTOTUNE) if infinite: data = data.repeat() if data_subset_mode == 'train': data = data.shuffle(buffer_size=200, seed=seed) augmentor = TRAIN_image_augmentor elif data_subset_mode == 'val': augmentor = VAL_image_augmentor elif data_subset_mode == 'test': augmentor = TEST_image_augmentor if augment: data = augmentor.apply_augmentations(data) data = data.batch(batch_size, drop_remainder=True) return data.prefetch(AUTOTUNE) def get_tfds_data_loader(data : tf.data.Dataset, data_subset_mode='train', batch_size=32, num_samples=100, num_classes=19, infinite=True, augment=True, seed=2836): def encode_example(x, y): x = tf.image.convert_image_dtype(x, tf.float32) * 255.0 y = _encode_label(y, num_classes=num_classes) return x, y test_d = next(iter(data)) print(test_d[0].numpy().min()) print(test_d[0].numpy().max()) data = data.shuffle(buffer_size=num_samples) \ .cache() \ .map(encode_example, num_parallel_calls=AUTOTUNE) test_d = next(iter(data)) print(test_d[0].numpy().min()) print(test_d[0].numpy().max()) data = data.map(preprocess_input, num_parallel_calls=AUTOTUNE) test_d = next(iter(data)) print(test_d[0].numpy().min()) print(test_d[0].numpy().max()) if data_subset_mode == 'train': data = data.shuffle(buffer_size=100, seed=seed) augmentor = TRAIN_image_augmentor elif data_subset_mode == 'val': augmentor = VAL_image_augmentor elif data_subset_mode == 'test': augmentor = TEST_image_augmentor if augment: data = augmentor.apply_augmentations(data) test_d = next(iter(data)) print(test_d[0].numpy().min()) print(test_d[0].numpy().max()) data = data.batch(batch_size, drop_remainder=True) if infinite: data = data.repeat() return data.prefetch(AUTOTUNE) # y_true = [[0, 1, 0], [0, 0, 1]] # y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]] def accuracy(y_true, y_pred): y_pred = tf.argmax(y_pred, axis=-1) y_true = tf.argmax(y_true, axis=-1) return tf.reduce_mean(tf.cast(tf.equal(y_true, y_pred), tf.float32)) def true_pos(y_true, y_pred): # y_true = K.ones_like(y_true) return K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) def false_pos(y_true, y_pred): # y_true = K.ones_like(y_true) true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) all_positives = K.sum(K.round(K.clip(y_true, 0, 1))) return all_positives - true_positives def true_neg(y_true, y_pred): # y_true = K.ones_like(y_true) return K.sum(1-K.round(K.clip(y_true * y_pred, 0, 1))) def recall(y_true, y_pred): # y_true = K.ones_like(y_true) true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) all_positives = K.sum(K.round(K.clip(y_true, 0, 1))) recall = true_positives / (all_positives + K.epsilon()) return recall def precision(y_true, y_pred): y_true = K.ones_like(y_true) true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1))) precision = true_positives / (predicted_positives + K.epsilon()) # tf.print(y_true, y_pred) return precision def f1_score(y_true, y_pred): m_precision = precision(y_true, y_pred) m_recall = recall(y_true, y_pred) # pdb.set_trace() return 2*((m_precision*m_recall)/(m_precision+m_recall+K.epsilon())) # def false_neg(y_true, y_pred): # y_true = K.ones_like(~y_true) # true_neg = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) # all_negative = K.sum(K.round(K.clip(y_true, 0, 1))) # return all_negatives - true_ # return K.mean(K.argmax(y_true,axis=1)*K.argmax(y_pred,axis=1)) # 'accuracy', # metrics.TrueNegatives(name='tn'), # metrics.FalseNegatives(name='fn'), METRICS = [ f1_score, metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.CategoricalAccuracy(name='accuracy'), metrics.TopKCategoricalAccuracy(name='top_3_categorical_accuracy', k=3), metrics.TopKCategoricalAccuracy(name='top_5_categorical_accuracy', k=5) ] PARAMS['sys.argv'] = ' '.join(sys.argv) with neptune.create_experiment(name=experiment_name, params=PARAMS, upload_source_files=[__file__]): print('Logging experiment tags:') for tag in args.tags: print(tag) neptune.append_tag(tag) neptune.append_tag(PARAMS['dataset_name']) neptune.append_tag(PARAMS['model_name']) neptune.log_artifact(args.config_path) cm_data_x = {'train':[],'val':[]} cm_data_y = {'train':[],'val':[]} if PARAMS['dataset_name'] in tfds.list_builders(): num_demo_samples=40 tfds_builder = tfds.builder(PARAMS['dataset_name']) tfds_builder.download_and_prepare() num_samples = tfds_builder.info.splits['train'].num_examples num_samples_dict = {'train':int(num_samples*PARAMS['train_size']), 'val':int(num_samples*PARAMS['val_size']), 'test':int(num_samples*PARAMS['test_size'])} classes = tfds_builder.info.features['label'].names num_classes = len(classes) train_slice = [0,int(PARAMS['train_size']*100)] val_slice = [int(PARAMS['train_size']*100), int((PARAMS['train_size']+PARAMS['val_size'])*100)] test_slice = [100 - int(PARAMS['test_size']*100), 100] tfds_train_data = tfds.load(PARAMS['dataset_name'], split=f"train[{train_slice[0]}%:{train_slice[1]}%]", shuffle_files=True, as_supervised=True) tfds_validation_data = tfds.load(PARAMS['dataset_name'], split=f"train[{val_slice[0]}%:{val_slice[1]}%]", shuffle_files=True, as_supervised=True) tfds_test_data = tfds.load(PARAMS['dataset_name'], split=f"train[{test_slice[0]}%:{test_slice[1]}%]", shuffle_files=True, as_supervised=True) # PARAMS['batch_size']=1 train_data = get_tfds_data_loader(data = tfds_train_data, data_subset_mode='train', batch_size=PARAMS['batch_size'], num_samples=num_samples_dict['train'], num_classes=num_classes, infinite=True, augment=True, seed=2836) validation_data = get_tfds_data_loader(data = tfds_validation_data, data_subset_mode='val', batch_size=PARAMS['batch_size'], num_samples=num_samples_dict['val'], num_classes=num_classes, infinite=True, augment=True, seed=2837) test_data = get_tfds_data_loader(data = tfds_test_data, data_subset_mode='test', batch_size=PARAMS['batch_size'], num_samples=num_samples_dict['test'], num_classes=num_classes, infinite=True, augment=True, seed=2838) # tfds_train_data = tfds.load(PARAMS['dataset_name'], split=f"train[{train_slice[0]}%:{train_slice[1]}%]", shuffle_files=True, as_supervised=True) # tfds_validation_data = tfds.load(PARAMS['dataset_name'], split=f"train[{val_slice[0]}%:{val_slice[1]}%]", shuffle_files=True, as_supervised=True) # tfds_test_data = tfds.load(PARAMS['dataset_name'], split=f"train[{test_slice[0]}%:{test_slice[1]}%]", shuffle_files=True, as_supervised=True) split_data = {'train':get_tfds_data_loader(data = tfds_train_data, data_subset_mode='train', batch_size=num_demo_samples, num_samples=num_samples_dict['train'], num_classes=num_classes, infinite=True, augment=True, seed=2836), 'val':get_tfds_data_loader(data = tfds_validation_data, data_subset_mode='val', batch_size=num_demo_samples, num_samples=num_samples_dict['val'], num_classes=num_classes, infinite=True, augment=True, seed=2837), 'test':get_tfds_data_loader(data = tfds_test_data, data_subset_mode='test', batch_size=num_demo_samples, num_samples=num_samples_dict['test'], num_classes=num_classes, infinite=True, augment=True, seed=2838) } steps_per_epoch=num_samples_dict['train']//PARAMS['batch_size'] validation_steps=num_samples_dict['val']//PARAMS['batch_size'] cm_data_x['train'], cm_data_y['train'] = next(iter(split_data['train'])) cm_data_x['val'], cm_data_y['val'] = next(iter(split_data['val'])) else: data = datasets[PARAMS['dataset_name']] neptune.set_property('num_classes',data.num_classes) neptune.set_property('class_distribution',data.metadata.class_distribution) encoder = base_dataset.LabelEncoder(data.data.family) split_data = base_dataset.preprocess_data(data, encoder, data_config) # import pdb;pdb.set_trace() for subset, subset_data in split_data.items(): split_data[subset] = [list(i) for i in unzip(subset_data)] PARAMS['batch_size'] = 32 steps_per_epoch=len(split_data['train'][0])//PARAMS['batch_size']#//10 validation_steps=len(split_data['val'][0])//PARAMS['batch_size']#//10 split_datasets = { k:base_dataset.BaseDataset.from_dataframe( pd.DataFrame({ 'path':v[0], 'family':v[1] })) \ for k,v in split_data.items() } for k,v in split_datasets.items(): print(k, v.num_classes) classes = split_datasets['train'].classes train_data=get_data_loader(data=split_data['train'], data_subset_mode='train', batch_size=PARAMS['batch_size'], infinite=True, augment=True, seed=2836) validation_data=get_data_loader(data=split_data['val'], data_subset_mode='val', batch_size=PARAMS['batch_size'], infinite=True, augment=True, seed=2837) if 'test' in split_data.keys(): test_data=get_data_loader(data=split_data['test'], data_subset_mode='test', batch_size=PARAMS['batch_size'], infinite=True, augment=True, seed=2838) num_demo_samples=150 # neptune_log_augmented_images(split_data, num_demo_samples=num_demo_samples, PARAMS=PARAMS) cm_data_x['train'], cm_data_y['train'] = next(iter(get_data_loader(data=split_data['train'], data_subset_mode='train', batch_size=num_demo_samples, infinite=True, augment=True, seed=2836))) cm_data_x['val'], cm_data_y['val'] = next(iter(get_data_loader(data=split_data['val'], data_subset_mode='val', batch_size=num_demo_samples, infinite=True, augment=True, seed=2836))) ######################################################################################## train_image_logger_cb = ImageLoggerCallback(data=train_data, freq=20, max_images=-1, name='train', encoder=encoder) val_image_logger_cb = ImageLoggerCallback(data=validation_data, freq=20, max_images=-1, name='val', encoder=encoder) ######################################################################################## cm_callback = ConfusionMatrixCallback(log_dir, cm_data_x, cm_data_y, classes=classes, seed=PARAMS['seed'], include_train=True) checkpoint = ModelCheckpoint(weights_best, monitor='val_loss', verbose=0, save_best_only=True, save_weights_only=False, mode='min',restore_best_weights=restore_best_weights) tfboard = TensorBoard(log_dir=log_dir, histogram_freq=histogram_freq, write_images=True) early = EarlyStopping(monitor='val_loss', patience=patience, verbose=1) callbacks = [checkpoint,tfboard,early, cm_callback, neptune_logger, train_image_logger_cb, val_image_logger_cb] ########################## if PARAMS['optimizer'] == 'Adam': optimizer = tf.keras.optimizers.Adam( learning_rate=PARAMS['lr'] ) elif PARAMS['optimizer'] == 'Nadam': optimizer = tf.keras.optimizers.Nadam( learning_rate=PARAMS['lr'] ) elif PARAMS['optimizer'] == 'SGD': optimizer = tf.keras.optimizers.SGD( learning_rate=PARAMS['lr'] ) ########################## if PARAMS['loss']=='focal_loss': loss = focal_loss(gamma=2.0, alpha=4.0) elif PARAMS['loss']=='categorical_crossentropy': loss = 'categorical_crossentropy' ########################## model_params = stuf(name=PARAMS['model_name'], model_dir=os.path.join(experiment_dir, experiment_name, 'models'), num_classes=PARAMS['num_classes'], frozen_layers = PARAMS['frozen_layers'], input_shape = (*PARAMS['image_size'],PARAMS['num_channels']), base_learning_rate = PARAMS['lr'], regularization = PARAMS['regularization']) #### if PARAMS['model_name']=='shallow': model = build_shallow(input_shape=model_params.input_shape, num_classes=PARAMS['num_classes'], optimizer=optimizer, loss=loss, METRICS=METRICS) else: model = build_model(model_params, optimizer, loss, METRICS) print(f"TRAINING {PARAMS['model_name']}") model.summary(print_fn=lambda x: neptune.log_text('model_summary', x)) history = model.fit(train_data, epochs=num_epochs, callbacks=callbacks, validation_data=validation_data, shuffle=True, initial_epoch=initial_epoch, steps_per_epoch=steps_per_epoch, validation_steps=validation_steps) if 'test' in split_data: results = model.evaluate(test_data, steps=len(split_data['test'][0])) else: results = model.evaluate(validation_data, steps=validation_steps)
def train_model(self, themes_weight: ThemeWeights, dataset: TrainValidationDataset, voc_size: int, keras_callback: LambdaCallback): input = keras.layers.Input(shape=(dataset.article_length)) outputs: List[keras.layers.Layer] = [] for i in range(0, dataset.theme_count): print("") dense = keras.layers.Embedding( input_dim=voc_size, output_dim=self.embedding_size)(input) ltsm = keras.layers.Bidirectional( keras.layers.LSTM(self.LTSM_output_size, recurrent_dropout=0.2, dropout=0.2))(dense) dropout = keras.layers.Dropout(0.2)(ltsm) dense2 = keras.layers.Dense(units=self.dense2_output_size, activation=tf.nn.relu)(dropout) output = keras.layers.Dense( units=1, activation=tf.nn.sigmoid, name=str(i), kernel_regularizer=regularizers.l2(0.01), activity_regularizer=regularizers.l1(0.01))(dense2) outputs.append(output) if len(outputs) > 1: outputs = [keras.layers.concatenate(outputs)] else: outputs = [outputs] model = keras.Model(inputs=[input], outputs=outputs) model.compile( optimizer=tf.keras.optimizers.Adam(clipnorm=1, clipvalue=0.5), #loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), loss=WeightedBinaryCrossEntropy( weights=themes_weight.weight_list(), from_logits=True), # loss = {"0" : tf.keras.losses.BinaryCrossentropy(from_logits=True), # "1" : tf.keras.losses.BinaryCrossentropy(from_logits=True)}, metrics=[ metrics.AUC(multi_label=True), metrics.BinaryAccuracy(), metrics.TruePositives(), metrics.TrueNegatives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.Recall(), metrics.Precision() ], run_eagerly=False) model.summary() keras.utils.plot_model(model, self.__model_name__ + '.png', show_shapes=True) callbacks = [ManualInterrupter, keras_callback] # model.fit(self.dataset.trainData, epochs=15, steps_per_epoch=self.dataset.train_batch_count, # validation_data=self.dataset.validationData, validation_steps=self.dataset.validation_batch_count, # callbacks=callbacks, class_weight=self.theme_weight) # model.fit(self.dataset.trainData, epochs=10, steps_per_epoch=self.dataset.train_batch_count, # validation_data=self.dataset.validationData, validation_steps=self.dataset.validation_batch_count, # callbacks=callbacks, class_weight={ 0 : 1, 1 : 7.8, 2 : 4.3}) model.fit(dataset.trainData, epochs=40, steps_per_epoch=dataset.train_batch_count, validation_data=dataset.validationData, validation_steps=dataset.validation_batch_count, callbacks=callbacks) self.__model__ = model
def train( csv_path, model_save_path, tfrecords_path, volume_shape=(128, 128, 128), image_size=(128, 128), dropout=0.2, batch_size=16, n_classes=2, n_epochs=15, mode="CV", ): """Train a model. Parameters ---------- csv_path: str - Path Path to the csv file containing training volume paths, labels (X, Y). model_save_path: str - Path Path to where the save model and model weights. tfrecords_path: str - Path Path to preprocessed training tfrecords. volume_shape: tuple of size 3, optional, default=(128, 128, 128) The shape of the preprocessed volumes. image_size: tuple of size 2, optional, default=(128, 128) The shape of a 2D slice along each volume axis. dropout: float, optional, default=0.4 Float between 0 and 1. Fraction of the input units to drop. batch_size: int, optional, default=16 No. of training examples utilized in each iteration. n_classes: int, optional, default=2 No. of unique classes to train the model on. Default assumption is a binary classifier. n_epochs: int, optional, default=15 No. of complete passes through the training dataset. mode: str, optional, default=15 One of "CV" or "full". Indicates the type of training to perform. Returns ------- `tf.keras.callbacks.History` A History object that records several metrics such as training/validation loss/metrics at successive epochs. """ train_csv_path = os.path.join(csv_path, "training.csv") train_paths = pd.read_csv(train_csv_path)["X"].values train_labels = pd.read_csv(train_csv_path)["Y"].values if mode == "CV": valid_csv_path = os.path.join(csv_path, "validation.csv") valid_paths = pd.read_csv(valid_csv_path)["X"].values # valid_labels = pd.read_csv(valid_csv_path)["Y"].values weights = class_weight.compute_class_weight("balanced", np.unique(train_labels), train_labels) weights = dict(enumerate(weights)) planes = ["axial", "coronal", "sagittal", "combined"] global_batch_size = batch_size os.makedirs(model_save_path, exist_ok=True) cp_save_path = os.path.join(model_save_path, "weights") logdir_path = os.path.join(model_save_path, "tb_logs") metrics_path = os.path.join(model_save_path, "metrics") os.makedirs(metrics_path, exist_ok=True) for plane in planes: logdir = os.path.join(logdir_path, plane) os.makedirs(logdir, exist_ok=True) tbCallback = TensorBoard(log_dir=logdir) os.makedirs(os.path.join(cp_save_path, plane), exist_ok=True) model_checkpoint = ModelCheckpoint( os.path.join(cp_save_path, plane, "best-wts.h5"), monitor="val_loss", save_weights_only=True, mode="min", ) if not plane == "combined": lr = 1e-3 model = _model.Submodel( input_shape=image_size, dropout=dropout, name=plane, include_top=True, weights=None, ) else: lr = 5e-4 model = _model.CombinedClassifier( input_shape=image_size, dropout=dropout, trainable=True, wts_root=cp_save_path, ) print("Submodel: ", plane) METRICS = [ metrics.TruePositives(name="tp"), metrics.FalsePositives(name="fp"), metrics.TrueNegatives(name="tn"), metrics.FalseNegatives(name="fn"), metrics.BinaryAccuracy(name="accuracy"), metrics.Precision(name="precision"), metrics.Recall(name="recall"), metrics.AUC(name="auc"), ] model.compile( loss=tf.keras.losses.binary_crossentropy, optimizer=Adam(learning_rate=lr), metrics=METRICS, ) dataset_train = get_dataset( file_pattern=os.path.join(tfrecords_path, "data-train_*"), n_classes=n_classes, batch_size=global_batch_size, volume_shape=volume_shape, plane=plane, shuffle_buffer_size=global_batch_size, ) steps_per_epoch = math.ceil(len(train_paths) / batch_size) if mode == "CV": earlystopping = EarlyStopping(monitor="val_loss", patience=3) dataset_valid = get_dataset( file_pattern=os.path.join(tfrecords_path, "data-valid_*"), n_classes=n_classes, batch_size=global_batch_size, volume_shape=volume_shape, plane=plane, shuffle_buffer_size=global_batch_size, ) validation_steps = math.ceil(len(valid_paths) / batch_size) history = model.fit( dataset_train, epochs=n_epochs, steps_per_epoch=steps_per_epoch, validation_data=dataset_valid, validation_steps=validation_steps, callbacks=[tbCallback, model_checkpoint, earlystopping], class_weight=weights, ) hist_df = pd.DataFrame(history.history) else: earlystopping = EarlyStopping(monitor="loss", patience=3) print(model.summary()) print("Steps/Epoch: ", steps_per_epoch) history = model.fit( dataset_train, epochs=n_epochs, steps_per_epoch=steps_per_epoch, callbacks=[tbCallback, model_checkpoint, earlystopping], class_weight=weights, ) hist_df = pd.DataFrame(history.history) jsonfile = os.path.join(metrics_path, plane + ".json") with open(jsonfile, mode="w") as f: hist_df.to_json(f) return history
def dag_2_cnn(dag, gpuID, input_shape=(256,256,1), target_shape=(256,256,1), pretrained_weights = None, compile=True): os.environ["CUDA_VISIBLE_DEVICES"] = str(gpuID) nodes = list(dag.nodes()) #breadth-first search starting at root bfs = nx.bfs_successors(dag, nodes[0]) modules = dict() #root will always have this name assert(nodes[0] == 'input_0_0') with tf.device('/gpu:{}'.format(gpuID)): modules[nodes[0]] = Input(input_shape) for branch in bfs: #branch: tuple with (node, [list of successors to node]) for successor in branch[1]: modules = traverse(dag, successor, modules) leaves = [x for x in dag.nodes() if dag.out_degree(x)==0 and dag.in_degree(x)>0] if len(leaves) == 1: output = modules[leaves[0]] else: raise NotImplementedError #NOTE: mean iou removed from metrics 21/07/2020 model = Model(inputs=modules['input_0_0'], outputs=output) if compile: model.compile(optimizer=Adam(lr=1e-4), loss='binary_crossentropy', metrics=['accuracy', metrics.Precision(), metrics.Recall(), metrics.TruePositives(), metrics.TrueNegatives(), metrics.FalsePositives(), metrics.FalseNegatives(), metrics.AUC()]) if pretrained_weights: model.load_weights(pretrained_weights) return model
def train_model(self, themes_weight: List[float], dataset: TrainValidationDataset, voc_size: int, keras_callback: LambdaCallback): article_length = dataset.article_length theme_count = dataset.theme_count model = tf.keras.Sequential([ # 1 # keras.layers.Embedding(input_dim=voc_size, output_dim=firstLayoutOutputDim), # keras.layers.Dropout(0.2), # keras.layers.Conv1D(200,3,input_shape=(ARTICLE_MAX_WORD_COUNT,firstLayoutOutputDim), activation=tf.nn.relu), # keras.layers.GlobalAveragePooling1D(), # keras.layers.Dense(250, activation=tf.nn.relu), # keras.layers.Dense(theme_count, activation=tf.nn.softmax) # 2 # keras.layers.Embedding(input_dim=voc_size, output_dim=firstLayoutOutputDim), # keras.layers.LSTM(ltsmOutputDim, dropout=0.2, recurrent_dropout=0.2, activation='tanh'), # keras.layers.Dense(theme_count, activation=tf.nn.softmax) # 3 # keras.layers.Embedding(input_dim=self.voc_size, output_dim=embedding_output_dim), # keras.layers.Bidirectional(keras.layers.LSTM(intermediate_dim, return_sequences=True)), # # keras.layers.Dropout(0.1), # keras.layers.Bidirectional(keras.layers.LSTM(last_dim, dropout=0.05, recurrent_dropout=0.05)), # keras.layers.Dense(last_dim, activation=tf.nn.relu), # keras.layers.Dense(self.theme_count, activation=tf.nn.softmax) # 4 # keras.layers.Embedding(input_dim=self.voc_size, input_length=self.article_length, output_dim=embedding_output_dim), # keras.layers.Bidirectional(keras.layers.LSTM(intermediate_dim, return_sequences=True, dropout=0.2, recurrent_dropout=0.2)), # keras.layers.Dropout(0.2), # keras.layers.Bidirectional(keras.layers.LSTM(last_dim * 2, recurrent_dropout=0.2)), #was last_dim * 2 # keras.layers.Dense(last_dim, activation=tf.nn.relu), # keras.layers.Dense(self.theme_count, activation=tf.nn.sigmoid) # 5 #keras.layers.Embedding(input_dim=self.voc_size, input_length=self.article_length, output_dim=embedding_output_dim), # keras.layers.Conv1D(filters=64, kernel_size=5, input_shape=(self.voc_size, embedding_output_dim), activation="relu"), # keras.layers.MaxPool1D(4), #keras.layers.Bidirectional(keras.layers.LSTM(intermediate_dim, recurrent_dropout=0.1)), #keras.layers.Dense(last_dim, activation=tf.nn.relu), #keras.layers.Dense(self.theme_count, activation=tf.nn.sigmoid) #6 keras.layers.Embedding(input_dim=voc_size, input_length=article_length, output_dim=128, mask_zero=True), keras.layers.Bidirectional( keras.layers.LSTM(128, recurrent_dropout=0.2, dropout=0.2)), #keras.layers.Dropout(0.2), #keras.layers.Dense(last_dim, activation=tf.nn.relu), # keras.layers.Dense(self.theme_count, activation=tf.nn.sigmoid, use_bias=True,bias_initializer=tf.keras.initializers.Constant(-1.22818328)) keras.layers.Dense(theme_count, activation=tf.nn.sigmoid, kernel_regularizer=regularizers.l2(0.1), activity_regularizer=regularizers.l1(0.05)) # 7 # keras.layers.Embedding(input_dim=self.voc_size, input_length=self.article_length, # output_dim=embedding_output_dim), # keras.layers.GlobalAvgPool1D(), # keras.layers.Dense(last_dim, activation=tf.nn.relu), # keras.layers.Dense(self.theme_count, activation=tf.nn.sigmoid) ]) model.summary() model.compile( optimizer=tf.keras.optimizers.Adam(clipnorm=1, clipvalue=0.5), #loss=WeightedBinaryCrossEntropy(themes_weight, from_logits=True), loss=keras.losses.BinaryCrossentropy(from_logits=True), metrics=[ metrics.AUC(), metrics.BinaryAccuracy(), metrics.TruePositives(), metrics.TrueNegatives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.Recall(), metrics.Precision() ], run_eagerly=self.run_eagerly) keras.utils.plot_model(model, 'Model1.png', show_shapes=True) cb_list = [ManualInterrupter, keras_callback] model.fit(dataset.trainData, epochs=10, steps_per_epoch=dataset.train_batch_count, validation_data=dataset.validationData, validation_steps=dataset.validation_batch_count, callbacks=cb_list, class_weight={ 0: 1, 1: themes_weight[0] }) model.save("output/" + self.get_model_name() + ".h5") model.save_weights("output/" + self.get_model_name() + "_weight.h5") self.__model__ = model
## fine-tune transformer from tensorflow.keras import metrics from tensorflow.keras.optimizers import RMSprop, SGD losses = {'clone': "binary_crossentropy", 'partial': "binary_crossentropy", 'fufi': "binary_crossentropy" } lossWeights = {'clone': weight_ccpf[1], 'partial': weight_ccpf[2], 'fufi': weight_ccpf[3] } metrics_use = {'clone': [metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives()], 'partial': [metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives()], 'fufi': [metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives()] } just_trnsf.compile(optimizer=RMSprop(lr=0.0001), loss = losses, loss_weights = lossWeights, metrics = metrics_use)
test_inputs = breast_cancer[training_num:,1:-1] test_outputs = breast_cancer[training_num:,-1] model = models.Sequential([ layers.InputLayer(input_shape=training_inputs.shape[1]), layers.Dense(32, activation='relu'), layers.Dense(64, activation='relu'), layers.Dropout(0.2), layers.Dense(32, activation='relu'), layers.Dropout(0.7), layers.Dense(16, activation='relu', kernel_regularizer=regularizers.l2(0.005)), layers.Dense(1, activation='sigmoid'), ]) model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(learning_rate=0.02), metrics=['accuracy', metrics.TruePositives(), metrics.TrueNegatives()]) model.summary() epochs = 50 batch_size = 2 hist = model.fit( training_inputs, training_outputs, epochs=epochs, batch_size=batch_size, validation_data = (test_inputs, test_outputs), ) import matplotlib.pyplot as plt
def train_model(self, themes_weight: List[float], dataset: TrainValidationDataset, voc_size: int, keras_callback: LambdaCallback): epochs = 60 embedding_output_dim = 128 last_dim = 128 article_length = dataset.article_length theme_count = dataset.theme_count model = tf.keras.Sequential([ keras.layers.Embedding(input_dim=voc_size, input_length=article_length, output_dim=embedding_output_dim, mask_zero=True), keras.layers.Conv1D(filters=64, kernel_size=3, input_shape=(voc_size, embedding_output_dim), activation=tf.nn.relu), keras.layers.GlobalMaxPooling1D(), keras.layers.Dropout(0.2), keras.layers.Dense(last_dim, activation=tf.nn.relu), keras.layers.Dropout(0.2), keras.layers.Dense(theme_count, activation=tf.nn.sigmoid, kernel_regularizer=regularizers.l2(0.2), activity_regularizer=regularizers.l1(0.1)) ]) model.summary() model.compile(optimizer=tf.keras.optimizers.Adam(clipnorm=1, clipvalue=0.5), loss=WeightedBinaryCrossEntropy(themes_weight, from_logits=True), metrics=[ metrics.AUC(), metrics.BinaryAccuracy(), metrics.TruePositives(), metrics.TrueNegatives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.Recall(), metrics.Precision() ], run_eagerly=self.run_eagerly) keras.utils.plot_model(model, "output/" + self.model_name + ".png", show_shapes=True) model.fit(dataset.trainData, epochs=epochs, steps_per_epoch=dataset.train_batch_count, validation_data=dataset.validationData, validation_steps=dataset.validation_batch_count, callbacks=[ManualInterrupter(), keras_callback]) model.save("output/" + self.model_name + ".h5") model.save_weights("output/" + self.model_name + "_weight.h5") self.__model__ = model
for model_index in parameters: print(model_index) model_parameters = parameters[model_index] for key in model_parameters.keys(): if type(model_parameters[key]) is np.int64: model_parameters[key] = int(model_parameters[key]) elif type(model_parameters[key]) is np.float64: model_parameters[key] = float(model_parameters[key]) out_parameters['Model_Index'].append(model_index) model_base_path = r'H:\Deeplearning_Recurrence_Work\Models\Model_Index_{}'.format(model_index) pred_path = os.path.join(model_base_path, 'Predictions.npy') truth_path = os.path.join(model_base_path, 'Truth.npy') model_path = os.path.join(model_base_path, 'cp-best.cpkt') # model_path = os.path.join(model_base_path, 'final_model.h5') METRICS = [ metrics.TruePositives(name='TruePositive'), metrics.FalsePositives(name='FalsePositive'), metrics.TrueNegatives(name='TrueNegative'), metrics.FalseNegatives(name='FalseNegative'), metrics.BinaryAccuracy(name='Accuracy'), metrics.Precision(name='Precision'), metrics.Recall(name='Recall'), metrics.AUC(name='AUC', multi_label=True), ] model = mydensenet(**model_parameters) model.load_weights(model_path) model.compile(optimizer=optimizers.Adam(), loss=CosineLoss(), metrics=METRICS) visualizer = ModelVisualizationClass(model=model, save_images=True, out_path=r'H:\Deeplearning_Recurrence_Work\Activation_Images_{}'.format(model_index)) all_layers = visualizer.all_layers
def compile_fit(self, model_input, q_train_padded, a_train_padded, y_q_label_df, y_a_label_df, y_q_classify_list, y_q_classify_dict, y_a_classify_list, y_a_classify_dict, epoch_num=3): """ This function is used to switch between numrical. The switch controled by hyperparameters self.TYPE When self.TYPE == 'num', input will be q_train_padded and y_q_label_df (others are same) Meanwhile, switch to ['MSE'] as loss and ['mse', 'mae'] as metrics When self.TYPE == 'classify', input will be q_train_padded and y_q_classify_list[0] etc. Meanwhile, swith to ['categorical_crossentropy'] as loss and ['accuracy'] as metrics """ start_time = time() print("*" * 40, "Start {} Processing".format(model_input._name), "*" * 40) # loss_fun = 'categorical_crossentropy' # loss_fun = 'MSE' #MeanSquaredError # loss_fun = ' METRICS = [ metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn'), metrics.FalseNegatives(name='fn'), metrics.CategoricalAccuracy(name='accuracy'), metrics.Precision(name='precision'), metrics.Recall(name='recall'), metrics.AUC(name='auc'), # F1Score(num_classes = int(y_train.shape[1]), name='F1') ] loss_fun = None metrics_fun = None # becase large data input, we want to process automaticaly. So set this arugs to choose # question process or answer process automatically if self.PART == 'q': print("Start processing question part") # start to decide complie parameters if self.TYPE == 'num': print("Start numerical output") # call split X_train, X_val, y_train, y_val = self.split_data( q_train_padded, y_q_label_df, test_size=0.2) loss_fun = losses.MeanSquaredError() metrics_fun = ['mse', 'mae'] elif self.TYPE == 'classify': print("Start classify output") X_train, X_val, y_train, y_val = self.split_data( q_train_padded, y_q_classify_list[0], test_size=0.2) loss_fun = losses.CategoricalCrossentropy() metrics_fun = METRICS else: print("UNKNOW self.TYPE") elif self.PART == 'a': print("Start processing answer part") if self.TYPE == 'num': print("Start numerical output") # call split X_train, X_val, y_train, y_val = self.split_data( a_train_padded, y_a_label_df, test_size=0.2) loss_fun = losses.MeanSquaredError() metrics_fun = ['mse', 'mae'] elif self.TYPE == 'classify': print("Start classify output") X_train, X_val, y_train, y_val = self.split_data( a_train_padded, y_a_classify_list[0], test_size=0.2) loss_fun = losses.CategoricalCrossentropy() metrics_fun = METRICS else: print("UNKNOW self.TYPE") learning_rate = 1e-3 opt_adam = optimizers.Adam(lr=learning_rate, decay=1e-5) model_input.compile(loss=loss_fun, optimizer=opt_adam, metrics=metrics_fun) # batch_size is subjected to my GPU and GPU memory, after testing, 32 is reasonable value size. # If vector bigger, this value should dercrease history = model_input.fit( X_train, y_train, validation_data=(X_val, y_val), epochs=epoch_num, batch_size=16, verbose=1, callbacks=[PredictCallback(X_val, y_val, model_input)]) # spearmanr_list = PredictCallback(X_val, y_val, model_input).spearmanr_list # dic = ['loss', 'accuracy', 'val_loss','val_accuracy'] history_dict = [x for x in history.history] # model_input.predict(train_features[:10]) cost_time = round((time() - start_time), 4) print("*" * 40, "End {} with {} seconds".format(model_input._name, cost_time), "*" * 40, end='\n\n') return history, model_input
def run_model(model, train_generator, validation_generator, min_lr, max_lr, model_path, tensorboard_path, trial_id, optimizer, hparams=None, step_factor=8, epochs=120, loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False)): checkpoint_path = os.path.join(model_path, 'cp-best.cpkt') checkpoint = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, monitor='val_AUC', mode='max', verbose=1, save_freq='epoch', save_best_only=True, save_weights_only=True) tensorboard = tf.keras.callbacks.TensorBoard( log_dir=tensorboard_path, profile_batch=0, write_graph=True) # profile_batch='300,401', lrate = SGDRScheduler(min_lr=min_lr, max_lr=max_lr, steps_per_epoch=len(train_generator), cycle_length=step_factor, lr_decay=0.5, mult_factor=1, gentle_start_epochs=0, gentle_fraction=1.0) add_lr = Add_Images_and_LR(log_dir=tensorboard_path, add_images=False) early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_AUC', patience=300, verbose=True, mode='max') callbacks = [tensorboard, lrate, add_lr] # if epochs < 9000: callbacks += [early_stop] if hparams is not None: hp_callback = Callback(tensorboard_path, hparams=hparams, trial_id='Trial_ID:{}'.format(trial_id)) callbacks += [hp_callback] callbacks += [checkpoint] METRICS = [ metrics.TruePositives(name='TruePositive'), metrics.FalsePositives(name='FalsePositive'), metrics.TrueNegatives(name='TrueNegative'), metrics.FalseNegatives(name='FalseNegative'), metrics.BinaryAccuracy(name='Accuracy'), metrics.Precision(name='Precision'), metrics.Recall(name='Recall'), metrics.AUC(name='AUC'), ] print('\n\n\n\nRunning {}\n\n\n\n'.format(tensorboard_path)) model.compile(optimizer, loss=loss, metrics=METRICS) model.fit(train_generator.data_set, epochs=epochs, steps_per_epoch=len(train_generator), validation_data=validation_generator.data_set, validation_steps=len(validation_generator), validation_freq=10, callbacks=callbacks) model.save(os.path.join(model_path, 'final_model.h5')) tf.keras.backend.clear_session() return None
def unet_sep(param, input_shape=(1024, 1024, 3), roi_pool_size=[10, 10], chan_num=3, weight_ccpf=[1, 1, 1, 1, 1], projection_dim=100, transformer_layers=4, num_heads=4, is_comp=True, lr=1e-3): num_bbox = param["num_bbox"] input_img = layers.Input(shape=input_shape) input_bbox = layers.Input(shape=(num_bbox, 4)) ## get unet stem model just_unet = strde_unet_xcept_gn_shallow() # just_unet = strde_unet_xcept_gn_deep() # just_unet = strde_sepconv_unet_xcept_gn_shallow() # just_unet = strde_sepconv_unet_xcept_gn_deep() # just_unet = res_unet() ## and classifier model just_trnsf = classify_branch(num_bbox=num_bbox, crypt_class=param['crypt_class']) ## crate instances of models inst_cr, inst_fm = just_unet(input_img) if param['crypt_class']: inst_cl, inst_pa, inst_fu, inst_crcls = just_trnsf( [inst_fm, input_bbox]) ## combine into final model final_model = Model( inputs=[input_img, input_bbox], outputs=[inst_cr, inst_cl, inst_pa, inst_fu, inst_crcls]) losses = { 'crypt': "binary_crossentropy", 'cpf': "binary_crossentropy", 'cpf_1': "binary_crossentropy", 'cpf_2': "binary_crossentropy", 'cpf_3': "binary_crossentropy" } lossWeights = { 'crypt': weight_ccpf[0], 'cpf': weight_ccpf[1], 'cpf_1': weight_ccpf[2], 'cpf_2': weight_ccpf[3], 'cpf_3': weight_ccpf[4] } metrics_use = { 'crypt': metrics.Accuracy(), 'cpf': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ], 'cpf_1': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ], 'cpf_2': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ], 'cpf_3': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ] } else: inst_cl, inst_pa, inst_fu = just_trnsf([inst_fm, input_bbox]) ## combine into final model final_model = Model(inputs=[input_img, input_bbox], outputs=[inst_cr, inst_cl, inst_pa, inst_fu]) losses = { 'crypt': "binary_crossentropy", 'cpf': "binary_crossentropy", 'cpf_1': "binary_crossentropy", 'cpf_2': "binary_crossentropy" } lossWeights = { 'crypt': weight_ccpf[0], 'cpf': weight_ccpf[1], 'cpf_1': weight_ccpf[2], 'cpf_2': weight_ccpf[3] } metrics_use = { 'crypt': metrics.Accuracy(), 'cpf': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ], 'cpf_1': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ], 'cpf_2': [ metrics.TruePositives(), metrics.FalseNegatives(), metrics.FalsePositives(), metrics.TrueNegatives() ] } if is_comp: # compile final_model.compile(optimizer=Adam(lr=lr), loss=losses, loss_weights=lossWeights, metrics=metrics_use) return final_model, just_trnsf, just_unet
def confusion_matrix_metric(self): return [metrics.TruePositives(name='tp'), metrics.FalsePositives(name='fp'), metrics.TrueNegatives(name='tn'), metrics.FalseNegatives(name='fn')]
args = parser.parse_args() RANDOM_STATE = int(args.random_state) TEST_SIZE = float(args.val_size) LEARNING_RATE = float(args.learning_rate) EPOCHS = int(args.epochs) BATCH_SIZE = int(args.batch_size) DROPOUT = float(args.dropout) IMGSIZE = (int(args.imgsize[0]), int(args.imgsize[1])) LOGDIR = args.logdir DATA = args.data BACKBONE = args.backbone NAME = args.model # --- define model metrics --- METRICS = [ metrics.TruePositives(name="True_Positives"), metrics.FalsePositives(name="False_Positives"), metrics.TrueNegatives(name="True_Negatives"), metrics.FalseNegatives(name="False_Negatives"), metrics.BinaryAccuracy(name="Binary_Accuracy"), metrics.Precision(name="Precision"), metrics.Recall(name="Recall"), metrics.AUC(name="AUC") ] # --- tensorflow calbacks --- date = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") if platform.system().lower() == "windows": LOGDIR = LOGDIR + "\\" + NAME + "\\" + date else: LOGDIR = LOGDIR + "/" + NAME + "/" + date
def find_best_lr(batch_size=24): tf.random.set_seed(3141) base_path, morfeus_drive, excel_path = return_paths() # if base_path.startswith('H'): # Only run this locally # create_excel_values(excel_path=excel_path) for iteration in [0]: out_path = os.path.join(morfeus_drive, 'Learning_Rates') model_parameters, out_path = return_model_parameters( out_path=out_path, excel_path=excel_path, iteration=iteration) if model_parameters is None: continue model_key = model_parameters['Model_Type'] optimizer = model_parameters['Optimizer'] model_base = return_model(model_key=model_key) model = model_base(**model_parameters) if model_parameters['loss'] == 'CosineLoss': loss = CosineLoss() min_lr = 1e-6 max_lr = 1e-1 elif model_parameters['loss'] == 'CategoricalCrossEntropy': loss = tf.keras.losses.CategoricalCrossentropy() min_lr = 1e-10 max_lr = 1e-3 _, _, train_generator, validation_generator = return_generators( batch_size=batch_size, model_key=model_key, all_training=True, cache=True, cache_add='LR_Finder_{}'.format(model_key)) print(out_path) k = TensorBoard(log_dir=out_path, profile_batch=0, write_graph=True) k.set_model(model) k.on_train_begin() lr_opt = tf.keras.optimizers.Adam if optimizer == 'SGD': lr_opt = tf.keras.optimizers.SGD elif optimizer == 'Adam': lr_opt = tf.keras.optimizers.Adam elif optimizer == 'RAdam': lr_opt = RectifiedAdam METRICS = [ metrics.TruePositives(name='TruePositive'), metrics.FalsePositives(name='FalsePositive'), metrics.TrueNegatives(name='TrueNegative'), metrics.FalseNegatives(name='FalseNegative'), metrics.CategoricalAccuracy(name='Accuracy'), metrics.Precision(name='Precision'), metrics.Recall(name='Recall'), metrics.AUC(name='AUC'), ] LearningRateFinder(epochs=10, model=model, metrics=METRICS, out_path=out_path, optimizer=lr_opt, loss=loss, steps_per_epoch=1000, train_generator=train_generator.data_set, lower_lr=min_lr, high_lr=max_lr) tf.keras.backend.clear_session() return False # repeat! return True