def forward(self):
     blob = {}
     blob['data'] = np.reshape(self.file.root.data[self.index], (1,) + (self.N,) * self.dim + (1,))
     if not self.is_testing:
         blob['labels'] = np.reshape(self.file.root.label[self.index], (1,) + (self.N,) * self.dim)
     blob['voxels'], blob['voxels_value'] = extract_voxels(blob['data'][0, ..., 0])
     blob['entries'] = [self.index]
     self.index = (self.index + 1) % self.n
     return blob
示例#2
0
def cluster(cfg, blob, results, index, name='cluster', directory=None):
    """
    Ad-hoc clustering algorithm. Can use UResNet predictions as a mask for
    to cluster track and shower separately, if results includes `predictions`
    key. Erases a 7x7 window around each point predicted by PPN in the data,
    then applies DBSCAN algorithm to perform rough clustering of track/shower
    instances.
    """
    data = blob['data']
    WINDOW_SIZE = 7
    # Hide window around each proposal
    for p in results['im_proposals']:
        p1 = (p - WINDOW_SIZE / 2).astype(int)
        p2 = (p + WINDOW_SIZE / 2).astype(int)
        if cfg.DATA_3D:
            data[0, p1[0]:p2[0], p1[1]:p2[1], p1[2]:p2[2], 0] = 0.0
        else:
            data[0, p1[0]:p2[0], p1[1]:p2[1], 0] = 0.0

    if 'predictions' in results:  # UResNet mask
        predictions = results['predictions'][0, ...]
        predictions[data[0, ..., 0] == 0.0] = 0.0  # mask with data
        track_voxels = np.argwhere(predictions == 1)  # track
        shower_voxels = np.argwhere(predictions == 2)  # track
        db_track, db_shower = [], []
        if track_voxels.shape[0]:
            db_track = DBSCAN(eps=2.5 if cfg.DATA_3D else 2.0,
                              min_samples=10).fit_predict(track_voxels)
        if shower_voxels.shape[0]:
            db_shower = DBSCAN(eps=2.5 if cfg.DATA_3D else 2.0,
                               min_samples=10).fit_predict(shower_voxels)
            db_shower = db_shower + len(np.unique(db_track))  # offset labels
        voxels = np.concatenate([track_voxels, shower_voxels], axis=0)
        voxels = np.flip(voxels, axis=1)
        db = np.concatenate([db_track, db_shower], axis=0)
    else:
        voxels, _ = extract_voxels(data[0, ..., 0])
        voxels = np.flip(voxels, axis=1)
        db = DBSCAN(eps=2.5 if cfg.DATA_3D else 2.0,
                    min_samples=10).fit_predict(voxels)

    print("Clusters: ", np.unique(db))
    new_blob = {}
    new_blob['data'] = data
    new_blob['voxels'] = voxels
    new_blob['voxels_value'] = db
    # display_uresnet(new_blob, cfg,
    #                 compute_voxels=False,
    #                 directory=directory,
    #                 vmin=np.amin(db),
    #                 vmax=np.amax(db),
    #                 index=index)
    kwargs = {}
    if cfg.DATA_3D:
        kwargs['projection'] = '3d'

    display_blob(new_blob,
                 cfg,
                 directory=directory,
                 index=index,
                 cmap='tab10',
                 **kwargs)
示例#3
0
def test(cfg, net):
    _, data = get_data(cfg)

    # Initialize the network the right way
    # net.train and net.eval account for differences in dropout/batch norm
    # during training and testing
    net.eval().cuda()
    metrics = {'acc_all': [], 'acc_nonzero': [], 'loss': []}
    metrics_mean = {'acc_all': [], 'acc_nonzero': [], 'loss': []}
    metrics_std = {'acc_all': [], 'acc_nonzero': [], 'loss': []}
    durations_mean = {'cuda': [], 'loss': [], 'forward': [], 'acc': []}
    durations_std = {'cuda': [], 'loss': [], 'forward': [], 'acc': []}
    # Only enable gradients if we are training
    # with torch.set_grad_enabled(is_training):
    durations, durations_cuda, durations_loss, durations_acc = [], [], [], []
    steps = []
    print('Listing weights...')
    weights = glob.glob(os.path.join(cfg.WEIGHTS_FILE_BASE, "*.ckpt"))
    weights.sort()
    print('Done.')

    blobs = []
    print('Fetch data...')
    for i in range(cfg.MAX_STEPS):
        print("%d/%d" % (i, cfg.MAX_STEPS))
        blob = data.forward()
        blob.pop('data')
        blob['label_voxels'], blob['label_values'] = extract_voxels(
            blob['labels'])
        blob.pop('labels')
        blobs.append(blob)
    print('Done.')

    for w in weights:
        step = int(re.findall(r'model-(\d+)', w)[0])
        steps.append(step)
        print('Restoring weights from %s...' % w)
        with open(w, 'rb') as f:
            checkpoint = torch.load(f)
            net.load_state_dict(checkpoint['state_dict'])
        print('Done.')
        for i, blob in enumerate(blobs):  # FIXME
            print("Step %d/%d" % (i, cfg.MAX_STEPS))
            if sparse:
                start = time.time()
                coords = torch.from_numpy(blob['voxels']).cuda()
                features = torch.from_numpy(
                    np.reshape(blob['voxels_value'], (-1, 1))).cuda()
                label_voxels, labels = blob['label_voxels'], blob[
                    'label_values']
                labels = torch.from_numpy(labels).cuda().type(
                    torch.cuda.LongTensor)
                end = time.time()
                durations_cuda.append(end - start)

                start = time.time()
                predictions_raw = net(coords,
                                      features)  # size N_voxels x num_classes
                end = time.time()
                durations.append(end - start)

            else:
                start = time.time()
                image = torch.from_numpy(np.moveaxis(blob['data'], -1,
                                                     1)).cuda()
                labels = torch.from_numpy(blob['labels']).cuda().type(
                    torch.cuda.LongTensor)
                end = time.time()
                durations_cuda.append(end - start)

                start = time.time()
                predictions_raw = net(image)
                end = time.time()
                durations.append(end - start)

            start = time.time()
            loss = criterion(predictions_raw, labels)
            end = time.time()
            durations_loss.append(end - start)
            metrics['loss'].append(loss.item())
            print("\tLoss = ", metrics['loss'][-1])

            # Accuracy
            start = time.time()
            predicted_labels = torch.argmax(predictions_raw, dim=1)
            acc_all = (predicted_labels == labels).sum().item() / float(
                labels.numel())
            nonzero_px = labels > 0
            nonzero_prediction = predicted_labels[nonzero_px]
            nonzero_label = labels[nonzero_px]
            acc_nonzero = (nonzero_prediction
                           == nonzero_label).sum().item() / float(
                               nonzero_label.numel())
            end = time.time()
            durations_acc.append(end - start)
            metrics['acc_all'].append(acc_all)
            metrics['acc_nonzero'].append(acc_nonzero)
            print("\tAccuracy = ", metrics['acc_all'][-1],
                  " - Nonzero accuracy = ", metrics['acc_nonzero'][-1])

        metrics_mean['loss'].append(np.array(metrics['loss']).mean())
        metrics_std['loss'].append(np.array(metrics['loss']).std())
        metrics_mean['acc_all'].append(np.array(metrics['acc_all']).mean())
        metrics_std['acc_all'].append(np.array(metrics['acc_all']).std())
        metrics_mean['acc_nonzero'].append(
            np.array(metrics['acc_nonzero']).mean())
        metrics_std['acc_nonzero'].append(
            np.array(metrics['acc_nonzero']).std())
        durations_mean['cuda'].append(np.array(durations_cuda).mean())
        durations_std['cuda'].append(np.array(durations_cuda).std())
        durations_mean['loss'].append(np.array(durations_loss).mean())
        durations_std['loss'].append(np.array(durations_loss).std())
        durations_mean['forward'].append(np.array(durations).mean())
        durations_std['forward'].append(np.array(durations).std())
        durations_mean['acc'].append(np.array(durations_acc).mean())
        durations_std['acc'].append(np.array(durations_acc).std())
        durations, durations_cuda, durations_loss, durations_acc = [], [], [], []
        metrics = {'acc_all': [], 'acc_nonzero': [], 'loss': []}

        print('Mean cuda duration = %f s' % durations_mean['cuda'][-1])
        print('Mean loss duration = %f s' % durations_mean['loss'][-1])
        print('Mean acc duration = %f s' % durations_mean['acc'][-1])
        print('Mean forward duration = %f s' % durations_mean['forward'][-1])

        print('Mean acc = %f s' % metrics_mean['acc_nonzero'][-1])

        np.savetxt(os.path.join(cfg.OUTPUT_DIR, 'steps_%d.csv' % step),
                   steps,
                   delimiter=',')
        for attr in metrics:
            np.savetxt(os.path.join(cfg.OUTPUT_DIR,
                                    '%s_mean_%d.csv' % (attr, step)),
                       metrics_mean[attr],
                       delimiter=',')
            np.savetxt(os.path.join(cfg.OUTPUT_DIR,
                                    '%s_std_%d.csv' % (attr, step)),
                       metrics_std[attr],
                       delimiter=',')
        for attr in durations_mean:
            np.savetxt(os.path.join(cfg.OUTPUT_DIR,
                                    'durations_%s_mean_%d.csv' % (attr, step)),
                       durations_mean[attr],
                       delimiter=',')
            np.savetxt(os.path.join(cfg.OUTPUT_DIR,
                                    'durations_%s_std_%d.csv' % (attr, step)),
                       durations_std[attr],
                       delimiter=',')
示例#4
0
def train_demo(cfg, net, criterion, optimizer, lr_scheduler):
    # Data generator
    train_data, test_data = get_data(cfg)
    if is_training:
        data = train_data
    else:
        data = test_data

    # Initialize the network the right way
    # net.train and net.eval account for differences in dropout/batch norm
    # during training and testing
    start = 0
    if is_training:
        net.train().cuda()
    else:
        net.eval().cuda()
    if cfg.WEIGHTS_FILE_BASE is not None and cfg.WEIGHTS_FILE_BASE != '':
        print('Restoring weights from %s...' % cfg.WEIGHTS_FILE_BASE)
        with open(cfg.WEIGHTS_FILE_BASE, 'rb') as f:
            checkpoint = torch.load(f)
            net.load_state_dict(checkpoint['state_dict'])
            # print(checkpoint['state_dict'])
            optimizer.load_state_dict(checkpoint['optimizer'])
            lr_scheduler.load_state_dict(checkpoint['lr_scheduler'])
            start = checkpoint['epoch'] + 1
        print('Done.')
    print('Done.')

    metrics = {'acc_all': [], 'acc_nonzero': [], 'loss': []}
    # Only enable gradients if we are training
    # with torch.set_grad_enabled(is_training):
    durations = []
    for i in range(cfg.MAX_STEPS):  # use with torch.no_grad() for test network
        # Check parameters for nan
        # print('Check for nan...')
        # had_nan = False
        # for p in net.parameters():
        #     if torch.isnan(p).any():
        #         print(i, p)
        #         had_nan = True
        #
        # for name in net.state_dict():
        #     tensor = net.state_dict()[name]
        #     if name == 'sparseModel.2.4.1.2.4.1.2.4.1.2.4.1.2.0.1.0.runningVar':
        #         print(i, name, tensor)
        #     if torch.isnan(tensor).any():
        #         print(i, name, tensor)
        #         had_nan = True
        # if had_nan:
        #     break
        # print('Done.')

        # inputs, label = dataloader(i)
        print("Step %d/%d" % (i, cfg.MAX_STEPS))
        blob = data.forward()
        print(blob['voxels'].shape, blob['voxels_value'].shape,
              blob['data'].shape, blob['labels'].shape)
        if sparse:
            coords = torch.from_numpy(blob['voxels']).cuda()
            features = torch.from_numpy(
                np.reshape(blob['voxels_value'], (-1, 1))).cuda()
            # print(coords.type(), features.type())
            start = time.time()
            predictions_raw = net(coords,
                                  features)  # size N_voxels x num_classes
            end = time.time()
            durations.append(end - start)
            # print(predictions_raw.size())
            label_voxels, labels = extract_voxels(blob['labels'])
            labels = torch.from_numpy(labels).cuda().type(
                torch.cuda.LongTensor)
            # print(labels, label_voxels, blob['voxels'])
            # print(net.parameters())
        else:
            image = torch.from_numpy(np.moveaxis(blob['data'], -1, 1)).cuda()
            labels = torch.from_numpy(blob['labels']).cuda().type(
                torch.cuda.LongTensor)
            start = time.time()
            predictions_raw = net(image)
            end = time.time()
            durations.append(end - start)

        loss = criterion(predictions_raw, labels)
        if is_training:
            lr_scheduler.step()  # Decay learning rate
            optimizer.zero_grad()  # Clear previous gradients
            loss.backward()  # Compute gradients of all variables wrt loss
            nn.utils.clip_grad_norm_(net.parameters(), 1.0)  # Clip gradient
            optimizer.step()  # update using computed gradients
        metrics['loss'].append(loss.item())
        print("\tLoss = ", metrics['loss'][-1])

        # Accuracy
        predicted_labels = torch.argmax(predictions_raw, dim=1)
        acc_all = (predicted_labels == labels).sum().item() / float(
            labels.numel())
        nonzero_px = labels > 0
        nonzero_prediction = predicted_labels[nonzero_px]
        nonzero_label = labels[nonzero_px]
        acc_nonzero = (nonzero_prediction
                       == nonzero_label).sum().item() / float(
                           nonzero_label.numel())
        metrics['acc_all'].append(acc_all)
        metrics['acc_nonzero'].append(acc_nonzero)
        print("\tAccuracy = ", metrics['acc_all'][-1],
              " - Nonzero accuracy = ", metrics['acc_nonzero'][-1])

        if is_training and i % 100 == 0:
            for attr in metrics:
                np.savetxt(os.path.join(cfg.OUTPUT_DIR,
                                        '%s_%d.csv' % (attr, i)),
                           metrics[attr],
                           delimiter=',')
                # metrics[attr] = []

        if is_training and i % 100 == 0:
            filename = os.path.join(cfg.OUTPUT_DIR, 'model-%d.ckpt' % i)
            # with open(filename, 'wb'):
            torch.save(
                {
                    'epoch': i,
                    'state_dict': net.state_dict(),
                    'optimizer': optimizer.state_dict(),
                    'lr_scheduler': lr_scheduler.state_dict()
                }, filename)

        if not is_training:
            print('Display...')
            if sparse:
                final_predictions = np.zeros(
                    (1, cfg.IMAGE_SIZE, cfg.IMAGE_SIZE, cfg.IMAGE_SIZE))
                indices = label_voxels.T
                final_predictions[
                    0, indices[0], indices[1],
                    indices[2]] = predicted_labels.cpu().data.numpy()
                display_uresnet(blob,
                                cfg,
                                index=i,
                                predictions=final_predictions)
            else:
                display_uresnet(
                    blob,
                    cfg,
                    index=i,
                    predictions=predicted_labels.cpu().data.numpy())
            print('Done.')
    print("Average duration = %f s" % np.array(durations).mean())
示例#5
0
    def reconcile(self, batch_results, patch_centers, patch_sizes):
        """
        Reconcile slices result together
        using batch_results, batch_blobs, patch_centers and patch_sizes
        """
        final_results = {}
        if len(batch_results) == 0:  # Empty batch
            return final_results

        # UResNet predictions
        if 'predictions' and 'scores' and 'softmax' in batch_results[0]:
            final_voxels = np.array([], dtype=np.int32).reshape(
                0, 3)  # Shape N_voxels x dim
            final_scores = np.array([], dtype=np.float32).reshape(
                0, self.cfg.NUM_CLASSES)  # Shape N_voxels x num_classes
            final_counts = np.array([], dtype=np.int32).reshape(
                0, )  # Shape N_voxels x 1
            for i, result in enumerate(batch_results):
                # Extract voxel and voxel values
                # Shape N_voxels x dim
                v, values = extract_voxels(result['predictions'])
                # Extract corresponding softmax scores
                # Shape N_voxels x num_classes
                scores = result['softmax'][v[:, 0], v[:, 1], v[:, 2], :]
                # Restore original blob coordinates
                v = (v + np.flipud(patch_centers[i]) -
                     patch_sizes[i] / 2.0).astype(np.int64)
                v = np.clip(v, 0, self.cfg.IMAGE_SIZE - 1)
                # indices are  indices of the *first* occurrences of the unique values
                # hence for doublons they are indices in final_voxels
                # We assume the only overlap that can occur is between
                # final_voxels and v, not inside these arrays themselves
                n = final_voxels.shape[0]
                final_voxels, indices, counts = np.unique(np.concatenate(
                    [final_voxels, v], axis=0),
                                                          axis=0,
                                                          return_index=True,
                                                          return_counts=True)
                final_scores = np.concatenate([final_scores, scores],
                                              axis=0)[indices]
                lower_indices = indices[indices < n]
                upper_indices = indices[indices >= n]
                final_counts[lower_indices] += counts[lower_indices] - 1
                final_counts = np.concatenate(
                    [final_counts,
                     np.ones((upper_indices.shape[0], ))],
                    axis=0)

            final_scores = final_scores / final_counts[:, np.
                                                       newaxis]  # Compute average
            final_predictions = np.argmax(final_scores, axis=1)
            final_results['predictions'] = np.zeros(
                (self.cfg.IMAGE_SIZE, ) * 3)
            final_results['predictions'][final_voxels.T[0], final_voxels.T[1],
                                         final_voxels.T[2]] = final_predictions
            final_results['scores'] = np.zeros((self.cfg.IMAGE_SIZE, ) * 3)
            final_results['scores'][final_voxels.T[0], final_voxels.T[1],
                                    final_voxels.T[2]] = final_scores[
                                        np.arange(final_scores.shape[0]),
                                        final_predictions]
            final_results['softmax'] = np.zeros((self.cfg.IMAGE_SIZE, ) * 3 +
                                                (self.cfg.NUM_CLASSES, ))
            final_results['softmax'][final_voxels.T[0], final_voxels.T[1],
                                     final_voxels.T[2], :] = final_scores
            final_results['predictions'] = final_results['predictions'][
                np.newaxis, ...]

        # PPN
        if 'im_proposals' and 'im_scores' and 'im_labels' and 'rois' in batch_results[
                0]:
            # print(batch_results[0]['im_proposals'].shape, batch_results[0]['im_scores'].shape, batch_results[0]['im_labels'].shape, batch_results[0]['rois'].shape)
            final_im_proposals = np.array([], dtype=np.float32).reshape(0, 3)
            final_im_scores = np.array([], dtype=np.float32).reshape(0, )
            final_im_labels = np.array([], dtype=np.int32).reshape(0, )
            final_rois = np.array([], dtype=np.float32).reshape(0, 3)
            for i, result in enumerate(batch_results):
                im_proposals = result['im_proposals'] + np.flipud(
                    patch_centers[i]) - patch_sizes[i] / 2.0
                im_proposals = np.clip(im_proposals, 0,
                                       self.cfg.IMAGE_SIZE - 1)
                # print(final_im_proposals, im_proposals)
                final_im_proposals = np.concatenate(
                    [final_im_proposals, im_proposals], axis=0)
                final_im_scores = np.concatenate(
                    [final_im_scores, result['im_scores']], axis=0)
                final_im_labels = np.concatenate(
                    [final_im_labels, result['im_labels']], axis=0)
                rois = result['rois'] + (np.flipud(patch_centers[i]) -
                                         patch_sizes[i] / 2.0) / (
                                             self.cfg.dim1 * self.cfg.dim2)
                rois = np.clip(rois, 0, self.cfg.IMAGE_SIZE - 1)
                final_rois = np.concatenate([final_rois, rois], axis=0)
            final_results['im_proposals'] = np.array(final_im_proposals)
            final_results['im_scores'] = np.array(final_im_scores)
            final_results['im_labels'] = np.array(final_im_labels)
            final_results['rois'] = np.array(final_rois)

            # Try thresholding
            # index = np.where(final_results['im_scores'] > 1e-3)
            # final_results['im_proposals'] = final_results['im_proposals'][index, :]
            # final_results['im_scores'] = final_results['im_scores'][index]
            # final_results['im_labels'] = final_results['im_labels'][index]

        return final_results