def __init__(self): self.data, self.label = Data().generate_data() self.model = LinearModel() self.learning_rate = cfg.LEARNING_RATE self.max_step = cfg.MAX_STEP self.stop_condition = cfg.STOP_CONDITION self.global_step = cfg.GLOBAL_STEP self.cost = [] self.weights = cfg.INIT_WEIGHTS
def __init__(self): self.data = Data().generate_data() self.model = LinearModel() self.num_data = cfg.NUM_DATA self.learning_rate = cfg.LEARNING_RATE self.max_step = cfg.MAX_STEP self.weights = cfg.INIT_W self.cost = [] self.stop_condition = cfg.STOP_CONDITION self.global_step = 0
def reducedPrices(self,model,objectiveMap,targetMap): ''' @type model: LinearModel @var model: The linear model for which reduced prices will be found for each variable @type objectiveMap: {objectiveTag:{var,coeff}} @var objectiveMap: key values of objective names and their coeffcient for variables @type targetMap: {objectiveTag:ceoff} For each objective in the objectiveMap. Finds reduced prices for each variable in the model. Use this method in library update instead of old library update ''' result = {} fluxValues = {} for oKey in objectiveMap.keys(): #print "\t Objective [%s]" % (oKey) obj = objectiveMap[oKey] iModel = LinearModel() iModel.addModel(model) lp = self.solverClass() lp.setModel(iModel) lp.clearObjective() lp.setObjectiveMap(obj) lp.runSimplex() prediction = lp.getPredictionMap() columnStatus = lp.getColumnsStatus() fluxValues[oKey] = prediction #! Finding reduced prices appears to alter model #! Hence the model must be copied before reduced prices are found statusReport = {} for sKey in columnStatus.keys(): status = columnStatus[sKey] prices = lp.getPointReducedCosts({sKey:-1.0},2) fluxValue = prediction[sKey] statusReport[(sKey,status,fluxValue)] = prices for tKey in targetMap.keys(): tValue = targetMap[tKey] values = lp.getPointReducedCosts(tValue,2) #print "\t target [%s] library size [%s]" % (tKey, len(values)) result[(oKey,tKey)] = values lp.clear() del lp return (fluxValues,result)
def reducedPriceLibrary(self,model,limitsMap,objectiveMap,targetMap): ''' @var limitsMap: set of limits to create the library of reduced prices @var objectiveMap: set of objectives to search for reduced prices @type fluxValuesMap: {condition:{var:value}} @var fluxValuesMap: map of flux values for given condition @type coeffecentLibrary: (tag,prefix,values:{string,float}) @var coeffecentLibrary: library of reduced prices for given limits,objectives and targets builds libraries of reduced prices for combination of limits, objectives and targets ''' p = {} n = {} fluxValuesMap = {} coeffecentLibrary = {} for key in limitsMap.keys(): #print "building library %s" % (key) limits = limitsMap[key] newModel = LinearModel() newModel.addModel(model) for name in limits.keys(): limit = limits[name] newModel.addColumnLimit(name,limit) (fluxValues, priceMap) = self.reducedPrices(newModel,objectiveMap,targetMap) fluxValuesMap[key] = fluxValues for (ikey,values) in priceMap.items(): coeffecentLibrary[(key,ikey[0],ikey[1])]= values for pKey in priceMap.keys(): prices = priceMap[pKey] (p,n) = self.divideMapsDir(p,n,prices) controlMap = {} for (key,valueMap) in coeffecentLibrary.items(): (k1,k2,k3) = key pkey = "price_" + k3 self.fillControlMap(controlMap, pkey, valueMap) return (fluxValuesMap,coeffecentLibrary,controlMap,p,n)
class LinearModelTrain: def __init__(self): self.data = Data().generate_data() self.model = LinearModel() self.num_data = cfg.NUM_DATA self.learning_rate = cfg.LEARNING_RATE self.max_step = cfg.MAX_STEP self.weights = cfg.INIT_W self.cost = [] self.stop_condition = cfg.STOP_CONDITION self.global_step = 0 def train(self): self.cost.append(self.model.calc_cost(self.weights)) while True: self.global_step += 1 grad = self.model.calc_grad(self.weights) for i in range(2): self.weights[i] = self.weights[i] - self.learning_rate * grad[i] new_cost = self.model.calc_cost(self.weights) self.cost.append(new_cost) if abs(self.cost[-1] - self.cost[-2]) < self.stop_condition or \ self.global_step > self.max_step: break print('steps {}, cost {}, weights {} {}' .format(self.global_step, self.cost[-1], self.weights[0], self.weights[1])) def visualize_cost(self): x = range(len(self.cost)) plt.figure(1) plt.plot(x, self.cost, linewidth=2, color='blue') plt.title('cost-step') plt.xlabel('step') plt.ylabel('cost') plt.grid() plt.show()
def updateLibrary(self,model,naturalObjectiveName,syntheticObjectiveName,coeffLibrary,factor1,factor2,mfactor=1.0): ''' Used to adjust the values of a set of libraries Needs to be worked on so that A) model is not altered during update (largely from reduced price discovery) B) more that basic reduced prices are discovered if its deemed worth while ''' matrixTools = MatrixTools() iModel = LinearModel() iModel.addModel(model) lo = self.solverClass() lo.setModel(iModel) lo.runSimplex() tpv = lo.getPredictionMap() iPosCoeff = {} iNegCoeff = {} iPosCoeff = lo.getPointReducedCosts({naturalObjectiveName: factor1},2) iNegCoeff = lo.getPointReducedCosts({syntheticObjectiveName: factor2},2) lo.clear() iPosCoeff = matrixTools.vectorMScalar(iPosCoeff,mfactor) iNegCoeff = matrixTools.vectorMScalar(iNegCoeff,mfactor) for (name,prefix,value) in coeffLibrary: iPosCoeff = self.trimWeightsDirection(value,iPosCoeff,inclusive=True) iNegCoeff = self.trimWeightsDirection(value,iNegCoeff,inclusive=True) if self.geneMap != None: iPosCoeff = self.changeToGeneLibrary(iPosCoeff,self.geneMap,dir=1.0) iNegCoeff = self.changeToGeneLibrary(iNegCoeff,self.geneMap,dir=-1.0) return(iPosCoeff,iNegCoeff)
def findSimpleSlopes(self,model,fluxes,objective,objValue,factor = 1.0,delta = 0.001, useZeros=False,constrict=False): ''' find dz/dv for variables in linear model. ''' iModel = LinearModel() iModel.addModel(model) posResult = {} negResult = {} max = abs(objValue)*2 step = 0.1 lp = self.solverClass() lp.setModel(iModel) lp.clearObjective() lp.setObjectiveMap(objective) lp.runSimplex() fluxes = lp.getPredictionMap() if constrict: for name in fluxes.keys(): value = fluxes[name] lower = None upper = None if value >= 0 : upper = value if value <= 0: lower = value lp.addColumnLimit(name,lower,upper) for fName in fluxes.keys(): fValue = fluxes[fName] (lower,upper) = model.getColumnLimit(fName) if lower == None: lower = float("-inf") if upper == None: upper = float("inf") if abs(fValue) <= delta: if abs(lower) != 0.0 and lower != float("-inf"): iLowerLimit = -step else: iLowerLimit = -step if abs(upper) != 0.0 and upper != float("inf"): iUpperLimit = step else: iUpperLimit = step else: iLowerLimit = fValue * 0.9 iUpperLimit = fValue * 1.10 negSlope = None if iLowerLimit > lower and iLowerLimit != fValue: negResult = self.findSlope(lp,fName,fValue,objValue,iLowerLimit,negResult,factor,max,useZeros) lp.addColumnLimit(fName,lower,upper) posSlope = None if iUpperLimit < upper and iUpperLimit != fValue: posResult = self.findSlope(lp,fName,fValue,objValue,iUpperLimit,posResult,factor,max,useZeros) lp.addColumnLimit(fName,lower,upper) if lower == float("-inf"): lower = None if upper == float("inf"): upper = None lp.addColumnLimit(fName,lower,upper) lp.clear() del lp return (negResult,posResult)