class OpLabelPreviewer(Operator): name = "LabelPreviewer" description = "Provides a Preview of the labels after gaussian smoothing" inputSlots = [InputSlot("Labels"), InputSlot("Sigma", stype="object")] outputSlots = [OutputSlot("Output")] def __init__(self, *args, **kwargs): super(OpLabelPreviewer, self).__init__(*args, **kwargs) self._svr = SVR() def setupOutputs(self): self.Output.meta.assignFrom(self.Labels.meta) self.Output.meta.dtype = np.float32 self.Output.meta.drange = (0.0, 1.0) @traceLogged(logger, level=logging.INFO, msg="OpTrainCounter: Training Counting Regressor") def execute(self, slot, subindex, roi, result): progress = 0 key = roi.toSlice() dot = self.Labels[key].wait() self._svr.set_params(Sigma=self.Sigma.value) result[...] = self._svr.smoothLabels(dot)[0] return result def propagateDirty(self, slot, subindex, roi): self.Output.setDirty((slice(None)))
def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() params = self._svr.get_params() self.initInputs(params) self.Classifier.meta.dtype = object self.Classifier.meta.shape = (self.numRegressors, ) # Normally, lane removal does not trigger a dirty notification. # But in this case, if the lane contained any label data whatsoever, # the classifier needs to be marked dirty. # We know which slots contain (or contained) label data because they have # been 'touched' at some point (they became dirty at some point). self._touched_slots = set() def handle_new_lane(multislot, index, newlength): def handle_dirty_lane(slot, roi): self._touched_slots.add(slot) multislot[index].notifyDirty(handle_dirty_lane) self.ForegroundLabels.notifyInserted(handle_new_lane) self.BackgroundLabels.notifyInserted(handle_new_lane) def handle_remove_lane(multislot, index, newlength): # If the lane we're removing contained # label data, then mark the downstream dirty if multislot[index] in self._touched_slots: self.Classifier.setDirty() self._touched_slots.remove(multislot[index]) self.ForegroundLabels.notifyRemove(handle_remove_lane) self.BackgroundLabels.notifyRemove(handle_remove_lane)
class OpLabelPreviewer(Operator): name = "LabelPreviewer" description = "Provides a Preview of the labels after gaussian smoothing" inputSlots = [InputSlot("Labels"), InputSlot("Sigma", stype = "object")] outputSlots = [OutputSlot("Output")] def __init__(self, *args, **kwargs): super(OpLabelPreviewer, self).__init__(*args, **kwargs) self._svr = SVR() def setupOutputs(self): self.Output.meta.assignFrom(self.Labels.meta) self.Output.meta.dtype = np.float32 self.Output.meta.drange = (0.0, 1.0) @traceLogged(logger, level=logging.INFO, msg="OpTrainCounter: Training Counting Regressor") def execute(self, slot, subindex, roi, result): progress = 0 key = roi.toSlice() dot=self.Labels[key].wait() self._svr.set_params(Sigma = self.Sigma.value) result[...] = self._svr.smoothLabels(dot)[0] return result def propagateDirty(self, slot, subindex, roi): self.Output.setDirty((slice(None)))
def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() params = self._svr.get_params() self.initInputs(params) self.Classifier.meta.dtype = object self.Classifier.meta.shape = (self.numRegressors,)
def _deserialize(self, classifierGroup, slot): # Due to non-shared hdf5 dlls, vigra can't read directly # from our open hdf5 group. Instead, we'll copy the # classfier data to a temporary file and give it to vigra. tmpDir = tempfile.mkdtemp() cachePath = os.path.join(tmpDir, 'tmp_classifier_cache.h5').replace('\\', '/') with h5py.File(cachePath, 'w') as cacheFile: cacheFile.copy(classifierGroup, self.name) forests = [] for name, forestGroup in sorted(classifierGroup.items()): targetname = '{0}/{1}'.format(self.name, name) #forests.append(vigra.learning.RandomForest(cachePath, targetname)) from ilastik.applets.counting.countingsvr import SVR forests.append(SVR.load(cachePath, targetname)) os.remove(cachePath) os.rmdir(tmpDir) # Now force the classifier into our classifier cache. The # downstream operators (e.g. the prediction operator) can # use the classifier without inducing it to be re-trained. # (This assumes that the classifier we are loading is # consistent with the images and labels that we just # loaded. As soon as training input changes, it will be # retrained.) self.cache.forceValue(numpy.array(forests))
def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() params = self._svr.get_params() self.initInputs(params) self.Classifier.meta.dtype = object self.Classifier.meta.shape = (self.numRegressors,) # Normally, lane removal does not trigger a dirty notification. # But in this case, if the lane contained any label data whatsoever, # the classifier needs to be marked dirty. # We know which slots contain (or contained) label data because they have # been 'touched' at some point (they became dirty at some point). self._touched_slots = set() def handle_new_lane( multislot, index, newlength ): def handle_dirty_lane( slot, roi ): self._touched_slots.add(slot) multislot[index].notifyDirty( handle_dirty_lane ) self.ForegroundLabels.notifyInserted( handle_new_lane ) self.BackgroundLabels.notifyInserted( handle_new_lane ) def handle_remove_lane( multislot, index, newlength ): # If the lane we're removing contained # label data, then mark the downstream dirty if multislot[index] in self._touched_slots: self.Classifier.setDirty() self._touched_slots.remove(multislot[index]) self.ForegroundLabels.notifyRemove( handle_remove_lane ) self.BackgroundLabels.notifyRemove( handle_remove_lane )
def _deserialize(self, classifierGroup, slot): # Due to non-shared hdf5 dlls, vigra can't read directly # from our open hdf5 group. Instead, we'll copy the # classfier data to a temporary file and give it to vigra. tmpDir = tempfile.mkdtemp() cachePath = os.path.join(tmpDir, 'tmp_classifier_cache.h5').replace('\\', '/') with h5py.File(cachePath, 'w') as cacheFile: cacheFile.copy(classifierGroup, self.name) try: forests = [] for name, forestGroup in sorted(classifierGroup.items()): targetname = '{0}/{1}'.format(self.name, name) #forests.append(vigra.learning.RandomForest(cachePath, targetname)) from ilastik.applets.counting.countingsvr import SVR forests.append(SVR.load(cachePath, targetname)) except: warnings.warn( "Wasn't able to deserialize the saved classifier. " "It will need to be retrainied" ) return finally: os.remove(cachePath) os.rmdir(tmpDir) # Now force the classifier into our classifier cache. The # downstream operators (e.g. the prediction operator) can # use the classifier without inducing it to be re-trained. # (This assumes that the classifier we are loading is # consistent with the images and labels that we just # loaded. As soon as training input changes, it will be # retrained.) self.cache.forceValue(numpy.array(forests))
def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() self.Classifier.meta.dtype = object self.Classifier.meta.shape = (1,) self.progressSignal = OrderedSignal()
def train_and_store(i): result[i] = SVR(minmax=normalizationFactors, **params) result[i].fitPrepared(fullFeatMatrix, fullLabelsMatrix, tags=fullTags, boxConstraints=boxConstraints, numRegressors=self.numRegressors, trainAll=False)
class OpTrainCounter(Operator): name = "TrainCounter" description = "Train a random forest on multiple images" category = "Learning" inputSlots = [InputSlot("Images", level=1), InputSlot("ForegroundLabels", level=1), InputSlot("BackgroundLabels", level=1), InputSlot("fixClassifier", stype="bool"), InputSlot("nonzeroLabelBlocks", level=1), InputSlot("Sigma", stype = "float", value=2.0), InputSlot("Epsilon", stype = "float"), InputSlot("C", stype = "float"), InputSlot("SelectedOption", stype = "object"), InputSlot("Ntrees", stype = "int"), #RF parameter InputSlot("MaxDepth", stype = "object"), #RF parameter, None means grow until purity InputSlot("BoxConstraintRois", level = 1, stype = "list", value = []), InputSlot("BoxConstraintValues", level = 1, stype = "list", value = []), InputSlot("UpperBound") ] outputSlots = [OutputSlot("Classifier")] options = SVR.options availableOptions = [checkOption(option["req"]) for option in SVR.options] numRegressors = 4 def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() params = self._svr.get_params() self.initInputs(params) self.Classifier.meta.dtype = object self.Classifier.meta.shape = (self.numRegressors,) def initInputs(self, params): fix = False if self.fixClassifier.ready(): fix = self.fixClassifier.value self.fixClassifier.setValue(True) self.Sigma.setValue(params["Sigma"]) self.Epsilon.setValue(params["epsilon"]) self.C.setValue(params["C"]) self.Ntrees.setValue(params["ntrees"]) self.MaxDepth.setValue(params["maxdepth"]) self.SelectedOption.setValue(params["method"]) self.fixClassifier.setValue(fix) def setupOutputs(self): if self.inputs["fixClassifier"].value == False: method = self.SelectedOption.value if type(method) is dict: method = method["method"] params = {"method" : method, "Sigma": self.Sigma.value, "epsilon" : self.Epsilon.value, "C" : self.C.value, "ntrees" : self.Ntrees.value, "maxdepth" :self.MaxDepth.value } self._svr.set_params(**params) #self.Classifier.setValue(self._svr) #self.outputs["Classifier"].meta.dtype = object #self.outputs["Classifier"].meta.shape = (self._forest_count,) #@traceLogged(logger, level=logging.INFO, msg="OpTrainCounter: Training Counting Regressor") def execute(self, slot, subindex, roi, result): progress = 0 numImages = len(self.Images) self.progressSignal(progress) featMatrix=[] labelsMatrix=[] tagList = [] #result[0] = self._svr for i,labels in enumerate(self.inputs["ForegroundLabels"]): if labels.meta.shape is not None: opGaussian = OpGaussianSmoothing(parent = self, graph = self.graph) opGaussian.Sigma.setValue(self.Sigma.value) opGaussian.Input.connect(self.ForegroundLabels[i]) blocks = self.inputs["nonzeroLabelBlocks"][i][0].wait() reqlistlabels = [] reqlistbg = [] reqlistfeat = [] progress += 10 / numImages self.progressSignal(progress) for b in blocks[0]: request = opGaussian.Output[b] #request = labels[b] featurekey = list(b) featurekey[-1] = slice(None, None, None) request2 = self.Images[i][featurekey] request3 = self.inputs["BackgroundLabels"][i][b] reqlistlabels.append(request) reqlistfeat.append(request2) reqlistbg.append(request3) traceLogger.debug("Requests prepared") numLabelBlocks = len(reqlistlabels) progress_outer = [progress] if numLabelBlocks > 0: progressInc = (80 - 10)/(numLabelBlocks * numImages) def progressNotify(req): progress_outer[0] += progressInc/2 self.progressSignal(progress_outer[0]) for ir, req in enumerate(reqlistfeat): req.notify_finished(progressNotify) req.submit() for ir, req in enumerate(reqlistlabels): req.notify_finished(progressNotify) req.submit() for ir, req in enumerate(reqlistbg): req.notify_finished(progressNotify) req.submit() traceLogger.debug("Requests fired") #Fixme: Maybe later request only part of the region? #image=self.inputs["Images"][i][:].wait() for ir, req in enumerate(reqlistlabels): labblock = req.wait() image = reqlistfeat[ir].wait() labbgblock = reqlistbg[ir].wait() labblock = labblock.reshape((image.shape[:-1])) image = image.reshape((-1, image.shape[-1])) labbgindices = np.where(labbgblock == 2) labbgindices = np.ravel_multi_index(labbgindices, labbgblock.shape) newDot, mapping, tags = \ self._svr.prepareDataRefactored(labblock, labbgindices) #self._svr.prepareData(labblock, smooth = True) labels = newDot[mapping] features = image[mapping] featMatrix.append(features) labelsMatrix.append(labels) tagList.append(tags) progress = progress_outer[0] traceLogger.debug("Requests processed") self.progressSignal(80 / numImages) if len(featMatrix) == 0 or len(labelsMatrix) == 0: result[:] = None else: posTags = [tag[0] for tag in tagList] negTags = [tag[1] for tag in tagList] numPosTags = np.sum(posTags) numTags = np.sum(posTags) + np.sum(negTags) fullFeatMatrix = np.ndarray((numTags, self.Images[0].meta.shape[-1]), dtype = np.float64) fullLabelsMatrix = np.ndarray((numTags), dtype = np.float64) fullFeatMatrix[:] = np.NAN fullLabelsMatrix[:] = np.NAN currPosCount = 0 currNegCount = numPosTags for i, posCount in enumerate(posTags): fullFeatMatrix[currPosCount:currPosCount + posTags[i],:] = featMatrix[i][:posCount,:] fullLabelsMatrix[currPosCount:currPosCount + posTags[i]] = labelsMatrix[i][:posCount] fullFeatMatrix[currNegCount:currNegCount + negTags[i],:] = featMatrix[i][posCount:,:] fullLabelsMatrix[currNegCount:currNegCount + negTags[i]] = labelsMatrix[i][posCount:] currPosCount += posTags[i] currNegCount += negTags[i] assert(not np.isnan(np.sum(fullFeatMatrix))) fullTags = [np.sum(posTags), np.sum(negTags)] #pool = RequestPool() maxima = np.max(fullFeatMatrix, axis=0) minima = np.min(fullFeatMatrix, axis=0) normalizationFactors = (minima,maxima) boxConstraintList = [] boxConstraints = None if self.BoxConstraintRois.ready() and self.BoxConstraintValues.ready(): for i, slot in enumerate(zip(self.BoxConstraintRois,self.BoxConstraintValues)): for constr, val in zip(slot[0].value, slot[1].value): boxConstraintList.append((i, constr, val)) if len(boxConstraintList) > 0: boxConstraints = self.constructBoxConstraints(boxConstraintList) params = self._svr.get_params() try: pool = RequestPool() def train_and_store(i): result[i] = SVR(minmax = normalizationFactors, **params) result[i].fitPrepared(fullFeatMatrix, fullLabelsMatrix, tags = fullTags, boxConstraints = boxConstraints, numRegressors = self.numRegressors, trainAll = False) for i in range(self.numRegressors): req = pool.request(partial(train_and_store, i)) pool.wait() pool.clean() except: logger.error("ERROR: could not learn regressor") logger.error("fullFeatMatrix shape = {}, dtype = {}".format(fullFeatMatrix.shape, fullFeatMatrix.dtype) ) logger.error("fullLabelsMatrix shape = {}, dtype = {}".format(fullLabelsMatrix.shape, fullLabelsMatrix.dtype) ) raise finally: self.progressSignal(100) return result def propagateDirty(self, slot, subindex, roi): if slot is not self.inputs["fixClassifier"] and self.inputs["fixClassifier"].value == False: self.outputs["Classifier"].setDirty((slice(None),)) def constructBoxConstraints(self, constraints): try: shape = np.array([[stop - start for start, stop in zip(constr[0][1:-2], constr[1][1:-2])] for _, constr,_ in constraints]) taggedShape = self.Images[0].meta.getTaggedShape() numcols = taggedShape['c'] shape = shape[:,0] * shape[:,1] shape = np.sum(shape,axis = 0) constraintmatrix = np.ndarray(shape = (shape, numcols)) constraintindices = [] constraintvalues = [] offset = 0 for imagenumber, constr, value in constraints: slicing = [slice(start,stop) for start, stop in zip(constr[0][1:-2], constr[1][1:-2])] numrows = (slicing[0].stop - slicing[0].start) * (slicing[1].stop - slicing[1].start) slicing.append(slice(None)) slicing = tuple(slicing) constraintmatrix[offset:offset + numrows,:] = self.Images[imagenumber][slicing].wait().reshape((numrows, -1)) constraintindices.append(offset) constraintvalues.append(value) offset = offset + numrows constraintindices.append(offset) constraintvalues = np.array(constraintvalues, np.float64) constraintindices = np.array(constraintindices, np.int) boxConstraints = {"boxFeatures" : constraintmatrix, "boxValues" : constraintvalues, "boxIndices" : constraintindices} except: boxConstraints = None logger.error("An error has occured with the box Constraints: {} ".format(constraints)) return boxConstraints
def __init__(self, *args, **kwargs): super(OpLabelPreviewer, self).__init__(*args, **kwargs) self._svr = SVR()
class OpTrainCounter(Operator): name = "TrainCounter" description = "Train a random forest on multiple images" category = "Learning" inputSlots = [InputSlot("Images", level=1),InputSlot("Labels", level=1), InputSlot("fixClassifier", stype="bool"), InputSlot("nonzeroLabelBlocks", level=1), InputSlot("Sigma", value = [2.5], stype = "object"), InputSlot("Epsilon", value = 1E-3, stype = "float"), #InputSlot("UnderMult", value = 100, stype = "float"), #InputSlot("OverMult", value = 100, stype = "float"), InputSlot("C", value = 1, stype = "float"), InputSlot("SelectedOption", value = SVR.options[0], stype = "object"), InputSlot("Ntrees", value = 10, stype = "int"), #RF parameter InputSlot("MaxDepth", value =50, stype = "object"), #RF parameter, None means grow until purity InputSlot("BoxConstraints", stype = "list", optional = True) ] outputSlots = [OutputSlot("Classifier")] options = SVR.options def __init__(self, *args, **kwargs): super(OpTrainCounter, self).__init__(*args, **kwargs) self.progressSignal = OrderedSignal() self._svr = SVR() self.Classifier.meta.dtype = object self.Classifier.meta.shape = (1,) self.progressSignal = OrderedSignal() def setupOutputs(self): if self.inputs["fixClassifier"].value == False: params = {"method" : self.SelectedOption.value["method"], "Sigma": self.Sigma.value, "epsilon" : self.Epsilon.value, "C" : self.C.value, "ntrees" : self.Ntrees.value, "maxdepth" :self.MaxDepth.value } self._svr.set_params(**params) #self.Classifier.setValue(self._svr) #self.outputs["Classifier"].meta.dtype = object #self.outputs["Classifier"].meta.shape = (self._forest_count,) @traceLogged(logger, level=logging.INFO, msg="OpTrainCounter: Training Counting Regressor") def execute(self, slot, subindex, roi, result): progress = 0 self.progressSignal(progress) featMatrix=[] labelsMatrix=[] tagList = [] result[0] = self._svr for i,labels in enumerate(self.inputs["Labels"]): if labels.meta.shape is not None: labels=labels[:].wait() #Fixme: Maybe later request only part of the region? image=self.inputs["Images"][i][:].wait() newImg, newDot, mapping, tags = \ result[0].prepareData(image, labels, smooth = True, normalize = False) features=newImg[mapping] labels=newDot[mapping] featMatrix.append(features) labelsMatrix.append(labels) tagList.append(tags) #tagsMatrix.append(tags) posTags = [tag[0] for tag in tagList] negTags = [tag[1] for tag in tagList] numPosTags = np.sum(posTags) numTags = np.sum(posTags) + np.sum(negTags) fullFeatMatrix = np.ndarray((numTags, self.Images[0].meta.shape[-1])) fullLabelsMatrix = np.ndarray((numTags)) fullFeatMatrix[:] = np.NAN fullLabelsMatrix[:] = np.NAN currPosCount = 0 currNegCount = numPosTags for i, posCount in enumerate(posTags): fullFeatMatrix[currPosCount:currPosCount + posTags[i],:] = featMatrix[i][:posCount,:] fullLabelsMatrix[currPosCount:currPosCount + posTags[i]] = labelsMatrix[i][:posCount] fullFeatMatrix[currNegCount:currNegCount + negTags[i],:] = featMatrix[i][posCount:,:] fullLabelsMatrix[currNegCount:currNegCount + negTags[i]] = labelsMatrix[i][posCount:] currPosCount += posTags[i] currNegCount += negTags[i] if np.isnan(np.sum(fullFeatMatrix)): raise Exception("NAN NAN NAN NAN BATMAN") #featMatrix=np.concatenate(featMatrix,axis=0) #labelsMatrix=np.concatenate(labelsMatrix,axis=0) #tagsMatrix=np.concatenate(tagsMatrix,axis=0) # train and store self._forest_count forests in parallel fullTags = [np.sum(posTags), np.sum(negTags)] #pool = RequestPool() self.progressSignal(30) boxConstraints = [] if self.BoxConstraints.ready(): constraints = self.BoxConstraints.value for constr in constraints: value = float(constr[2].toDouble()[0]) slicing = [slice(start,stop) for start, stop in zip(constr[0][1:-2], constr[1][1:-2])] slicing.append(slice(None)) slicing = tuple(slicing) features = self.Images[0][slicing].wait() features = features.reshape((-1, features.shape[-1])) constraint = (value, features) boxConstraints.append(constraint) self.progressSignal(50) try: result[0].fitPrepared(fullFeatMatrix, fullLabelsMatrix, tags = fullTags, boxConstraints = boxConstraints) #req = pool.request(partial(result[0].fitPrepared, featMatrix, labelsMatrix, tagsMatrix, self.Epsilon.value)) #pool.wait() #pool.clean() except: logger.error("ERROR: could not learn regressor") logger.error("fullFeatMatrix shape = {}, dtype = {}".format(fullFeatMatrix.shape, fullFeatMatrix.dtype) ) logger.error("fullLabelsMatrix shape = {}, dtype = {}".format(fullLabelsMatrix.shape, fullLabelsMatrix.dtype) ) self.progressSignal(100) return result def propagateDirty(self, slot, subindex, roi): if slot is not self.inputs["fixClassifier"] and self.inputs["fixClassifier"].value == False: self.outputs["Classifier"].setDirty((slice(None),))