def test_chunk(self, points_and_features, labels, save, names): is_training = False feed_dict = { self.pl['pointclouds_pl']: np.expand_dims(points_and_features, 0), self.pl['labels_pl']: np.expand_dims(labels, 0), self.pl['is_training_pl']: is_training, } pred_val, probs = self.sess.run([self.op['pred'], self.op['softmax']], feed_dict=feed_dict) pred_val_max = np.argmax(pred_val[0], 1) for cl in np.unique(pred_val_max): elem_cnt = np.count_nonzero(pred_val_max == cl) logging.debug( "Class %d: %d points (%.2f %%)" % (cl, elem_cnt, 100 * elem_cnt / points_and_features.shape[0])) if any(labels): correct = np.sum(pred_val_max == labels) self.cumsum_test_correct += correct self.cumsum_test += points_and_features.shape[0] logging.info(" -- Cum. Accuracy: %.2f %%" % (100 * self.cumsum_test_correct / self.cumsum_test)) logging.info(" -- Curr. Accuracy: %.2f %%" % (100 * correct / points_and_features.shape[0])) if self.logger: self.logger.valid_points_seen.append( (self.cumsum_train + points_and_features.shape[0]) * 1e-6) self.logger.valid_points_acc.append( 100 * correct / points_and_features.shape[0]) self.logger.valid_points_cumacc.append( 100 * self.cumsum_test_correct / self.cumsum_test) cm = np.zeros((self.num_classes, self.num_classes)) for a, p in zip(labels, pred_val_max): cm[a][p] += 1 cm /= len(labels) del_i = [ i for i in range(self.num_classes) if i not in [2, 3, 4, 5, 6] ] cm = np.delete(cm, del_i, 0) cm = np.delete(cm, del_i, 1) self.logger.valid_confusion.append(cm) if save: if any(labels): Dataset.Save(save, points_and_features, names, labels, pred_val_max, probs[0]) else: Dataset.Save(save, points_and_features, names, new_classes=pred_val_max, probs=probs[0])
def test_single(self, file_in, save_to=None, save_prob=False, unload=True): if isinstance(file_in, Dataset): ds = file_in else: ds = Dataset(file_in) probs = self.predict_probability(ds.points_and_features) new_classes = np.argmax(probs, axis=2) if save_to: Dataset.Save(save_to, ds.points_and_features, ds.names, ds.labels, new_classes[0], probs[0] if save_prob else None) cm = confusion_matrix(ds.labels, new_classes[0], range(self.num_classes)) self.eval_history.add_history_step(cm, self._train_points_seen, 0) if unload: ds.unload() return np.count_nonzero(ds.labels == new_classes[0]) / self.num_points
def train_batch(self, points_and_features, labels): with self.graph.as_default(): is_training = True feed_dict = { self.pl['pointclouds_pl']: points_and_features, self.pl['labels_pl']: labels, self.pl['is_training_pl']: is_training, } if np.count_nonzero(labels == 6) / (labels.shape[0] * labels.shape[1]) > 0.1: logging.debug("Building batch (> 10 %)") if (np.count_nonzero(labels > 2) - np.count_nonzero(labels > 6) ) / (labels.shape[0] * labels.shape[1]) > 0.4: logging.debug("Vegetation batch (> 40%)") if np.count_nonzero(labels == 2) / (labels.shape[0] * labels.shape[1]) > 0.9: logging.debug("Ground batch (> 90%)") _, loss_val, pred_val, end_points, lr, _ = self.sess.run( [ self.op['train_op'], self.op['loss'], self.op['pred'], self.op['end_points'], self.op['learning_rate'], self.increment_global_step ], feed_dict=feed_dict) if False: # debug: save superpoint-clouds if not os.path.exists(os.path.join(self.logDir, 'subsampl')): os.makedirs(os.path.join(self.logDir, 'subsampl')) logging.debug("Saving subsampl to %s" % os.path.join(self.logDir, 'subsampl')) Dataset.Save(os.path.join(self.logDir, 'subsampl', 'l0.laz'), end_points['l0_xyz'][0]) Dataset.Save(os.path.join(self.logDir, 'subsampl', 'l1.laz'), end_points['l1_xyz'][0]) Dataset.Save(os.path.join(self.logDir, 'subsampl', 'l2.laz'), end_points['l2_xyz'][0]) Dataset.Save(os.path.join(self.logDir, 'subsampl', 'l3.laz'), end_points['l3_xyz'][0]) pred_val = np.argmax(pred_val, 2) correct = np.sum(pred_val == labels) self.cumsum_train_correct += correct points_in_batch = labels.shape[0] * labels.shape[1] self.cumsum_train += points_in_batch logging.info(" --- Cum. Accuracy: %.2f %%" % (100 * self.cumsum_train_correct / self.cumsum_train)) logging.info(" --- Curr. Accuracy: %.2f %%" % (100 * correct / points_in_batch)) logging.info(" --- Curr. avg. Loss: %.5f" % np.mean(loss_val)) if self.logger: self.logger.points_seen.append(self.cumsum_train * 1e-6) self.logger.losses.append(np.mean(loss_val)) self.logger.cumaccuracy_train.append( 100 * self.cumsum_train_correct / self.cumsum_train) self.logger.accuracy_train.append(100 * correct / points_in_batch) self.logger.perc_building.append( 100 * np.count_nonzero(labels == 6) / points_in_batch) self.logger.perc_ground.append( 100 * np.count_nonzero(labels == 2) / points_in_batch) self.logger.perc_hi_veg.append( 100 * np.count_nonzero(labels == 5) / points_in_batch) self.logger.perc_med_veg.append( 100 * np.count_nonzero(labels == 4) / points_in_batch) self.logger.perc_lo_veg.append( 100 * np.count_nonzero(labels == 3) / points_in_batch) self.logger.perc_water.append( 100 * np.count_nonzero(labels == 9) / points_in_batch) self.logger.perc_rest.append(0) self.logger.lr.append(lr) self.logger.save()
def main(in_files, ref_file, out_file, write_probs=True): input_files = [] for filepattern in in_files: for file in glob.glob(filepattern): input_files.append(file) logging.info("Found %d files to merge" % len(input_files)) overall_points = None out_points = [] out_attrs = [] out_counts = [] out_meanvar = [] out_labels = [] new_max_class = [] names = None for file in input_files: ds = Dataset(file) points = np.hstack( (ds.points_and_features, np.expand_dims(ds.labels, -1))) if overall_points is None: overall_points = points else: overall_points = np.vstack((overall_points, points)) names = ds.names ref_ds = Dataset(ref_file) ref_points = ref_ds._xyz prob_cols = [] estim_col = None addDims = [] for idx, name in enumerate(names): if name.startswith('prob_class'): prob_cols.append(idx) addDims.append(name) if name == 'estim_class': estim_col = idx + 3 tree = ckdtree.cKDTree(overall_points[:, 0:3]) idx_processed = [] for line in range(ref_points.shape[0]): if line % 10 == 0: #logging.info("Currently in line %d from %d" % (line, ref_points.shape[0])) pass curr_xyz = ref_points[line, :] multiples = tree.query_ball_point(curr_xyz, r=0.0001, eps=0.0001) #print(curr_xyz) #print(overall_points[multiples, 0:3]) idx_processed += multiples if len(multiples) == 0: logging.info("Point missing: %s" % curr_xyz) continue out_points.append(curr_xyz) out_labels.append(overall_points[multiples[0], -1]) avg_feats = np.mean(overall_points[multiples, 3:-1], axis=0) var_feats = np.std(overall_points[multiples, 3:-1], axis=0) out_meanvar.append(np.mean(var_feats)) out_attrs.append(avg_feats) new_max_class.append(np.argmax(avg_feats[prob_cols], axis=0)) #print(np.argmax(avg_feats[prob_cols], axis=0)) #print(multiples, len(multiples)) out_counts.append(len(multiples)) out_attrs = np.array(out_attrs) out_counts = np.expand_dims(np.array(out_counts), -1) out_meanvar = np.expand_dims(np.array(out_meanvar), -1) names.append('meanvar') names.append('count') #attr_avg = np.sum(out_attrs, axis=1)/out_counts out_labels = np.array(out_labels).astype(np.int) Dataset.Save( out_file, np.hstack((out_points, out_attrs, out_meanvar, out_counts)), names, labels=out_labels, new_classes=new_max_class, ) #addDims=addDims + ['meanvar', 'count']) #staticstics pre_acc = np.count_nonzero(overall_points[:, estim_col] == overall_points[:, -1]) / overall_points.shape[0] post_acc = np.count_nonzero(new_max_class == out_labels) / len(out_points) post_cm = metrics.confusion_matrix(out_labels, new_max_class) post_prec = metrics.precision_score(out_labels, new_max_class, average=None) post_recall = metrics.recall_score(out_labels, new_max_class, average=None) post_f1 = metrics.f1_score(out_labels, new_max_class, average=None) np.savetxt(out_file + '_cm.txt', post_cm, fmt='%.4f') np.savetxt(out_file + '_prec.txt', post_prec, fmt='%.4f') np.savetxt(out_file + '_recall.txt', post_recall, fmt='%.4f') np.savetxt(out_file + '_f1.txt', post_f1, fmt='%.4f') logging.info("Finished. Pre-acc: %.3f | Post-acc: %.3f" % (pre_acc, post_acc))