diff --git a/higher/smart_aug/test_dataug.py b/higher/smart_aug/test_dataug.py index 1052775..7ffa195 100755 --- a/higher/smart_aug/test_dataug.py +++ b/higher/smart_aug/test_dataug.py @@ -6,9 +6,10 @@ from LeNet import * from dataug import * #from utils import * from train_utils import * +#from transformations import TF_loader postfix='' -TF_loader=TF_loader() +TF_loader=TF.TF_loader() device = torch.device('cuda') #Select device to use diff --git a/higher/smart_aug/transformations.py b/higher/smart_aug/transformations.py index 4f454f9..1abb00f 100755 --- a/higher/smart_aug/transformations.py +++ b/higher/smart_aug/transformations.py @@ -17,6 +17,7 @@ import torch import kornia import random +import json #TF that don't have use for magnitude parameter. TF_no_mag={'Identity', 'FlipUD', 'FlipLR', 'Random', 'RandBlend', 'identity', 'flip'} @@ -88,6 +89,126 @@ TF_dict={ #Dataugv5+ #'Equalize': (lambda mag: None), } ''' +class TF_loader(object): + """ Transformations builder. + + See 'config' folder for pre-defined config files. + + Attributes: + _filename (str): Path to config file (JSON) used. + _TF_dict (dict): Transformations dictionnary built from config file. + _TF_ignore_mag (set): Ensemble of transformations names for which magnitude should be ignored. + _TF_names (list): List of transformations names/keys. + """ + def __init__(self): + """ Initialize TF_loader. + + """ + self._filename='' + self._TF_dict={} + self._TF_ignore_mag=set() + self._TF_names=[] + + def load_TF_dict(self, filename): + """ Build a TF dictionnary. + + Args: + filename (str): Path to config file (JSON) defining the transformations. + Returns: + (dict, set) : TF dicttionnary built and ensemble of TF names for which mag should be ignored. + """ + self._filename=filename + self._TF_names=[] + self._TF_dict={} + self._TF_ignore_mag=set() + + with open(filename) as json_file: + TF_params = json.load(json_file) + + for tf in TF_params: + self._TF_names.append(tf['name']) + if tf['function'] in TF_ignore_mag: + self._TF_ignore_mag.add(tf['name']) + + if tf['function'] == 'identity': + self._TF_dict[tf['name']]=(lambda x, mag: x) + + elif tf['function'] == 'flip': + #Inverser axes ? + if tf['param']['axis'] == 'X': + self._TF_dict[tf['name']]=(lambda x, mag: flipLR(x)) + elif tf['param']['axis'] == 'Y': + self._TF_dict[tf['name']]=(lambda x, mag: flipUD(x)) + else: + raise Exception("Unknown TF axis : %s in %s"%(tf['function'], self._filename)) + + elif tf['function'] in {'translate', 'shear'}: + rand_fct= 'invScale_rand_floats' if tf['param']['invScale'] else 'rand_floats' + self._TF_dict[tf['name']]=self.build_lambda(tf['function'], rand_fct, tf['param']['min'], tf['param']['max'], tf['param']['absolute'], tf['param']['axis']) + + else: + rand_fct= 'invScale_rand_floats' if tf['param']['invScale'] else 'rand_floats' + self._TF_dict[tf['name']]=self.build_lambda(tf['function'], rand_fct, tf['param']['min'], tf['param']['max']) + + return self._TF_dict, self._TF_ignore_mag + + def build_lambda(self, fct_name, rand_fct_name, minval, maxval, absolute=True, axis=None): + """ Build a lambda function performing transformations. + + Args: + fct_name (str): Name of the transformations to use (see transformations.py). + rand_fct_name (str): Name of the random mapping function to use (see transformations.py). + minval (float): minimum magnitude value of the TF. + maxval (float): maximum magnitude value of the TF. + absolute (bool): Wether the maxval should be relative (absolute=False) to the image size. (default: True) + axis (str): Axis ('X' / 'Y') of the TF, if relevant. Should be used for (flip)/translate/shear functions. (default: None) + + Returns: + (function) transformations function : Tensor=f(Tensor, magnitude) + """ + if absolute: + max_val_fct=(lambda x: maxval) + else: #Relative to img size + max_val_fct=(lambda x: x*maxval) + + if axis is None: + return (lambda x, mag: + globals()[fct_name]( #getattr(TF, fct_name) + x, + globals()[rand_fct_name]( + size=x.shape[0], + mag=mag, + minval=minval, + maxval=maxval))) + elif axis =='X': + return (lambda x, mag: + globals()[fct_name]( + x, + zero_stack( + globals()[rand_fct_name]( + size=(x.shape[0],), + mag=mag, + minval=minval, + maxval=max_val_fct(x.shape[2])), + zero_pos=0))) + elif axis == 'Y': + return (lambda x, mag: + globals()[fct_name]( + x, + zero_stack( + globals()[rand_fct_name]( + size=(x.shape[0],), + mag=mag, + minval=minval, + maxval=max_val_fct(x.shape[3])), + zero_pos=1))) + else: + raise Exception("Unknown TF axis : %s in %s"%(fct_name, self._filename)) + + def get_TF_names(self): + return self._TF_names + def get_TF_dict(self): + return self._TF_dict ## Image type cast ## def int_image(float_image): """Convert a float Tensor/Image to an int Tensor/Image. diff --git a/higher/smart_aug/utils.py b/higher/smart_aug/utils.py index 2480268..4a4b5ae 100755 --- a/higher/smart_aug/utils.py +++ b/higher/smart_aug/utils.py @@ -14,128 +14,6 @@ import torch.nn.functional as F import time -import transformations as TF -class TF_loader(object): - """ Transformations builder. - - See 'config' folder for pre-defined config files. - - Attributes: - _filename (str): Path to config file (JSON) used. - _TF_dict (dict): Transformations dictionnary built from config file. - _TF_ignore_mag (set): Ensemble of transformations names for which magnitude should be ignored. - _TF_names (list): List of transformations names/keys. - """ - def __init__(self): - """ Initialize TF_loader. - - """ - self._filename='' - self._TF_dict={} - self._TF_ignore_mag=set() - self._TF_names=[] - - def load_TF_dict(self, filename): - """ Build a TF dictionnary. - - Args: - filename (str): Path to config file (JSON) defining the transformations. - Returns: - (dict, set) : TF dicttionnary built and ensemble of TF names for which mag should be ignored. - """ - self._filename=filename - self._TF_names=[] - self._TF_dict={} - self._TF_ignore_mag=set() - - with open(filename) as json_file: - TF_params = json.load(json_file) - - for tf in TF_params: - self._TF_names.append(tf['name']) - if tf['function'] in TF.TF_ignore_mag: - self._TF_ignore_mag.add(tf['name']) - - if tf['function'] == 'identity': - self._TF_dict[tf['name']]=(lambda x, mag: x) - - elif tf['function'] == 'flip': - #Inverser axes ? - if tf['param']['axis'] == 'X': - self._TF_dict[tf['name']]=(lambda x, mag: TF.flipLR(x)) - elif tf['param']['axis'] == 'Y': - self._TF_dict[tf['name']]=(lambda x, mag: TF.flipUD(x)) - else: - raise Exception("Unknown TF axis : %s in %s"%(tf['function'], self._filename)) - - elif tf['function'] in {'translate', 'shear'}: - rand_fct= 'invScale_rand_floats' if tf['param']['invScale'] else 'rand_floats' - self._TF_dict[tf['name']]=self.build_lambda(tf['function'], rand_fct, tf['param']['min'], tf['param']['max'], tf['param']['absolute'], tf['param']['axis']) - - else: - rand_fct= 'invScale_rand_floats' if tf['param']['invScale'] else 'rand_floats' - self._TF_dict[tf['name']]=self.build_lambda(tf['function'], rand_fct, tf['param']['min'], tf['param']['max']) - - return self._TF_dict, self._TF_ignore_mag - - def build_lambda(self, fct_name, rand_fct_name, minval, maxval, absolute=True, axis=None): - """ Build a lambda function performing transformations. - - Args: - fct_name (str): Name of the transformations to use (see transformations.py). - rand_fct_name (str): Name of the random mapping function to use (see transformations.py). - minval (float): minimum magnitude value of the TF. - maxval (float): maximum magnitude value of the TF. - absolute (bool): Wether the maxval should be relative (absolute=False) to the image size. (default: True) - axis (str): Axis ('X' / 'Y') of the TF, if relevant. Should be used for (flip)/translate/shear functions. (default: None) - - Returns: - (function) transformations function : Tensor=f(Tensor, magnitude) - """ - if absolute: - max_val_fct=(lambda x: maxval) - else: #Relative to img size - max_val_fct=(lambda x: x*maxval) - - if axis is None: - return (lambda x, mag: - getattr(TF, fct_name)( - x, - getattr(TF, rand_fct_name)( - size=x.shape[0], - mag=mag, - minval=minval, - maxval=maxval))) - elif axis =='X': - return (lambda x, mag: - getattr(TF, fct_name)( - x, - TF.zero_stack( - getattr(TF, rand_fct_name)( - size=(x.shape[0],), - mag=mag, - minval=minval, - maxval=max_val_fct(x.shape[2])), - zero_pos=0))) - elif axis == 'Y': - return (lambda x, mag: - getattr(TF, fct_name)( - x, - TF.zero_stack( - getattr(TF, rand_fct_name)( - size=(x.shape[0],), - mag=mag, - minval=minval, - maxval=max_val_fct(x.shape[3])), - zero_pos=1))) - else: - raise Exception("Unknown TF axis : %s in %s"%(fct_name, self._filename)) - - def get_TF_names(self): - return self._TF_names - def get_TF_dict(self): - return self._TF_dict - class ConfusionMatrix(object): """ Confusion matrix.