Module see.base_classes
The base_classes module is used for the rest of the image grammar to set up base classes.
Expand source code
"""The base_classes module is used for the rest of the image grammar to set up base classes."""
import copy
import time
import random
import inspect
class pipedata(object):
"""
The pipedata is just an instance of a basic python object.
It is used to dynamically
store output data from a wide variety of algorithms. Most algorithms in the pipe jsut add
data to this objet which is passed in as an input argument and returned as an output argument.
"""
pass
class param_space(dict):
"""Construct an parameter dictionary that represents the search space.
Components:
pkeys - paramters keys used by the current algorithsm.
descriptions - Descriptions of the parameters
ranges - List of possible choices for each parameter.
"""
descriptions = dict()
ranges = dict()
pkeys = []
@classmethod
def add(cls, key, prange, description):
"""Add in parameters.
Inputs:
key - the paramter name
prange - the parameter range
description - the description of the parameter
"""
cls.descriptions[key] = description
cls.ranges[key] = prange
if key not in cls.pkeys:
cls.pkeys.append(key)
def addall(self,params):
"""Add a list of paramters to the current paramter list."""
if issubclass(type(params), param_space):
for key in params:
self.add(key, params.ranges[key], params.descriptions[key])
self[key] = params[key]
else:
raise TypeError('A very specific bad thing happened.')
def printparam(self, key):
"""Return description of parameter from param list."""
outstring = f"{key}={self[key]}\n\t{self.descriptions[key]}"
if len(self.ranges) < 10:
outstring += "\n\t{self.ranges[key]}\n\n"
else:
outstring += "\n\t{self.ranges[key][:2]}...{self.ranges[key][-2:]}\n\n"
return outstring
# def __str__(self):
# """Return descriptions of all parameters in param list."""
# out = ""
# for index, k in enumerate(self.pkeys):
# out += f"{index} " + self.printparam(k)
# return out
def tolist(self):
"""Convert dictionary of params into list of parameters."""
plist = []
for key in self.pkeys:
plist.append(self[key])
return plist
def fromlist(self, individual):
"""Convert individual's list into dictionary of params."""
#logging.getLogger().info(f"Parsing Parameter List for {len(individual)} parameters")
for index, key in enumerate(self.pkeys):
self[key] = individual[index]
class algorithm(object):
"""Base class for any image alogirthm.
Functions:
evaluate -- Run segmentation algorithm to get inferred mask.
"""
def __init__(self, paramlist=None):
"""Generate algorithm params from parameter list."""
self.params = param_space()
self.set_params(paramlist)
def set_params(self, paramlist=None):
"""Set parameters from parameter list."""
if paramlist:
if issubclass(type(paramlist), param_space):
self.params = copy.deepcopy(paramlist)
else:
# print(f"{type(paramlist)}_paramlist={paramlist}")
self.params.fromlist(list(paramlist))
# TODO Comment this back in
# self.checkparamindex()
def checkparamindex(self):
"""Check paramiter keys to ensure values are valid."""
for myparams in self.params.pkeys:
assert myparams in self.params, f"ERROR {myparams} is not in parameter list"
def mutateself(self, flip_prob=0.5):
"""Mutate self and return new params."""
for myparam in self.params.pkeys:
rand_val = random.random()
if rand_val < flip_prob:
self.params[myparam] = random.choice(
self.params.ranges[myparam])
return self.params
def pipe(self, data):
"""Run segmentation algorithm to get inferred mask."""
print("WARNING: Default Pipe, doing nothing\n")
return data
def __str__(self):
"""Return params for algorithm."""
mystring = f"{type(self)} parameters: \n"
for p in self.params.pkeys:
mystring += f"\t{p} = {self.params[p]}\n"
return mystring
def runAlgo(self, data, params=None):
"""Run and evaluate the performance of an individual.
Keyword arguments:
data -- pipedata both input and output.
params -- the list representing an individual in our population
Output:
fitness -- resulting fitness value for the individual
mask -- resulting image mask associated with the individual (if return_mask=True)
"""
#TODO make this funciton more flexible and allow multiple types of params
# i'm thinking (list, param_space and algorithm)
startTime = int(round(time.time() * 1000))
if params:
print(f"{seg}")
seg = type(self)(paramlist=params)
data = seg.pipe(data)
endTime = int(round(time.time() * 1000))
print(f"Time: {(endTime - startTime)/1000} s")
else:
print(f"{self}")
data = self.pipe(data)
endTime = int(round(time.time() * 1000))
print(f"Time: {(endTime - startTime)/1000} s")
return data
def mutate_self(self,flip_prob=0.5):
"""Mutate self.
Mutate algorithm if random value is
less than 0.5.
"""
print("using default mutation function")
for keys in self.params:
rand_val = random.random()
if rand_val < flip_prob:
# Let's mutate the algorithm
self.params[index] = random.choice(self.params.ranges[index])
def algorithm_code(self):
"""Print usable code to run segmentation algorithm.
Based on an
individual's genetic representation vector.
"""
original_function = inspect.getsource(self.evaluate)
return original_function
def mutateAlgo(algorithm, paramlist, flip_prob=0.5):
"""Generate an offspring based on current individual."""
child = algorithm(paramlist=paramlist)
child.mutateself(flip_prob=flip_prob)
return child
def popCounts(pop):
"""Count the number of each algorihtm in a population."""
algorithms = seg_params.ranges["algorithm"]
counts = {a: 0 for a in algorithms}
for p in pop:
# print(p[0])
counts[p[0]] += 1
return counts
Functions
def mutateAlgo(algorithm, paramlist, flip_prob=0.5)
-
Generate an offspring based on current individual.
Expand source code
def mutateAlgo(algorithm, paramlist, flip_prob=0.5): """Generate an offspring based on current individual.""" child = algorithm(paramlist=paramlist) child.mutateself(flip_prob=flip_prob) return child
def popCounts(pop)
-
Count the number of each algorihtm in a population.
Expand source code
def popCounts(pop): """Count the number of each algorihtm in a population.""" algorithms = seg_params.ranges["algorithm"] counts = {a: 0 for a in algorithms} for p in pop: # print(p[0]) counts[p[0]] += 1 return counts
Classes
class algorithm (paramlist=None)
-
Base class for any image alogirthm.
Functions: evaluate – Run segmentation algorithm to get inferred mask.
Generate algorithm params from parameter list.
Expand source code
class algorithm(object): """Base class for any image alogirthm. Functions: evaluate -- Run segmentation algorithm to get inferred mask. """ def __init__(self, paramlist=None): """Generate algorithm params from parameter list.""" self.params = param_space() self.set_params(paramlist) def set_params(self, paramlist=None): """Set parameters from parameter list.""" if paramlist: if issubclass(type(paramlist), param_space): self.params = copy.deepcopy(paramlist) else: # print(f"{type(paramlist)}_paramlist={paramlist}") self.params.fromlist(list(paramlist)) # TODO Comment this back in # self.checkparamindex() def checkparamindex(self): """Check paramiter keys to ensure values are valid.""" for myparams in self.params.pkeys: assert myparams in self.params, f"ERROR {myparams} is not in parameter list" def mutateself(self, flip_prob=0.5): """Mutate self and return new params.""" for myparam in self.params.pkeys: rand_val = random.random() if rand_val < flip_prob: self.params[myparam] = random.choice( self.params.ranges[myparam]) return self.params def pipe(self, data): """Run segmentation algorithm to get inferred mask.""" print("WARNING: Default Pipe, doing nothing\n") return data def __str__(self): """Return params for algorithm.""" mystring = f"{type(self)} parameters: \n" for p in self.params.pkeys: mystring += f"\t{p} = {self.params[p]}\n" return mystring def runAlgo(self, data, params=None): """Run and evaluate the performance of an individual. Keyword arguments: data -- pipedata both input and output. params -- the list representing an individual in our population Output: fitness -- resulting fitness value for the individual mask -- resulting image mask associated with the individual (if return_mask=True) """ #TODO make this funciton more flexible and allow multiple types of params # i'm thinking (list, param_space and algorithm) startTime = int(round(time.time() * 1000)) if params: print(f"{seg}") seg = type(self)(paramlist=params) data = seg.pipe(data) endTime = int(round(time.time() * 1000)) print(f"Time: {(endTime - startTime)/1000} s") else: print(f"{self}") data = self.pipe(data) endTime = int(round(time.time() * 1000)) print(f"Time: {(endTime - startTime)/1000} s") return data def mutate_self(self,flip_prob=0.5): """Mutate self. Mutate algorithm if random value is less than 0.5. """ print("using default mutation function") for keys in self.params: rand_val = random.random() if rand_val < flip_prob: # Let's mutate the algorithm self.params[index] = random.choice(self.params.ranges[index]) def algorithm_code(self): """Print usable code to run segmentation algorithm. Based on an individual's genetic representation vector. """ original_function = inspect.getsource(self.evaluate) return original_function
Subclasses
Methods
def algorithm_code(self)
-
Print usable code to run segmentation algorithm.
Based on an individual's genetic representation vector.
Expand source code
def algorithm_code(self): """Print usable code to run segmentation algorithm. Based on an individual's genetic representation vector. """ original_function = inspect.getsource(self.evaluate) return original_function
def checkparamindex(self)
-
Check paramiter keys to ensure values are valid.
Expand source code
def checkparamindex(self): """Check paramiter keys to ensure values are valid.""" for myparams in self.params.pkeys: assert myparams in self.params, f"ERROR {myparams} is not in parameter list"
def mutate_self(self, flip_prob=0.5)
-
Mutate self.
Mutate algorithm if random value is less than 0.5.
Expand source code
def mutate_self(self,flip_prob=0.5): """Mutate self. Mutate algorithm if random value is less than 0.5. """ print("using default mutation function") for keys in self.params: rand_val = random.random() if rand_val < flip_prob: # Let's mutate the algorithm self.params[index] = random.choice(self.params.ranges[index])
def mutateself(self, flip_prob=0.5)
-
Mutate self and return new params.
Expand source code
def mutateself(self, flip_prob=0.5): """Mutate self and return new params.""" for myparam in self.params.pkeys: rand_val = random.random() if rand_val < flip_prob: self.params[myparam] = random.choice( self.params.ranges[myparam]) return self.params
def pipe(self, data)
-
Run segmentation algorithm to get inferred mask.
Expand source code
def pipe(self, data): """Run segmentation algorithm to get inferred mask.""" print("WARNING: Default Pipe, doing nothing\n") return data
def runAlgo(self, data, params=None)
-
Run and evaluate the performance of an individual.
Keyword arguments: data – pipedata both input and output. params – the list representing an individual in our population
Output: fitness – resulting fitness value for the individual mask – resulting image mask associated with the individual (if return_mask=True)
Expand source code
def runAlgo(self, data, params=None): """Run and evaluate the performance of an individual. Keyword arguments: data -- pipedata both input and output. params -- the list representing an individual in our population Output: fitness -- resulting fitness value for the individual mask -- resulting image mask associated with the individual (if return_mask=True) """ #TODO make this funciton more flexible and allow multiple types of params # i'm thinking (list, param_space and algorithm) startTime = int(round(time.time() * 1000)) if params: print(f"{seg}") seg = type(self)(paramlist=params) data = seg.pipe(data) endTime = int(round(time.time() * 1000)) print(f"Time: {(endTime - startTime)/1000} s") else: print(f"{self}") data = self.pipe(data) endTime = int(round(time.time() * 1000)) print(f"Time: {(endTime - startTime)/1000} s") return data
def set_params(self, paramlist=None)
-
Set parameters from parameter list.
Expand source code
def set_params(self, paramlist=None): """Set parameters from parameter list.""" if paramlist: if issubclass(type(paramlist), param_space): self.params = copy.deepcopy(paramlist) else: # print(f"{type(paramlist)}_paramlist={paramlist}") self.params.fromlist(list(paramlist))
class param_space (*args, **kwargs)
-
Construct an parameter dictionary that represents the search space.
Components
pkeys - paramters keys used by the current algorithsm. descriptions - Descriptions of the parameters ranges - List of possible choices for each parameter.
Expand source code
class param_space(dict): """Construct an parameter dictionary that represents the search space. Components: pkeys - paramters keys used by the current algorithsm. descriptions - Descriptions of the parameters ranges - List of possible choices for each parameter. """ descriptions = dict() ranges = dict() pkeys = [] @classmethod def add(cls, key, prange, description): """Add in parameters. Inputs: key - the paramter name prange - the parameter range description - the description of the parameter """ cls.descriptions[key] = description cls.ranges[key] = prange if key not in cls.pkeys: cls.pkeys.append(key) def addall(self,params): """Add a list of paramters to the current paramter list.""" if issubclass(type(params), param_space): for key in params: self.add(key, params.ranges[key], params.descriptions[key]) self[key] = params[key] else: raise TypeError('A very specific bad thing happened.') def printparam(self, key): """Return description of parameter from param list.""" outstring = f"{key}={self[key]}\n\t{self.descriptions[key]}" if len(self.ranges) < 10: outstring += "\n\t{self.ranges[key]}\n\n" else: outstring += "\n\t{self.ranges[key][:2]}...{self.ranges[key][-2:]}\n\n" return outstring # def __str__(self): # """Return descriptions of all parameters in param list.""" # out = "" # for index, k in enumerate(self.pkeys): # out += f"{index} " + self.printparam(k) # return out def tolist(self): """Convert dictionary of params into list of parameters.""" plist = [] for key in self.pkeys: plist.append(self[key]) return plist def fromlist(self, individual): """Convert individual's list into dictionary of params.""" #logging.getLogger().info(f"Parsing Parameter List for {len(individual)} parameters") for index, key in enumerate(self.pkeys): self[key] = individual[index]
Ancestors
- builtins.dict
Subclasses
Class variables
var descriptions
var pkeys
var ranges
Static methods
def add(key, prange, description)
-
Add in parameters.
Inputs
key - the paramter name prange - the parameter range description - the description of the parameter
Expand source code
@classmethod def add(cls, key, prange, description): """Add in parameters. Inputs: key - the paramter name prange - the parameter range description - the description of the parameter """ cls.descriptions[key] = description cls.ranges[key] = prange if key not in cls.pkeys: cls.pkeys.append(key)
Methods
def addall(self, params)
-
Add a list of paramters to the current paramter list.
Expand source code
def addall(self,params): """Add a list of paramters to the current paramter list.""" if issubclass(type(params), param_space): for key in params: self.add(key, params.ranges[key], params.descriptions[key]) self[key] = params[key] else: raise TypeError('A very specific bad thing happened.')
def fromlist(self, individual)
-
Convert individual's list into dictionary of params.
Expand source code
def fromlist(self, individual): """Convert individual's list into dictionary of params.""" #logging.getLogger().info(f"Parsing Parameter List for {len(individual)} parameters") for index, key in enumerate(self.pkeys): self[key] = individual[index]
def printparam(self, key)
-
Return description of parameter from param list.
Expand source code
def printparam(self, key): """Return description of parameter from param list.""" outstring = f"{key}={self[key]}\n\t{self.descriptions[key]}" if len(self.ranges) < 10: outstring += "\n\t{self.ranges[key]}\n\n" else: outstring += "\n\t{self.ranges[key][:2]}...{self.ranges[key][-2:]}\n\n" return outstring
def tolist(self)
-
Convert dictionary of params into list of parameters.
Expand source code
def tolist(self): """Convert dictionary of params into list of parameters.""" plist = [] for key in self.pkeys: plist.append(self[key]) return plist
class pipedata
-
The pipedata is just an instance of a basic python object.
It is used to dynamically store output data from a wide variety of algorithms. Most algorithms in the pipe jsut add data to this objet which is passed in as an input argument and returned as an output argument.
Expand source code
class pipedata(object): """ The pipedata is just an instance of a basic python object. It is used to dynamically store output data from a wide variety of algorithms. Most algorithms in the pipe jsut add data to this objet which is passed in as an input argument and returned as an output argument. """ pass