def test_pyflann_searches(): """ CommandLine: python -m vtool.tests.test_pyflann --test-test_pyflann_searches Example: >>> # ENABLE_DOCTEST >>> from vtool.tests.test_pyflann import * # NOQA >>> # build test data >>> # execute function >>> result = test_pyflann_searches() >>> # verify results >>> print(result) """ try: num_neighbors = 3 pts = testdata_points(nPts=5743, nDims=2) qpts = testdata_points(nPts=7, nDims=2) import vtool as vt # sample a radius radius = vt.L2(pts[0:1], qpts[0:1])[0] * 2 + 1 flann = pyflann.FLANN() print('NN_OnTheFly') # build nn_index on the fly indices1, dists1 = flann.nn(pts, qpts, num_neighbors, algorithm='hierarchical') print(utool.hz_str('indices1, dists1 = ', indices1, dists1)) _build_params = flann.build_index(pts, algorithm='kmeans') del _build_params print('NN_Index') indices2, dists2 = flann.nn_index(qpts, num_neighbors=num_neighbors) print(utool.hz_str('indices2, dists2 = ', indices2, dists2)) # this can only be called on one query point at a time # because the output size is unknown print('NN_Radius, radius=%r' % (radius, )) indices3, dists3 = flann.nn_radius(pts[0], radius) print('indices3 = %r ' % (indices3, )) print('dists3 = %r ' % (dists3, )) assert np.all(dists3 < radius) except Exception as ex: utool.printex(ex, key_list=[ 'query', 'query.shape', 'pts.shape', ], pad_stdout=True) #utool.embed() raise
def augment_graph_mst(ibs, graph): import wbia.plottool as pt # spantree_aids1_ = [] # spantree_aids2_ = [] # Add edges between all names aid_list = list(graph.nodes()) aug_digraph = graph.copy() # Change all weights in initial graph to be small (likely to be part of mst) nx.set_edge_attributes(aug_digraph, name='weight', values=0.0001) aids1, aids2 = get_name_rowid_edges_from_aids(ibs, aid_list) if False: # Weight edges in the MST based on tenative distances # Get tentative node positions initial_pos = pt.get_nx_layout(graph.to_undirected(), 'graphviz')['node_pos'] # initial_pos = pt.get_nx_layout(graph.to_undirected(), 'agraph')['node_pos'] edge_pts1 = ut.dict_take(initial_pos, aids1) edge_pts2 = ut.dict_take(initial_pos, aids2) edge_pts1 = vt.atleast_nd(np.array(edge_pts1, dtype=np.int32), 2) edge_pts2 = vt.atleast_nd(np.array(edge_pts2, dtype=np.int32), 2) edge_weights = vt.L2(edge_pts1, edge_pts2) else: edge_weights = [1.0] * len(aids1) # Create implicit fully connected (by name) graph aug_edges = [(a1, a2, { 'weight': w }) for a1, a2, w in zip(aids1, aids2, edge_weights)] aug_digraph.add_edges_from(aug_edges) # Determine which edges need to be added to # make original graph connected by name aug_graph = aug_digraph.to_undirected() for cc_sub_graph in connected_component_subgraphs(aug_graph): mst_sub_graph = nx.minimum_spanning_tree(cc_sub_graph) mst_edges = mst_sub_graph.edges() for edge in mst_edges: redge = edge[::-1] # attr_dict = {'color': pt.DARK_ORANGE[0:3]} attr_dict = {'color': pt.BLACK[0:3]} if not (graph.has_edge(*edge) or graph.has_edge(*redge)): graph.add_edge(*redge, attr_dict=attr_dict)
def true_dist_metric(vecs1, vecs2): g1_ = np.roll(vecs1, 1, axis=1) dist = vt.L2(g1_, vecs2) return dist
def test_siamese_performance(model, data, labels, flat_metadata, dataname=''): r""" CommandLine: utprof.py -m ibeis_cnn --tf pz_patchmatch --db liberty --test --weights=liberty:current --arch=siaml2_128 --test python -m ibeis_cnn --tf netrun --db liberty --arch=siaml2_128 --test --ensure python -m ibeis_cnn --tf netrun --db liberty --arch=siaml2_128 --test --ensure --weights=new python -m ibeis_cnn --tf netrun --db liberty --arch=siaml2_128 --train --weights=new python -m ibeis_cnn --tf netrun --db pzmtest --weights=liberty:current --arch=siaml2_128 --test # NOQA python -m ibeis_cnn --tf netrun --db pzmtest --weights=liberty:current --arch=siaml2_128 """ import vtool as vt import plottool as pt # TODO: save in model.trainind_dpath/diagnostics/figures ut.colorprint('\n[siam_perf] Testing Siamese Performance', 'white') #epoch_dpath = model.get_epoch_diagnostic_dpath() epoch_dpath = model.arch_dpath ut.vd(epoch_dpath) dataname += ' ' + model.get_history_hashid() + '\n' history_text = ut.list_str(model.era_history, newlines=True) ut.write_to(ut.unixjoin(epoch_dpath, 'era_history.txt'), history_text) #if True: # import matplotlib as mpl # mpl.rcParams['agg.path.chunksize'] = 100000 #data = data[::50] #labels = labels[::50] #from ibeis_cnn import utils #data, labels = utils.random_xy_sample(data, labels, 10000, model.data_per_label_input) FULL = not ut.get_argflag('--quick') fnum_gen = pt.make_fnum_nextgen() ut.colorprint('[siam_perf] Show era history', 'white') fig = model.show_era_loss(fnum=fnum_gen()) pt.save_figure(fig=fig, dpath=epoch_dpath, dpi=180) # hack ut.colorprint('[siam_perf] Show weights image', 'white') fig = model.show_weights_image(fnum=fnum_gen()) pt.save_figure(fig=fig, dpath=epoch_dpath, dpi=180) #model.draw_all_conv_layer_weights(fnum=fnum_gen()) #model.imwrite_weights(1) #model.imwrite_weights(2) # Compute each type of score ut.colorprint('[siam_perf] Building Scores', 'white') test_outputs = model.predict2(model, data) network_output = test_outputs['network_output_determ'] # hack converting network output to distances for non-descriptor networks if len(network_output.shape) == 2 and network_output.shape[1] == 1: cnn_scores = network_output.T[0] elif len(network_output.shape) == 1: cnn_scores = network_output elif len(network_output.shape) == 2 and network_output.shape[1] > 1: assert model.data_per_label_output == 2 vecs1 = network_output[0::2] vecs2 = network_output[1::2] cnn_scores = vt.L2(vecs1, vecs2) else: assert False cnn_scores = cnn_scores.astype(np.float64) # Segfaults with the data passed in is large (AND MEMMAPPED apparently) # Fixed in hesaff implementation SIFT = FULL if SIFT: sift_scores, sift_list = test_sift_patchmatch_scores(data, labels) sift_scores = sift_scores.astype(np.float64) ut.colorprint('[siam_perf] Learning Encoders', 'white') # Learn encoders encoder_kw = { #'monotonize': False, 'monotonize': True, } cnn_encoder = vt.ScoreNormalizer(**encoder_kw) cnn_encoder.fit(cnn_scores, labels) if SIFT: sift_encoder = vt.ScoreNormalizer(**encoder_kw) sift_encoder.fit(sift_scores, labels) # Visualize ut.colorprint('[siam_perf] Visualize Encoders', 'white') viz_kw = dict( with_scores=False, with_postbayes=False, with_prebayes=False, target_tpr=.95, ) inter_cnn = cnn_encoder.visualize( figtitle=dataname + ' CNN scores. #data=' + str(len(data)), fnum=fnum_gen(), **viz_kw) if SIFT: inter_sift = sift_encoder.visualize( figtitle=dataname + ' SIFT scores. #data=' + str(len(data)), fnum=fnum_gen(), **viz_kw) # Save pt.save_figure(fig=inter_cnn.fig, dpath=epoch_dpath) if SIFT: pt.save_figure(fig=inter_sift.fig, dpath=epoch_dpath) # Save out examples of hard errors #cnn_fp_label_indicies, cnn_fn_label_indicies = #cnn_encoder.get_error_indicies(cnn_scores, labels) #sift_fp_label_indicies, sift_fn_label_indicies = #sift_encoder.get_error_indicies(sift_scores, labels) with_patch_examples = FULL if with_patch_examples: ut.colorprint('[siam_perf] Visualize Confusion Examples', 'white') cnn_indicies = cnn_encoder.get_confusion_indicies(cnn_scores, labels) if SIFT: sift_indicies = sift_encoder.get_confusion_indicies(sift_scores, labels) warped_patch1_list, warped_patch2_list = list(zip(*ut.ichunks(data, 2))) samp_args = (warped_patch1_list, warped_patch2_list, labels) _sample = functools.partial(draw_results.get_patch_sample_img, *samp_args) cnn_fp_img = _sample({'fs': cnn_scores}, cnn_indicies.fp)[0] cnn_fn_img = _sample({'fs': cnn_scores}, cnn_indicies.fn)[0] cnn_tp_img = _sample({'fs': cnn_scores}, cnn_indicies.tp)[0] cnn_tn_img = _sample({'fs': cnn_scores}, cnn_indicies.tn)[0] if SIFT: sift_fp_img = _sample({'fs': sift_scores}, sift_indicies.fp)[0] sift_fn_img = _sample({'fs': sift_scores}, sift_indicies.fn)[0] sift_tp_img = _sample({'fs': sift_scores}, sift_indicies.tp)[0] sift_tn_img = _sample({'fs': sift_scores}, sift_indicies.tn)[0] #if ut.show_was_requested(): #def rectify(arr): # return np.flipud(arr) SINGLE_FIG = False if SINGLE_FIG: def dump_img(img_, lbl, fnum): fig, ax = pt.imshow(img_, figtitle=dataname + ' ' + lbl, fnum=fnum) pt.save_figure(fig=fig, dpath=epoch_dpath, dpi=180) dump_img(cnn_fp_img, 'cnn_fp_img', fnum_gen()) dump_img(cnn_fn_img, 'cnn_fn_img', fnum_gen()) dump_img(cnn_tp_img, 'cnn_tp_img', fnum_gen()) dump_img(cnn_tn_img, 'cnn_tn_img', fnum_gen()) dump_img(sift_fp_img, 'sift_fp_img', fnum_gen()) dump_img(sift_fn_img, 'sift_fn_img', fnum_gen()) dump_img(sift_tp_img, 'sift_tp_img', fnum_gen()) dump_img(sift_tn_img, 'sift_tn_img', fnum_gen()) #vt.imwrite(dataname + '_' + 'cnn_fp_img.png', (cnn_fp_img)) #vt.imwrite(dataname + '_' + 'cnn_fn_img.png', (cnn_fn_img)) #vt.imwrite(dataname + '_' + 'sift_fp_img.png', (sift_fp_img)) #vt.imwrite(dataname + '_' + 'sift_fn_img.png', (sift_fn_img)) else: print('Drawing TP FP TN FN') fnum = fnum_gen() pnum_gen = pt.make_pnum_nextgen(4, 2) fig = pt.figure(fnum) pt.imshow(cnn_fp_img, title='CNN FP', fnum=fnum, pnum=pnum_gen()) pt.imshow(sift_fp_img, title='SIFT FP', fnum=fnum, pnum=pnum_gen()) pt.imshow(cnn_fn_img, title='CNN FN', fnum=fnum, pnum=pnum_gen()) pt.imshow(sift_fn_img, title='SIFT FN', fnum=fnum, pnum=pnum_gen()) pt.imshow(cnn_tp_img, title='CNN TP', fnum=fnum, pnum=pnum_gen()) pt.imshow(sift_tp_img, title='SIFT TP', fnum=fnum, pnum=pnum_gen()) pt.imshow(cnn_tn_img, title='CNN TN', fnum=fnum, pnum=pnum_gen()) pt.imshow(sift_tn_img, title='SIFT TN', fnum=fnum, pnum=pnum_gen()) pt.set_figtitle(dataname + ' confusions') pt.adjust_subplots(left=0, right=1.0, bottom=0., wspace=.01, hspace=.05) pt.save_figure(fig=fig, dpath=epoch_dpath, dpi=180, figsize=(9, 18)) with_patch_desc = FULL if with_patch_desc: ut.colorprint('[siam_perf] Visualize Patch Descriptors', 'white') fnum = fnum_gen() fig = pt.figure(fnum=fnum, pnum=(1, 1, 1)) num_rows = 7 pnum_gen = pt.make_pnum_nextgen(num_rows, 3) # Compare actual output descriptors for index in ut.random_indexes(len(sift_list), num_rows): vec_sift = sift_list[index] vec_cnn = network_output[index] patch = data[index] pt.imshow(patch, fnum=fnum, pnum=pnum_gen()) pt.plot_descriptor_signature(vec_cnn, 'cnn vec', fnum=fnum, pnum=pnum_gen()) pt.plot_sift_signature(vec_sift, 'sift vec', fnum=fnum, pnum=pnum_gen()) pt.set_figtitle('Patch Descriptors') pt.adjust_subplots(left=0, right=0.95, bottom=0., wspace=.1, hspace=.15) pt.save_figure(fig=fig, dpath=epoch_dpath, dpi=180, figsize=(9, 18))
def understanding_pseudomax_props(mode=2): """ Function showing some properties of distances between normalized pseudomax vectors CommandLine: python -m vtool.distance --test-understanding_pseudomax_props Example: >>> # ENABLE_DOCTEST >>> from vtool.distance import * # NOQA >>> for mode in [0, 1, 2, 3]: ... print('+---') ... print('mode = %r' % (mode,)) ... result = understanding_pseudomax_props(mode) ... print('L___') >>> print(result) """ import vtool as vt pseudo_max = 512 rng = np.random.RandomState(0) num = 10 if mode == 0: dim = 2 p1_01 = (vt.normalize_rows(rng.rand(num, dim))) p2_01 = (vt.normalize_rows(rng.rand(num, dim))) elif mode == 1: p1_01 = vt.dummy.testdata_dummy_sift(num, rng) / pseudo_max p2_01 = vt.dummy.testdata_dummy_sift(num, rng) / pseudo_max elif mode == 2: # Build theoretically maximally distant normalized vectors (type 1) dim = 128 p1_01 = np.zeros((1, dim)) p2_01 = np.zeros((1, dim)) p2_01[:, 0::2] = 1 p1_01[:, 1::2] = 1 p1_01 = vt.normalize_rows(p1_01) p2_01 = vt.normalize_rows(p2_01) elif mode == 3: # Build theoretically maximally distant vectors (type 2) # This mode will clip if cast to uint8, thus failing the test dim = 128 p1_01 = np.zeros((1, dim)) p2_01 = np.zeros((1, dim)) p2_01[:, 0] = 1 p1_01[:, 1:] = 1 p1_01 = vt.normalize_rows(p1_01) p2_01 = vt.normalize_rows(p2_01) pass print('ndims = %r' % (p1_01.shape[1])) p1_01 = p1_01.astype(TEMP_VEC_DTYPE) p2_01 = p2_01.astype(TEMP_VEC_DTYPE) p1_256 = p1_01 * pseudo_max p2_256 = p2_01 * pseudo_max dist_sqrd_01 = vt.L2_sqrd(p1_01, p2_01) dist_sqrd_256 = vt.L2_sqrd(p1_256, p2_256) dist_01 = np.sqrt(dist_sqrd_01) dist_256 = np.sqrt(dist_sqrd_256) print('dist_sqrd_01 = %s' % (ut.numpy_str(dist_sqrd_01, precision=2), )) print('dist_sqrd_256 = %s' % (ut.numpy_str(dist_sqrd_256, precision=2), )) print('dist_01 = %s' % (ut.numpy_str(dist_01, precision=2), )) print('dist_256 = %s' % (ut.numpy_str(dist_256, precision=2), )) print('--') print('sqrt(2) = %f' % (np.sqrt(2))) print('--') assert np.all(dist_01 == vt.L2(p1_01, p2_01)) assert np.all(dist_256 == vt.L2(p1_256, p2_256)) const_sqrd = dist_sqrd_256 / dist_sqrd_01 const = dist_256 / dist_01 print('const = %r' % (const[0], )) print('const_sqrd = %r' % (const_sqrd[0], )) print('1 / const = %r' % (1 / const[0], )) print('1 / const_sqrd = %r' % (1 / const_sqrd[0], )) assert ut.allsame(const) assert ut.allsame(const_sqrd) assert np.all(const == np.sqrt(const_sqrd)) # Assert that distance conversions work assert np.all(dist_256 / const == dist_01) assert np.all(dist_sqrd_256 / const_sqrd == dist_sqrd_01) print('Conversions work') print('Maximal L2 distance between any two NON-NEGATIVE L2-NORMALIZED' ' vectors should always be sqrt(2)')