Пример #1
0
def eval_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = int(math.ceil((1.0*len(TEST_DATASET))/BATCH_SIZE))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]

    labelweights = np.zeros(NUM_CLASSES)
    tp = np.zeros(NUM_CLASSES)
    fp = np.zeros(NUM_CLASSES)
    fn = np.zeros(NUM_CLASSES)
        
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(TEST_DATASET, test_idxs, start_idx, end_idx)

        if FLAGS.extra_dims:
            aug_data = np.concatenate((provider.rotate_point_cloud_z(batch_data[:,:,0:3]),
                    batch_data[:,:,3:]),axis=2)
        else:
            aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {ops['pointclouds_pl']: aug_data,
                     ops['labels_pl']: batch_label,
                       ops['smpws_pl']: batch_smpw,
                     ops['is_training_pl']: is_training}
        summary, step, loss_val, pred_val = sess.run([ops['merged'], ops['step'],
            ops['loss'], ops['pred']], feed_dict=feed_dict)
        test_writer.add_summary(summary, step)

        pred_val = np.argmax(pred_val, 2) # BxN
        correct = np.sum((pred_val == batch_label) & (batch_label>0) & (batch_smpw>0)) # evaluate only all categories except unknown
        total_correct += correct
        total_seen += np.sum((batch_label>0) & (batch_smpw>0))
        loss_sum += loss_val
    
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label==l) & (batch_smpw>0))
            total_correct_class[l] += np.sum((pred_val==l) & (batch_label==l) & (batch_smpw>0))
            tp[l] += ((pred_val==l) & (batch_label==l)).sum()
            fp[l] += ((pred_val==l) & (batch_label!=l)).sum()
            fn[l] += ((pred_val!=l) & (batch_label==l)).sum()

    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point accuracy: %f'% (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(np.array(total_correct_class)/(np.array(total_seen_class,dtype=np.float)+1e-6))))
    per_class_str = '     '
    iou = np.divide(tp,tp+fp+fn)
    for l in range(NUM_CLASSES):
        per_class_str += 'class %d[%d] acc: %f, iou: %f; ' % (TEST_DATASET.decompress_label_map[l],l,total_correct_class[l]/float(total_seen_class[l]),iou[l])
    log_string(per_class_str)
    log_string('mIOU: {}'.format(iou.mean()))
    
    return total_correct/float(total_seen)
Пример #2
0
    def train_one_epoch(self, sess, ops, train_writer):
        """ ops: dict mapping from string to tf ops """
        is_training = True

        # Shuffle train samples
        train_idxs = np.arange(0, self.train_data.__len__(
        ))  # train_idx ,idx is a list [1263, 396,1309 .... 41 398 495]
        np.random.shuffle(train_idxs)
        num_batches = int(math.ceil((1.0 * self.train_sz) / self.batch_sz))

        self.log_string(str(datetime.now()))

        total_correct = 0
        total_seen = 0
        loss_sum = 0
        for batch_idx in range(num_batches):
            start_idx = batch_idx * self.batch_sz
            end_idx = (batch_idx + 1) * self.batch_sz
            batch_data, batch_label, batch_smpw = self.get_batch_wdp(
                self.train_data, train_idxs, start_idx, end_idx)
            # Augment batched point clouds by rotation and jitter
            if FLAGS.extra_dims:
                aug_data = np.concatenate((provider.rotate_point_cloud_z(
                    batch_data[:, :, 0:3]), batch_data[:, :, 3:]),
                                          axis=2)
                aug_data = np.concatenate((provider.jitter_point_cloud(
                    aug_data[:, :, 0:3]), aug_data[:, :, 3:]),
                                          axis=2)
            else:
                aug_data = provider.rotate_point_cloud_z(batch_data)
                aug_data = provider.jitter_point_cloud(aug_data)

            feed_dict = {
                ops['pointclouds_pl']: aug_data,
                ops['labels_pl']: batch_label,
                ops['smpws_pl']: batch_smpw,
                ops['is_training_pl']: is_training,
            }
            summary, step, _, loss_val, pred_val = sess.run(
                [
                    ops['merged'], ops['step'], ops['train_op'], ops['loss'],
                    ops['pred']
                ],
                feed_dict=feed_dict)
            train_writer.add_summary(summary, step)
            # pred_val = np.argmax(pred_val, 2)
            correct = np.sum(pred_val == batch_label)
            total_correct += correct
            total_seen += (self.batch_sz * self.point_sz)
            loss_sum += loss_val
            if (batch_idx + 1) % 5 == 0:
                self.log_string(' -- %03d / %03d --' %
                                (batch_idx + 1, num_batches))
                self.log_string('mean loss: %f' % (loss_sum / 5))
                self.log_string('accuracy: %f' %
                                (total_correct / float(total_seen)))
                total_correct = 0
                total_seen = 0
                loss_sum = 0
Пример #3
0
def train_one_epoch_my(sess, ops, train_writer):
    is_training = True
    # ops: dict mapping from string to tf ops """
    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = int(math.ceil((1.0*len(TRAIN_DATASET))/BATCH_SIZE))
    
    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(TRAIN_DATASET, train_idxs, start_idx, end_idx)
        # Augment batched point clouds by rotation
        if FLAGS.extra_dims:
            aug_data = np.concatenate((provider.rotate_point_cloud_z(batch_data[:,:,0:3]),
                    batch_data[:,:,3:]),axis=2)
        else:
            aug_data = provider.rotate_point_cloud_z(batch_data)
        feed_dict = {ops['pointclouds_pl']: aug_data,
                     ops['labels_pl']: batch_label,
                     ops['smpws_pl']:batch_smpw,
                     ops['is_training_pl']: is_training,}
        summary, step, _, loss_val,loss_batch, pred_val = sess.run([ops['merged'], ops['step'],
            ops['train_op'], ops['loss'],ops['all_loss'], ops['pred']], feed_dict=feed_dict)

        train_writer.add_summary(summary, step)
        loss_batch_row = tf.reshape(loss_batch,[loss_batch.shape[0]*loss_batch.shape[1],])
        top_k, index = tf.nn.top_k(loss_batch_row, int(loss_batch.shape[0]*loss_batch.shape[1]*0.05)) #提取前20%个loss最大索引
        rows, cols = get_batch_index(index.eval(session=sess))
        print("Alive1")
        for i,j in zip(rows, cols):
            # i = m.eval(session=sess)
            # j = n.eval(session=sess)
            bad_sample_data.append(batch_data[i,j,:])
            bad_sample_label.append(batch_label[i,j])
            bad_sample_smpw.append(batch_smpw[i,j])
        print("Alive2")
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE*NUM_POINT)
        loss_sum += loss_val
        if (batch_idx+1)%10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx+1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
Пример #4
0
def train_one_epoch(sess, ops, train_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = int(math.ceil((1.0 * len(TRAIN_DATASET)) / BATCH_SIZE))

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(
            TRAIN_DATASET, train_idxs, start_idx, end_idx)
        # Augment batched point clouds by rotation
        if FLAGS.extra_dims:
            aug_data = np.concatenate((provider.rotate_point_cloud_z(
                batch_data[:, :, 0:3]), batch_data[:, :, 3:]),
                                      axis=2)
        else:
            aug_data = provider.rotate_point_cloud_z(batch_data)
        feed_dict = {
            ops['pointclouds_pl']: aug_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training,
        }
        summary, step, _, loss_val, pred_val = sess.run([
            ops['merged'], ops['step'], ops['train_op'], ops['loss'],
            ops['pred']
        ],
                                                        feed_dict=feed_dict)
        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        # print(np.unique(batch_label))
        # print(np.unique(pred_val))
        # input()
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE * NUM_POINT)
        loss_sum += loss_val
        if (batch_idx + 1) % 10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx + 1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
Пример #5
0
def pre_processor(files, input_queue):
    for file in files:

        logging.info('Loading {}'.format(file))
        pset = PointSet(file)
        [block_data_total, block_label_total] = pset.cloud2blocks_finaltest()
        test_data_psets = np.concatenate((block_data_total[0], block_data_total[1], block_data_total[2],
                                          block_data_total[3], block_data_total[4], block_data_total[5],
                                          block_data_total[6], block_data_total[7], block_data_total[8],
                                          block_data_total[9]), axis=0) # concat all the blocks
        sz=test_data_psets.__len__()
        print(sz)
        # psets = pset.split()  # current splited
        num_batches = int(math.ceil((1.0 * sz) / BATCH_SIZE))
        print('num_batches: ', num_batches)

        data = []
        for batch_idx in range(num_batches):
            start_idx = batch_idx * BATCH_SIZE
            end_idx = (batch_idx + 1) * BATCH_SIZE

            for k in range(FLAGS.n_angles):
                batch_raw, batch_data = get_batch(test_data_psets, start_idx, end_idx)

                if k == 0:
                    aug_data = batch_data
                    # aug_data = np.concatenate((provider.rotate_point_cloud_z(batch_data[:, :, 0:3]),
                    #                            batch_data[:, :, 3:]), axis=2)
                    # aug_data = np.concatenate((provider.jitter_point_cloud(aug_data[:, :, 0:3]),
                    #                            aug_data[:, :, 3:]), axis=2)
                else:
                    ang = (1.0 * k) / (1.0 * FLAGS.n_angles) * 2 * np.pi
                    if FLAGS.extra_dims:
                        aug_data = np.concatenate((provider.rotate_point_cloud_z(batch_data[:, :, 0:3], angle=ang),
                                                   batch_data[:, :, 3:]), axis=2)
                        # aug_data = np.concatenate((provider.rotate_point_cloud_z(batch_data[:, :, 0:3]),
                        #                            batch_data[:, :, 3:]), axis=2)
                        # aug_data = np.concatenate((provider.jitter_point_cloud(aug_data[:, :, 0:3]),
                        #                            aug_data[:, :, 3:]), axis=2)
                    else:
                        aug_data = provider.rotate_point_cloud_z(batch_data)
                        aug_data = provider.jitter_point_cloud(aug_data)
                data.append((batch_raw, aug_data))

        logging.debug('Adding {} to queue'.format(file))
        input_queue.put((pset, data))
        logging.debug('Added {} to queue'.format(file))
    logging.info('Pre-processing finished')
    input_queue.put(None)
    logging.debug('Pre-processing thread finished')
Пример #6
0
def train_one_epoch(sess, ops, train_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    log_string('----')

    # Shuffle train samples
    train_idxs = np.arange(0, len(train_xyz))
    np.random.shuffle(train_idxs)
    num_batches = len(train_xyz) // BATCH_SIZE

    #     num_batches = len(trainSet) // BATCH_SIZE

    #     num_batches = 20

    total_correct = 0
    total_seen = 0
    loss_sum = 0

    for batch_idx in range(num_batches):

        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE

        batch_data, batch_label, batch_smpw, batch_feats = get_batch_wdp(
            'train', batch_idx)

        if batch_idx % (num_batches / 2) == 0:
            print('Current batch/total batch num: %d/%d' %
                  (batch_idx, num_batches))

        aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {
            ops['pointclouds_pl']: aug_data,
            ops['feature_pl']: batch_feats,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training,
        }
        summary, step, _, loss_val, pred_val, lr_val = sess.run(
            [
                ops['merged'], ops['step'], ops['train_op'], ops['loss'],
                ops['pred'], ops['learnrate']
            ],
            feed_dict=feed_dict)
        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE * NUM_POINT)
        loss_sum += loss_val

    log_string('learn rate: %f' % (lr_val))
    log_string('mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('accuracy: %f' % (total_correct / float(total_seen)))

    mloss = loss_sum / float(num_batches)
    macc = total_correct / float(total_seen)
    return mloss, macc
Пример #7
0
def eval_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = len(TEST_DATASET) / BATCH_SIZE

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]

    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----' % (EPOCH_CNT))

    labelweights = np.zeros(21)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(
            TEST_DATASET, test_idxs, start_idx, end_idx)

        aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {
            ops['pointclouds_pl']: aug_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training
        }
        summary, step, loss_val, pred_val = sess.run(
            [ops['merged'], ops['step'], ops['loss'], ops['pred']],
            feed_dict=feed_dict)
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)  # BxN
        correct = np.sum(
            (pred_val == batch_label) &
            (batch_smpw > 0))  # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_smpw > 0))
        loss_sum += loss_val
        tmp, _ = np.histogram(batch_label, range(22))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label == l)
                                          & (batch_smpw > 0))
            total_correct_class[l] += np.sum((pred_val == l)
                                             & (batch_label == l)
                                             & (batch_smpw > 0))

    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))

    log_string('eval point accuracy: %f' % (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(
        np.array(total_correct_class[0:]) /
        (np.array(total_seen_class[0:], dtype=np.float) + 1e-6))))

    EPOCH_CNT += 1
    return total_correct / float(total_seen)
Пример #8
0
def train_one_epoch(sess, ops, train_writer, epoch=None):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = int(len(TRAIN_DATASET) / BATCH_SIZE)

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_iou_deno = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        #batch_data, batch_label, batch_smpw = get_batch_wdp(TRAIN_DATASET, train_idxs, start_idx, end_idx)
        batch_data, batch_label, batch_smpw = get_batch(
            TRAIN_DATASET, train_idxs, start_idx, end_idx)
        # Augment batched point clouds by rotation
        batch_data[:, :, :3] = provider.rotate_point_cloud_z(
            batch_data[:, :, :3])
        #aug_data = provider.rotate_point_cloud(batch_data)

        feed_dict = {
            ops['pointclouds_pl']: batch_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training,
        }

        summary, step, _, loss_val, pred_val = sess.run([
            ops['merged'], ops['step'], ops['train_op'], ops['loss'],
            ops['pred']
        ],
                                                        feed_dict=feed_dict)

        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE * NUM_POINT)
        iou_deno = 0
        for l in range(NUM_CLASSES):
            iou_deno += np.sum((pred_val == l) | (batch_label == l))
        total_iou_deno += iou_deno
        loss_sum += loss_val
        if (batch_idx + 1) % 10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx + 1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            log_string('total IoU: %f' %
                       (total_correct / float(total_iou_deno)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
            total_iou_deno = 0
Пример #9
0
def pre_processor(files, input_queue):
    for file in files:

        logging.info('Loading {}'.format(file))
        pset = PointSet(file)
        psets = pset.split()
        num_batches = int(math.ceil((1.0 * len(psets)) / BATCH_SIZE))

        data = []
        for batch_idx in range(num_batches):
            start_idx = batch_idx * BATCH_SIZE
            end_idx = (batch_idx + 1) * BATCH_SIZE

            for k in range(FLAGS.n_angles):
                batch_raw, batch_data = get_batch(psets, start_idx, end_idx)

                if k == 0:
                    aug_data = batch_data
                else:
                    ang = (1.0 * k) / (1.0 * FLAGS.n_angles) * 2 * np.pi
                    if FLAGS.extra_dims:
                        aug_data = np.concatenate(
                            (provider.rotate_point_cloud_z(
                                batch_data[:, :, 0:3],
                                angle=ang), batch_data[:, :, 3:]),
                            axis=2)
                    else:
                        aug_data = provider.rotate_point_cloud_z(batch_data)

                data.append((batch_raw, aug_data))

        logging.debug('Adding {} to queue'.format(file))
        input_queue.put((pset, data))
        logging.debug('Added {} to queue'.format(file))
    logging.info('Pre-processing finished')
    input_queue.put(None)
    logging.debug('Pre-processing thread finished')
Пример #10
0
def train_one_epoch(sess, ops, train_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = len(TRAIN_DATASET) / BATCH_SIZE

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch_wdp(
            TRAIN_DATASET, train_idxs, start_idx, end_idx)
        # Augment batched point clouds by rotation
        aug_data = provider.rotate_point_cloud_z(batch_data)
        feed_dict = {
            ops["pointclouds_pl"]: aug_data,
            ops["labels_pl"]: batch_label,
            ops["smpws_pl"]: batch_smpw,
            ops["is_training_pl"]: is_training,
        }
        summary, step, _, loss_val, pred_val = sess.run(
            [
                ops["merged"], ops["step"], ops["train_op"], ops["loss"],
                ops["pred"]
            ],
            feed_dict=feed_dict,
        )
        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += BATCH_SIZE * NUM_POINT
        loss_sum += loss_val
        if (batch_idx + 1) % 10 == 0:
            log_string(" -- %03d / %03d --" % (batch_idx + 1, num_batches))
            log_string("mean loss: %f" % (loss_sum / 10))
            log_string("accuracy: %f" % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
Пример #11
0
def visualization(sess, ops):
    batch_data, batch_label, batch_smpw = get_batch(
        TEST_DATASET, np.arange(0, len(TEST_DATASET)), 0, BATCH_SIZE)
    aug_data = provider.rotate_point_cloud_z(batch_data)

    feed_dict = {
        ops['pointclouds_pl']: aug_data,
        ops['labels_pl']: batch_label,
        ops['smpws_pl']: batch_smpw,
        ops['is_training_pl']: False
    }
    summary, step, loss_val, pred_val = sess.run(
        [ops['merged'], ops['step'], ops['loss'], ops['pred']],
        feed_dict=feed_dict)
    pred_val = np.argmax(pred_val, 2)
    point_gt = [[] for i in range(NUM_CLASSES)]
    point_pr = [[] for i in range(NUM_CLASSES)]
    for i in range(batch_label[0].shape[0]):
        point_gt[batch_label[0, i]].append(aug_data[0, i, :])
        point_pr[pred_val[0, i]].append(aug_data[0, i, :])
    drawpc(FLAGS.suffix, point_gt, point_pr)
Пример #12
0
def train_one_epoch(sess, ops, train_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = True
    
    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = len(TRAIN_DATASET)/BATCH_SIZE
    
    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch_wdp(TRAIN_DATASET, train_idxs, start_idx, end_idx)
        # Augment batched point clouds by rotation
	aug_data = provider.rotate_point_cloud_z(batch_data)
        feed_dict = {ops['pointclouds_pl']: aug_data,
                     ops['labels_pl']: batch_label,
		     ops['smpws_pl']:batch_smpw,
                     ops['is_training_pl']: is_training,}
        summary, step, _, loss_val, pred_val = sess.run([ops['merged'], ops['step'],
            ops['train_op'], ops['loss'], ops['pred']], feed_dict=feed_dict)
        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE*NUM_POINT)
        loss_sum += loss_val
        if (batch_idx+1)%10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx+1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
Пример #13
0
    def training(self):
        with tf.Graph().as_default():
            self.build_graph()
            # merge operator (for tensorboard)
            merged = tf.summary.merge_all()
            iter_in_epoch = self.train_sz // self.batch_sz
            saver = tf.train.Saver()

            # Create a session
            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True
            config.allow_soft_placement = True
            config.log_device_placement = False
            best_acc = 0.0
            with tf.Session(config=config) as sess:
                train_writer = tf.summary.FileWriter(TRAIN_LOG_PATH,
                                                     sess.graph)
                evaluate_writer = tf.summary.FileWriter(
                    TEST_LOG_PATH, sess.graph)
                sess.run(tf.global_variables_initializer())
                epoch_sz = MAX_EPOCH
                tic = time.time()
                for epoch in range(epoch_sz):
                    ave_loss = 0
                    train_idxs = np.arange(0, self.train_data.__len__())
                    np.random.shuffle(train_idxs)
                    for _iter in range(iter_in_epoch):
                        start_idx = _iter * self.batch_sz
                        end_idx = (_iter + 1) * self.batch_sz
                        batch_data, batch_label, batch_smpw = self.get_batch_wdp(
                            self.train_data, train_idxs, start_idx, end_idx)
                        aug_data = provider.rotate_point_cloud_z(batch_data)
                        loss, _, summary, step = sess.run(
                            [self.loss, self.train_op, merged, self.batch],
                            feed_dict={
                                self.point_pl: aug_data,
                                self.label_pl: batch_label,
                                self.smpws_pl: batch_smpw,
                                self.is_train_pl: True
                            })
                        ave_loss += loss
                        train_writer.add_summary(summary, step)
                    ave_loss /= iter_in_epoch
                    #print("epoch %d , loss is %f take %.3f s" % (epoch + 1, ave_loss, time.time() - tic))
                    log_string("epoch %d , loss is %f take %.3f s" %
                               (epoch + 1, ave_loss, time.time() - tic))
                    tic = time.time()
                    if (epoch + 1) % 5 == 0:
                        acc = self.evaluate_one_epoch(sess, evaluate_writer,
                                                      step, epoch)
                        if acc > best_acc:
                            _path = saver.save(
                                sess,
                                os.path.join(
                                    SAVE_PATH,
                                    "best_seg_model_%d.ckpt" % (epoch + 1)))
                            log_string("epoch %d " % (epoch + 1))
                            #print("epoch %d, best saved in file: " % (epoch + 1), _path)
                            best_acc = acc
                _path = saver.save(
                    sess, os.path.join(SAVE_PATH, 'train_base_seg_model.ckpt'))
                print("Model saved in file: ", _path)
Пример #14
0
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu

    '''CREATE DIR'''
    timestr = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    experiment_dir = Path('./log/')
    experiment_dir.mkdir(exist_ok=True)
    experiment_dir = experiment_dir.joinpath('sem_seg')
    experiment_dir.mkdir(exist_ok=True)
    if args.log_dir is None:
        experiment_dir = experiment_dir.joinpath(timestr)
    else:
        experiment_dir = experiment_dir.joinpath(args.log_dir)
    experiment_dir.mkdir(exist_ok=True)
    checkpoints_dir = experiment_dir.joinpath('checkpoints/')
    checkpoints_dir.mkdir(exist_ok=True)
    log_dir = experiment_dir.joinpath('logs/')
    log_dir.mkdir(exist_ok=True)

    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/%s.txt' % (log_dir, args.model))
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)

    root = 'data/stanford_indoor3d/'
    NUM_CLASSES = 13
    NUM_POINT = args.npoint
    BATCH_SIZE = args.batch_size
    FEATURE_CHANNEL = 3 if args.with_rgb else 0

    print("start loading training data ...")
    TRAIN_DATASET = S3DISDataset(root, split='train', with_rgb=args.with_rgb, test_area=args.test_area, block_points=NUM_POINT)
    print("start loading whole scene validation data ...")
    TEST_DATASET_WHOLE_SCENE = S3DISDatasetWholeScene(root, split='test', with_rgb=args.with_rgb, test_area=args.test_area, block_points=NUM_POINT)
    trainDataLoader = torch.utils.data.DataLoader(TRAIN_DATASET, batch_size=BATCH_SIZE,shuffle=True, num_workers=4)
    weights = TRAIN_DATASET.labelweights
    weights = torch.Tensor(weights).cuda()

    log_string("The number of training data is: %d" % len(TRAIN_DATASET))
    log_string("The number of test data is: %d" %  len(TEST_DATASET_WHOLE_SCENE))

    '''MODEL LOADING'''
    MODEL = importlib.import_module(args.model)
    shutil.copy('models/%s.py' % args.model, str(experiment_dir))
    shutil.copy('models/pointnet_util.py', str(experiment_dir))

    classifier = MODEL.get_model(NUM_CLASSES, with_rgb=args.with_rgb).cuda()
    criterion = MODEL.get_loss().cuda()


    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv2d') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)
        elif classname.find('Linear') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)

    try:
        checkpoint = torch.load(str(experiment_dir) + '/checkpoints/best_model.pth')
        start_epoch = checkpoint['epoch']
        classifier.load_state_dict(checkpoint['model_state_dict'])
        log_string('Use pretrain model')
    except:
        log_string('No existing model, starting training from scratch...')
        start_epoch = 0
        classifier = classifier.apply(weights_init)

    if args.optimizer == 'Adam':
        optimizer = torch.optim.Adam(
            classifier.parameters(),
            lr=args.learning_rate,
            betas=(0.9, 0.999),
            eps=1e-08,
            weight_decay=args.decay_rate
        )
    else:
        optimizer = torch.optim.SGD(classifier.parameters(), lr=args.learning_rate, momentum=0.9)

    def bn_momentum_adjust(m, momentum):
        if isinstance(m, torch.nn.BatchNorm2d) or isinstance(m, torch.nn.BatchNorm1d):
            m.momentum = momentum

    LEARNING_RATE_CLIP = 1e-5
    MOMENTUM_ORIGINAL = 0.1
    MOMENTUM_DECCAY = 0.5
    MOMENTUM_DECCAY_STEP = args.step_size

    global_epoch = 0
    best_iou = 0

    for epoch in range(start_epoch,args.epoch):
        log_string('Epoch %d (%d/%s):' % (global_epoch + 1, epoch + 1, args.epoch))
        '''Adjust learning rate and BN momentum'''
        lr = max(args.learning_rate * (args.lr_decay ** (epoch // args.step_size)), LEARNING_RATE_CLIP)
        log_string('Learning rate:%f' % lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr
        mean_correct = []
        momentum = MOMENTUM_ORIGINAL * (MOMENTUM_DECCAY ** (epoch // MOMENTUM_DECCAY_STEP))
        if momentum < 0.01:
            momentum = 0.01
        print('BN momentum updated to: %f' % momentum)
        classifier = classifier.apply(lambda x: bn_momentum_adjust(x,momentum))

        '''learning one epoch'''
        for i, data in tqdm(enumerate(trainDataLoader), total=len(trainDataLoader), smoothing=0.9):
            points, target, weight = data
            points = points.data.numpy()
            points[:,:, 0:3] = provider.random_scale_point_cloud(points[:,:, 0:3])
            points[:,:, 0:3] = provider.rotate_point_cloud_z(points[:,:, 0:3])
            points = torch.Tensor(points)
            points, target = points.float().cuda(),target.long().cuda()
            points = points.transpose(2, 1)
            optimizer.zero_grad()
            classifier = classifier.train()
            seg_pred, trans_feat = classifier(points)
            seg_pred = seg_pred.contiguous().view(-1, NUM_CLASSES)
            target = target.view(-1, 1)[:, 0]
            pred_choice = seg_pred.data.max(1)[1]
            correct = pred_choice.eq(target.data).cpu().sum()
            mean_correct.append(correct.item() / (args.batch_size * args.npoint))
            loss = criterion(seg_pred, target, trans_feat, weights)
            loss.backward()
            optimizer.step()
        train_instance_acc = np.mean(mean_correct)
        log_string('Train accuracy is: %.5f' % train_instance_acc)

        # evaluate on whole scenes, for each block, only sample NUM_POINT points
        if epoch % 10 ==0:
            with torch.no_grad():
                num_batches = len(TEST_DATASET_WHOLE_SCENE)

                total_correct = 0
                total_seen = 0
                loss_sum = 0
                total_seen_class = [0 for _ in range(NUM_CLASSES)]
                total_correct_class = [0 for _ in range(NUM_CLASSES)]
                total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]

                labelweights = np.zeros(NUM_CLASSES)
                is_continue_batch = False

                extra_batch_data = np.zeros((0, NUM_POINT, 3 + FEATURE_CHANNEL))
                extra_batch_label = np.zeros((0, NUM_POINT))
                extra_batch_smpw = np.zeros((0, NUM_POINT))
                for batch_idx in tqdm(range(num_batches),total=num_batches):
                    if not is_continue_batch:
                        batch_data, batch_label, batch_smpw = TEST_DATASET_WHOLE_SCENE[batch_idx]
                        batch_data = np.concatenate((batch_data, extra_batch_data), axis=0)
                        batch_label = np.concatenate((batch_label, extra_batch_label), axis=0)
                        batch_smpw = np.concatenate((batch_smpw, extra_batch_smpw), axis=0)
                    else:
                        batch_data_tmp, batch_label_tmp, batch_smpw_tmp = TEST_DATASET_WHOLE_SCENE[batch_idx]
                        batch_data = np.concatenate((batch_data, batch_data_tmp), axis=0)
                        batch_label = np.concatenate((batch_label, batch_label_tmp), axis=0)
                        batch_smpw = np.concatenate((batch_smpw, batch_smpw_tmp), axis=0)
                    if batch_data.shape[0] < BATCH_SIZE:
                        is_continue_batch = True
                        continue
                    elif batch_data.shape[0] == BATCH_SIZE:
                        is_continue_batch = False
                        extra_batch_data = np.zeros((0, NUM_POINT, 3 + FEATURE_CHANNEL))
                        extra_batch_label = np.zeros((0, NUM_POINT))
                        extra_batch_smpw = np.zeros((0, NUM_POINT))
                    else:
                        is_continue_batch = False
                        extra_batch_data = batch_data[BATCH_SIZE:, :, :]
                        extra_batch_label = batch_label[BATCH_SIZE:, :]
                        extra_batch_smpw = batch_smpw[BATCH_SIZE:, :]
                        batch_data = batch_data[:BATCH_SIZE, :, :]
                        batch_label = batch_label[:BATCH_SIZE, :]
                        batch_smpw = batch_smpw[:BATCH_SIZE, :]

                    batch_label = torch.Tensor(batch_label)
                    batch_data = torch.Tensor(batch_data)
                    batch_data, batch_label = batch_data.float().cuda(), batch_label.long().cuda()
                    batch_data = batch_data.transpose(2, 1)
                    seg_pred, _ = classifier(batch_data)
                    seg_pred = seg_pred.contiguous()
                    batch_label = batch_label.cpu().data.numpy()
                    pred_val = seg_pred.cpu().data.max(2)[1].numpy()
                    correct = np.sum((pred_val == batch_label) & (batch_smpw > 0))
                    total_correct += correct
                    total_seen += np.sum(batch_smpw > 0)
                    tmp, _ = np.histogram(batch_label, range(NUM_CLASSES + 1))
                    labelweights += tmp
                    for l in range(NUM_CLASSES):
                        total_seen_class[l] += np.sum((batch_label == l) & (batch_smpw > 0))
                        total_correct_class[l] += np.sum((pred_val == l) & (batch_label == l) & (batch_smpw > 0))
                        total_iou_deno_class[l] += np.sum(((pred_val == l) | (batch_label == l)) & (batch_smpw > 0))

                mIoU = np.mean(np.array(total_correct_class) / (np.array(total_iou_deno_class, dtype=np.float) + 1e-6))
                log_string('eval whole scene mean loss: %f' % (loss_sum / float(num_batches)))
                log_string('eval point avg class IoU: %f' % mIoU)
                log_string('eval whole scene point accuracy: %f' % (total_correct / float(total_seen)))
                log_string('eval whole scene point avg class acc: %f' % (
                    np.mean(np.array(total_correct_class) / (np.array(total_seen_class, dtype=np.float) + 1e-6))))
                labelweights = labelweights.astype(np.float32) / np.sum(labelweights.astype(np.float32))

                iou_per_class_str = '------- IoU --------\n'
                for l in range(NUM_CLASSES):
                    iou_per_class_str += 'class %s weight: %.3f, IoU: %.3f \n' % (
                        seg_label_to_cat[l] + ' ' * (14 - len(seg_label_to_cat[l])), labelweights[l],
                        total_correct_class[l] / float(total_iou_deno_class[l]))
                log_string(iou_per_class_str)

                if (mIoU >= best_iou):
                    logger.info('Save model...')
                    savepath = str(checkpoints_dir) + '/best_model.pth'
                    log_string('Saving at %s' % savepath)
                    state = {
                        'epoch': epoch,
                        'class_avg_iou': mIoU,
                        'model_state_dict': classifier.state_dict(),
                        'optimizer_state_dict': optimizer.state_dict(),
                    }
                    torch.save(state, savepath)
                    log_string('Saving model....')

        global_epoch += 1
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu
    '''CREATE DIR'''
    timestr = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    experiment_dir = Path('./log/')
    experiment_dir.mkdir(exist_ok=True)
    experiment_dir = experiment_dir.joinpath('classification')
    experiment_dir.mkdir(exist_ok=True)
    if args.log_dir is None:
        experiment_dir = experiment_dir.joinpath(timestr)
    else:
        experiment_dir = experiment_dir.joinpath(args.log_dir)
    experiment_dir.mkdir(exist_ok=True)
    checkpoints_dir = experiment_dir.joinpath('checkpoints/')
    checkpoints_dir.mkdir(exist_ok=True)
    log_dir = experiment_dir.joinpath('logs/')
    log_dir.mkdir(exist_ok=True)
    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/%s.txt' % (log_dir, args.model))
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)
    '''DATA LOADING'''
    log_string('Load dataset ...')
    traindata_manager = Manager()
    testdata_manager = Manager()
    train_cache = traindata_manager.dict()
    test_cache = testdata_manager.dict()

    DATA_PATH = '/disk/users/sc468/no_backup/my_kitti'

    TRAIN_DATASET = MyKittiDataLoader(root=DATA_PATH,
                                      cache=train_cache,
                                      npoint=args.num_point,
                                      split='train',
                                      normal_channel=args.normal)
    TEST_DATASET = MyKittiDataLoader(root=DATA_PATH,
                                     cache=test_cache,
                                     npoint=args.num_point,
                                     split='test',
                                     normal_channel=args.normal)
    trainDataLoader = torch.utils.data.DataLoader(TRAIN_DATASET,
                                                  batch_size=args.batch_size,
                                                  shuffle=True,
                                                  num_workers=4)
    testDataLoader = torch.utils.data.DataLoader(TEST_DATASET,
                                                 batch_size=args.batch_size,
                                                 shuffle=False,
                                                 num_workers=4)
    '''MODEL LOADING'''
    num_class = 4
    MODEL = importlib.import_module(args.model)
    shutil.copy('./models/%s.py' % args.model, str(experiment_dir))
    shutil.copy('./models/pointnet_util.py', str(experiment_dir))

    classifier = MODEL.get_model(num_class, normal_channel=args.normal).cuda()
    criterion = MODEL.get_loss().cuda()

    try:
        checkpoint = torch.load(
            str(experiment_dir) + '/checkpoints/best_model.pth')
        start_epoch = checkpoint['epoch']
        classifier.load_state_dict(checkpoint['model_state_dict'])
        log_string('Use pretrain model')
    except:
        log_string('No existing model, starting training from scratch...')
        start_epoch = 0

    if args.optimizer == 'Adam':
        optimizer = torch.optim.Adam(classifier.parameters(),
                                     lr=args.learning_rate,
                                     betas=(0.9, 0.999),
                                     eps=1e-08,
                                     weight_decay=args.decay_rate)
    else:
        optimizer = torch.optim.SGD(classifier.parameters(),
                                    lr=0.01,
                                    momentum=0.9)

    scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                step_size=20,
                                                gamma=0.7)
    global_epoch = 0
    global_step = 0
    best_instance_acc = 0.0
    best_class_acc = 0.0
    mean_correct = []
    '''TRANING'''
    logger.info('Start training...')
    for epoch in range(start_epoch, args.epoch):
        log_string('Epoch %d (%d/%s):' %
                   (global_epoch + 1, epoch + 1, args.epoch))
        print("Train cache size {}".format(len(train_cache)))
        print("Test cache size {}".format(len(test_cache)))

        mean_loss = 0
        scheduler.step()
        for batch_id, data in tqdm(enumerate(trainDataLoader, 0),
                                   total=len(trainDataLoader),
                                   smoothing=0.9):
            points, target = data
            points = points.data.numpy()

            # data augmentation
            points = provider.random_point_dropout(points)
            points[:, :, 0:3] = provider.rotate_point_cloud_z(points[:, :,
                                                                     0:3])
            points[:, :, 0:3] = provider.random_scale_point_cloud(points[:, :,
                                                                         0:3])
            points[:, :, 0:3] = provider.shift_point_cloud(points[:, :, 0:3])
            points[:, :, 0:3] = provider.jitter_point_cloud(points[:, :, 0:3])
            points = torch.Tensor(points)
            target = target[:, 0]

            points = points.transpose(2, 1)
            points, target = points.cuda(), target.cuda()
            optimizer.zero_grad()

            classifier = classifier.train()
            pred, trans_feat = classifier(points)
            loss = criterion(pred, target.long(), trans_feat)
            mean_loss += loss.item()
            pred_choice = pred.data.max(1)[1]
            correct = pred_choice.eq(target.long().data).cpu().sum()
            mean_correct.append(correct.item() / float(points.size()[0]))
            loss.backward()
            optimizer.step()
            global_step += 1

        train_instance_acc = np.mean(mean_correct)
        log_string('Train Instance Accuracy: %f' % train_instance_acc)

        # tensorboard
        mean_loss /= len(trainDataLoader)
        writer_train.add_scalar('loss', mean_loss, epoch)
        writer_train.add_scalar('overall accuracy', train_instance_acc, epoch)

        with torch.no_grad():
            instance_acc, class_acc = test(epoch, classifier.eval(), criterion,
                                           testDataLoader)
            mean_class_acc = np.mean(class_acc[:, 2])

            if (instance_acc >= best_instance_acc):
                best_instance_acc = instance_acc

            if (mean_class_acc >= best_class_acc):
                best_class_acc = mean_class_acc
                best_epoch = epoch + 1

            log_string('Test Instance Accuracy: %f, Class Accuracy: %f' %
                       (instance_acc, mean_class_acc))
            log_string('Best Instance Accuracy: %f, Class Accuracy: %f' %
                       (best_instance_acc, best_class_acc))
            log_string('Each Class Accuracy:')
            log_string('Car: %f' % class_acc[0, 2])
            log_string('Cyclist: %f' % class_acc[1, 2])
            log_string('Pedestrian: %f' % class_acc[2, 2])
            log_string('DontCare: %f' % class_acc[3, 2])
            print("")

            # tensorboard
            writer_test.add_scalar('overall accuracy', instance_acc, epoch)
            writer_car_acc.add_scalar('accuracy of each class',
                                      class_acc[0, 2], epoch)
            writer_cyclist_acc.add_scalar('accuracy of each class',
                                          class_acc[1, 2], epoch)
            writer_pedestrian_acc.add_scalar('accuracy of each class',
                                             class_acc[2, 2], epoch)
            writer_dontcare_acc.add_scalar('accuracy of each class',
                                           class_acc[3, 2], epoch)

            if (mean_class_acc >= best_class_acc):
                logger.info('Save model...')
                savepath = str(checkpoints_dir) + '/best_model.pth'
                log_string('Saving at %s' % savepath)
                state = {
                    'epoch': best_epoch,
                    'instance_acc': instance_acc,
                    'class_acc': mean_class_acc,
                    'each_class_acc': class_acc[:, 2],
                    'model_state_dict': classifier.state_dict(),
                    'optimizer_state_dict': optimizer.state_dict(),
                }
                torch.save(state, savepath)
            global_epoch += 1

    logger.info('End of training...')
Пример #16
0
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu
    experiment_dir = 'log/sem_seg/' + args.log_dir
    visual_dir = experiment_dir + '/visual/'
    visual_dir = Path(visual_dir)
    visual_dir.mkdir(exist_ok=True)
    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/eval.txt' % experiment_dir)
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)

    NUM_CLASSES = 13
    WITH_RGB = args.with_rgb
    BATCH_SIZE = args.batch_size
    NUM_POINT = args.num_point

    root = 'data/stanford_indoor3d/'

    TEST_DATASET_WHOLE_SCENE = ScannetDatasetWholeScene_evaluation(
        root,
        split='test',
        with_rgb=WITH_RGB,
        test_area=args.test_area,
        block_points=NUM_POINT)
    log_string("The number of test data is: %d" %
               len(TEST_DATASET_WHOLE_SCENE))
    '''MODEL LOADING'''
    model_name = os.listdir(experiment_dir + '/logs')[0].split('.')[0]
    MODEL = importlib.import_module(model_name)
    classifier = MODEL.get_model(NUM_CLASSES, with_rgb=WITH_RGB).cuda()
    checkpoint = torch.load(
        str(experiment_dir) + '/checkpoints/best_model.pth')
    classifier.load_state_dict(checkpoint['model_state_dict'])

    with torch.no_grad():
        scene_id = TEST_DATASET_WHOLE_SCENE.file_list
        scene_id = [x[:-4] for x in scene_id]
        num_batches = len(TEST_DATASET_WHOLE_SCENE)

        total_seen_class = [0 for _ in range(NUM_CLASSES)]
        total_correct_class = [0 for _ in range(NUM_CLASSES)]
        total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]

        log_string('---- EVALUATION WHOLE SCENE----')

        for batch_idx in range(num_batches):
            print("visualize %d %s ..." % (batch_idx, scene_id[batch_idx]))
            total_seen_class_tmp = [0 for _ in range(NUM_CLASSES)]
            total_correct_class_tmp = [0 for _ in range(NUM_CLASSES)]
            total_iou_deno_class_tmp = [0 for _ in range(NUM_CLASSES)]
            if args.visual:
                fout = open(
                    os.path.join(visual_dir,
                                 scene_id[batch_idx] + '_pred.obj'), 'w')
                fout_gt = open(
                    os.path.join(visual_dir, scene_id[batch_idx] + '_gt.obj'),
                    'w')

            whole_scene_data = TEST_DATASET_WHOLE_SCENE.scene_points_list[
                batch_idx]
            whole_scene_label = TEST_DATASET_WHOLE_SCENE.semantic_labels_list[
                batch_idx]
            vote_label_pool = np.zeros(
                (whole_scene_label.shape[0], NUM_CLASSES))
            for _ in tqdm(range(args.num_votes), total=args.num_votes):
                scene_data, scene_label, scene_smpw, scene_point_index = TEST_DATASET_WHOLE_SCENE[
                    batch_idx]
                num_blocks = scene_data.shape[0]
                s_batch_num = (num_blocks + BATCH_SIZE - 1) // BATCH_SIZE
                if WITH_RGB:
                    batch_data = np.zeros((BATCH_SIZE, NUM_POINT, 6))
                else:
                    batch_data = np.zeros((BATCH_SIZE, NUM_POINT, 3))
                batch_label = np.zeros((BATCH_SIZE, NUM_POINT))
                batch_point_index = np.zeros((BATCH_SIZE, NUM_POINT))
                batch_smpw = np.zeros((BATCH_SIZE, NUM_POINT))
                for sbatch in range(s_batch_num):
                    start_idx = sbatch * BATCH_SIZE
                    end_idx = min((sbatch + 1) * BATCH_SIZE, num_blocks)
                    real_batch_size = end_idx - start_idx
                    batch_data[0:real_batch_size,
                               ...] = scene_data[start_idx:end_idx, ...]
                    batch_label[0:real_batch_size,
                                ...] = scene_label[start_idx:end_idx, ...]
                    batch_point_index[0:real_batch_size,
                                      ...] = scene_point_index[
                                          start_idx:end_idx, ...]
                    batch_smpw[0:real_batch_size,
                               ...] = scene_smpw[start_idx:end_idx, ...]

                    if WITH_RGB:
                        batch_data[:, :, 3:6] /= 1.0

                    aug_data = batch_data
                    aug_data[:, :, :3] = provider.rotate_point_cloud_z(
                        aug_data[:, :, :3])

                    aug_data = torch.Tensor(aug_data)
                    aug_data = aug_data.float().cuda()
                    aug_data = aug_data.transpose(2, 1)
                    seg_pred, _ = classifier(aug_data)
                    batch_pred_label = seg_pred.contiguous().cpu().data.max(
                        2)[1].numpy()

                    vote_label_pool = add_vote(
                        vote_label_pool, batch_point_index[0:real_batch_size,
                                                           ...],
                        batch_pred_label[0:real_batch_size, ...],
                        batch_smpw[0:real_batch_size, ...])

            pred_label = np.argmax(vote_label_pool, 1)

            for l in range(NUM_CLASSES):
                total_seen_class_tmp[l] += np.sum((whole_scene_label == l))
                total_correct_class_tmp[l] += np.sum((pred_label == l) &
                                                     (whole_scene_label == l))
                total_iou_deno_class_tmp[l] += np.sum(
                    ((pred_label == l) | (whole_scene_label == l)))
                total_seen_class[l] += total_seen_class_tmp[l]
                total_correct_class[l] += total_correct_class_tmp[l]
                total_iou_deno_class[l] += total_iou_deno_class_tmp[l]

            iou_map = np.array(total_correct_class_tmp) / (
                np.array(total_iou_deno_class_tmp, dtype=np.float) + 1e-6)
            print(iou_map)
            arr = np.array(total_seen_class_tmp)
            tmp_iou = np.mean(iou_map[arr != 0])
            log_string('Mean IoU of %s: %.4f' % (scene_id[batch_idx], tmp_iou))
            print('----------------------------')

            filename = os.path.join(visual_dir, scene_id[batch_idx] + '.txt')
            with open(filename, 'w') as pl_save:
                for i in pred_label:
                    pl_save.write(str(int(i)) + '\n')
                pl_save.close()
            for i in range(whole_scene_label.shape[0]):
                color = g_label2color[pred_label[i]]
                color_gt = g_label2color[whole_scene_label[i]]
                if args.visual:
                    fout.write(
                        'v %f %f %f %d %d %d\n' %
                        (whole_scene_data[i, 0], whole_scene_data[i, 1],
                         whole_scene_data[i, 2], color[0], color[1], color[2]))
                    fout_gt.write(
                        'v %f %f %f %d %d %d\n' %
                        (whole_scene_data[i, 0], whole_scene_data[i, 1],
                         whole_scene_data[i, 2], color_gt[0], color_gt[1],
                         color_gt[2]))
            if args.visual:
                fout.close()
                fout_gt.close()

        IoU = np.array(total_correct_class) / (
            np.array(total_iou_deno_class, dtype=np.float) + 1e-6)
        iou_per_class_str = '------- IoU --------\n'
        for l in range(NUM_CLASSES):
            iou_per_class_str += 'class %s, IoU: %.3f \n' % (
                seg_label_to_cat[l] + ' ' * (14 - len(seg_label_to_cat[l])),
                total_correct_class[l] / float(total_iou_deno_class[l]))
        log_string(iou_per_class_str)
        log_string('eval point avg class IoU: %f' % np.mean(IoU))
        log_string('eval whole scene point avg class acc: %f' % (np.mean(
            np.array(total_correct_class) /
            (np.array(total_seen_class, dtype=np.float) + 1e-6))))
        log_string('eval whole scene point accuracy: %f' %
                   (np.sum(total_correct_class) /
                    float(np.sum(total_seen_class) + 1e-6)))

        print("Done!")
Пример #17
0
def eval_one_epoch(sess, ops, num_votes=1):
    is_training = False

    num_scans = len(TEST_DATASET_WHOLE_SCENE)

    log_string(str(datetime.now()))
    log_string('----PREPARING PREDICTIONS----')

    total_correct = 0
    total_seen = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]
    total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]
    labelweights = np.zeros(NUM_CLASSES)
    full_points_names = TEST_DATASET_WHOLE_SCENE.points_name
    for batch_idx in range(num_scans):
        start = time.time()
        t_seen_class = [0 for _ in range(NUM_CLASSES)]
        t_correct_class = [0 for _ in range(NUM_CLASSES)]
        t_iou_deno_class = [0 for _ in range(NUM_CLASSES)]
        full_points_name = full_points_names[batch_idx]

        components = full_points_name.split('/')
        sequence = components[-3]
        points_name = components[-1]
        label_name = points_name.replace('bin', 'label')
        log_string("Inference sequence %s-%s [%d/%d] ..." %
                   (sequence, label_name.split('.')[0], batch_idx, num_scans))
        full_save_dir = os.path.join(SAVE_DIR, 'sequences', sequence,
                                     'predictions')
        os.makedirs(full_save_dir, exist_ok=True)
        full_label_name = os.path.join(full_save_dir, label_name)
        whole_scene_label = None

        for vote_idx in range(num_votes):
            print("Voting [%d/%d] ..." % (vote_idx + 1, num_votes))
            if DATASET == 'test':
                scene_data, scene_point_index, whole_scene_data = TEST_DATASET_WHOLE_SCENE[
                    batch_idx]
            else:
                scene_data, scene_point_index, whole_scene_data, whole_scene_label = TEST_DATASET_WHOLE_SCENE[
                    batch_idx]
            num_blocks = scene_data.shape[0]
            s_batch_num = (num_blocks + BATCH_SIZE - 1) // BATCH_SIZE
            if WITH_REMISSION:
                batch_data = np.zeros((BATCH_SIZE, NUM_POINT, 4))
            else:
                batch_data = np.zeros((BATCH_SIZE, NUM_POINT, 3))
            batch_point_index = np.zeros((BATCH_SIZE, NUM_POINT))
            for sbatch in range(s_batch_num):
                start_idx = sbatch * BATCH_SIZE
                end_idx = min((sbatch + 1) * BATCH_SIZE, num_blocks)
                real_batch_size = end_idx - start_idx
                batch_data[0:real_batch_size,
                           ...] = scene_data[start_idx:end_idx, ...]
                batch_point_index[0:real_batch_size,
                                  ...] = scene_point_index[start_idx:end_idx,
                                                           ...]

                if FLAGS.random_rotate:
                    batch_data[:, :, :3] = provider.rotate_point_cloud_z(
                        batch_data[:, :, :3])

                feed_dict = {
                    ops['pointclouds_pl']: batch_data,
                    ops['is_training_pl']: is_training
                }
                pred_val = sess.run(ops['pred'],
                                    feed_dict=feed_dict)  # BxNxNUM_CLASSES
                batch_pred_label = np.argmax(pred_val[:, :, 1:], 2) + 1  # BxN

                if sbatch == 0:
                    vote_label_pool = np.zeros(
                        (whole_scene_data.shape[0], NUM_CLASSES))

                vote_label_pool = add_vote(
                    vote_label_pool, batch_point_index[0:real_batch_size, ...],
                    batch_pred_label[0:real_batch_size, ...])

        final_preds = np.argmax(vote_label_pool, axis=1)
        final_preds = final_preds.astype(np.uint32)
        print('writing %s' % full_label_name)
        final_preds.tofile(full_label_name)
        print('Visualuze %s-%s' % (sequence, label_name.split('.')[0]))
        end = time.time()
        print('Use Time %.2f s' % (end - start))

        fout = open(
            os.path.join(DUMP_DIR, '%s_%s_pred.obj' % (sequence, label_name)),
            'w')
        if DATASET != 'test':
            fout_gt = open(
                os.path.join(DUMP_DIR,
                             '%s_%s_gt.obj' % (sequence, label_name)), 'w')
        for i in range(whole_scene_data.shape[0]):
            color = g_label2color[final_preds[i]]
            fout.write('v %f %f %f %d %d %d\n' %
                       (whole_scene_data[i, 0], whole_scene_data[i, 1],
                        whole_scene_data[i, 2], color[0], color[1], color[2]))
            if DATASET != 'test':
                color_gt = g_label2color[whole_scene_label[i]]
                fout_gt.write('v %f %f %f %d %d %d\n' %
                              (whole_scene_data[i, 0], whole_scene_data[i, 1],
                               whole_scene_data[i, 2], color_gt[0],
                               color_gt[1], color_gt[2]))
        fout.close()
        if DATASET != 'test':
            fout_gt.close()
            correct = np.sum(final_preds == whole_scene_label)
            seen = len(whole_scene_label)
            total_correct += correct
            total_seen += seen
            tmp, _ = np.histogram(whole_scene_label, range(NUM_CLASSES + 1))
            labelweights += tmp
            for l in range(NUM_CLASSES):
                tem_seen = np.sum(whole_scene_label == l)
                t_seen_class[l] += tem_seen
                total_seen_class[l] += tem_seen
                temp_correct = np.sum((final_preds == l)
                                      & (whole_scene_label == l))
                temp_iou_deno_class = np.sum((final_preds == l)
                                             | (whole_scene_label == l))
                total_correct_class[l] += temp_correct
                t_correct_class[l] += temp_correct
                total_iou_deno_class[l] += temp_iou_deno_class
                t_iou_deno_class[l] += temp_iou_deno_class
            iou = np.array(t_correct_class[1:]) / (
                np.array(t_iou_deno_class[1:], dtype=np.float) + 1e-6)
            arr = np.array(t_seen_class[1:])
            mIoU = np.mean(iou[arr != 0])
            log_string('Mean IoU of %s-%s: %.4f' %
                       (sequence, label_name.split('.')[0], mIoU))
        print('---------------------')
        if DATASET != 'test':
            if batch_idx % 10 == 0:
                mIoU = np.mean(
                    np.array(total_correct_class[1:]) /
                    (np.array(total_iou_deno_class[1:], dtype=np.float) +
                     1e-6))
                log_string('eval point avg class IoU: %f' % mIoU)
                log_string('eval whole scene point accuracy: %f' %
                           (total_correct / float(total_seen)))
                log_string(
                    'eval whole scene point avg class acc: %f' % (np.mean(
                        np.array(total_correct_class) /
                        (np.array(total_seen_class, dtype=np.float) + 1e-6))))
                labelweights = labelweights.astype(np.float32) / np.sum(
                    labelweights.astype(np.float32))

                iou_per_class_str = '------- IoU --------\n'
                for l in range(1, NUM_CLASSES):
                    iou_per_class_str += 'class %s weight: %.3f, IoU: %.3f \n' % (
                        seg_label_to_cat[l] + ' ' *
                        (14 - len(seg_label_to_cat[l])), labelweights[l - 1],
                        total_correct_class[l] /
                        float(total_iou_deno_class[l]))
                log_string(iou_per_class_str)
                print('---------------------')
    print("Done!")
Пример #18
0
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu
    '''CREATE DIR'''
    timestr = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    experiment_dir = Path('./log/')
    experiment_dir.mkdir(exist_ok=True)
    experiment_dir = experiment_dir.joinpath('sem_seg')
    experiment_dir.mkdir(exist_ok=True)
    if args.log_dir is None:
        experiment_dir = experiment_dir.joinpath(timestr)
    else:
        experiment_dir = experiment_dir.joinpath(args.log_dir)
    experiment_dir.mkdir(exist_ok=True)
    checkpoints_dir = experiment_dir.joinpath('checkpoints/')
    checkpoints_dir.mkdir(exist_ok=True)
    log_dir = experiment_dir.joinpath('logs/')
    log_dir.mkdir(exist_ok=True)
    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/%s.txt' % (log_dir, args.model))
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)

    NUM_CLASSES = len(classes)
    NUM_POINT = args.npoint
    NUM_CHANNEL = args.nchannel
    BATCH_SIZE = args.batch_size
    FOLD = args.fold
    TRAIN_DIR = os.path.join(BASE_DIR, args.train_dir)
    TEST_DIR = os.path.join(BASE_DIR, args.test_dir)

    print("start loading training data ...")
    TRAIN_DATASET = PointCloudDataset(root=TRAIN_DIR,
                                      nClasses=NUM_CLASSES,
                                      nPoints=NUM_POINT,
                                      split="train",
                                      fold=FOLD)
    trainDataLoader = torch.utils.data.DataLoader(
        TRAIN_DATASET,
        batch_size=BATCH_SIZE,
        shuffle=True,
        num_workers=4,
        pin_memory=True,
        drop_last=True,
        worker_init_fn=lambda x: np.random.seed(x + int(time.time())))
    weights = torch.Tensor(TRAIN_DATASET.labelweights).cuda()
    #weights = torch.Tensor([1/5,1/5,1/5,1/5,1/5]).cuda()
    print("start loading test data ...")
    TEST_DATASET = PointCloudDataset(root=TEST_DIR,
                                     nClasses=NUM_CLASSES,
                                     nPoints=NUM_POINT,
                                     split="test",
                                     fold=FOLD)
    testDataLoader = torch.utils.data.DataLoader(TEST_DATASET,
                                                 batch_size=BATCH_SIZE,
                                                 shuffle=False,
                                                 num_workers=4,
                                                 pin_memory=True,
                                                 drop_last=True)
    '''MODEL LOADING'''
    MODEL = importlib.import_module(args.model)
    shutil.copy(ROOT_DIR + '/models/%s.py' % args.model, str(experiment_dir))
    shutil.copy(ROOT_DIR + '/models/pointnet_util.py', str(experiment_dir))

    classifier = MODEL.get_model(num_class=NUM_CLASSES,
                                 num_point=NUM_POINT,
                                 num_channel=NUM_CHANNEL).cuda()
    criterion = MODEL.get_loss().cuda()

    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv2d') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)
        elif classname.find('Linear') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)

    try:
        checkpoint = torch.load(
            str(experiment_dir) + '/checkpoints/best_model.pth')
        start_epoch = checkpoint['epoch']
        classifier.load_state_dict(checkpoint['model_state_dict'])
        log_string('Use pretrain model')
    except:
        log_string('No existing model, starting training from scratch...')
        start_epoch = 0
        classifier = classifier.apply(weights_init)

    # TRANSFER LEARNING
    if ((args.log_dir is None) & (args.pretrained_dir is not None)):
        MODEL_PRE = importlib.import_module("pointnet2_sem_seg")
        shutil.copy(ROOT_DIR + '/models/pointnet2_sem_seg.py',
                    str(experiment_dir))
        shutil.copy(ROOT_DIR + '/models/pointnet_util.py', str(experiment_dir))
        classifier_pre = MODEL_PRE.get_model(num_class=10,
                                             num_point=512,
                                             num_channel=3)  # Paris-Lille-3D
        checkpoint = torch.load(
            str(args.pretrained_dir) + '/checkpoints/best_model.pth')
        classifier_pre.load_state_dict(checkpoint['model_state_dict'])

        classifier_dict = classifier.state_dict()
        classifier_pre_dict = classifier_pre.state_dict()

        # load from pretrained_dict all the layer parameters except for the output layers (conv1, bn1, conv2)
        classifier_pre_dict = {
            k: v
            for k, v in classifier_pre_dict.items() if k in classifier_dict
        }
        for k in [
                'conv1.weight', 'conv1.bias', 'bn1.weight', 'bn1.bias',
                'bn1.running_mean', 'bn1.running_var',
                'bn1.num_batches_tracked', 'conv2.weight', 'conv2.bias'
        ]:
            classifier_pre_dict.pop(k)

        classifier_dict.update(classifier_pre_dict)

        # load classifier parameters
        classifier.load_state_dict(classifier_dict)

        # freeze core layers
        '''
		for i, child in enumerate(classifier.children()):
			if (i < 8):
				for param in child.parameters():
					param.requires_grad = False
		'''

    if args.optimizer == 'Adam':
        optimizer = torch.optim.Adam(
            filter(lambda p: p.requires_grad,
                   classifier.parameters()),  # classifier.parameters(),
            lr=args.learning_rate,
            betas=(0.9, 0.999),
            eps=1e-08,
            weight_decay=args.decay_rate)
    else:
        optimizer = torch.optim.SGD(classifier.parameters(),
                                    lr=args.learning_rate,
                                    momentum=0.9)

    def bn_momentum_adjust(m, momentum):
        if isinstance(m, torch.nn.BatchNorm2d) or isinstance(
                m, torch.nn.BatchNorm1d):
            m.momentum = momentum

    LEARNING_RATE_CLIP = 1e-5
    MOMENTUM_ORIGINAL = 0.1
    MOMENTUM_DECCAY = 0.5
    MOMENTUM_DECCAY_STEP = args.step_size

    global_epoch = 0
    best_iou = 0

    for epoch in range(start_epoch, args.epoch):

        log_string('**** Epoch %d (%d/%s) ****' %
                   (global_epoch + 1, epoch + 1, args.epoch))
        lr = max(
            args.learning_rate * (args.lr_decay**(epoch // args.step_size)),
            LEARNING_RATE_CLIP)
        log_string('Learning rate:%f' % lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr
        momentum = MOMENTUM_ORIGINAL * (MOMENTUM_DECCAY
                                        **(epoch // MOMENTUM_DECCAY_STEP))
        if momentum < 0.01:
            momentum = 0.01
        print('BN momentum updated to: %f' % momentum)
        classifier = classifier.apply(
            lambda x: bn_momentum_adjust(x, momentum))
        num_batches = len(trainDataLoader)
        total_correct = 0
        total_seen = 0
        loss_sum = 0
        '''learning one epoch'''
        for i, data in tqdm(enumerate(trainDataLoader),
                            total=len(trainDataLoader),
                            smoothing=0.9):
            points, target = data
            points = points.data.numpy()
            points[:, :, :3] = provider.rotate_point_cloud_z(points[:, :, :3])
            points = torch.Tensor(points)
            points, target = points.float().cuda(), target.long().cuda()
            points = points.transpose(2, 1)
            optimizer.zero_grad()
            classifier = classifier.train()
            seg_pred, trans_feat = classifier(points)
            seg_pred = seg_pred.contiguous().view(-1, NUM_CLASSES)
            batch_label = target.view(-1, 1)[:, 0].cpu().data.numpy()
            target = target.view(-1, 1)[:, 0]
            loss = criterion(seg_pred, target, trans_feat, weights)
            loss.backward()
            optimizer.step()
            pred_choice = seg_pred.cpu().data.max(1)[1].numpy()
            correct = np.sum(pred_choice == batch_label)
            total_correct += correct
            total_seen += (BATCH_SIZE * NUM_POINT)
            loss_sum += loss
        log_string('Training mean loss: %f' % (loss_sum / num_batches))
        log_string('Training accuracy: %f' %
                   (total_correct / float(total_seen)))

        if epoch % 5 == 0:
            logger.info('Save model...')
            savepath = str(checkpoints_dir) + '/model.pth'
            log_string('Saving at %s' % savepath)
            state = {
                'epoch': epoch,
                'model_state_dict': classifier.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
            }
            torch.save(state, savepath)
            log_string('Saving model....')

        with torch.no_grad():
            num_batches = len(testDataLoader)
            total_correct = 0
            total_seen = 0
            loss_sum = 0
            labelweights = np.zeros(NUM_CLASSES)
            total_seen_class = [0 for _ in range(NUM_CLASSES)]
            total_correct_class = [0 for _ in range(NUM_CLASSES)]
            total_predicted_class = [0 for _ in range(NUM_CLASSES)]
            total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]
            log_string('---- EPOCH %03d EVALUATION ----' % (global_epoch + 1))
            for i, data in tqdm(enumerate(testDataLoader),
                                total=len(testDataLoader),
                                smoothing=0.9):
                points, target = data
                points = points.data.numpy()
                points = torch.Tensor(points)
                points, target = points.float().cuda(), target.long().cuda()
                points = points.transpose(2, 1)
                classifier = classifier.eval()
                seg_pred, trans_feat = classifier(points)
                pred_val = seg_pred.contiguous().cpu().data.numpy()
                seg_pred = seg_pred.contiguous().view(-1, NUM_CLASSES)
                batch_label = target.cpu().data.numpy()
                target = target.view(-1, 1)[:, 0]
                loss = criterion(seg_pred, target, trans_feat, weights)
                loss_sum += loss
                pred_val = np.argmax(pred_val, 2)
                correct = np.sum((pred_val == batch_label))
                total_correct += correct
                total_seen += (BATCH_SIZE * NUM_POINT)
                tmp, _ = np.histogram(batch_label, range(NUM_CLASSES + 1))
                labelweights += tmp
                for l in range(NUM_CLASSES):
                    total_seen_class[l] += np.sum((batch_label == l))
                    total_predicted_class[l] += np.sum((pred_val == l))
                    total_correct_class[l] += np.sum((pred_val == l)
                                                     & (batch_label == l))
                    total_iou_deno_class[l] += np.sum(
                        ((pred_val == l) | (batch_label == l)))
            labelweights = labelweights.astype(np.float32) / np.sum(
                labelweights.astype(np.float32))
            mIoU = np.mean(
                np.array(total_correct_class) /
                (np.array(total_iou_deno_class, dtype=np.float) + 1e-6))
            log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
            log_string('eval point avg class IoU: %f' % (mIoU))
            log_string('eval point accuracy: %f' %
                       (total_correct / float(total_seen)))
            log_string('eval point avg class acc: %f' % (np.mean(
                np.array(total_correct_class) /
                (np.array(total_seen_class, dtype=np.float) + 1e-6))))
            iou_per_class_str = '------- IoU --------\n'
            for l in range(NUM_CLASSES):
                iou_per_class_str += 'class %s weight: %.3f, IoU: %.3f \n' % (
                    seg_label_to_cat[l] + ' ' *
                    (14 - len(seg_label_to_cat[l])), labelweights[l],
                    total_correct_class[l] / float(total_iou_deno_class[l]))

            log_string(iou_per_class_str)
            '''
			print('AIUTO\n')
			for l in range(NUM_CLASSES):
				print('class %s %.3f: seen %d, predicted %d, correct %d, union %d \n' % (seg_label_to_cat[l],labelweights[l],total_seen_class[l],total_predicted_class[l],total_correct_class[l],total_iou_deno_class[l]))
			'''
            log_string('Eval mean loss: %f' % (loss_sum / num_batches))
            log_string('Eval accuracy: %f' %
                       (total_correct / float(total_seen)))
            if mIoU >= best_iou:
                best_iou = mIoU
                logger.info('Save model...')
                savepath = str(checkpoints_dir) + '/best_model.pth'
                log_string('Saving at %s' % savepath)
                state = {
                    'epoch': epoch,
                    'class_avg_iou': mIoU,
                    'model_state_dict': classifier.state_dict(),
                    'optimizer_state_dict': optimizer.state_dict(),
                }
                torch.save(state, savepath)
                log_string('Saving model....')
            log_string('Best mIoU: %f' % best_iou)
        global_epoch += 1
Пример #19
0
def eval_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = len(TEST_DATASET)//BATCH_SIZE

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]

    total_correct_vox = 0
    total_seen_vox = 0
    total_seen_class_vox = [0 for _ in range(NUM_CLASSES)]
    total_correct_class_vox = [0 for _ in range(NUM_CLASSES)]
    
    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----'%(EPOCH_CNT))

    labelweights = np.zeros(21)
    labelweights_vox = np.zeros(21)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(TEST_DATASET, test_idxs, start_idx, end_idx)

        aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {ops['pointclouds_pl']: aug_data,
                     ops['labels_pl']: batch_label,
	  	     ops['smpws_pl']: batch_smpw,
                     ops['is_training_pl']: is_training}
        summary, step, loss_val, pred_val = sess.run([ops['merged'], ops['step'],
            ops['loss'], ops['pred']], feed_dict=feed_dict)
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2) # BxN
        correct = np.sum((pred_val == batch_label) & (batch_label>0) & (batch_smpw>0)) # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_label>0) & (batch_smpw>0))
        loss_sum += loss_val
        tmp,_ = np.histogram(batch_label,range(22))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label==l) & (batch_smpw>0))
            total_correct_class[l] += np.sum((pred_val==l) & (batch_label==l) & (batch_smpw>0))
        for b in range(batch_label.shape[0]):
            _, uvlabel, _ = pc_util.point_cloud_label_to_surface_voxel_label_fast(aug_data[b,batch_smpw[b,:]>0,:], np.concatenate((np.expand_dims(batch_label[b,batch_smpw[b,:]>0],1),np.expand_dims(pred_val[b,batch_smpw[b,:]>0],1)),axis=1), res=0.02)
            total_correct_vox += np.sum((uvlabel[:,0]==uvlabel[:,1])&(uvlabel[:,0]>0))
            total_seen_vox += np.sum(uvlabel[:,0]>0)
            tmp,_ = np.histogram(uvlabel[:,0],range(22))
            labelweights_vox += tmp
            for l in range(NUM_CLASSES):
                total_seen_class_vox[l] += np.sum(uvlabel[:,0]==l)
                total_correct_class_vox[l] += np.sum((uvlabel[:,0]==l) & (uvlabel[:,1]==l))

    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point accuracy vox: %f'% (total_correct_vox / float(total_seen_vox)))
    log_string('eval point avg class acc vox: %f' % (np.mean(np.array(total_correct_class_vox[1:])/(np.array(total_seen_class_vox[1:],dtype=np.float)+1e-6))))
    log_string('eval point accuracy: %f'% (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(np.array(total_correct_class[1:])/(np.array(total_seen_class[1:],dtype=np.float)+1e-6))))
    labelweights_vox = labelweights_vox[1:].astype(np.float32)/np.sum(labelweights_vox[1:].astype(np.float32))
    caliweights = np.array([0.388,0.357,0.038,0.033,0.017,0.02,0.016,0.025,0.002,0.002,0.002,0.007,0.006,0.022,0.004,0.0004,0.003,0.002,0.024,0.029])
    log_string('eval point calibrated average acc: %f' % (np.average(np.array(total_correct_class[1:])/(np.array(total_seen_class[1:],dtype=np.float)+1e-6),weights=caliweights)))
    per_class_str = 'vox based --------'
    for l in range(1,NUM_CLASSES):
        per_class_str += 'class %d weight: %f, acc: %f; ' % (l,labelweights_vox[l-1],total_correct_class[l]/float(total_seen_class[l]))
    log_string(per_class_str)
    EPOCH_CNT += 1
    return total_correct/float(total_seen)
Пример #20
0
def train_one_epoch(sess, ops, train_writer, copy_from_model0_op,
                    copy_to_model0_op):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = len(TRAIN_DATASET) / (BATCH_SIZE // 2)

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    batch_idx_suncg = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * (BATCH_SIZE // 2)
        end_idx = (batch_idx + 1) * (BATCH_SIZE // 2)
        while DATA_QUEUE_SUN.empty():
            pass
        temp_batch_data, batch_smpw = DATA_QUEUE_SUN.get()

        SUNCG_DATASET.check_gone(
            temp_batch_data[-1],
            batch_smpw[-1])  ## Only give 12288 points to voxel
        batch_data = []
        for i in range(len(temp_batch_data)):
            batch_data.append(np.zeros((BATCH_SIZE, NUM_POINT_MORE[i], 3)))
            batch_data[i][0:BATCH_SIZE // 2, :, :] = temp_batch_data[i]

        pred_val = []
        counter = 0
        for i in range(len(NUM_POINT)):
            for j in range(NUM_REP[i]):
                sess.run(copy_to_model0_op[i])
                feed_dict = {}
                feed_dict[ops['is_training_pl']] = False
                feed_dict[ops['data_select']] = i
                feed_dict[ops['pointclouds_pl' +
                              str(i + 1)]] = batch_data[counter]
                temp_pred_val = sess.run(ops['pred'],
                                         feed_dict=add_empty(
                                             feed_dict, i, ops))
                pred_val.append(
                    np.squeeze(
                        np.argmax(temp_pred_val[0:BATCH_SIZE // 2, ...], 2)))
                counter += 1

        ### Combine with other sources here
        batch_data_extra, batch_label_extra, batch_smpw_extra = SUNCG_DATASET.ready(
            temp_batch_data, pred_val, batch_smpw, TRAIN_DATASET.labelweights)

        while DATA_QUEUE.empty():
            pass
        batch_data, batch_label, batch_smpw = DATA_QUEUE.get()
        shuffled_data = shuffle_data([batch_data, batch_label, batch_smpw])
        batch_data, batch_label, batch_smpw = shuffled_data[0], shuffled_data[
            1], shuffled_data[2]
        shuffled_data = shuffle_data(
            [batch_data_extra, batch_label_extra, batch_smpw_extra])
        batch_data_extra, batch_label_extra, batch_smpw_extra = shuffled_data[
            0], shuffled_data[1], shuffled_data[2]
        ### Combine data
        counter = 0
        for i in range(len(NUM_POINT)):
            for j in range(NUM_REP[i]):
                if j == 0:
                    sess.run(copy_to_model0_op[i])
                    batch_data_temp = np.concatenate(
                        [batch_data[counter], batch_data_extra[counter]], 0)
                    batch_label_temp = np.concatenate(
                        [batch_label[counter], batch_label_extra[counter]], 0)
                    batch_smpw_temp = np.concatenate(
                        [batch_smpw[counter], batch_smpw_extra[counter]], 0)

                    aug_data = provider.rotate_point_cloud_z(batch_data_temp)
                    feed_dict = {
                        ops['pointclouds_pl' + str(i + 1)]: aug_data,
                        ops['labels_pl' + str(i + 1)]: batch_label_temp,
                        ops['smpws_pl' + str(i + 1)]: batch_smpw_temp,
                        ops['data_select']: i,
                        ops['is_training_pl']: is_training,
                    }
                    summary, step, _, loss_val, pred_val = sess.run(
                        [
                            ops['merged'], ops['step'], ops['train_op'],
                            ops['loss'], ops['pred']
                        ],
                        feed_dict=add_empty(feed_dict, i, ops))
                    sess.run(copy_from_model0_op[i])
                    train_writer.add_summary(summary, step)
                    pred_val = np.argmax(pred_val, 2)
                    correct = np.sum(pred_val == batch_label_temp)
                    total_correct += correct
                    total_seen += (BATCH_SIZE * NUM_POINT[i])
                    loss_sum += loss_val
                counter += 1

        if (batch_idx + 1) % 10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx + 1, num_batches))
            log_string('mean loss: %f' %
                       (loss_sum / 10.0 / float(len(NUM_POINT))))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
Пример #21
0
def eval_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = len(TEST_DATASET)/BATCH_SIZE

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]

    total_correct_vox = 0
    total_seen_vox = 0
    total_seen_class_vox = [0 for _ in range(NUM_CLASSES)]
    total_correct_class_vox = [0 for _ in range(NUM_CLASSES)]
    
    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----'%(EPOCH_CNT))

    labelweights = np.zeros(21)
    labelweights_vox = np.zeros(21)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(TEST_DATASET, test_idxs, start_idx, end_idx)

	aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {ops['pointclouds_pl']: aug_data,
                     ops['labels_pl']: batch_label,
	  	     ops['smpws_pl']: batch_smpw,
                     ops['is_training_pl']: is_training}
        summary, step, loss_val, pred_val = sess.run([ops['merged'], ops['step'],
            ops['loss'], ops['pred']], feed_dict=feed_dict)
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2) # BxN
        correct = np.sum((pred_val == batch_label) & (batch_label>0) & (batch_smpw>0)) # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_label>0) & (batch_smpw>0))
        loss_sum += loss_val
	tmp,_ = np.histogram(batch_label,range(22))
	labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label==l) & (batch_smpw>0))
            total_correct_class[l] += np.sum((pred_val==l) & (batch_label==l) & (batch_smpw>0))

	for b in xrange(batch_label.shape[0]):
	    _, uvlabel, _ = pc_util.point_cloud_label_to_surface_voxel_label_fast(aug_data[b,batch_smpw[b,:]>0,:], np.concatenate((np.expand_dims(batch_label[b,batch_smpw[b,:]>0],1),np.expand_dims(pred_val[b,batch_smpw[b,:]>0],1)),axis=1), res=0.02)
	    total_correct_vox += np.sum((uvlabel[:,0]==uvlabel[:,1])&(uvlabel[:,0]>0))
            total_seen_vox += np.sum(uvlabel[:,0]>0)
	    tmp,_ = np.histogram(uvlabel[:,0],range(22))
	    labelweights_vox += tmp
	    for l in range(NUM_CLASSES):
                total_seen_class_vox[l] += np.sum(uvlabel[:,0]==l)
                total_correct_class_vox[l] += np.sum((uvlabel[:,0]==l) & (uvlabel[:,1]==l))

    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point accuracy vox: %f'% (total_correct_vox / float(total_seen_vox)))
    log_string('eval point avg class acc vox: %f' % (np.mean(np.array(total_correct_class_vox[1:])/(np.array(total_seen_class_vox[1:],dtype=np.float)+1e-6))))
    log_string('eval point accuracy: %f'% (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(np.array(total_correct_class[1:])/(np.array(total_seen_class[1:],dtype=np.float)+1e-6))))
    labelweights_vox = labelweights_vox[1:].astype(np.float32)/np.sum(labelweights_vox[1:].astype(np.float32))
    caliweights = np.array([0.388,0.357,0.038,0.033,0.017,0.02,0.016,0.025,0.002,0.002,0.002,0.007,0.006,0.022,0.004,0.0004,0.003,0.002,0.024,0.029])
    log_string('eval point calibrated average acc: %f' % (np.average(np.array(total_correct_class[1:])/(np.array(total_seen_class[1:],dtype=np.float)+1e-6),weights=caliweights)))
    per_class_str = 'vox based --------'
    for l in range(1,NUM_CLASSES):
	per_class_str += 'class %d weight: %f, acc: %f; ' % (l,labelweights_vox[l-1],total_correct_class[l]/float(total_seen_class[l]))
    log_string(per_class_str)
    EPOCH_CNT += 1
    return total_correct/float(total_seen)
Пример #22
0
def eval_all_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(test_data))
    num_batches = int(test_idxs.shape[0] / BATCH_SIZE)
    #test_idxs = np.arange(0, len(TEST_DATASET))
    #current_data = test_data[:,0:NUM_POINT,:]
    #current_label = np.squeeze(test_label)
    #num_batches = int(current_data.shape[0]/BATCH_SIZE)

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]
    total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]

    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d ALL EVALUATION ----' % (EPOCH_CNT))

    labelweights = np.zeros(13)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        #batch_data, batch_label, batch_smpw = get_batch(TEST_DATASET, test_idxs, start_idx, end_idx)
        #batch_data = current_data[start_idx:end_idx,...]
        #batch_label = current_label[start_idx:end_idx,...]
        batch_data, batch_label, _ = my_get_batch(test_data, test_label,
                                                  test_idxs, start_idx,
                                                  end_idx)
        #batch_smpw = np.ones(batch_label.shape)
        batch_smpw = (batch_data[:, :, 0] >= -0.25) & (
            batch_data[:, :, 0] <= 0.25) & (batch_data[:, :, 1] >= -0.25) & (
                batch_data[:, :, 1] <= 0.25)
        batch_smpw = batch_smpw.astype(np.float32)

        batch_data[:, :, :3] = provider.rotate_point_cloud_z(
            batch_data[:, :, :3])
        #aug_data = provider.rotate_point_cloud(batch_data)
        bandwidth = BANDWIDTH

        feed_dict = {
            ops['pointclouds_pl']: batch_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training
        }
        summary, step, loss_val, pred_val, boundary_loss = sess.run(
            [
                ops['merged'], ops['step'], ops['loss'], ops['pred'],
                ops['boundary_loss']
            ],
            feed_dict=feed_dict)

        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)  # BxN
        correct = np.sum(
            (pred_val == batch_label) &
            (batch_smpw > 0))  # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_smpw > 0))
        loss_sum += loss_val
        tmp, _ = np.histogram(batch_label, range(14))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label == l)
                                          & (batch_smpw > 0))
            total_correct_class[l] += np.sum((pred_val == l)
                                             & (batch_label == l)
                                             & (batch_smpw > 0))
            total_iou_deno_class[l] += np.sum((
                (pred_val == l) | (batch_label == l)) & (batch_smpw > 0))

    mIoU = np.mean(
        np.array(total_correct_class[:]) /
        (np.array(total_iou_deno_class[:], dtype=np.float) + 1e-8))
    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point avg class IoU: %f' % (mIoU))
    log_string('eval point accuracy: %f' % (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(
        np.array(total_correct_class[:]) /
        (np.array(total_seen_class[:], dtype=np.float) + 1e-8))))
    iou_per_class_str = '------- IoU --------\n'
    for l in range(NUM_CLASSES):
        iou_per_class_str += 'class %d, acc: %f \n' % (
            l, total_correct_class[l] / float(total_iou_deno_class[l]))
    log_string(iou_per_class_str)
    EPOCH_CNT += 1
    return mIoU
Пример #23
0
def eval_one_epoch(sess, ops, test_writer):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = int(len(TEST_DATASET)/BATCH_SIZE)

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]
    total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]

    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----' % (EPOCH_CNT))

    labelweights = np.zeros(NUM_CLASSES)
    for batch_idx in tqdm(range(num_batches),total=num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx+1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(TEST_DATASET, test_idxs, start_idx, end_idx)

        batch_data[:, :, :3] = provider.rotate_point_cloud_z(batch_data[:, :, :3])

        feed_dict = {ops['pointclouds_pl']: batch_data,
                     ops['labels_pl']: batch_label,
                     ops['smpws_pl']: batch_smpw,
                     ops['is_training_pl']: is_training}
        summary, step, loss_val, pred_val = sess.run([ops['merged'], ops['step'],
                                                      ops['loss'], ops['pred']], feed_dict=feed_dict)
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)  # BxN
        correct = np.sum((pred_val == batch_label) & (batch_label > 0) & (
            batch_smpw > 0))  # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_label > 0) & (batch_smpw > 0))
        loss_sum += loss_val
        tmp, _ = np.histogram(batch_label, range(NUM_CLASSES + 1))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label == l)& (batch_smpw > 0))
            total_correct_class[l] += np.sum((pred_val == l)& (batch_label == l) & (batch_smpw > 0))
            total_iou_deno_class[l] += np.sum(((pred_val == l) | (batch_label == l)) & (batch_smpw > 0))
    labelweights = labelweights[1:].astype(
        np.float32)/np.sum(labelweights[1:].astype(np.float32))
    mIoU = np.mean(np.array(
        total_correct_class[1:])/(np.array(total_iou_deno_class[1:], dtype=np.float)+1e-6))
    log_string('Eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('Eval point avg class IoU: %f' % (mIoU))
    log_string('Eval point accuracy: %f' % (total_correct / float(total_seen)))
    log_string('Eval point avg class acc: %f' % (np.mean(np.array(
        total_correct_class[1:])/(np.array(total_seen_class[1:], dtype=np.float)+1e-6))))
    iou_per_class_str = '------- IoU --------\n'
    for l in range(1, NUM_CLASSES):
        iou_per_class_str += 'class %s weight: %.3f, IoU: %.3f \n' % (seg_label_to_cat[l]+' '*(14-len(
            seg_label_to_cat[l])), labelweights[l-1], total_correct_class[l] / float(total_iou_deno_class[l]))

    log_string(iou_per_class_str)
    EPOCH_CNT += 1

    return mIoU
Пример #24
0
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu
    '''CREATE DIR'''
    timestr = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    experiment_dir = Path('./log/')
    experiment_dir.mkdir(exist_ok=True)
    experiment_dir = experiment_dir.joinpath('sem_seg')
    experiment_dir.mkdir(exist_ok=True)
    if args.log_dir is None:
        experiment_dir = experiment_dir.joinpath(timestr)
    else:
        experiment_dir = experiment_dir.joinpath(args.log_dir)
    experiment_dir.mkdir(exist_ok=True)
    checkpoints_dir = experiment_dir.joinpath('checkpoints/')
    checkpoints_dir.mkdir(exist_ok=True)
    log_dir = experiment_dir.joinpath('logs/')
    log_dir.mkdir(exist_ok=True)
    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/%s.txt' % (log_dir, args.model))
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)

    root = 'data/s3dis/stanford_indoor3d/'
    NUM_CLASSES = 13
    NUM_POINT = args.npoint
    BATCH_SIZE = args.batch_size

    print("start loading training data ...")
    TRAIN_DATASET = S3DISDataset(split='train',
                                 data_root=root,
                                 num_point=NUM_POINT,
                                 test_area=args.test_area,
                                 block_size=1.0,
                                 sample_rate=1.0,
                                 transform=None)
    print("start loading test data ...")
    TEST_DATASET = S3DISDataset(split='test',
                                data_root=root,
                                num_point=NUM_POINT,
                                test_area=args.test_area,
                                block_size=1.0,
                                sample_rate=1.0,
                                transform=None)

    trainDataLoader = torch.utils.data.DataLoader(
        TRAIN_DATASET,
        batch_size=BATCH_SIZE,
        shuffle=True,
        num_workers=10,
        pin_memory=True,
        drop_last=True,
        worker_init_fn=lambda x: np.random.seed(x + int(time.time())))
    testDataLoader = torch.utils.data.DataLoader(TEST_DATASET,
                                                 batch_size=BATCH_SIZE,
                                                 shuffle=False,
                                                 num_workers=10,
                                                 pin_memory=True,
                                                 drop_last=True)
    weights = torch.Tensor(TRAIN_DATASET.labelweights).cuda()

    log_string("The number of training data is: %d" % len(TRAIN_DATASET))
    log_string("The number of test data is: %d" % len(TEST_DATASET))
    '''MODEL LOADING'''
    MODEL = importlib.import_module(args.model)
    shutil.copy('models/%s.py' % args.model, str(experiment_dir))
    shutil.copy('models/pointnet2_utils.py', str(experiment_dir))

    classifier = MODEL.get_model(NUM_CLASSES).cuda()
    criterion = MODEL.get_loss().cuda()
    classifier.apply(inplace_relu)

    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv2d') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)
        elif classname.find('Linear') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)

    try:
        checkpoint = torch.load(
            str(experiment_dir) + '/checkpoints/best_model.pth')
        start_epoch = checkpoint['epoch']
        classifier.load_state_dict(checkpoint['model_state_dict'])
        log_string('Use pretrain model')
    except:
        log_string('No existing model, starting training from scratch...')
        start_epoch = 0
        classifier = classifier.apply(weights_init)

    if args.optimizer == 'Adam':
        optimizer = torch.optim.Adam(classifier.parameters(),
                                     lr=args.learning_rate,
                                     betas=(0.9, 0.999),
                                     eps=1e-08,
                                     weight_decay=args.decay_rate)
    else:
        optimizer = torch.optim.SGD(classifier.parameters(),
                                    lr=args.learning_rate,
                                    momentum=0.9)

    def bn_momentum_adjust(m, momentum):
        if isinstance(m, torch.nn.BatchNorm2d) or isinstance(
                m, torch.nn.BatchNorm1d):
            m.momentum = momentum

    LEARNING_RATE_CLIP = 1e-5
    MOMENTUM_ORIGINAL = 0.1
    MOMENTUM_DECCAY = 0.5
    MOMENTUM_DECCAY_STEP = args.step_size

    global_epoch = 0
    best_iou = 0

    for epoch in range(start_epoch, args.epoch):
        '''Train on chopped scenes'''
        log_string('**** Epoch %d (%d/%s) ****' %
                   (global_epoch + 1, epoch + 1, args.epoch))
        lr = max(
            args.learning_rate * (args.lr_decay**(epoch // args.step_size)),
            LEARNING_RATE_CLIP)
        log_string('Learning rate:%f' % lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr
        momentum = MOMENTUM_ORIGINAL * (MOMENTUM_DECCAY
                                        **(epoch // MOMENTUM_DECCAY_STEP))
        if momentum < 0.01:
            momentum = 0.01
        print('BN momentum updated to: %f' % momentum)
        classifier = classifier.apply(
            lambda x: bn_momentum_adjust(x, momentum))
        num_batches = len(trainDataLoader)
        total_correct = 0
        total_seen = 0
        loss_sum = 0
        classifier = classifier.train()

        for i, (points, target) in tqdm(enumerate(trainDataLoader),
                                        total=len(trainDataLoader),
                                        smoothing=0.9):
            optimizer.zero_grad()

            points = points.data.numpy()
            points[:, :, :3] = provider.rotate_point_cloud_z(points[:, :, :3])
            points = torch.Tensor(points)
            points, target = points.float().cuda(), target.long().cuda()
            points = points.transpose(2, 1)

            seg_pred, trans_feat = classifier(points)
            seg_pred = seg_pred.contiguous().view(-1, NUM_CLASSES)

            batch_label = target.view(-1, 1)[:, 0].cpu().data.numpy()
            target = target.view(-1, 1)[:, 0]
            loss = criterion(seg_pred, target, trans_feat, weights)
            loss.backward()
            optimizer.step()

            pred_choice = seg_pred.cpu().data.max(1)[1].numpy()
            correct = np.sum(pred_choice == batch_label)
            total_correct += correct
            total_seen += (BATCH_SIZE * NUM_POINT)
            loss_sum += loss
        log_string('Training mean loss: %f' % (loss_sum / num_batches))
        log_string('Training accuracy: %f' %
                   (total_correct / float(total_seen)))

        if epoch % 5 == 0:
            logger.info('Save model...')
            savepath = str(checkpoints_dir) + '/model.pth'
            log_string('Saving at %s' % savepath)
            state = {
                'epoch': epoch,
                'model_state_dict': classifier.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
            }
            torch.save(state, savepath)
            log_string('Saving model....')
        '''Evaluate on chopped scenes'''
        with torch.no_grad():
            num_batches = len(testDataLoader)
            total_correct = 0
            total_seen = 0
            loss_sum = 0
            labelweights = np.zeros(NUM_CLASSES)
            total_seen_class = [0 for _ in range(NUM_CLASSES)]
            total_correct_class = [0 for _ in range(NUM_CLASSES)]
            total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]
            classifier = classifier.eval()

            log_string('---- EPOCH %03d EVALUATION ----' % (global_epoch + 1))
            for i, (points, target) in tqdm(enumerate(testDataLoader),
                                            total=len(testDataLoader),
                                            smoothing=0.9):
                points = points.data.numpy()
                points = torch.Tensor(points)
                points, target = points.float().cuda(), target.long().cuda()
                points = points.transpose(2, 1)

                seg_pred, trans_feat = classifier(points)
                pred_val = seg_pred.contiguous().cpu().data.numpy()
                seg_pred = seg_pred.contiguous().view(-1, NUM_CLASSES)

                batch_label = target.cpu().data.numpy()
                target = target.view(-1, 1)[:, 0]
                loss = criterion(seg_pred, target, trans_feat, weights)
                loss_sum += loss
                pred_val = np.argmax(pred_val, 2)
                correct = np.sum((pred_val == batch_label))
                total_correct += correct
                total_seen += (BATCH_SIZE * NUM_POINT)
                tmp, _ = np.histogram(batch_label, range(NUM_CLASSES + 1))
                labelweights += tmp

                for l in range(NUM_CLASSES):
                    total_seen_class[l] += np.sum((batch_label == l))
                    total_correct_class[l] += np.sum((pred_val == l)
                                                     & (batch_label == l))
                    total_iou_deno_class[l] += np.sum(
                        ((pred_val == l) | (batch_label == l)))

            labelweights = labelweights.astype(np.float32) / np.sum(
                labelweights.astype(np.float32))
            mIoU = np.mean(
                np.array(total_correct_class) /
                (np.array(total_iou_deno_class, dtype=np.float) + 1e-6))
            log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
            log_string('eval point avg class IoU: %f' % (mIoU))
            log_string('eval point accuracy: %f' %
                       (total_correct / float(total_seen)))
            log_string('eval point avg class acc: %f' % (np.mean(
                np.array(total_correct_class) /
                (np.array(total_seen_class, dtype=np.float) + 1e-6))))

            iou_per_class_str = '------- IoU --------\n'
            for l in range(NUM_CLASSES):
                iou_per_class_str += 'class %s weight: %.3f, IoU: %.3f \n' % (
                    seg_label_to_cat[l] + ' ' *
                    (14 - len(seg_label_to_cat[l])), labelweights[l - 1],
                    total_correct_class[l] / float(total_iou_deno_class[l]))

            log_string(iou_per_class_str)
            log_string('Eval mean loss: %f' % (loss_sum / num_batches))
            log_string('Eval accuracy: %f' %
                       (total_correct / float(total_seen)))

            if mIoU >= best_iou:
                best_iou = mIoU
                logger.info('Save model...')
                savepath = str(checkpoints_dir) + '/best_model.pth'
                log_string('Saving at %s' % savepath)
                state = {
                    'epoch': epoch,
                    'class_avg_iou': mIoU,
                    'model_state_dict': classifier.state_dict(),
                    'optimizer_state_dict': optimizer.state_dict(),
                }
                torch.save(state, savepath)
                log_string('Saving model....')
            log_string('Best mIoU: %f' % best_iou)
        global_epoch += 1
Пример #25
0
def train_one_epoch(sess, ops, train_writer, epoch=None):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    #current_data, current_label, _ = provider.shuffle_data(train_data[:,0:NUM_POINT,:], train_label)
    #current_data = current_data[:2*num_test_data,...]
    #current_label = current_label[:2*num_test_data,...]
    train_idxs = np.arange(0, len(train_data))
    np.random.shuffle(train_idxs)
    train_idxs = train_idxs[:2 * num_test_data]
    # Shuffle train samples
    #train_idxs = np.arange(0, len(TRAIN_DATASET))
    #train_idxs = np.arange(0, train_data.shape[0])
    #np.random.shuffle(train_idxs)
    #num_batches = int(current_data.shape[0]/BATCH_SIZE)
    num_batches = int(train_idxs.shape[0] / BATCH_SIZE)

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_iou_deno = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        #batch_data, batch_label, batch_smpw = get_batch_wdp(TRAIN_DATASET, train_idxs, start_idx, end_idx)
        #batch_data, batch_label, batch_smpw = get_batch(train_data, train_idxs, start_idx, end_idx)
        #batch_data = current_data[start_idx:end_idx,...]
        #batch_label = current_label[start_idx:end_idx,...]
        batch_data, batch_label, batch_smpw_tmp = my_get_batch(
            train_data, train_label, train_idxs, start_idx, end_idx)
        #batch_smpw = np.ones(batch_label.shape)
        batch_smpw = (batch_data[:, :, 0] >= -0.25) & (
            batch_data[:, :, 0] <= 0.25) & (batch_data[:, :, 1] >= -0.25) & (
                batch_data[:, :, 1] <= 0.25)
        batch_smpw = batch_smpw.astype(np.float32)
        batch_smpw = batch_smpw * batch_smpw_tmp
        # Augment batched point clouds by rotation
        batch_data[:, :, :3] = provider.rotate_point_cloud_z(
            batch_data[:, :, :3])
        #aug_data = provider.rotate_point_cloud(batch_data)

        feed_dict = {
            ops['pointclouds_pl']: batch_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training,
        }

        summary, step, _, loss_val, pred_val = sess.run([
            ops['merged'], ops['step'], ops['train_op'], ops['loss'],
            ops['pred']
        ],
                                                        feed_dict=feed_dict)

        train_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)
        correct = np.sum(pred_val == batch_label)
        total_correct += correct
        total_seen += (BATCH_SIZE * NUM_POINT)
        iou_deno = 0
        for l in range(NUM_CLASSES):
            iou_deno += np.sum((pred_val == l) | (batch_label == l))
        total_iou_deno += iou_deno
        loss_sum += loss_val
        if (batch_idx + 1) % 10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx + 1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            log_string('total IoU: %f' %
                       (total_correct / float(total_iou_deno)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0
            total_iou_deno = 0
Пример #26
0
def main(args):
    def log_string(str):
        logger.info(str)
        print(str)

    '''HYPER PARAMETER'''
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu
    '''CREATE DIR'''
    timestr = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    experiment_dir = Path('./log/')
    experiment_dir.mkdir(exist_ok=True)
    experiment_dir = experiment_dir.joinpath('part_seg')
    experiment_dir.mkdir(exist_ok=True)
    if args.log_dir is None:
        experiment_dir = experiment_dir.joinpath(timestr)
    else:
        experiment_dir = experiment_dir.joinpath(args.log_dir)
    experiment_dir.mkdir(exist_ok=True)
    checkpoints_dir = experiment_dir.joinpath('checkpoints/')
    checkpoints_dir.mkdir(exist_ok=True)
    log_dir = experiment_dir.joinpath('logs/')
    log_dir.mkdir(exist_ok=True)
    '''LOG'''
    args = parse_args()
    logger = logging.getLogger("Model")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler = logging.FileHandler('%s/%s.txt' % (log_dir, args.model))
    file_handler.setLevel(logging.INFO)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    log_string('PARAMETER ...')
    log_string(args)

    root = 'data/plant_data/'

    TRAIN_DATASET = PartNormalDataset(root=root,
                                      npoints=args.npoint,
                                      split='trainval',
                                      normal_channel=args.normal)
    trainDataLoader = torch.utils.data.DataLoader(TRAIN_DATASET,
                                                  batch_size=args.batch_size,
                                                  shuffle=True,
                                                  num_workers=4)
    TEST_DATASET = PartNormalDataset(root=root,
                                     npoints=args.npoint,
                                     split='test',
                                     normal_channel=args.normal)
    testDataLoader = torch.utils.data.DataLoader(TEST_DATASET,
                                                 batch_size=args.batch_size,
                                                 shuffle=False,
                                                 num_workers=4)
    log_string("The number of training data is: %d" % len(TRAIN_DATASET))
    log_string("The number of test data is: %d" % len(TEST_DATASET))
    num_classes = 16
    num_part = 50
    num_part = 3
    '''MODEL LOADING'''
    MODEL = importlib.import_module(args.model)
    shutil.copy('models/%s.py' % args.model, str(experiment_dir))
    shutil.copy('models/pointnet_util.py', str(experiment_dir))

    classifier = MODEL.get_model(num_part,
                                 normal_channel=args.normal)  #.cuda()
    criterion = MODEL.get_loss().cuda()

    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv2d') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)
        elif classname.find('Linear') != -1:
            torch.nn.init.xavier_normal_(m.weight.data)
            torch.nn.init.constant_(m.bias.data, 0.0)

    # try:
    checkpoint = torch.load(
        str(experiment_dir) + '/checkpoints/best_model.pth')
    start_epoch = checkpoint['epoch']
    classifier.load_state_dict(checkpoint['model_state_dict'])
    log_string('Use pretrain model')
    num_part = 3
    seg_classes = {'plant': [0, 1, 2]}
    seg_label_to_cat = {}  # {0:Airplane, 1:Airplane, ...49:Table}
    for cat in seg_classes.keys():
        for label in seg_classes[cat]:
            seg_label_to_cat[label] = cat
    classifier.reinit_lastlayer(num_part)  # for transfer learning
    classifier = classifier.cuda()
    # except:
    #     log_string('No existing model, starting training from scratch...')
    #     start_epoch = 0
    #     classifier = classifier.apply(weights_init)

    if args.optimizer == 'Adam':
        optimizer = torch.optim.Adam(classifier.parameters(),
                                     lr=args.learning_rate,
                                     betas=(0.9, 0.999),
                                     eps=1e-08,
                                     weight_decay=args.decay_rate)
    else:
        optimizer = torch.optim.SGD(classifier.parameters(),
                                    lr=args.learning_rate,
                                    momentum=0.9)

    def bn_momentum_adjust(m, momentum):
        if isinstance(m, torch.nn.BatchNorm2d) or isinstance(
                m, torch.nn.BatchNorm1d):
            m.momentum = momentum

    LEARNING_RATE_CLIP = 1e-5
    MOMENTUM_ORIGINAL = 0.1
    MOMENTUM_DECCAY = 0.5
    MOMENTUM_DECCAY_STEP = args.step_size

    best_acc = 0
    global_epoch = 0
    best_class_avg_iou = 0
    best_inctance_avg_iou = 0

    for epoch in range(start_epoch, args.epoch):
        log_string('Epoch %d (%d/%s):' %
                   (global_epoch + 1, epoch + 1, args.epoch))
        '''Adjust learning rate and BN momentum'''
        lr = max(
            args.learning_rate * (args.lr_decay**(epoch // args.step_size)),
            LEARNING_RATE_CLIP)
        log_string('Learning rate:%f' % lr)
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr
        mean_correct = []
        momentum = MOMENTUM_ORIGINAL * (MOMENTUM_DECCAY
                                        **(epoch // MOMENTUM_DECCAY_STEP))
        if momentum < 0.01:
            momentum = 0.01
        print('BN momentum updated to: %f' % momentum)
        classifier = classifier.apply(
            lambda x: bn_momentum_adjust(x, momentum))
        '''learning one epoch'''
        for i, data in tqdm(enumerate(trainDataLoader),
                            total=len(trainDataLoader),
                            smoothing=0.9):
            points, label, target = data
            points = points.data.numpy()

            if np.random.random(1)[0] > 0.5:
                points[:, :, 0:3] = provider.shift_point_cloud(points[:, :,
                                                                      0:3])
                points[:, :, 0:3] = provider.rotate_point_cloud(
                    points[:, :, 0:3])  ## added _z
            elif np.random.random(1)[0] > 0.5:
                points[:, :, 0:3] = provider.rotate_point_cloud_z(points[:, :,
                                                                         0:3])
                # points[:,:, 0:3] = provider.random_scale_point_cloud(points[:,:, 0:3])
                points[:, :, 0:3] = provider.shift_point_cloud(points[:, :,
                                                                      0:3])
            elif np.random.random(1)[0] > 0.5:
                # points[:,:, 0:3] = provider.random_scale_point_cloud(points[:,:, 0:3])
                points[:, :, 0:3] = provider.shift_point_cloud(points[:, :,
                                                                      0:3])

            # if np.random.random(1)[0] > 0.5:
            #     if np.random.random(1)[0] > 0.5:
            #         points[:,:, 0:3] = provider.shift_point_cloud(points[:,:, 0:3])
            #     else:
            #         points[:,:, 0:3] = provider.rotate_point_cloud_z(points[:,:, 0:3]) ## added _z

            points = torch.Tensor(points)
            points, label, target = points.float().cuda(), label.long().cuda(
            ), target.long().cuda()
            points = points.transpose(2, 1)
            optimizer.zero_grad()
            classifier = classifier.train()
            seg_pred, trans_feat = classifier(
                points, to_categorical(label, num_classes))
            seg_pred = seg_pred.contiguous().view(-1, num_part)
            target = target.view(-1, 1)[:, 0]
            pred_choice = seg_pred.data.max(1)[1]
            correct = pred_choice.eq(target.data).cpu().sum()
            mean_correct.append(correct.item() /
                                (args.batch_size * args.npoint))
            loss = criterion(seg_pred, target, trans_feat)
            loss.backward()
            optimizer.step()
        train_instance_acc = np.mean(mean_correct)
        log_string('Train accuracy is: %.5f' % train_instance_acc)

        with torch.no_grad():
            test_metrics = {}
            total_correct = 0
            total_seen = 0
            total_seen_class = [0 for _ in range(num_part)]
            total_correct_class = [0 for _ in range(num_part)]
            shape_ious = {cat: [] for cat in seg_classes.keys()}
            seg_label_to_cat = {}  # {0:Airplane, 1:Airplane, ...49:Table}
            for cat in seg_classes.keys():
                for label in seg_classes[cat]:
                    seg_label_to_cat[label] = cat

            for batch_id, (points, label,
                           target) in tqdm(enumerate(testDataLoader),
                                           total=len(testDataLoader),
                                           smoothing=0.9):
                cur_batch_size, NUM_POINT, _ = points.size()
                points, label, target = points.float().cuda(), label.long(
                ).cuda(), target.long().cuda()
                points = points.transpose(2, 1)
                classifier = classifier.eval()
                seg_pred, _ = classifier(points,
                                         to_categorical(label, num_classes))
                cur_pred_val = seg_pred.cpu().data.numpy()
                cur_pred_val_logits = cur_pred_val
                cur_pred_val = np.zeros(
                    (cur_batch_size, NUM_POINT)).astype(np.int32)
                target = target.cpu().data.numpy()
                for i in range(cur_batch_size):
                    cat = seg_label_to_cat[target[i, 0]]
                    logits = cur_pred_val_logits[i, :, :]
                    cur_pred_val[i, :] = np.argmax(logits[:, seg_classes[cat]],
                                                   1) + seg_classes[cat][0]
                correct = np.sum(cur_pred_val == target)
                total_correct += correct
                total_seen += (cur_batch_size * NUM_POINT)

                for l in range(num_part):
                    total_seen_class[l] += np.sum(target == l)
                    total_correct_class[l] += (np.sum((cur_pred_val == l)
                                                      & (target == l)))

                for i in range(cur_batch_size):
                    segp = cur_pred_val[i, :]
                    segl = target[i, :]
                    cat = seg_label_to_cat[segl[0]]
                    part_ious = [0.0 for _ in range(len(seg_classes[cat]))]
                    for l in seg_classes[cat]:
                        if (np.sum(segl == l) == 0) and (
                                np.sum(segp == l) == 0
                        ):  # part is not present, no prediction as well
                            part_ious[l - seg_classes[cat][0]] = 1.0
                        else:
                            part_ious[l - seg_classes[cat][0]] = np.sum(
                                (segl == l) & (segp == l)) / float(
                                    np.sum((segl == l) | (segp == l)))
                    shape_ious[cat].append(np.mean(part_ious))

            all_shape_ious = []
            for cat in shape_ious.keys():
                for iou in shape_ious[cat]:
                    all_shape_ious.append(iou)
                shape_ious[cat] = np.mean(shape_ious[cat])
            mean_shape_ious = np.mean(list(shape_ious.values()))
            test_metrics['accuracy'] = total_correct / float(total_seen)
            test_metrics['class_avg_accuracy'] = np.mean(
                np.array(total_correct_class) /
                np.array(total_seen_class, dtype=np.float))
            for cat in sorted(shape_ious.keys()):
                log_string('eval mIoU of %s %f' %
                           (cat + ' ' * (14 - len(cat)), shape_ious[cat]))
            test_metrics['class_avg_iou'] = mean_shape_ious
            test_metrics['inctance_avg_iou'] = np.mean(all_shape_ious)

        log_string(
            'Epoch %d test Accuracy: %f  Class avg mIOU: %f   Inctance avg mIOU: %f'
            %
            (epoch + 1, test_metrics['accuracy'],
             test_metrics['class_avg_iou'], test_metrics['inctance_avg_iou']))
        if (test_metrics['inctance_avg_iou'] >= best_inctance_avg_iou):
            logger.info('Save model...')
            savepath = str(checkpoints_dir) + '/best_model.pth'
            log_string('Saving at %s' % savepath)
            state = {
                'epoch': epoch,
                'train_acc': train_instance_acc,
                'test_acc': test_metrics['accuracy'],
                'class_avg_iou': test_metrics['class_avg_iou'],
                'inctance_avg_iou': test_metrics['inctance_avg_iou'],
                'model_state_dict': classifier.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
            }
            torch.save(state, savepath)
            log_string('Saving model....')

        if test_metrics['accuracy'] > best_acc:
            best_acc = test_metrics['accuracy']
        if test_metrics['class_avg_iou'] > best_class_avg_iou:
            best_class_avg_iou = test_metrics['class_avg_iou']
        if test_metrics['inctance_avg_iou'] > best_inctance_avg_iou:
            best_inctance_avg_iou = test_metrics['inctance_avg_iou']
        log_string('Best accuracy is: %.5f' % best_acc)
        log_string('Best class avg mIOU is: %.5f' % best_class_avg_iou)
        log_string('Best inctance avg mIOU is: %.5f' % best_inctance_avg_iou)
        global_epoch += 1
Пример #27
0
def eval_one_epoch(sess, ops, test_writer, out_filename):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = int(len(TEST_DATASET) / BATCH_SIZE)

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]

    total_correct_vox = 0
    total_seen_vox = 0
    total_seen_class_vox = [0 for _ in range(NUM_CLASSES)]
    total_correct_class_vox = [0 for _ in range(NUM_CLASSES)]

    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----' % (EPOCH_CNT))

    labelweights = np.zeros(21)
    labelweights_vox = np.zeros(21)
    #predlabels = np.zeros(num_batches*BATCH_SIZE)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(
            TEST_DATASET, test_idxs, start_idx, end_idx)

        aug_data = provider.rotate_point_cloud_z(batch_data)

        feed_dict = {
            ops['pointclouds_pl']: aug_data,
            ops['labels_pl']: batch_label,
            ops['smpws_pl']: batch_smpw,
            ops['is_training_pl']: is_training
        }
        summary, step, loss_val, pred_val = sess.run(
            [ops['merged'], ops['step'], ops['loss'], ops['pred']],
            feed_dict=feed_dict)
        #print(pred_val)
        #predlabels[batch_idx] = pred_val
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)  # BxN

        #print(pred_val) #predval is all labels for one image
        #print(pred_val.shape)
        #print(batch_label)
        #print(batch_label.shape)
        fname = out_filename + str(batch_idx) + "_pred.txt"
        gt_fname = out_filename + str(batch_idx) + "_gt.txt"
        fout = open(fname, 'w')
        gtfout = open(gt_fname, 'w')
        for i in range(NUM_POINT):
            color = label2color[pred_val[0, i]]
            gtcolor = label2color[batch_label[0, i]]
            fout.write('%f %f %f %d %d %d\n' %
                       (batch_data[0, i, 0], batch_data[0, i, 1],
                        batch_data[0, i, 2], color[0], color[1], color[2]))
            gtfout.write(
                '%f %f %f %d %d %d\n' %
                (batch_data[0, i, 0], batch_data[0, i, 1], batch_data[0, i, 2],
                 gtcolor[0], gtcolor[1], gtcolor[2]))
        #writes ground truth and prediction files by converting each class label into a unique color.

        correct = np.sum(
            (pred_val == batch_label) & (batch_label > 0) &
            (batch_smpw > 0))  # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_label > 0) & (batch_smpw > 0))
        loss_sum += loss_val
        tmp, _ = np.histogram(batch_label, range(22))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label == l)
                                          & (batch_smpw > 0))
            total_correct_class[l] += np.sum((pred_val == l)
                                             & (batch_label == l)
                                             & (batch_smpw > 0))

        for b in xrange(batch_label.shape[0]):
            _, uvlabel, _ = pc_util.point_cloud_label_to_surface_voxel_label_fast(
                aug_data[b, batch_smpw[b, :] > 0, :],
                np.concatenate(
                    (np.expand_dims(batch_label[b, batch_smpw[b, :] > 0], 1),
                     np.expand_dims(pred_val[b, batch_smpw[b, :] > 0], 1)),
                    axis=1),
                res=0.02)
            total_correct_vox += np.sum((uvlabel[:, 0] == uvlabel[:, 1])
                                        & (uvlabel[:, 0] > 0))
            total_seen_vox += np.sum(uvlabel[:, 0] > 0)
            tmp, _ = np.histogram(uvlabel[:, 0], range(22))
            labelweights_vox += tmp
            for l in range(NUM_CLASSES):
                total_seen_class_vox[l] += np.sum(uvlabel[:, 0] == l)
                total_correct_class_vox[l] += np.sum((uvlabel[:, 0] == l)
                                                     & (uvlabel[:, 1] == l))

    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point accuracy vox: %f' %
               (total_correct_vox / float(total_seen_vox)))
    log_string('eval point avg class acc vox: %f' % (np.mean(
        np.array(total_correct_class_vox[1:]) /
        (np.array(total_seen_class_vox[1:], dtype=np.float) + 1e-6))))
    log_string('eval point accuracy: %f' % (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(
        np.array(total_correct_class[1:]) /
        (np.array(total_seen_class[1:], dtype=np.float) + 1e-6))))
    labelweights_vox = labelweights_vox[1:].astype(np.float32) / np.sum(
        labelweights_vox[1:].astype(np.float32))
    caliweights = np.array([
        0.388, 0.357, 0.038, 0.033, 0.017, 0.02, 0.016, 0.025, 0.002, 0.002,
        0.002, 0.007, 0.006, 0.022, 0.004, 0.0004, 0.003, 0.002, 0.024, 0.029
    ])
    #caliweights correspond to the frequency of each class in the data. These particular weights are set up for the scannet data as seen in table 7 at:
    #http://openaccess.thecvf.com/content_cvpr_2017/papers/Dai_ScanNet_Richly-Annotated_3D_CVPR_2017_paper.pdf
    log_string(
        'eval point calibrated average acc: %f' %
        (np.average(np.array(total_correct_class[1:]) /
                    (np.array(total_seen_class[1:], dtype=np.float) + 1e-6),
                    weights=caliweights)))
    per_class_str = 'vox based --------'
    for l in range(1, NUM_CLASSES):
        per_class_str += 'class %d weight: %f, acc: %f; ' % (
            l, labelweights_vox[l - 1],
            total_correct_class[l] / float(total_seen_class[l]))
    log_string(per_class_str)
    EPOCH_CNT += 1
    return total_correct / float(total_seen)
Пример #28
0
def eval_scene_one_epoch(sess, ops, test_writer, num_classes):
    """ ops: dict mapping from string to tf ops """
    global EPOCH_CNT
    is_training = False
    test_idxs = np.arange(0, len(TEST_DATASET))
    num_batches = int(len(TEST_DATASET) / BATCH_SIZE)

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    total_seen_class = [0 for _ in range(NUM_CLASSES)]
    total_correct_class = [0 for _ in range(NUM_CLASSES)]
    total_iou_deno_class = [0 for _ in range(NUM_CLASSES)]
    total_cross_matrix = np.zeros((NUM_CLASSES, NUM_CLASSES))

    log_string(str(datetime.now()))
    log_string('---- EPOCH %03d EVALUATION ----' % (EPOCH_CNT))

    labelweights = np.zeros(21)
    for batch_idx in range(num_batches):
        start_idx = batch_idx * BATCH_SIZE
        end_idx = (batch_idx + 1) * BATCH_SIZE
        batch_data, batch_label, batch_smpw = get_batch(
            TEST_DATASET, test_idxs, start_idx, end_idx)
        batch_label_onehot = np.eye(num_classes)[batch_label]
        external_batch_scene_encode = np.max(batch_label_onehot, axis=1)

        aug_data = provider.rotate_point_cloud_z(batch_data)
        #aug_data = provider.rotate_point_cloud(batch_data)
        bandwidth = BANDWIDTH

        feed_dict = {
            ops['pointclouds_pl']: aug_data,
            ops['labels_pl']: batch_label,
            ops['labels_onehot_pl']: batch_label_onehot,
            ops['smpws_pl']: batch_smpw,
            ops['external_scene_encode_pl']: external_batch_scene_encode,
            ops['is_training_pl']: is_training,
            ops['cos_loss_weight']: 1.0
        }

        summary, step, loss_val, pred_val = sess.run(
            [ops['merged'], ops['step'], ops['loss'], ops['pred']],
            feed_dict=feed_dict)
        test_writer.add_summary(summary, step)
        pred_val = np.argmax(pred_val, 2)  # BxN
        correct = np.sum(
            (pred_val == batch_label) & (batch_label > 0) &
            (batch_smpw > 0))  # evaluate only on 20 categories but not unknown
        total_correct += correct
        total_seen += np.sum((batch_label > 0) & (batch_smpw > 0))
        loss_sum += loss_val
        tmp, _ = np.histogram(batch_label, range(22))
        labelweights += tmp
        for l in range(NUM_CLASSES):
            total_seen_class[l] += np.sum((batch_label == l)
                                          & (batch_smpw > 0))
            total_correct_class[l] += np.sum((pred_val == l)
                                             & (batch_label == l)
                                             & (batch_smpw > 0))
            total_iou_deno_class[l] += np.sum((
                (pred_val == l) | (batch_label == l)) & (batch_smpw > 0))
            for m in range(NUM_CLASSES):
                total_cross_matrix[l, m] += np.sum((
                    (pred_val == l) & (batch_label == m)) & (batch_smpw > 0))

    mIoU = np.mean(
        np.array(total_correct_class[1:]) /
        (np.array(total_iou_deno_class[1:], dtype=np.float) + 1e-6))
    log_string('eval mean loss: %f' % (loss_sum / float(num_batches)))
    log_string('eval point avg class IoU: %f' % (mIoU))
    log_string('eval point accuracy: %f' % (total_correct / float(total_seen)))
    log_string('eval point avg class acc: %f' % (np.mean(
        np.array(total_correct_class[1:]) /
        (np.array(total_seen_class[1:], dtype=np.float) + 1e-6))))
    iou_per_class_str = '------- IoU --------\n'
    for l in range(1, NUM_CLASSES):
        iou_per_class_str += 'class %d, acc: %f \n' % (
            l, total_correct_class[l] / float(total_iou_deno_class[l]))
    log_string(iou_per_class_str)
    EPOCH_CNT += 1
    return mIoU, total_cross_matrix
Пример #29
0
def train_one_epoch(sess, ops, train_writer):
    """ ops: dict mapping from string to tf ops """
    is_training = True

    # Shuffle train samples
    train_idxs = np.arange(0, len(TRAIN_DATASET))
    np.random.shuffle(train_idxs)
    num_batches = len(TRAIN_DATASET) / (BATCH_SIZE // 2)

    log_string(str(datetime.now()))

    total_correct = 0
    total_seen = 0
    loss_sum = 0
    loss_sum1 = 0
    loss_sum2 = 0
    for batch_idx in range(num_batches):
        start_idx = batch_idx * (BATCH_SIZE // 2)
        end_idx = (batch_idx + 1) * (BATCH_SIZE // 2)

        ### Get input from other process
        batch_data, batch_smpw = SUNCG_DATASET.wait_other()
        ###Convert it to voxel
        batch_data_norm = pc_normalize_batch(batch_data)

        batch_data_temp = pc_util.point_cloud_label_to_volume_batch_exact(
            batch_data_norm, vsize=V_SIZE, flatten=True)
        batch_data_vol = np.zeros((BATCH_SIZE, V_SIZE, V_SIZE, V_SIZE, 1))
        batch_data_vol[0:BATCH_SIZE // 2, :, :, :, :] = batch_data_temp
        feed_dict = {
            ops['pointclouds_pl']: batch_data_vol,
            ops['is_training_pl']: False
        }
        pred_val = sess.run(ops['pred'], feed_dict=feed_dict)
        pred_val = np.expand_dims(np.argmax(pred_val, 4), -1)
        pred_val = pred_val[0:BATCH_SIZE // 2, :, :, :, :]
        ###Convert it back to pc
        pred_val = np.clip(
            pc_util.volume_topc_batch_exact(pred_val, batch_data_norm) - 1,
            a_min=0,
            a_max=None)  ### Clip the label in case of Nan in training
        batch_data_extra, batch_label_extra, batch_smpw_extra = SUNCG_DATASET.ready(
            batch_data, np.squeeze(pred_val), batch_smpw,
            TRAIN_DATASET.labelweights)

        batch_data, batch_label, batch_smpw = get_batch_wdp(
            TRAIN_DATASET, train_idxs, start_idx, end_idx)
        batch_data = np.concatenate([batch_data, batch_data_extra], 0)
        batch_label = np.concatenate([batch_label, batch_label_extra], 0)
        batch_smpw = np.concatenate([batch_smpw, batch_smpw_extra], 0)

        # Augment batched point clouds by rotation
        aug_data = provider.rotate_point_cloud_z(batch_data)
        ###Convert it to voxel
        aug_data_vol, batch_label_vol, batch_smpw_vol = pc_util.point_cloud_label_to_volume_batch(
            pc_normalize_batch(aug_data),
            batch_label + 1,
            batch_smpw,
            vsize=V_SIZE,
            flatten=True)

        feed_dict = {
            ops['pointclouds_pl']: aug_data_vol,
            ops['labels_pl']: batch_label_vol,
            ops['smpws_pl']: batch_smpw_vol,
            ops['is_training_pl']: is_training,
        }

        summary, step, _, loss_val, loss_val1, loss_val2, pred_val = sess.run(
            [
                ops['merged'], ops['step'], ops['train_op'], ops['loss'],
                ops['loss1'], ops['loss2'], ops['pred']
            ],
            feed_dict=feed_dict)
        train_writer.add_summary(summary, step)
        ### Change the voxel back to pc
        pred_val = np.argmax(pred_val, 4)
        pred_val, batch_label, batch_smpw, _, _ = pc_util.volume_topc_batch(
            pred_val, batch_label_vol, batch_smpw_vol)
        for i in range(len(pred_val)):
            pred_val[i] -= 1
        for i in range(len(batch_label)):
            batch_label[i] -= 1
        for i in range(len(pred_val)):
            correct = np.sum(pred_val[i] == batch_label[i])
            total_correct += correct
            total_seen += pred_val[i].shape[0]
        loss_sum += loss_val
        loss_sum1 += loss_val1
        loss_sum2 += loss_val2
        if (batch_idx + 1) % 10 == 0:
            log_string(' -- %03d / %03d --' % (batch_idx + 1, num_batches))
            log_string('mean loss: %f' % (loss_sum / 10))
            log_string('mean loss1: %f' % (loss_sum1 / 10))
            log_string('mean loss2: %f' % (loss_sum2 / 10))
            log_string('accuracy: %f' % (total_correct / float(total_seen)))
            total_correct = 0
            total_seen = 0
            loss_sum = 0