def testSSLWorkflowBuilder(self): segmenter = DumbSegmenter() builder = SSLWorkflowBuilder() builder.set_n_jobs(5) builder.set_tile_size(512, 768) builder.set_overlap(3) builder.set_distance_tolerance(7) builder.set_background_class(5) builder.set_logger(StandardOutputLogger(Logger.DEBUG)) with self.assertRaises(MissingComponentException): builder.get() builder.set_segmenter(segmenter) builder.set_default_tile_builder() workflow = builder.get() self.assertIsInstance(workflow, SSLWorkflow) self.assertEqual(workflow._n_jobs, 5) self.assertEqual(workflow._tile_overlap, 3) self.assertEqual(workflow._tile_max_height, 512) self.assertEqual(workflow._tile_max_width, 768) self.assertIsInstance(workflow._tile_builder, DefaultTileBuilder) self.assertIsInstance(workflow.logger, StandardOutputLogger) self.assertEqual(workflow._locator._background, 5)
def __init__(self, build_fn=None, logger=StandardOutputLogger(Logger.INFO), **sk_params): super(CellCountRandomizedTrees, self).__init__(build_fn, logger, **sk_params) self.__forest = None
def __init__(self, build_fn=None, logger=StandardOutputLogger(Logger.INFO), **sk_params): self.build_fn = build_fn self.sk_params = sk_params self.logger = logger
def __init__(self, cytomine, software_id, project_id, job_parameters, tile_overlap, tile_width, tile_height, n_jobs, threshold, min_area, model_path, rseed, working_path): """An example job implementing an sldc workflow. Parameters ---------- cytomine: Cytomine Cytomine client software_id: int Cytomine software id project_id: int Cytomine project id job_parameters: dict Job parameters tile_overlap: int Number of pixel of overlap between the tiles tile_width: int Maximum width of the tiles tile_height: int Maximum height of the tiles n_jobs: int Number of available jobs threshold: int Segmentation threshold in [0, 255] min_area: int Minimum area of the valid objects in pixel squared model_path: str Path to the pickled pyxit model rseed: int Random seed working_path: str Working path of the workflow (for temporary files) """ CytomineJob.__init__(self, cytomine, software_id, project_id, parameters=job_parameters) Loggable.__init__(self, logger=StandardOutputLogger(Logger.INFO)) self._cytomine = cytomine # create workflow component random_state = check_random_state(rseed) tile_builder = CytomineTileBuilder(cytomine, working_path=working_path) segmenter = DemoSegmenter(threshold) area_rule = ValidAreaRule(min_area) classifier = PyxitClassifierAdapter.build_from_pickle( model_path, tile_builder, self.logger, random_state=random_state, n_jobs=n_jobs, working_path=working_path ) builder = WorkflowBuilder() builder.set_n_jobs(n_jobs) builder.set_logger(self.logger) builder.set_overlap(tile_overlap) builder.set_tile_size(tile_width, tile_height) builder.set_tile_builder(tile_builder) builder.set_segmenter(segmenter) builder.add_classifier(area_rule, classifier, dispatching_label="valid") self._workflow = builder.get()
def main(argv): with CytomineJob.from_cli(argv) as job: if not os.path.exists(job.parameters.working_path): os.makedirs(job.parameters.working_path) # create workflow component logger = StandardOutputLogger(Logger.INFO) random_state = check_random_state(int(job.parameters.rseed)) tile_builder = CytomineTileBuilder( working_path=job.parameters.working_path) segmenter = DemoSegmenter(job.parameters.threshold) area_rule = ValidAreaRule(job.parameters.min_area) classifier = PyxitClassifierAdapter.build_from_pickle( job.parameters.pyxit_model_path, tile_builder, logger, random_state=random_state, n_jobs=job.parameters.n_jobs, working_path=job.parameters.working_path) builder = SLDCWorkflowBuilder() builder.set_n_jobs(job.parameters.n_jobs) builder.set_logger(logger) builder.set_overlap(job.parameters.sldc_tile_overlap) builder.set_tile_size(job.parameters.sldc_tile_width, job.parameters.sldc_tile_height) builder.set_tile_builder(tile_builder) builder.set_segmenter(segmenter) builder.add_classifier(area_rule, classifier, dispatching_label="valid") workflow = builder.get() slide = CytomineSlide(job.parameters.cytomine_image_id) results = workflow.process(slide) # Upload results for polygon, label, proba, dispatch in results: if label is not None: # if image is a window, the polygon must be translated if isinstance(slide, ImageWindow): polygon = translate(polygon, slide.abs_offset_x, slide.abs_offset_y) # upload the annotation polygon = affine_transform( polygon, [1, 0, 0, -1, 0, slide.image_instance.height]) annotation = Annotation( location=polygon.wkt, id_image=slide.image_instance.id).save() AlgoAnnotationTerm(id_annotation=annotation.id, id_term=label, rate=float(proba)).save()
def testSLDCWorkflowWithOneShotDispatcher(self): # pre build components segmenter = DumbSegmenter() dispatcher = DumbDispatcher() classifier = DumbClassifier() rule = DumbRule() logger = StandardOutputLogger(Logger.DEBUG) builder = SLDCWorkflowBuilder() builder.set_tile_size(512, 768) builder.set_overlap(3) builder.set_distance_tolerance(5) builder.set_n_jobs(5) builder.set_logger(logger) builder.set_parallel_dc(True) builder.set_tile_builder(None) with self.assertRaises(MissingComponentException): builder.get() builder.set_segmenter(segmenter) with self.assertRaises(MissingComponentException): builder.get() builder.set_default_tile_builder() with self.assertRaises(MissingComponentException): builder.get() builder.set_one_shot_dispatcher(dispatcher, {"default": classifier}) with self.assertRaises(InvalidBuildingException): builder.add_classifier(rule, classifier, dispatching_label="default") with self.assertRaises(InvalidBuildingException): builder.add_catchall_classifier(classifier, dispatching_label="default") workflow = builder.get() self.assertIsInstance(workflow, SLDCWorkflow) self.assertEqual(workflow._segmenter, segmenter) self.assertEqual(workflow._n_jobs, 5) self.assertEqual(workflow._tile_overlap, 3) self.assertEqual(workflow._tile_max_height, 512) self.assertEqual(workflow._tile_max_width, 768) self.assertEqual(workflow.logger, logger) self.assertIsInstance(workflow._tile_builder, DefaultTileBuilder) self.assertEqual(workflow._dispatch_classifier._dispatcher, dispatcher) self.assertEqual(len(workflow._dispatch_classifier._classifiers), 1) self.assertEqual(workflow._dispatch_classifier._classifiers[0], classifier)
def __init__(self, colorspaces, dtype=np.float16, logger=StandardOutputLogger(Logger.INFO)): if colorspaces is None: raise ValueError("Colorspace cannot be None") self.logger = logger self.dtype = dtype self.features = None self.colorspaces = list() colorspaces_dict = split_list_to_dict(colorspaces, splitter='__') for colorspace, features in colorspaces_dict.items(): if colorspace in ('rgb', 'RGB', 'color'): self.colorspaces.append(ColorspaceRGB(features)) elif colorspace in ('gray', 'grayscale', 'L'): self.colorspaces.append(ColorspaceGrayscale(features))
def __init__(self, default_estimator, param_grid, cv, me, untrainable_param_grid=None, scoring_rank='f1_score', refit=False, iid=True, n_jobs=1, pre_dispatch='2*n_jobs', logger=StandardOutputLogger(Logger.INFO)): self.default_estimator = default_estimator self.param_grid = param_grid self.untrainable_param_grid = untrainable_param_grid self.cv = cv self.me = me self.scoring_rank = scoring_rank self.n_jobs = n_jobs self.pre_dispatch = pre_dispatch self.logger = logger self.refit = refit self.iid = iid _check_param_grid(param_grid) _check_param_grid(untrainable_param_grid)
def testMerge(self): timing1 = WorkflowTiming() timing2 = WorkflowTiming() timing1.start("root1") timing1.end("root1") timing1.start("root") timing1.end("root") timing1.start("root1.adj") timing1.end("root1.adj") timing2.start("root2") timing2.end("root2") timing2.start("root") timing2.end("root") timing2.start("root1.adj") timing2.end("root1.adj") # merge without update of initial objects merged = merge_timings(timing1, timing2) self.assertEqual(len(merged["root1"]), 1) self.assertEqual(len(merged["root2"]), 1) self.assertEqual(len(merged["root"]), 2) self.assertEqual(len(merged["root1.adj"]), 2) # merge with update of timing1 timing1.merge(timing2) self.assertEqual(len(timing1["root1"]), 1) self.assertEqual(len(timing1["root2"]), 1) self.assertEqual(len(timing1["root"]), 2) self.assertEqual(len(timing1["root1.adj"]), 2) with self.assertRaises(TypeError): timing1.merge(StandardOutputLogger(level=Logger.DEBUG)) timing1.merge(timing1) self.assertEqual(len(timing1["root1"]), 1) self.assertEqual(len(timing1["root2"]), 1) self.assertEqual(len(timing1["root"]), 2) self.assertEqual(len(timing1["root1.adj"]), 2)
def main(): """ (4) build the workflow """ logger = StandardOutputLogger(Logger.INFO) builder = SLDCWorkflowBuilder() builder.set_n_jobs(4) builder.set_logger(logger) builder.set_default_tile_builder() builder.set_tile_size(256, 256) builder.set_segmenter(BasicSegmenter()) builder.add_classifier(ShapeRule(ShapeRule.CIRCLE), ColorClassifier(), "circle") builder.add_classifier(ShapeRule(ShapeRule.SQUARE), ColorClassifier(), "square") workflow = builder.get() """ (5) build a (fake) image """ np_image = np.zeros([2000, 2000], dtype=np.uint8) np_image = draw_circle(np_image, 100, (500, 1500), 255) np_image = draw_circle(np_image, 100, (1500, 600), 127) np_image = draw_square(np_image, 200, (500, 500), 255) np_image = draw_square(np_image, 200, (1500, 1500), 127) np_image = draw_square(np_image, 300, (1000, 1000), 255) image = NumpyImage(np_image) """ (6) process the image """ results = workflow.process(image) """ (7) report execution times """ report_timing(results.timing, logger) """ (8) explore the results """ for i, object_info in enumerate(results): print( "Object {}:".format(i + 1) + os.linesep + "> area : {}".format(object_info.polygon.area) + os.linesep + "> label : '{}'".format(object_info.label) + os.linesep + "> proba : {}".format(object_info.proba) + os.linesep + "> dispatch: '{}'".format(object_info.dispatch) )
def __init__(self, cytomine, software_id, project_id, job_parameters, fix_image_id, moving_image_id, nb_spatial_sample, nb_iterations, storage_id, annotation_fix_id, annotation_moving_id, working_path, cytomine_host, cytomine_upload, pk, prk, export_overlay_images, number_of_resolutions, result_file_name): print("After init") # call init from parent classes # print("project id = " + str(project_id)) if (cytomine == None): print "Cytomine obj null" print("soft_id =" + str(software_id)) CytomineJob.__init__(self, cytomine, software_id, project_id, parameters=None) Loggable.__init__(self, logger=StandardOutputLogger(Logger.INFO)) # keep var from parameters # self._fix_image_id = fix_image_id self._moving_image_id = moving_image_id self._nb_spatial_sample = nb_spatial_sample self._nb_iterations = nb_iterations self._storage_id = storage_id self._id_annotation_fix = annotation_fix_id self._id_annotation_moving = annotation_moving_id self._working_path = working_path self._cytomine_upload = cytomine_upload self._cytomine_host = cytomine_host self._cytomine = cytomine self._project_id = project_id self._pk = pk self._prk = prk self._overlayed_images = export_overlay_images self._job_parameters = job_parameters self._number_of_resolutions = number_of_resolutions self._result_file_name = result_file_name
def testWorkflowChainBuilder(self): segmenter = DumbSegmenter() dispatcher = DumbDispatcher() classifier = DumbClassifier() builder = SLDCWorkflowBuilder() builder.set_segmenter(segmenter) builder.set_default_tile_builder() builder.set_one_shot_dispatcher(dispatcher, {"default": classifier}) workflow1 = builder.get() builder2 = SSLWorkflowBuilder() builder2.set_segmenter(segmenter) builder2.set_default_tile_builder() workflow2 = builder2.get() _filter = DefaultFilter() logger = StandardOutputLogger(Logger.DEBUG) chain_builder = WorkflowChainBuilder() chain_builder.set_logger(logger) with self.assertRaises(MissingComponentException): chain_builder.get() chain_builder.set_first_workflow(workflow1, label="first") chain_builder.add_executor(workflow2, label="second", filter=_filter, n_jobs=2, logger=logger) chain = chain_builder.get() self.assertIsInstance(chain, WorkflowChain) self.assertEqual(chain.logger, logger) self.assertEqual(chain._first_workflow, workflow1) self.assertEqual(len(chain._executors), 1) self.assertEqual(chain._executors[0]._workflow, workflow2) self.assertEqual(len(chain._labels), 2) self.assertEqual(tuple(chain._labels), ("first", "second")) self.assertEqual(len(chain._filters), 1) self.assertEqual(chain._filters[0], _filter)
def main(argv): with CytomineJob.from_cli(argv) as cj: # use only images from the current project cj.job.update(progress=1, statusComment="Preparing execution") # extract images to process if cj.parameters.cytomine_zoom_level > 0 and ( cj.parameters.cytomine_tile_size != 256 or cj.parameters.cytomine_tile_overlap != 0): raise ValueError( "when using zoom_level > 0, tile size should be 256 " "(given {}) and overlap should be 0 (given {})".format( cj.parameters.cytomine_tile_size, cj.parameters.cytomine_tile_overlap)) cj.job.update( progress=1, statusComment="Preparing execution (creating folders,...).") # working path root_path = str(Path.home()) working_path = os.path.join(root_path, "images") os.makedirs(working_path, exist_ok=True) # load training information cj.job.update(progress=5, statusComment="Extract properties from training job.") train_job = Job().fetch(cj.parameters.cytomine_id_job) properties = PropertyCollection(train_job).fetch().as_dict() binary = str2bool(properties["binary"].value) classes = parse_domain_list(properties["classes"].value) cj.job.update(progress=10, statusComment="Download the model file.") attached_files = AttachedFileCollection(train_job).fetch() model_file = attached_files.find_by_attribute("filename", "model.joblib") model_filepath = os.path.join(root_path, "model.joblib") model_file.download(model_filepath, override=True) pyxit = joblib.load(model_filepath) # set n_jobs pyxit.base_estimator.n_jobs = cj.parameters.n_jobs pyxit.n_jobs = cj.parameters.n_jobs cj.job.update(progress=45, statusComment="Build workflow.") builder = SSLWorkflowBuilder() builder.set_tile_size(cj.parameters.cytomine_tile_size, cj.parameters.cytomine_tile_size) builder.set_overlap(cj.parameters.cytomine_tile_overlap) builder.set_tile_builder( CytomineTileBuilder(working_path, n_jobs=cj.parameters.n_jobs)) builder.set_logger(StandardOutputLogger(level=Logger.INFO)) builder.set_n_jobs(1) builder.set_background_class(0) # value 0 will prevent merging but still requires to run the merging check # procedure (inefficient) builder.set_distance_tolerance(2 if cj.parameters.union_enabled else 0) builder.set_segmenter( ExtraTreesSegmenter( pyxit=pyxit, classes=classes, prediction_step=cj.parameters.pyxit_prediction_step, background=0, min_std=cj.parameters.tile_filter_min_stddev, max_mean=cj.parameters.tile_filter_max_mean)) workflow = builder.get() area_checker = AnnotationAreaChecker( min_area=cj.parameters.min_annotation_area, max_area=cj.parameters.max_annotation_area) def get_term(label): if binary: if "cytomine_id_predict_term" not in cj.parameters: return [] else: return [int(cj.parameters.cytomine_id_predict_term)] # multi-class return [label] zones = extract_images_or_rois(cj.parameters) for zone in cj.monitor(zones, start=50, end=90, period=0.05, prefix="Segmenting images/ROIs"): results = workflow.process(zone) annotations = AnnotationCollection() for obj in results: if not area_checker.check(obj.polygon): continue polygon = obj.polygon if isinstance(zone, ImageWindow): polygon = affine_transform( polygon, [1, 0, 0, 1, zone.abs_offset_x, zone.abs_offset_y]) polygon = change_referential(polygon, zone.base_image.height) if cj.parameters.cytomine_zoom_level > 0: zoom_mult = (2**cj.parameters.cytomine_zoom_level) polygon = affine_transform( polygon, [zoom_mult, 0, 0, zoom_mult, 0, 0]) annotations.append( Annotation(location=polygon.wkt, id_terms=get_term(obj.label), id_project=cj.project.id, id_image=zone.base_image.image_instance.id)) annotations.save() cj.job.update(status=Job.TERMINATED, status_comment="Finish", progress=100)
def flip(m, axis): indexer = [slice(None)] * m.ndim indexer[axis] = slice(None, None, -1) return m[tuple(indexer)] filename = sys.argv[1] if not os.path.exists(filename): raise IOError("File " + filename + " does not exist !") img = cv2.imread(filename, cv2.IMREAD_COLOR) img = img[250:,250:,...] colorspaces = ['RGB__rgb', 'RGB__luv', 'RGB__hsv', 'L__normalized', 'L__sobel1', 'L__sobel_gradmagn', 'L__sobel2'] fe = FeaturesExtractor(colorspaces, logger=StandardOutputLogger(Logger.DEBUG)) fe.build(img) titles = ['Red', 'Green', 'Blue', 'L*', 'u*', 'v*', 'Hue', 'Saturation', 'Value', 'Eq. grayscale', '1st-Sobel x', '1st-Sobel y', 'Sobel grad. magn.', '2st-Sobel x', '2st-Sobel y'] n_rows = 4 n_cols = 4 fig = plt.figure() a = fig.add_subplot(n_rows, n_cols, 1) plt.imshow(flip(img, 2)) a.set_title('Original RGB image') a.set_axis_off()
def train(argv): parser = ArgumentParser(prog="Extra-Trees Object Counter Model Builder") # Cytomine parser.add_argument('--cytomine_host', dest='cytomine_host', default='demo.cytomine.be', help="The Cytomine host") parser.add_argument('--cytomine_public_key', dest='cytomine_public_key', help="The Cytomine public key") parser.add_argument('--cytomine_private_key', dest='cytomine_private_key', help="The Cytomine private key") parser.add_argument('--cytomine_base_path', dest='cytomine_base_path', default='/api/', help="The Cytomine base path") parser.add_argument('--cytomine_working_path', dest='cytomine_working_path', default=None, help="The working directory (eg: /tmp)") parser.add_argument('--cytomine_id_software', dest='cytomine_software', type=int, help="The Cytomine software identifier") parser.add_argument('--cytomine_id_project', dest='cytomine_project', type=int, help="The Cytomine project identifier") parser.add_argument('--cytomine_force_download', dest='cytomine_force_download', type=bool, default=True, help="Force download from Cytomine or not") # Objects parser.add_argument('--cytomine_object_term', dest='cytomine_object_term', type=int, help="The Cytomine identifier of object term") parser.add_argument('--cytomine_object_user', dest='cytomine_object_user', type=int, help="The Cytomine identifier of object owner") parser.add_argument('--cytomine_object_reviewed_only', dest='cytomine_object_reviewed_only', type=bool, help="Whether objects have to be reviewed or not") # ROI parser.add_argument('--cytomine_roi_term', dest='cytomine_roi_term', type=int, default=None, help="The Cytomine identifier of region of interest term") parser.add_argument('--cytomine_roi_user', dest='cytomine_roi_user', type=int, help="The Cytomine identifier of ROI owner") parser.add_argument('--cytomine_roi_reviewed_only', dest='cytomine_roi_reviewed_only', type=bool, help="Whether ROIs have to be reviewed or not") # Pre-processing parser.add_argument('--mean_radius', dest='mean_radius', type=int, required=True, help="The mean radius of object to detect") parser.add_argument('--pre_transformer', dest='pre_transformer', default=None, choices=['edt', 'euclidean_distance_transform', 'density', None, 'None'], help="Scoremap transformer (None, edt, euclidean_distance_transform, density)") parser.add_argument('--pre_alpha', dest='pre_alpha', action='append', type=int, help="Exponential decrease rate of distance (if EDT)") # Subwindows parser.add_argument('--sw_input_size', dest='sw_input_size', action='append', type=int, help="Size of input subwindow") parser.add_argument('--sw_output_size', dest='sw_output_size', action='append', type=int, help="Size of output subwindow (ignored for FCRN)") parser.add_argument('--sw_extr_mode', dest='sw_extr_mode', choices=['random', 'sliding', 'scoremap_constrained'], help="Mode of extraction (random, scoremap_constrained)") parser.add_argument('--sw_extr_score_thres', dest='sw_extr_score_thres', action='append', type=float, help="Minimum threshold to be foreground in subwindows extraction" "(if 'scoremap_constrained' mode)") parser.add_argument('--sw_extr_ratio', dest='sw_extr_ratio', action='append', type=float, help="Ratio of background subwindows extracted in subwindows " "extraction (if 'scoremap_constrained' mode)") parser.add_argument('--sw_extr_npi', dest="sw_extr_npi", action='append', type=int, help="Number of extracted subwindows per image (if 'random' mode)") parser.add_argument('--sw_colorspace', dest="sw_colorspace", type=str, default='RGB__rgb', help="List of colorspace features") # Forest parser.add_argument('--forest_method', dest='forest_method', type=str, action='append', choices=['ET-clf', 'ET-regr', 'RF-clf', 'RF-regr'], help="Type of forest method") parser.add_argument('--forest_n_estimators', dest='forest_n_estimators', action='append', type=int, help="Number of trees in forest") parser.add_argument('--forest_min_samples_split', dest='forest_min_samples_split', action='append', type=int, help="Minimum number of samples for further splitting") parser.add_argument('--forest_max_features', dest='forest_max_features', action='append', help="Max features") # Dataset augmentation parser.add_argument('--augmentation', dest='augmentation', type=bool) parser.add_argument('--aug_rotation_range', dest='rotation_range', type=float) parser.add_argument('--aug_width_shift_range', dest='width_shift_range', type=float) parser.add_argument('--aug_height_shift_range', dest='height_shift_range', type=float) parser.add_argument('--aug_zoom_range', dest='zoom_range', type=float) parser.add_argument('--aug_fill_mode', dest='fill_mode', type=str) parser.add_argument('--aug_horizontal_flip', dest='horizontal_flip', type=bool) parser.add_argument('--aug_vertical_flip', dest='vertical_flip', type=bool) parser.add_argument('--aug_featurewise_center', dest='featurewise_center', type=bool) parser.add_argument('--aug_featurewise_std_normalization', dest='featurewise_std_normalization', type=bool) # Execution parser.add_argument('--n_jobs', dest='n_jobs', type=int, default=1, help="Number of jobs") parser.add_argument('--verbose', '-v', dest='verbose', default=0, help="Level of verbosity") params, other = parser.parse_known_args(argv) if params.cytomine_working_path is None: params.cytomine_working_path = os.path.join(tempfile.gettempdir(), "cytomine") make_dirs(params.cytomine_working_path) params.pre_transformer = check_default(params.pre_transformer, None, return_list=False) params.pre_alpha = check_default(params.pre_alpha, 5) params.forest_method = check_default(params.forest_method, 'ET-regr') params.forest_n_estimators = check_default(params.forest_n_estimators, 1) params.forest_min_samples_split = check_default(params.forest_min_samples_split, 2) params.forest_max_features = check_default(params.forest_max_features, 'sqrt') params.forest_max_features = check_max_features(params.forest_max_features) params.sw_input_size = check_default(params.sw_input_size, 4) params.sw_input_size = [(s, s) for s in params.sw_input_size] params.sw_output_size = check_default(params.sw_output_size, 1) params.sw_output_size = [(s, s) for s in params.sw_output_size] params.sw_extr_mode = check_default(params.sw_extr_mode, 'scoremap_constrained', return_list=False) params.sw_extr_ratio = check_default(params.sw_extr_ratio, 0.5) params.sw_extr_score_thres = check_default(params.sw_extr_score_thres, 0.4) params.sw_extr_npi = check_default(params.sw_extr_npi, 100) params.sw_colorspace = params.sw_colorspace.split(' ') params.augmentation = check_default(params.augmentation, False, return_list=False) if params.augmentation: params.rotation_range = check_default(params.rotation_range, 30., return_list=False) params.width_shift_range = check_default(params.width_shift_range, 0.3, return_list=False) params.height_shift_range = check_default(params.height_shift_range, 0.3, return_list=False) params.zoom_range = check_default(params.zoom_range, 0.3, return_list=False) params.fill_mode = check_default(params.fill_mode, 'constant', return_list=False) params.horizontal_flip = check_default(params.horizontal_flip, True, return_list=False) params.vertical_flip = check_default(params.vertical_flip, True, return_list=False) params.featurewise_center = check_default(params.featurewise_center, False, return_list=False) params.featurewise_std_normalization = check_default(params.featurewise_std_normalization, False, return_list=False) else: params.rotation_range = 0. params.width_shift_range = 0. params.height_shift_range = 0. params.zoom_range = 0. params.fill_mode = 'reflect' params.horizontal_flip = False params.vertical_flip = False params.featurewise_center = False params.featurewise_std_normalization = False params = params_remove_list(params) # Initialize logger logger = StandardOutputLogger(params.verbose) for key, val in sorted(vars(params).iteritems()): logger.info("[PARAMETER] {}: {}".format(key, val)) # Initialize Cytomine client cytomine = Cytomine( params.cytomine_host, params.cytomine_public_key, params.cytomine_private_key, working_path=params.cytomine_working_path, base_path=params.cytomine_base_path, verbose=(params.verbose >= Logger.DEBUG) ) # Start job with CytomineJob(cytomine, params.cytomine_software, params.cytomine_project, parameters=vars(params_remove_none(params))) as job: cytomine.update_job_status(job.job, status_comment="Starting...", progress=0) cytomine.update_job_status(job.job, status_comment="Loading training set...", progress=1) X, y = get_dataset(cytomine, params.cytomine_working_path, params.cytomine_project, params.cytomine_object_term, params.cytomine_roi_term, params.cytomine_object_user, params.cytomine_object_reviewed_only, params.cytomine_roi_user, params.cytomine_roi_reviewed_only, params.cytomine_force_download) logger.d("X size: {} samples".format(len(X))) logger.d("y size: {} samples".format(len(y))) cytomine.update_job_status(job.job, status_comment="Training forest...", progress=5) estimator = CellCountRandomizedTrees(logger=logger, **vars(params)) estimator.fit(np.asarray(X), np.asarray(y)) cytomine.update_job_status(job.job, status_comment="Saving (best) model", progress=95) model_path = os.path.join(params.cytomine_working_path, "models", str(params.cytomine_software)) model_file = os.path.join(model_path, "{}.pkl".format(job.job.id)) make_dirs(model_path) estimator.save(model_file) cytomine.update_job_status(job.job, status_comment="Finished.", progress=100)
def predict(argv): parser = ArgumentParser(prog="Extra-Trees Object Counter Predictor") # Cytomine parser.add_argument('--cytomine_host', dest='cytomine_host', default='demo.cytomine.be', help="The Cytomine host") parser.add_argument('--cytomine_public_key', dest='cytomine_public_key', help="The Cytomine public key") parser.add_argument('--cytomine_private_key', dest='cytomine_private_key', help="The Cytomine private key") parser.add_argument('--cytomine_base_path', dest='cytomine_base_path', default='/api/', help="The Cytomine base path") parser.add_argument('--cytomine_working_path', dest='cytomine_working_path', default=None, help="The working directory (eg: /tmp)") parser.add_argument('--cytomine_id_software', dest='cytomine_software', type=int, help="The Cytomine software identifier") parser.add_argument('--cytomine_id_project', dest='cytomine_project', type=int, help="The Cytomine project identifier") # Objects parser.add_argument('--cytomine_object_term', dest='cytomine_object_term', type=int, help="The Cytomine identifier of object term") # Post-processing parser.add_argument('--post_threshold', dest='post_threshold', type=float, help="Post-processing discarding threshold") parser.add_argument('--post_sigma', dest='post_sigma', type=float, help="Std-dev of Gauss filter applied to smooth prediction") parser.add_argument('--post_min_dist', dest='post_min_dist', type=int, help="Minimum distance between two peaks") # ROI parser.add_argument('--annotation', dest='annotation', type=str, action='append', default=[]) parser.add_argument('--image', dest='image', type=str, action='append', default=[]) # Execution parser.add_argument('--n_jobs', dest='n_jobs', type=int, default=1, help="Number of jobs") parser.add_argument('--verbose', '-v', dest='verbose', type=int, default=0, help="Level of verbosity") parser.add_argument('--model_id_job', dest='model_id_job', type=str, default=None, help="Model job ID") parser.add_argument('--model_file', dest="model_file", type=str, default=None, help="Model file") params, other = parser.parse_known_args(argv) if params.cytomine_working_path is None: params.cytomine_working_path = os.path.join(tempfile.gettempdir(), "cytomine") make_dirs(params.cytomine_working_path) params.model_id_job = str2int(params.model_id_job) params.image = [str2int(i) for i in params.image] params.annotation = [str2int(i) for i in params.annotation] # Initialize logger logger = StandardOutputLogger(params.verbose) for key, val in sorted(vars(params).iteritems()): logger.info("[PARAMETER] {}: {}".format(key, val)) # Start job with CytomineJob(params.cytomine_host, params.cytomine_public_key, params.cytomine_private_key, params.cytomine_software, params.cytomine_project, parameters=vars(params), working_path=params.cytomine_working_path, base_path=params.cytomine_base_path, verbose=(params.verbose >= Logger.DEBUG)) as job: cytomine = job cytomine.update_job_status(job.job, status_comment="Starting...", progress=0) cytomine.update_job_status(job.job, status_comment="Loading model...", progress=1) logger.i("Loading model...") if params.model_file: model_file = params.model_file else: model_job = cytomine.get_job(params.model_id_job) model_file = os.path.join(params.cytomine_working_path, "models", str(model_job.software), "{}.pkl".format(model_job.id)) with open(model_file, 'rb') as f: estimator = pickle.load(f) predict_params = vars(params).copy() predict_params.pop("image", None) predict_params.pop("annotation", None) estimator.set_params(**predict_params) cytomine.update_job_status(job.job, status_comment="Dumping annotations/images to predict...", progress=3) logger.i("Dumping annotations/images to predict...") if params.annotation[0] is not None: annots = [cytomine.get_annotation(id) for id in params.annotation] annots_collection = AnnotationCollection() annots_collection._data = annots crops = cytomine.dump_annotations(annotations=annots_collection, dest_path=os.path.join(params.cytomine_working_path, "crops", str(params.cytomine_project)), desired_zoom=0, get_image_url_func=Annotation.get_annotation_alpha_crop_url) X = crops.data() elif params.image[0] is not None: image_instances = [cytomine.get_image_instance(id) for id in params.image] image_instances = cytomine.dump_project_images(id_project=params.cytomine_project, dest_path="/imageinstances/", image_instances=image_instances, max_size=True) X = image_instances else: X = [] logger.d("X size: {} samples".format(len(X))) for i, x in enumerate(X): logger.i("Predicting ID {}...".format(x.id)) cytomine.update_job_status(job.job, status_comment="Predicting ID {}...".format(x.id), progress=5 + np.ceil(i / len(X)) * 95) y = estimator.predict([x.filename]) y = estimator.postprocessing([y], **estimator.filter_sk_params(estimator.postprocessing)) logger.i("Uploading annotations...") cytomine.update_job_status(job.job, status_comment="Uploading annotations...") upload_annotations(cytomine, x, y, term=params.cytomine_object_term) logger.i("Finished.") cytomine.update_job_status(job.job, status_comment="Finished.", progress=100)
def create_from_parameters(cls, parameters, logger=StandardOutputLogger(Logger.INFO)): kwargs = parameters if isinstance(parameters, dict) else vars(parameters) kwargs.update({'logger': logger}) return cls(**kwargs)
def train(argv): parser = ArgumentParser(prog="CNN Object Counter Model Builder") # Cytomine parser.add_argument('--cytomine_host', dest='cytomine_host', default='demo.cytomine.be', help="The Cytomine host") parser.add_argument('--cytomine_public_key', dest='cytomine_public_key', help="The Cytomine public key") parser.add_argument('--cytomine_private_key', dest='cytomine_private_key', help="The Cytomine private key") parser.add_argument('--cytomine_base_path', dest='cytomine_base_path', default='/api/', help="The Cytomine base path") parser.add_argument('--cytomine_working_path', dest='cytomine_working_path', default=None, help="The working directory (eg: /tmp)") parser.add_argument('--cytomine_id_software', dest='cytomine_software', type=int, help="The Cytomine software identifier") parser.add_argument('--cytomine_id_project', dest='cytomine_project', type=int, help="The Cytomine project identifier") parser.add_argument('--cytomine_force_download', dest='cytomine_force_download', type=str, default=True, help="Force download from Cytomine or not") # Objects parser.add_argument('--cytomine_object_term', dest='cytomine_object_term', type=int, help="The Cytomine identifier of object term") parser.add_argument('--cytomine_object_user', dest='cytomine_object_user', type=str, help="The Cytomine identifier of object owner") parser.add_argument('--cytomine_object_reviewed_only', dest='cytomine_object_reviewed_only', type=str, help="Whether objects have to be reviewed or not") # ROI parser.add_argument('--cytomine_roi_term', dest='cytomine_roi_term', type=int, default=None, help="The Cytomine identifier of region of interest term") parser.add_argument('--cytomine_roi_user', dest='cytomine_roi_user', type=str, help="The Cytomine identifier of ROI owner") parser.add_argument('--cytomine_roi_reviewed_only', dest='cytomine_roi_reviewed_only', type=str, help="Whether ROIs have to be reviewed or not") # Pre-processing parser.add_argument('--pre_transformer', dest='pre_transformer', default='density', choices=['edt', 'euclidean_distance_transform', 'density', None, 'None'], help="Scoremap transformer (None, edt, euclidean_distance_transform, density)") parser.add_argument('--pre_alpha', dest='pre_alpha', type=int, default=3, help="Exponential decrease rate of distance (if EDT)") # Subwindows for training parser.add_argument('--sw_input_size', dest='sw_input_size', type=int, default=128, help="Size of input subwindow") parser.add_argument('--sw_colorspace', dest="sw_colorspace", type=str, default='RGB__rgb', help="List of colorspace features") parser.add_argument('--sw_extr_npi', dest="sw_extr_npi", type=int, default=100, help="Number of extracted subwindows per image (if 'random' mode)") # CNN parser.add_argument('--cnn_architecture', '--architecture', dest='cnn_architecture', type=str, choices=['FCRN-A', 'FCRN-B'], default='FCRN-A') parser.add_argument('--cnn_initializer', '--initializer', dest='cnn_initializer', type=str, default='orthogonal') parser.add_argument('--cnn_batch_normalization', '--batch_normalization', dest='cnn_batch_normalization', type=str, default=True) parser.add_argument('--cnn_learning_rate', '--learning_rate', '--lr', dest='cnn_learning_rate', type=float, default=0.01) parser.add_argument('--cnn_momentum', '--momentum', dest='cnn_momentum', type=float, default=0.9) parser.add_argument('--cnn_nesterov', '--nesterov', dest='cnn_nesterov', type=str, default=True) parser.add_argument('--cnn_decay', '--decay', dest='cnn_decay', type=float, default=0.0) parser.add_argument('--cnn_epochs', '--epochs', dest='cnn_epochs', type=int, default=24) parser.add_argument('--cnn_batch_size', '--batch_size', dest='cnn_batch_size', type=int, default=16) # Dataset augmentation parser.add_argument('--augmentation', dest='augmentation', type=str, default=True) parser.add_argument('--aug_rotation_range', dest='rotation_range', type=float, default=0.) parser.add_argument('--aug_width_shift_range', dest='width_shift_range', type=float, default=0.) parser.add_argument('--aug_height_shift_range', dest='height_shift_range', type=float, default=0.) parser.add_argument('--aug_zoom_range', dest='zoom_range', type=float, default=0.) parser.add_argument('--aug_fill_mode', dest='fill_mode', type=str, default="reflect") parser.add_argument('--aug_horizontal_flip', dest='horizontal_flip', type=bool, default=False) parser.add_argument('--aug_vertical_flip', dest='vertical_flip', type=bool, default=False) parser.add_argument('--aug_featurewise_center', dest='featurewise_center', type=bool, default=False) parser.add_argument('--aug_featurewise_std_normalization', dest='featurewise_std_normalization', type=bool, default=False) # Execution parser.add_argument('--n_jobs', dest='n_jobs', type=int, default=1, help="Number of jobs") parser.add_argument('--verbose', '-v', dest='verbose', type=int, default=0, help="Level of verbosity") params, other = parser.parse_known_args(argv) if params.cytomine_working_path is None: params.cytomine_working_path = os.path.join(tempfile.gettempdir(), "cytomine") make_dirs(params.cytomine_working_path) params.cytomine_force_download = str2bool(params.cytomine_force_download) params.cytomine_object_reviewed_only = str2bool(params.cytomine_object_reviewed_only) params.cytomine_roi_reviewed_only = str2bool(params.cytomine_roi_reviewed_only) params.cnn_batch_normalization = str2bool(params.cnn_batch_normalization) params.cnn_nesterov = str2bool(params.cnn_nesterov) params.augmentation = str2bool(params.augmentation) d = 8. if params.cnn_architecture == 'FCRN-A' else 4. params.sw_size = (int(np.ceil(params.sw_input_size / d) * d), int(np.ceil(params.sw_input_size / d) * d)) params.sw_input_size = params.sw_size params.sw_output_size = params.sw_size params.sw_colorspace = params.sw_colorspace.split(' ') params.sw_extr_mode = 'random' params.cnn_regularizer = None params.mean_radius = 2 params.k_factor = 100 if params.augmentation: params.rotation_range = check_default(params.rotation_range, 30., return_list=False) params.width_shift_range = check_default(params.width_shift_range, 0.3, return_list=False) params.height_shift_range = check_default(params.height_shift_range, 0.3, return_list=False) params.zoom_range = check_default(params.zoom_range, 0.3, return_list=False) params.fill_mode = check_default(params.fill_mode, 'constant', return_list=False) params.horizontal_flip = check_default(params.horizontal_flip, True, return_list=False) params.vertical_flip = check_default(params.vertical_flip, True, return_list=False) params.featurewise_center = check_default(params.featurewise_center, False, return_list=False) params.featurewise_std_normalization = check_default(params.featurewise_std_normalization, False, return_list=False) # Initialize logger logger = StandardOutputLogger(params.verbose) for key, val in sorted(vars(params).iteritems()): logger.info("[PARAMETER] {}: {}".format(key, val)) # Start job with CytomineJob(params.cytomine_host, params.cytomine_public_key, params.cytomine_private_key, params.cytomine_software, params.cytomine_project, parameters=vars(params), working_path=params.cytomine_working_path, base_path=params.cytomine_base_path, verbose=(params.verbose >= Logger.DEBUG)) as job: cytomine = job cytomine.update_job_status(job.job, status_comment="Starting...", progress=0) cytomine.update_job_status(job.job, status_comment="Loading training set...", progress=1) logger.i("Loading training set...") X, y = get_dataset(cytomine, params.cytomine_working_path, params.cytomine_project, params.cytomine_object_term, params.cytomine_roi_term, params.cytomine_object_user, params.cytomine_object_reviewed_only, params.cytomine_roi_user, params.cytomine_roi_reviewed_only, params.cytomine_force_download) logger.d("X size: {} samples".format(len(X))) logger.d("y size: {} samples".format(len(y))) # Rename parameters params.architecture = params.cnn_architecture params.initializer = params.cnn_initializer params.regularizer = params.cnn_regularizer params.batch_normalization = params.cnn_batch_normalization params.learning_rate = params.cnn_learning_rate params.momentum = params.cnn_momentum params.nesterov = params.cnn_nesterov params.decay = params.cnn_decay params.epochs = params.cnn_epochs params.batch_size = params.cnn_batch_size model_path = os.path.join(params.cytomine_working_path, "models", str(params.cytomine_software)) model_file = os.path.join(model_path, "{}.h5".format(job.job.id)) make_dirs(model_path) # Callbacks # checkpoint_callback = ModelCheckpoint(model_file, monitor='loss', save_best_only=True) lr_callback = LearningRateScheduler(lr_scheduler) callbacks = [lr_callback] logger.i("Training FCRN...") cytomine.update_job_status(job.job, status_comment="Training FCRN...", progress=5) estimator = FCRN(FCRN.build_fcrn, callbacks, **vars(params)) estimator.fit(np.asarray(X), np.asarray(y)) logger.i("Saving model...") cytomine.update_job_status(job.job, status_comment="Saving (best) model", progress=95) estimator.save(model_file) logger.i("Finished.") cytomine.update_job_status(job.job, status_comment="Finished.", progress=100)