def stop_max_activations(): """ Stop Max Activations Job """ job = job_from_request() args = flask.request.args job_id = args["gradient_ascent_id"] scheduler.abort_job(job_id) return flask.jsonify({"status": "success"}), 200
def image_classification_model_classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ job = job_from_request() image = None if "image_url" in flask.request.form and flask.request.form["image_url"]: image = utils.image.load_image(flask.request.form["image_url"]) elif "image_file" in flask.request.files and flask.request.files["image_file"]: outfile = tempfile.mkstemp(suffix=".bin") flask.request.files["image_file"].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest("must provide image_url or image_file") # resize image db_task = job.train_task().dataset.train_db_task() height = db_task.image_dims[0] width = db_task.image_dims[1] if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image( image, height, width, channels=db_task.image_dims[2], resize_mode=db_task.resize_mode ) epoch = None if "snapshot_epoch" in flask.request.form: epoch = float(flask.request.form["snapshot_epoch"]) layers = "none" if "show_visualizations" in flask.request.form and flask.request.form["show_visualizations"]: layers = "all" predictions, visualizations = None, None try: predictions, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) except frameworks.errors.InferenceError as e: return e.__str__(), 403 # take top 5 if predictions: predictions = [(p[0], round(100.0 * p[1], 2)) for p in predictions[:5]] if request_wants_json(): return flask.jsonify({"predictions": predictions}) else: return flask.render_template( "models/images/classification/classify_one.html", job=job, image_src=utils.image.embed_image_html(image), predictions=predictions, visualizations=visualizations, total_parameters=sum(v["param_count"] for v in visualizations if v["vis_type"] == "Weights"), )
def generic_image_dataset_summary(): """ Return a short HTML summary of a DatasetJob """ job = job_from_request() return flask.render_template('datasets/images/generic/summary.html', dataset=job)
def image_classification_model_large_graph(): """ Show the loss/accuracy graph, but bigger """ job = job_from_request() return flask.render_template("models/images/classification/large_graph.html", job=job)
def large_graph(): """ Show the loss/accuracy graph, but bigger """ job = job_from_request() return flask.render_template('models/large_graph.html', job=job)
def generic_image_model_infer_one(): """ Infer one image """ job = job_from_request() image = None if 'image_url' in flask.request.form and flask.request.form['image_url']: image = utils.image.load_image(flask.request.form['image_url']) elif 'image_file' in flask.request.files and flask.request.files[ 'image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest( 'must provide image_url or image_file') # resize image db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image( image, height, width, channels=db_task.image_channels, resize_mode='squash', ) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form[ 'show_visualizations']: layers = 'all' outputs, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) if request_wants_json(): return flask.jsonify({ 'outputs': dict((name, blob.tolist()) for name, blob in outputs.iteritems()) }) else: return flask.render_template( 'models/images/generic/infer_one.html', image_src=utils.image.embed_image_html(image), network_outputs=outputs, visualizations=visualizations, )
def image_classification_dataset_summary(): """ Return a short HTML summary of a DatasetJob """ job = job_from_request() return flask.render_template('datasets/images/classification/summary.html', dataset=job)
def image_classification_dataset_summary(): """ Return a short HTML summary of a DatasetJob """ job = job_from_request() return flask.render_template("datasets/images/classification/summary.html", dataset=job)
def summary(): """ Return a short HTML summary of a DatasetJob """ job = job_from_request() return flask.render_template('datasets/images/generic/summary.html', dataset=job)
def image_classification_model_large_graph(): """ Show the loss/accuracy graph, but bigger """ job = job_from_request() return flask.render_template('models/images/classification/large_graph.html', job=job)
def generic_image_model_large_graph(): """ Show the loss/accuracy graph, but bigger """ job = job_from_request() return flask.render_template("models/images/generic/large_graph.html", job=job)
def feature_extraction_model_large_graph(): """ Show the loss/accuracy graph, but bigger """ job = job_from_request() workspace = get_workspace_details(flask.request.url) return flask.render_template('models/images/extraction/large_graph.html', job=job, workspace = workspace)
def timeline_tracing(): """ Shows timeline trace of a model """ job = job_from_request() return flask.render_template('models/timeline_tracing.html', job=job)
def image_classification_model_classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ job = job_from_request() image = None if 'image_url' in flask.request.form and flask.request.form['image_url']: image = utils.image.load_image(flask.request.form['image_url']) elif 'image_file' in flask.request.files and flask.request.files[ 'image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest( 'must provide image_url or image_file') # resize image db_task = job.train_task().dataset.train_db_task() height = db_task.image_dims[0] width = db_task.image_dims[1] if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image( image, height, width, channels=db_task.image_dims[2], resize_mode=db_task.resize_mode, ) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form[ 'show_visualizations']: layers = 'all' predictions, visualizations = job.train_task().infer_one( image, snapshot_epoch=epoch, layers=layers) # take top 5 predictions = [(p[0], round(100.0 * p[1], 2)) for p in predictions[:5]] if request_wants_json(): return flask.jsonify({'predictions': predictions}) else: return flask.render_template( 'models/images/classification/classify_one.html', image_src=utils.image.embed_image_html(image), predictions=predictions, visualizations=visualizations, )
def generic_image_model_infer_many(): """ Infer many images """ job = job_from_request() image_list = flask.request.files.get("image_list") if not image_list: raise werkzeug.exceptions.BadRequest("image_list is a required field") epoch = None if "snapshot_epoch" in flask.request.form: epoch = float(flask.request.form["snapshot_epoch"]) paths = [] images = [] db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width channels = db_task.image_channels for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r"(.*\S)\s+\d+$", line) if match: path = match.group(1) else: path = line try: image = utils.image.load_image(path) image = utils.image.resize_image(image, height, width, channels=channels, resize_mode="squash") paths.append(path) images.append(image) except utils.errors.LoadImageError as e: print e if not len(images): raise werkzeug.exceptions.BadRequest("Unable to load any images from the file") outputs = job.train_task().infer_many(images, snapshot_epoch=epoch) if outputs is None: raise RuntimeError("An error occured while processing the images") if request_wants_json(): result = {} for i, path in enumerate(paths): result[path] = dict((name, blob[i].tolist()) for name, blob in outputs.iteritems()) return flask.jsonify({"outputs": result}) else: return flask.render_template( "models/images/generic/infer_many.html", job=job, paths=paths, network_outputs=outputs )
def timeline_trace_data(): """ Shows timeline trace of a model """ job = job_from_request() step = get_request_arg('step') if step is None: raise werkzeug.exceptions.BadRequest('step is a required field') return job.train_task().timeline_trace(int(step))
def image_classification_model_classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ job = job_from_request() image = None if 'image_url' in flask.request.form and flask.request.form['image_url']: image = utils.image.load_image(flask.request.form['image_url']) elif 'image_file' in flask.request.files and flask.request.files['image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest('must provide image_url or image_file') # resize image db_task = job.train_task().dataset.train_db_task() height = db_task.image_dims[0] width = db_task.image_dims[1] if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image(image, height, width, channels = db_task.image_dims[2], resize_mode = db_task.resize_mode, ) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' predictions, visualizations = None, None predictions, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) # take top 5 if predictions: predictions = [(p[0], round(100.0*p[1],2)) for p in predictions[:5]] if request_wants_json(): return flask.jsonify({'predictions': predictions}) else: return flask.render_template('models/images/classification/classify_one.html', job = job, image_src = utils.image.embed_image_html(image), predictions = predictions, visualizations = visualizations, total_parameters= sum(v['param_count'] for v in visualizations if v['vis_type'] == 'Weights'), )
def explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = job.path(flask.request.args.get('db')) db_path = job.path(db) labels = [] if COLOR_PALETTE_ATTRIBUTE in job.extension_userdata: # assume single-channel 8-bit palette palette = job.extension_userdata[COLOR_PALETTE_ATTRIBUTE] palette = np.array(palette).reshape((len(palette)/3,3)) / 255. # normalize input pixels to [0,1] norm = mpl.colors.Normalize(vmin=0,vmax=255) # create map cmap = mpl.pyplot.cm.ScalarMappable(norm=norm, cmap=mpl.colors.ListedColormap(palette)) else: cmap = None page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) total_entries = reader.total_entries max_page = min((total_entries-1) / size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page*size: datum = caffe_pb2.Datum() datum.ParseFromString(value) if not datum.encoded: raise RuntimeError("Expected encoded database") s = StringIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) if cmap and img.mode in ['L', '1']: data = np.array(img) data = cmap.to_rgba(data)*255 data = data.astype('uint8') # keep RGB values only, remove alpha channel data = data[:, :, 0:3] img = PIL.Image.fromarray(data) imgs.append({"label": None, "b64": utils.image.embed_image_html(img)}) count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/explore.html', page=page, size=size, job=job, imgs=imgs, labels=None, pages=pages, label=None, total_entries=total_entries, db=db)
def remove_max_activations(): """ Deletes Max Activations Dataset pertaining to specified layer in job """ job = job_from_request() args = flask.request.args layer_name = args["layer_name"] if os.path.isfile(job.get_max_activations_path()): f = h5py.File(job.get_max_activations_path(), 'a') if layer_name in f: del f[layer_name] return flask.jsonify({"status": "success"}), 200 return flask.jsonify({"status": "error"}), 500
def summary(): """ Return a short HTML summary of a DatasetJob """ job = job_from_request() if isinstance(job, dataset_images.ImageClassificationDatasetJob): return dataset_images.classification.views.summary(job) elif isinstance(job, dataset_images.GenericImageDatasetJob): return dataset_images.generic.views.summary(job) elif isinstance(job, generic.GenericDatasetJob): return generic.views.summary(job) else: raise werkzeug.exceptions.BadRequest('Invalid job type')
def explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = job.path(flask.request.args.get('db')) db_path = job.path(db) labels = [] page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) total_entries = reader.total_entries max_page = min((total_entries - 1) / size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page * size: datum = caffe_pb2.Datum() datum.ParseFromString(value) if not datum.encoded: raise RuntimeError("Expected encoded database") s = StringIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) imgs.append({ "label": None, "b64": utils.image.embed_image_html(img) }) count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/explore.html', page=page, size=size, job=job, imgs=imgs, labels=None, pages=pages, label=None, total_entries=total_entries, db=db)
def generic_image_model_infer_one(): """ Infer one image """ job = job_from_request() image = None if 'image_url' in flask.request.form and flask.request.form['image_url']: image = utils.image.load_image(flask.request.form['image_url']) elif 'image_file' in flask.request.files and flask.request.files['image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest('must provide image_url or image_file') # resize image db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image(image, height, width, channels = db_task.image_channels, resize_mode = 'squash', ) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' outputs, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) if request_wants_json(): return flask.jsonify({'outputs': dict((name, blob.tolist()) for name,blob in outputs.iteritems())}) else: return flask.render_template('models/images/generic/infer_one.html', job = job, image_src = utils.image.embed_image_html(image), network_outputs = outputs, visualizations = visualizations, total_parameters= sum(v['param_count'] for v in visualizations if v['vis_type'] == 'Weights'), )
def top_n(): """ Classify many images and show the top N images per category by confidence """ model_job = job_from_request() image_list = flask.request.files['image_list'] if not image_list: raise werkzeug.exceptions.BadRequest('File upload not found') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'top_n' in flask.request.form and flask.request.form['top_n'].strip(): top_n = int(flask.request.form['top_n']) else: top_n = 9 if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None paths, _ = read_image_list(image_list, image_folder, num_test_images) # create inference job inference_job = ImageInferenceTopNJob( username = utils.auth.get_username(), name = "TopN Image Classification", model = model_job, images = paths, epoch = epoch, layers = 'none', top_n = top_n, ) # schedule tasks scheduler.add_job(inference_job) if request_wants_json(): return flask.jsonify(inference_job.json_dict()) else: return flask.redirect(flask.url_for('digits.inference.views.show', job_id=inference_job.id()))
def image_classification_model_classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ job = job_from_request() image = None if "image_url" in flask.request.form and flask.request.form["image_url"]: image = utils.image.load_image(flask.request.form["image_url"]) elif "image_file" in flask.request.files and flask.request.files["image_file"]: with tempfile.NamedTemporaryFile() as outfile: flask.request.files["image_file"].save(outfile.name) image = utils.image.load_image(outfile.name) else: raise werkzeug.exceptions.BadRequest("must provide image_url or image_file") # resize image db_task = job.train_task().dataset.train_db_task() height = db_task.image_dims[0] width = db_task.image_dims[1] if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image( image, height, width, channels=db_task.image_dims[2], resize_mode=db_task.resize_mode ) epoch = None if "snapshot_epoch" in flask.request.form: epoch = float(flask.request.form["snapshot_epoch"]) layers = "none" if "show_visualizations" in flask.request.form and flask.request.form["show_visualizations"]: layers = "all" predictions, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) # take top 5 predictions = [(p[0], round(100.0 * p[1], 2)) for p in predictions[:5]] if request_wants_json(): return flask.jsonify({"predictions": predictions}) else: return flask.render_template( "models/images/classification/classify_one.html", image_src=utils.image.embed_image_html(image), predictions=predictions, visualizations=visualizations, )
def classify_many(): """ Start a new classify_may job """ # kicking off a new inference job model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths, ground_truths = read_image_list(image_list, image_folder, num_test_images) # create inference job inference_job = ImageInferenceClassifyManyJob( username = utils.auth.get_username(), name = "Classify Many Images", model = model_job, images = paths, epoch = epoch, layers = 'none', ground_truths = ground_truths, ) # schedule tasks scheduler.add_job(inference_job) if request_wants_json(): return flask.jsonify(inference_job.json_dict()) else: return flask.redirect(flask.url_for('digits.inference.views.show', job_id=inference_job.id()))
def generic_image_model_infer_one(): """ Infer one image """ job = job_from_request() image = None if 'image_url' in flask.request.form and flask.request.form['image_url']: image = utils.image.load_image(flask.request.form['image_url']) elif 'image_file' in flask.request.files and flask.request.files['image_file']: with tempfile.NamedTemporaryFile() as outfile: flask.request.files['image_file'].save(outfile.name) image = utils.image.load_image(outfile.name) else: raise werkzeug.exceptions.BadRequest('must provide image_url or image_file') # resize image db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size image = utils.image.resize_image(image, height, width, channels = db_task.image_channels, resize_mode = 'squash', ) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' outputs, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) if request_wants_json(): return flask.jsonify({'outputs': dict((name, blob.tolist()) for name,blob in outputs.iteritems())}) else: return flask.render_template('models/images/generic/infer_one.html', image_src = utils.image.embed_image_html(image), network_outputs = outputs, visualizations = visualizations, )
def generic_image_model_infer_one(): """ Infer one image """ job = job_from_request() image = None if "image_url" in flask.request.form and flask.request.form["image_url"]: image = utils.image.load_image(flask.request.form["image_url"]) elif "image_file" in flask.request.files and flask.request.files["image_file"]: outfile = tempfile.mkstemp(suffix=".bin") flask.request.files["image_file"].save(outfile[1]) image = utils.image.load_image(outfile[1]) os.close(outfile[0]) os.remove(outfile[1]) else: raise werkzeug.exceptions.BadRequest("must provide image_url or image_file") # resize image db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width image = utils.image.resize_image(image, height, width, channels=db_task.image_channels, resize_mode="squash") epoch = None if "snapshot_epoch" in flask.request.form: epoch = float(flask.request.form["snapshot_epoch"]) layers = "none" if "show_visualizations" in flask.request.form and flask.request.form["show_visualizations"]: layers = "all" outputs, visualizations = job.train_task().infer_one(image, snapshot_epoch=epoch, layers=layers) if request_wants_json(): return flask.jsonify({"outputs": dict((name, blob.tolist()) for name, blob in outputs.iteritems())}) else: return flask.render_template( "models/images/generic/infer_one.html", job=job, image_src=utils.image.embed_image_html(image), network_outputs=outputs, visualizations=visualizations, total_parameters=sum(v["param_count"] for v in visualizations if v["vis_type"] == "Weights"), )
def classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ model_job = job_from_request() if 'image_url' in flask.request.form and flask.request.form['image_url']: image_path = flask.request.form['image_url'] elif 'image_file' in flask.request.files and flask.request.files['image_file']: outfile = tempfile.mkstemp(suffix='.png') flask.request.files['image_file'].save(outfile[1]) image_path = outfile[1] os.close(outfile[0]) else: raise werkzeug.exceptions.BadRequest('must provide image_url or image_file') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' # create inference job inference_job = ImageInferenceClassifyOneJob( username = utils.auth.get_username(), name = "Classify One Image", model = model_job, images = [image_path], epoch = epoch, layers = layers ) # schedule tasks scheduler.add_job(inference_job) if request_wants_json(): return flask.jsonify(inference_job.json_dict()) else: return flask.redirect(flask.url_for('digits.inference.views.show', job_id=inference_job.id()))
def get_weights(): """ Return the weights for a given layer """ job = job_from_request() args = flask.request.args layer_name = args["layer_name"] range_min = int(args["range_min"]) range_max = int(args["range_max"]) data = [] stats = {} num_units = 0 # Open h5py file, and retrieve weights in specified range for given layer: if os.path.isfile(job.get_filters_path()): f = h5py.File(job.get_filters_path()) if layer_name in f: num_units = len(f[layer_name]) stats = json.loads(f[layer_name].attrs["stats"]) data = f[layer_name][:][range_min:range_max].tolist() return flask.jsonify({"data": data, "length": num_units, "stats": stats})
def get_max_activations(): """ Returns array of maximum activations for a given layer """ job = job_from_request() args = flask.request.args layer_name = args["layer_name"] range_min = int(args["range_min"]) range_max = int(args["range_max"]) data = [] stats = {} if layer_has_max_activations(job, layer_name): f = h5py.File(job.get_max_activations_path(), 'r') completed_units = len(f[layer_name].keys()) for unit in range(completed_units): data.append(True) w = h5py.File(job.get_filters_path(), 'r') if layer_name in w: stats = json.loads(w[layer_name].attrs["stats"]) total_units = stats["shape"][0] uncompleted_units = total_units - completed_units if uncompleted_units > 0: for unit in range(uncompleted_units): data.append(False) elif os.path.isfile(job.get_filters_path()): f = h5py.File(job.get_filters_path(), 'r') if layer_name in f: stats = json.loads(f[layer_name].attrs["stats"]) data = fill_empty(stats["shape"][0]) return flask.jsonify({ "stats": stats, "data": data[range_min:range_max], "length": len(data) })
def explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = job.path(flask.request.args.get('db')) db_path = job.path(db) labels = [] page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) total_entries = reader.total_entries max_page = min((total_entries-1) / size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page*size: datum = caffe_pb2.Datum() datum.ParseFromString(value) if not datum.encoded: raise RuntimeError("Expected encoded database") s = StringIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) imgs.append({"label": None, "b64": utils.image.embed_image_html(img)}) count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/explore.html', page=page, size=size, job=job, imgs=imgs, labels=None, pages=pages, label=None, total_entries=total_entries, db=db)
def max_activation(): args = flask.request.args job = job_from_request() layer_name = args["layer_name"] unit = args["unit"] raw_data = 128 * np.ones((256, 256)).astype(int) max_activation_path = job.get_max_activations_path() if os.path.isfile(max_activation_path): f = h5py.File(max_activation_path, 'r') if layer_name in f: if str(unit) in f[layer_name]: raw_data = np.transpose(f[layer_name][str(unit)]['cropped'][:], (1, 2, 0)) f.close() # Add one channel for greyscale images: if len(raw_data[0][0]) == 1: raw_data = np.transpose(raw_data, (2, 0, 1))[0] img = PIL.Image.fromarray(np.uint8(raw_data)) return serve_pil_image(img)
def infer_one(): """ Infer one image """ model_job = job_from_request() remove_image_path = False if 'image_path' in flask.request.form and flask.request.form['image_path']: image_path = flask.request.form['image_path'] elif 'image_file' in flask.request.files and flask.request.files['image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image_path = outfile[1] os.close(outfile[0]) remove_image_path = True else: raise werkzeug.exceptions.BadRequest('must provide image_path or image_file') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' if 'dont_resize' in flask.request.form and flask.request.form['dont_resize']: resize = False else: resize = True # create inference job inference_job = ImageInferenceJob( username= utils.auth.get_username(), name= "Infer One Image", model=model_job, images=[image_path], epoch=epoch, layers=layers, resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, model_visualization = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if remove_image_path: os.remove(image_path) if inputs is not None and len(inputs['data']) == 1: image = utils.image.embed_image_html(inputs['data'][0]) visualizations, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) inference_view_html = visualizations[0] else: image = None inference_view_html = None header_html = None app_begin_html = None app_end_html = None if request_wants_json(): return flask.jsonify({'outputs': dict((name, blob.tolist()) for name, blob in outputs.iteritems())}), status_code else: return flask.render_template( 'models/images/generic/infer_one.html', model_job=model_job, job=inference_job, image_src=image, inference_view_html=inference_view_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, visualizations=model_visualization, total_parameters=sum(v['param_count'] for v in model_visualization if v['vis_type'] == 'Weights'), ), status_code
def infer_db(): """ Infer a database """ model_job = job_from_request() if 'db_path' not in flask.request.form or flask.request.form[ 'db_path'] is None: raise werkzeug.exceptions.BadRequest('db_path is a required field') db_path = flask.request.form['db_path'] if not os.path.exists(db_path): raise werkzeug.exceptions.BadRequest('DB "%s" does not exit' % db_path) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'dont_resize' in flask.request.form and flask.request.form[ 'dont_resize']: resize = False else: resize = True # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Infer Many Images", model=model_job, images=db_path, epoch=epoch, layers='none', resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: keys = [str(idx) for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None keys = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, key in enumerate(keys): result[key] = dict( (name, blob[i].tolist()) for name, blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_db.html', model_job=model_job, job=inference_job, keys=keys, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, ), status_code
def infer_many(): """ Infer many images """ model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form[ 'image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest( 'image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form[ 'num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'dont_resize' in flask.request.form and flask.request.form[ 'dont_resize']: resize = False else: resize = True paths = [] for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+\d+$', line) if match: path = match.group(1) else: path = line if not utils.is_url(path) and image_folder and not os.path.isabs(path): path = os.path.join(image_folder, path) paths.append(path) if num_test_images is not None and len(paths) >= num_test_images: break # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Infer Many Images", model=model_job, images=paths, epoch=epoch, layers='none', resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: paths = [paths[idx] for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, path in enumerate(paths): result[path] = dict( (name, blob[i].tolist()) for name, blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_many.html', model_job=model_job, job=inference_job, paths=paths, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, ), status_code
def infer_one(): """ Infer one image """ model_job = job_from_request() remove_image_path = False if 'image_path' in flask.request.form and flask.request.form['image_path']: image_path = flask.request.form['image_path'] elif 'image_file' in flask.request.files and flask.request.files[ 'image_file']: outfile = tempfile.mkstemp(suffix='.bin') flask.request.files['image_file'].save(outfile[1]) image_path = outfile[1] os.close(outfile[0]) remove_image_path = True else: raise werkzeug.exceptions.BadRequest( 'must provide image_path or image_file') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form[ 'show_visualizations']: layers = 'all' if 'dont_resize' in flask.request.form and flask.request.form[ 'dont_resize']: resize = False else: resize = True # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Infer One Image", model=model_job, images=[image_path], epoch=epoch, layers=layers, resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, model_visualization = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if remove_image_path: os.remove(image_path) if inputs is not None and len(inputs['data']) == 1: image = utils.image.embed_image_html(inputs['data'][0]) visualizations, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) inference_view_html = visualizations[0] else: image = None inference_view_html = None header_html = None app_begin_html = None app_end_html = None if request_wants_json(): return flask.jsonify({ 'outputs': dict((name, blob.tolist()) for name, blob in outputs.iteritems()) }), status_code else: return flask.render_template( 'models/images/generic/infer_one.html', model_job=model_job, job=inference_job, image_src=image, inference_view_html=inference_view_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, visualizations=model_visualization, total_parameters=sum(v['param_count'] for v in model_visualization if v['vis_type'] == 'Weights'), ), status_code
def infer_extension(): """ Perform inference using the data from an extension inference form """ model_job = job_from_request() inference_db_job = None try: # create an inference database inference_db_job = create_inference_db(model_job) db_path = inference_db_job.get_feature_db_path(constants.TEST_DB) # create database creation job epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form[ 'show_visualizations']: layers = 'all' # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Inference", model=model_job, images=db_path, epoch=epoch, layers=layers, resize=False, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() finally: if inference_db_job: scheduler.delete_job(inference_db_job) # retrieve inference data inputs, outputs, model_visualization = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: keys = [str(idx) for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None keys = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, key in enumerate(keys): result[key] = dict( (name, blob[i].tolist()) for name, blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_extension.html', model_job=model_job, job=inference_job, keys=keys, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, visualizations=model_visualization, total_parameters=sum(v['param_count'] for v in model_visualization if v['vis_type'] == 'Weights'), ), status_code
def image_classification_model_classify_many(): """ Classify many images and return the top 5 classifications for each Returns JSON when requested: {classifications: {filename: [[category,confidence],...],...}} """ job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths = [] images = [] dataset = job.train_task().dataset for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+\d+$', line) if match: path = match.group(1) else: path = line try: image = utils.image.load_image(path) image = utils.image.resize_image( image, dataset.image_dims[0], dataset.image_dims[1], channels=dataset.image_dims[2], resize_mode=dataset.resize_mode, ) paths.append(path) images.append(image) except utils.errors.LoadImageError as e: print e if not len(images): raise werkzeug.exceptions.BadRequest( 'Unable to load any images from the file') labels, scores = job.train_task().infer_many(images, snapshot_epoch=epoch) if scores is None: raise RuntimeError('An error occured while processing the images') # take top 5 indices = (-scores).argsort()[:, :5] classifications = [] for image_index, index_list in enumerate(indices): result = [] for i in index_list: # `i` is a category in labels and also an index into scores result.append((labels[i], round(100.0 * scores[image_index, i], 2))) classifications.append(result) if request_wants_json(): joined = dict(zip(paths, classifications)) return flask.jsonify({'classifications': joined}) else: return flask.render_template( 'models/images/classification/classify_many.html', paths=paths, classifications=classifications, )
def explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = flask.request.args.get('db', 'train') if 'train' in db.lower(): task = job.train_db_task() elif 'val' in db.lower(): task = job.val_db_task() elif 'test' in db.lower(): task = job.test_db_task() if task is None: raise ValueError('No create_db task for {0}'.format(db)) if task.status != 'D': raise ValueError( "This create_db task's status should be 'D' but is '{0}'".format( task.status)) if task.backend != 'lmdb': raise ValueError( "Backend is {0} while expected backend is lmdb".format( task.backend)) db_path = job.path(task.db_name) labels = task.get_labels() page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) label = flask.request.args.get('label', None) if label is not None: try: label = int(label) except ValueError: label = None reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) if label is None: total_entries = reader.total_entries else: # After PR#1500, task.distribution[str(label)] is a dictionary # with keys = 'count' and 'error_count' label_entries = task.distribution[str(label)] if isinstance(label_entries, dict): total_entries = label_entries['count'] else: total_entries = label_entries max_page = min((total_entries - 1) // size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page * size: datum = dataset_pb2.Datum() datum.ParseFromString(value) if label is None or datum.label == label: if datum.encoded: s = BytesIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) else: arr = datum_to_array(datum) # CHW -> HWC arr = arr.transpose((1, 2, 0)) if arr.shape[2] == 1: # HWC -> HW arr = arr[:, :, 0] elif arr.shape[2] == 3: # BGR -> RGB # XXX see issue #59 arr = arr[:, :, [2, 1, 0]] img = PIL.Image.fromarray(arr) imgs.append({ "label": labels[datum.label], "b64": utils.image.embed_image_html(img) }) if label is None: count += 1 else: datum = dataset_pb2.Datum() datum.ParseFromString(value) if datum.label == int(label): count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/explore.html', page=page, size=size, job=job, imgs=imgs, labels=labels, pages=pages, label=label, total_entries=total_entries, db=db)
def infer_many(): """ Infer many images """ model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'dont_resize' in flask.request.form and flask.request.form['dont_resize']: resize = False else: resize = True paths = [] for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+\d+$', line) if match: path = match.group(1) else: path = line if not utils.is_url(path) and image_folder and not os.path.isabs(path): path = os.path.join(image_folder, path) paths.append(path) if num_test_images is not None and len(paths) >= num_test_images: break # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Infer Many Images", model=model_job, images=paths, epoch=epoch, layers='none', resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: paths = [paths[idx] for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, path in enumerate(paths): result[path] = dict((name, blob[i].tolist()) for name, blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_many.html', model_job=model_job, job=inference_job, paths=paths, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, ), status_code
def image_classification_model_top_n(): """ Classify many images and show the top N images per category by confidence """ job = job_from_request() image_list = flask.request.files['image_list'] if not image_list: raise werkzeug.exceptions.BadRequest('File upload not found') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'top_n' in flask.request.form and flask.request.form['top_n'].strip(): top_n = int(flask.request.form['top_n']) else: top_n = 9 if 'num_test_images' in flask.request.form and flask.request.form[ 'num_test_images'].strip(): num_images = int(flask.request.form['num_test_images']) else: num_images = None paths = [] for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+\d+$', line) if match: path = match.group(1) else: path = line paths.append(path) random.shuffle(paths) images = [] dataset = job.train_task().dataset for path in paths: try: image = utils.image.load_image(path) image = utils.image.resize_image( image, dataset.image_dims[0], dataset.image_dims[1], channels=dataset.image_dims[2], resize_mode=dataset.resize_mode, ) images.append(image) if num_images and len(images) >= num_images: break except utils.errors.LoadImageError as e: print e if not len(images): raise werkzeug.exceptions.BadRequest( 'Unable to load any images from the file') labels, scores = job.train_task().infer_many(images, snapshot_epoch=epoch) if scores is None: raise RuntimeError('An error occured while processing the images') indices = (-scores).argsort(axis=0)[:top_n] results = [] for i in xrange(indices.shape[1]): result_images = [] for j in xrange(top_n): result_images.append(images[indices[j][i]]) results.append((labels[i], utils.image.embed_image_html( utils.image.vis_square(np.array(result_images))))) return flask.render_template( 'models/images/classification/top_n.html', job=job, results=results, )
def classify_many(): """ Classify many images and return the top 5 classifications for each Returns JSON when requested: {classifications: {filename: [[category,confidence],...],...}} """ model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths, ground_truths = read_image_list(image_list, image_folder, num_test_images) # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Classify Many Images", model=model_job, images=paths, epoch=epoch, layers='none' ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: # retrieve path and ground truth of images that were successfully processed paths = [paths[idx] for idx in inputs['ids']] ground_truths = [ground_truths[idx] for idx in inputs['ids']] # defaults classifications = None show_ground_truth = None top1_accuracy = None top5_accuracy = None confusion_matrix = None per_class_accuracy = None labels = None if outputs is not None: # convert to class probabilities for viewing last_output_name, last_output_data = outputs.items()[-1] if len(last_output_data) < 1: raise werkzeug.exceptions.BadRequest( 'Unable to classify any image from the file') scores = last_output_data # take top 5 indices = (-scores).argsort()[:, :5] labels = model_job.train_task().get_labels() n_labels = len(labels) # remove invalid ground truth ground_truths = [x if x is not None and (0 <= x < n_labels) else None for x in ground_truths] # how many pieces of ground truth to we have? n_ground_truth = len([1 for x in ground_truths if x is not None]) show_ground_truth = n_ground_truth > 0 # compute classifications and statistics classifications = [] n_top1_accurate = 0 n_top5_accurate = 0 confusion_matrix = np.zeros((n_labels, n_labels), dtype=np.dtype(int)) for image_index, index_list in enumerate(indices): result = [] if ground_truths[image_index] is not None: if ground_truths[image_index] == index_list[0]: n_top1_accurate += 1 if ground_truths[image_index] in index_list: n_top5_accurate += 1 if (0 <= ground_truths[image_index] < n_labels) and (0 <= index_list[0] < n_labels): confusion_matrix[ground_truths[image_index], index_list[0]] += 1 for i in index_list: # `i` is a category in labels and also an index into scores # ignore prediction if we don't have a label for the corresponding class # the user might have set the final fully-connected layer's num_output to # too high a value if i < len(labels): result.append((labels[i], round(100.0 * scores[image_index, i], 2))) classifications.append(result) # accuracy if show_ground_truth: top1_accuracy = round(100.0 * n_top1_accurate / n_ground_truth, 2) top5_accuracy = round(100.0 * n_top5_accurate / n_ground_truth, 2) per_class_accuracy = [] for x in xrange(n_labels): n_examples = sum(confusion_matrix[x]) per_class_accuracy.append( round(100.0 * confusion_matrix[x, x] / n_examples, 2) if n_examples > 0 else None) else: top1_accuracy = None top5_accuracy = None per_class_accuracy = None # replace ground truth indices with labels ground_truths = [labels[x] if x is not None and (0 <= x < n_labels) else None for x in ground_truths] if request_wants_json(): joined = dict(zip(paths, classifications)) return flask.jsonify({'classifications': joined}), status_code else: return flask.render_template('models/images/classification/classify_many.html', model_job=model_job, job=inference_job, paths=paths, classifications=classifications, show_ground_truth=show_ground_truth, ground_truths=ground_truths, top1_accuracy=top1_accuracy, top5_accuracy=top5_accuracy, confusion_matrix=confusion_matrix, per_class_accuracy=per_class_accuracy, labels=labels, ), status_code
def generic_image_model_infer_many(): """ Infer many images """ job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths = [] images = [] db_task = job.train_task().dataset.analyze_db_tasks()[0] height = db_task.image_height width = db_task.image_width if job.train_task().crop_size: height = job.train_task().crop_size width = job.train_task().crop_size channels = db_task.image_channels for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+\d+$', line) if match: path = match.group(1) else: path = line try: image = utils.image.load_image(path) image = utils.image.resize_image(image, height, width, channels = channels, resize_mode = 'squash', ) paths.append(path) images.append(image) except utils.errors.LoadImageError as e: print e if not len(images): raise werkzeug.exceptions.BadRequest( 'Unable to load any images from the file') outputs = job.train_task().infer_many(images, snapshot_epoch=epoch) if outputs is None: raise RuntimeError('An error occured while processing the images') if request_wants_json(): result = {} for i, path in enumerate(paths): result[path] = dict((name, blob[i].tolist()) for name,blob in outputs.iteritems()) return flask.jsonify({'outputs': result}) else: return flask.render_template('models/images/generic/infer_many.html', paths = paths, network_outputs = outputs, )
def classify_many(): """ Classify many images and return the top 5 classifications for each Returns JSON when requested: {classifications: {filename: [[category,confidence],...],...}} """ model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths, ground_truths = read_image_list(image_list, image_folder, num_test_images) # create inference job inference_job = ImageInferenceJob( username = utils.auth.get_username(), name = "Classify Many Images", model = model_job, images = paths, epoch = epoch, layers = 'none' ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # delete job scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: # retrieve path and ground truth of images that were successfully processed paths = [paths[idx] for idx in inputs['ids']] ground_truths = [ground_truths[idx] for idx in inputs['ids']] classifications = None if outputs is not None: # convert to class probabilities for viewing last_output_name, last_output_data = outputs.items()[-1] if len(last_output_data) < 1: raise werkzeug.exceptions.BadRequest( 'Unable to classify any image from the file') scores = last_output_data # take top 5 indices = (-scores).argsort()[:, :5] labels = model_job.train_task().get_labels() classifications = [] for image_index, index_list in enumerate(indices): result = [] for i in index_list: # `i` is a category in labels and also an index into scores result.append((labels[i], round(100.0*scores[image_index, i],2))) classifications.append(result) # replace ground truth indices with labels ground_truths = [labels[x] if x is not None and (0 <= x < len(labels)) else None for x in ground_truths] if request_wants_json(): joined = dict(zip(paths, classifications)) return flask.jsonify({'classifications': joined}) else: return flask.render_template('models/images/classification/classify_many.html', model_job = model_job, job = inference_job, paths = paths, classifications = classifications, show_ground_truth= not(ground_truths == [None]*len(ground_truths)), ground_truths = ground_truths )
def explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = flask.request.args.get('db', 'train') if 'train' in db.lower(): task = job.train_db_task() elif 'val' in db.lower(): task = job.val_db_task() elif 'test' in db.lower(): task = job.test_db_task() if task is None: raise ValueError('No create_db task for {0}'.format(db)) if task.status != 'D': raise ValueError("This create_db task's status should be 'D' but is '{0}'".format(task.status)) if task.backend != 'lmdb': raise ValueError("Backend is {0} while expected backend is lmdb".format(task.backend)) db_path = job.path(task.db_name) labels = task.get_labels() page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) label = flask.request.args.get('label', None) if label is not None: try: label = int(label) label_str = labels[label] except ValueError: label = None reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) if label is None: total_entries = reader.total_entries else: total_entries = task.distribution[str(label)] max_page = min((total_entries-1) / size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page*size: datum = caffe_pb2.Datum() datum.ParseFromString(value) if label is None or datum.label == label: if datum.encoded: s = StringIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) else: import caffe.io arr = caffe.io.datum_to_array(datum) # CHW -> HWC arr = arr.transpose((1,2,0)) if arr.shape[2] == 1: # HWC -> HW arr = arr[:,:,0] elif arr.shape[2] == 3: # BGR -> RGB # XXX see issue #59 arr = arr[:,:,[2,1,0]] img = PIL.Image.fromarray(arr) imgs.append({"label":labels[datum.label], "b64": utils.image.embed_image_html(img)}) if label is None: count += 1 else: datum = caffe_pb2.Datum() datum.ParseFromString(value) if datum.label == int(label): count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/explore.html', page=page, size=size, job=job, imgs=imgs, labels=labels, pages=pages, label=label, total_entries=total_entries, db=db)
def infer_db(): """ Infer a database """ model_job = job_from_request() if not 'db_path' in flask.request.form or flask.request.form['db_path'] is None: raise werkzeug.exceptions.BadRequest('db_path is a required field') db_path = flask.request.form['db_path'] if not os.path.exists(db_path): raise werkzeug.exceptions.BadRequest('DB "%s" does not exit' % db_path) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) # create inference job inference_job = ImageInferenceJob( username = utils.auth.get_username(), name = "Infer Many Images", model = model_job, images = db_path, epoch = epoch, layers = 'none', ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: keys = [str(idx) for idx in inputs['ids']] else: keys = None if request_wants_json(): result = {} for i, key in enumerate(keys): result[key] = dict((name, blob[i].tolist()) for name,blob in outputs.iteritems()) return flask.jsonify({'outputs': result}) else: return flask.render_template('models/images/generic/infer_db.html', model_job = model_job, job = inference_job, keys = keys, network_outputs = outputs, )
def classify_many(): """ Classify many images and return the top 5 classifications for each Returns JSON when requested: {classifications: {filename: [[category,confidence],...],...}} """ model_job = job_from_request() image_list = flask.request.files.get('image_list') if not image_list: raise werkzeug.exceptions.BadRequest('image_list is a required field') if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) paths = [] ground_truths = [] for line in image_list.readlines(): line = line.strip() if not line: continue path = None # might contain a numerical label at the end match = re.match(r'(.*\S)\s+(\d+)$', line) if match: path = match.group(1) ground_truth = int(match.group(2)) else: path = line ground_truth = None if not utils.is_url(path) and image_folder and not os.path.isabs(path): path = os.path.join(image_folder, path) paths.append(path) ground_truths.append(ground_truth) if num_test_images is not None and len(paths) >= num_test_images: break # create inference job inference_job = ImageInferenceJob( username = utils.auth.get_username(), name = "Classify Many Images", model = model_job, images = paths, epoch = epoch, layers = 'none' ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # delete job scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: # retrieve path and ground truth of images that were successfully processed paths = [paths[idx] for idx in inputs['ids']] ground_truths = [ground_truths[idx] for idx in inputs['ids']] classifications = None if outputs is not None: # convert to class probabilities for viewing last_output_name, last_output_data = outputs.items()[-1] if len(last_output_data) < 1: raise werkzeug.exceptions.BadRequest( 'Unable to classify any image from the file') scores = last_output_data # take top 5 indices = (-scores).argsort()[:, :5] labels = model_job.train_task().get_labels() classifications = [] for image_index, index_list in enumerate(indices): result = [] for i in index_list: # `i` is a category in labels and also an index into scores result.append((labels[i], round(100.0*scores[image_index, i],2))) classifications.append(result) # replace ground truth indices with labels ground_truths = [labels[x] if x is not None and (0 <= x < len(labels)) else None for x in ground_truths] if request_wants_json(): joined = dict(zip(paths, classifications)) return flask.jsonify({'classifications': joined}) else: return flask.render_template('models/images/classification/classify_many.html', model_job = model_job, job = inference_job, paths = paths, classifications = classifications, show_ground_truth= not(ground_truths == [None]*len(ground_truths)), ground_truths = ground_truths )
def image_classification_dataset_explore(): """ Returns a gallery consisting of the images of one of the dbs """ job = job_from_request() # Get LMDB db = flask.request.args.get('db', 'train') if 'train' in db.lower(): task = job.train_db_task() elif 'val' in db.lower(): task = job.val_db_task() elif 'test' in db.lower(): task = job.test_db_task() if task == None: raise ValueError('No create_db task for {0}'.format(db)) if task.status != 'D': raise ValueError( "This create_db task's status should be 'D' but is '{0}'".format( task.status)) if task.backend != 'lmdb': raise ValueError( "Backend is {0} while expected backend is lmdb".format( task.backend)) db_path = job.path(task.db_name) labels = task.get_labels() page = int(flask.request.args.get('page', 0)) size = int(flask.request.args.get('size', 25)) label = flask.request.args.get('label', None) if label is not None: try: label = int(label) label_str = labels[label] except ValueError: label = None reader = DbReader(db_path) count = 0 imgs = [] min_page = max(0, page - 5) if label is None: total_entries = reader.total_entries else: total_entries = task.distribution[str(label)] max_page = min((total_entries - 1) / size, page + 5) pages = range(min_page, max_page + 1) for key, value in reader.entries(): if count >= page * size: datum = caffe_pb2.Datum() datum.ParseFromString(value) if label is None or datum.label == label: s = StringIO() s.write(datum.data) s.seek(0) img = PIL.Image.open(s) imgs.append({ "label": labels[datum.label], "b64": utils.image.image_to_base64(img) }) if label is None: count += 1 else: datum = caffe_pb2.Datum() datum.ParseFromString(value) if datum.label == int(label): count += 1 if len(imgs) >= size: break return flask.render_template('datasets/images/classification/explore.html', page=page, size=size, job=job, imgs=imgs, labels=labels, pages=pages, label=label, total_entries=total_entries, db=db)
def classify_one(): """ Classify one image and return the top 5 classifications Returns JSON when requested: {predictions: {category: confidence,...}} """ model_job = job_from_request() remove_image_path = False if 'image_path' in flask.request.form and flask.request.form['image_path']: image_path = flask.request.form['image_path'] elif 'image_file' in flask.request.files and flask.request.files['image_file']: outfile = tempfile.mkstemp(suffix='.png') flask.request.files['image_file'].save(outfile[1]) image_path = outfile[1] os.close(outfile[0]) remove_image_path = True else: raise werkzeug.exceptions.BadRequest('must provide image_path or image_file') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Classify One Image", model=model_job, images=[image_path], epoch=epoch, layers=layers ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, visualizations = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job scheduler.delete_job(inference_job) if remove_image_path: os.remove(image_path) image = None predictions = [] if inputs is not None and len(inputs['data']) == 1: image = utils.image.embed_image_html(inputs['data'][0]) # convert to class probabilities for viewing last_output_name, last_output_data = outputs.items()[-1] if len(last_output_data) == 1: scores = last_output_data[0].flatten() indices = (-scores).argsort() labels = model_job.train_task().get_labels() predictions = [] for i in indices: # ignore prediction if we don't have a label for the corresponding class # the user might have set the final fully-connected layer's num_output to # too high a value if i < len(labels): predictions.append((labels[i], scores[i])) predictions = [(p[0], round(100.0 * p[1], 2)) for p in predictions[:5]] if request_wants_json(): return flask.jsonify({'predictions': predictions}), status_code else: return flask.render_template('models/images/classification/classify_one.html', model_job=model_job, job=inference_job, image_src=image, predictions=predictions, visualizations=visualizations, total_parameters=sum(v['param_count'] for v in visualizations if v['vis_type'] == 'Weights'), ), status_code
def infer_extension(): """ Perform inference using the data from an extension inference form """ model_job = job_from_request() inference_db_job = None try: # create an inference database inference_db_job = create_inference_db(model_job) db_path = inference_db_job.get_feature_db_path(constants.TEST_DB) # create database creation job epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) layers = 'none' if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: layers = 'all' # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Inference", model=model_job, images=db_path, epoch=epoch, layers=layers, resize=False, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() finally: if inference_db_job: scheduler.delete_job(inference_db_job) # retrieve inference data inputs, outputs, model_visualization = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: keys = [str(idx) for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None keys = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, key in enumerate(keys): result[key] = dict((name, blob[i].tolist()) for name,blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_extension.html', model_job=model_job, job=inference_job, keys=keys, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, visualizations=model_visualization, total_parameters=sum(v['param_count'] for v in model_visualization if v['vis_type'] == 'Weights'), ), status_code
def top_n(): """ Classify many images and show the top N images per category by confidence """ model_job = job_from_request() image_list = flask.request.files['image_list'] if not image_list: raise werkzeug.exceptions.BadRequest('File upload not found') epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'top_n' in flask.request.form and flask.request.form['top_n'].strip(): top_n = int(flask.request.form['top_n']) else: top_n = 9 if 'image_folder' in flask.request.form and flask.request.form['image_folder'].strip(): image_folder = flask.request.form['image_folder'] if not os.path.exists(image_folder): raise werkzeug.exceptions.BadRequest('image_folder "%s" does not exit' % image_folder) else: image_folder = None if 'num_test_images' in flask.request.form and flask.request.form['num_test_images'].strip(): num_test_images = int(flask.request.form['num_test_images']) else: num_test_images = None paths, _ = read_image_list(image_list, image_folder, num_test_images) # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="TopN Image Classification", model=model_job, images=paths, epoch=epoch, layers='none' ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # delete job scheduler.delete_job(inference_job) results = None if outputs is not None and len(outputs) > 0: # convert to class probabilities for viewing last_output_name, last_output_data = outputs.items()[-1] scores = last_output_data if scores is None: raise RuntimeError('An error occurred while processing the images') labels = model_job.train_task().get_labels() images = inputs['data'] indices = (-scores).argsort(axis=0)[:top_n] results = [] # Can't have more images per category than the number of images images_per_category = min(top_n, len(images)) # Can't have more categories than the number of labels or the number of outputs n_categories = min(indices.shape[1], len(labels)) for i in xrange(n_categories): result_images = [] for j in xrange(images_per_category): result_images.append(images[indices[j][i]]) results.append(( labels[i], utils.image.embed_image_html( utils.image.vis_square(np.array(result_images), colormap='white') ) )) return flask.render_template('models/images/classification/top_n.html', model_job=model_job, job=inference_job, results=results, )
def infer_db(): """ Infer a database """ model_job = job_from_request() if not 'db_path' in flask.request.form or flask.request.form['db_path'] is None: raise werkzeug.exceptions.BadRequest('db_path is a required field') db_path = flask.request.form['db_path'] if not os.path.exists(db_path): raise werkzeug.exceptions.BadRequest('DB "%s" does not exit' % db_path) epoch = None if 'snapshot_epoch' in flask.request.form: epoch = float(flask.request.form['snapshot_epoch']) if 'dont_resize' in flask.request.form and flask.request.form['dont_resize']: resize = False else: resize = True # create inference job inference_job = ImageInferenceJob( username=utils.auth.get_username(), name="Infer Many Images", model=model_job, images=db_path, epoch=epoch, layers='none', resize=resize, ) # schedule tasks scheduler.add_job(inference_job) # wait for job to complete inference_job.wait_completion() # retrieve inference data inputs, outputs, _ = inference_job.get_data() # set return status code status_code = 500 if inference_job.status == 'E' else 200 # delete job folder and remove from scheduler list scheduler.delete_job(inference_job) if outputs is not None and len(outputs) < 1: # an error occurred outputs = None if inputs is not None: keys = [str(idx) for idx in inputs['ids']] inference_views_html, header_html, app_begin_html, app_end_html = get_inference_visualizations( model_job.dataset, inputs, outputs) else: inference_views_html = None header_html = None keys = None app_begin_html = None app_end_html = None if request_wants_json(): result = {} for i, key in enumerate(keys): result[key] = dict((name, blob[i].tolist()) for name,blob in outputs.iteritems()) return flask.jsonify({'outputs': result}), status_code else: return flask.render_template( 'models/images/generic/infer_db.html', model_job=model_job, job=inference_job, keys=keys, inference_views_html=inference_views_html, header_html=header_html, app_begin_html=app_begin_html, app_end_html=app_end_html, ), status_code