Exemple #1
0
def main(args):
    eddl.download_mnist()

    num_classes = 10

    in_ = eddl.Input([784])
    layer = in_
    layer = eddl.Activation(eddl.Dense(layer, 1024), "relu")
    layer = eddl.Activation(eddl.Dense(layer, 1024), "relu")
    layer = eddl.Activation(eddl.Dense(layer, 1024), "relu")
    out = eddl.Softmax(eddl.Dense(layer, num_classes))
    net = eddl.Model([in_], [out])

    acc = CategoricalAccuracy()
    net.build(
        eddl.sgd(0.01, 0.9),
        [eddl.getLoss("soft_cross_entropy")],
        [acc],
        eddl.CS_GPU(mem=args.mem) if args.gpu else eddl.CS_CPU(mem=args.mem)
    )

    eddl.summary(net)
    eddl.plot(net, "model.pdf")

    x_train = Tensor.load("mnist_trX.bin")
    y_train = Tensor.load("mnist_trY.bin")
    x_test = Tensor.load("mnist_tsX.bin")
    # y_test = Tensor.load("mnist_tsY.bin")

    x_train.div_(255.0)
    x_test.div_(255.0)

    num_samples = x_train.shape[0]
    num_batches = num_samples // args.batch_size
    test_samples = x_test.shape[0]
    test_batches = test_samples // args.batch_size

    eddl.set_mode(net, TRMODE)

    for i in range(args.epochs):
        for j in range(num_batches):
            print("Epoch %d/%d (batch %d/%d)" %
                  (i + 1, args.epochs, j + 1, num_batches))
            indices = np.random.randint(0, num_samples, args.batch_size)
            eddl.train_batch(net, [x_train], [y_train], indices)
        for j in range(test_batches):
            print("Epoch %d/%d (batch %d/%d)" %
                  (i + 1, args.epochs, j + 1, test_batches))
            indices = np.random.randint(0, num_samples, args.batch_size)
            eddl.eval_batch(net, [x_train], [y_train], indices)
    print("All done")
Exemple #2
0
def cassandra_fit(cass_ds, net, epochs=3):
    cs = 0  # current split = training
    cass_ds.current_split = cs
    num_batches = cass_ds.num_batches[cs]
    # loop through the epochs
    for e in range(epochs):
        cass_ds.rewind_splits(cs, shuffle=True)
        eddl.reset_loss(net)
        # loop through batches
        for b in trange(num_batches):
            x, y = cass_ds.load_batch()
            x.div_(255.0)
            tx, ty = [x], [y]
            eddl.train_batch(net, tx, ty)
        # print loss
        eddl.print_loss(net, b)
        print()
Exemple #3
0
def main(args):
    num_classes = 1
    size = [192, 192]  # size of images
    thresh = 0.5

    if args.out_dir:
        os.makedirs(args.out_dir, exist_ok=True)

    in_ = eddl.Input([3, size[0], size[1]])
    out = SegNet(in_, num_classes)
    out_sigm = eddl.Sigmoid(out)
    net = eddl.Model([in_], [out_sigm])
    eddl.build(net, eddl.adam(0.0001), ["cross_entropy"],
               ["mean_squared_error"],
               eddl.CS_GPU([1]) if args.gpu else eddl.CS_CPU())
    eddl.summary(net)
    eddl.setlogfile(net, "skin_lesion_segmentation")

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(size),
        ecvl.AugMirror(0.5),
        ecvl.AugFlip(0.5),
        ecvl.AugRotate([-180, 180]),
        ecvl.AugAdditivePoissonNoise([0, 10]),
        ecvl.AugGammaContrast([0.5, 1.5]),
        ecvl.AugGaussianBlur([0, 0.8]),
        ecvl.AugCoarseDropout([0, 0.3], [0.02, 0.05], 0.5)
    ])
    validation_augs = ecvl.SequentialAugmentationContainer(
        [ecvl.AugResizeDim(size)])
    dataset_augs = ecvl.DatasetAugmentations(
        [training_augs, validation_augs, None])

    print("Reading dataset")
    d = ecvl.DLDataset(args.in_ds, args.batch_size, dataset_augs)
    x = Tensor([args.batch_size, d.n_channels_, size[0], size[1]])
    y = Tensor([args.batch_size, d.n_channels_gt_, size[0], size[1]])
    num_samples_train = len(d.GetSplit())
    num_batches_train = num_samples_train // args.batch_size
    d.SetSplit(ecvl.SplitType.validation)
    num_samples_validation = len(d.GetSplit())
    num_batches_validation = num_samples_validation // args.batch_size
    indices = list(range(args.batch_size))

    evaluator = utils.Evaluator()
    print("Starting training")
    for e in range(args.epochs):
        print("Epoch {:d}/{:d} - Training".format(e + 1, args.epochs),
              flush=True)
        d.SetSplit(ecvl.SplitType.training)
        eddl.reset_loss(net)
        s = d.GetSplit()
        random.shuffle(s)
        d.split_.training_ = s
        d.ResetAllBatches()
        for b in range(num_batches_train):
            print("Epoch {:d}/{:d} (batch {:d}/{:d}) - ".format(
                e + 1, args.epochs, b + 1, num_batches_train),
                  end="",
                  flush=True)
            d.LoadBatch(x, y)
            x.div_(255.0)
            y.div_(255.0)
            tx, ty = [x], [y]
            eddl.train_batch(net, tx, ty, indices)
            eddl.print_loss(net, b)
            print()

        print("Saving weights")
        eddl.save(net, "isic_segmentation_checkpoint_epoch_%s.bin" % e, "bin")

        d.SetSplit(ecvl.SplitType.validation)
        evaluator.ResetEval()
        print("Epoch %d/%d - Evaluation" % (e + 1, args.epochs), flush=True)
        for b in range(num_batches_validation):
            n = 0
            print("Epoch {:d}/{:d} (batch {:d}/{:d}) ".format(
                e + 1, args.epochs, b + 1, num_batches_validation),
                  end="",
                  flush=True)
            d.LoadBatch(x, y)
            x.div_(255.0)
            y.div_(255.0)
            eddl.forward(net, [x])
            output = eddl.getOutput(out_sigm)
            for k in range(args.batch_size):
                img = output.select([str(k)])
                gt = y.select([str(k)])
                img_np = np.array(img, copy=False)
                gt_np = np.array(gt, copy=False)
                iou = evaluator.BinaryIoU(img_np, gt_np, thresh=thresh)
                print("- IoU: %.6g " % iou, end="", flush=True)
                if args.out_dir:
                    # C++ BinaryIoU modifies image as a side effect
                    img_np[img_np >= thresh] = 1
                    img_np[img_np < thresh] = 0
                    img_t = ecvl.TensorToView(img)
                    img_t.colortype_ = ecvl.ColorType.GRAY
                    img_t.channels_ = "xyc"
                    img.mult_(255.)
                    # orig_img
                    orig_img = x.select([str(k)])
                    orig_img.mult_(255.)
                    orig_img_t = ecvl.TensorToImage(orig_img)
                    orig_img_t.colortype_ = ecvl.ColorType.BGR
                    orig_img_t.channels_ = "xyc"

                    tmp, labels = ecvl.Image.empty(), ecvl.Image.empty()
                    ecvl.CopyImage(img_t, tmp, ecvl.DataType.uint8)
                    ecvl.ConnectedComponentsLabeling(tmp, labels)
                    ecvl.CopyImage(labels, tmp, ecvl.DataType.uint8)
                    contours = ecvl.FindContours(tmp)
                    ecvl.CopyImage(orig_img_t, tmp, ecvl.DataType.uint8)
                    tmp_np = np.array(tmp, copy=False)
                    for cseq in contours:
                        for c in cseq:
                            tmp_np[c[0], c[1], 0] = 0
                            tmp_np[c[0], c[1], 1] = 0
                            tmp_np[c[0], c[1], 2] = 255
                    filename = d.samples_[d.GetSplit()[n]].location_[0]
                    head, tail = os.path.splitext(os.path.basename(filename))
                    bname = "%s.png" % head
                    output_fn = os.path.join(args.out_dir, bname)
                    ecvl.ImWrite(output_fn, tmp)
                    if e == 0:
                        gt_t = ecvl.TensorToView(gt)
                        gt_t.colortype_ = ecvl.ColorType.GRAY
                        gt_t.channels_ = "xyc"
                        gt.mult_(255.)
                        gt_filename = d.samples_[d.GetSplit()[n]].label_path_
                        gt_fn = os.path.join(args.out_dir,
                                             os.path.basename(gt_filename))
                        ecvl.ImWrite(gt_fn, gt_t)
                n += 1
            print()
        print("MIoU: %.6g" % evaluator.MeanMetric())
Exemple #4
0
def main(args):
    net_name = "vgg16"
    num_classes = 2
    size = [256, 256]  # size of images

    ### Parse GPU
    if args.gpu:
        gpus = [int(i) for i in args.gpu]
    else:
        gpus = []

    print('GPUs mask: %r' % gpus)
    ### Get Network
    net_init = eddl.HeNormal
    net, dataset_augs = get_net(net_name='vgg16',
                                in_size=size,
                                num_classes=num_classes,
                                lr=args.lr,
                                augs=args.augs_on,
                                gpus=gpus,
                                lsb=args.lsb,
                                init=net_init,
                                dropout=args.dropout,
                                l2_reg=args.l2_reg)
    out = net.layers[-1]

    ## Load weights if requested
    if args.init_weights_fn:
        print("Loading initialization weights")
        eddl.load(net, args.init_weights_fn)

    ## Check options
    if args.out_dir:
        working_dir = "model_cnn_%s_ps.%d_bs_%d_lr_%.2e" % (
            net_name, size[0], args.batch_size, args.lr)
        res_dir = os.path.join(args.out_dir, working_dir)
        try:
            os.makedirs(res_dir, exist_ok=True)
        except:
            print("Directory already exists.")
            sys.exit()

    ########################################
    ### Set database and read split file ###
    ########################################

    if not args.cassandra_pwd_fn:
        cass_pass = getpass('Insert Cassandra password: '******'prom', password=cass_pass)
    #cd = CassandraDataset(ap, ['cassandra_db'])
    cd = CassandraDataset(ap, ['127.0.0.1'], seed=args.seed)

    # Check if file exists
    if Path(args.splits_fn).exists():
        # Load splits
        cd.load_splits(args.splits_fn,
                       batch_size=args.batch_size,
                       augs=dataset_augs)
    else:
        print("Split file %s not found" % args.splits_fn)
        sys.exit(-1)

    print('Number of batches for each split (train, val, test):',
          cd.num_batches)

    ## validation index check and creation of split indexes lists
    if args.val_split_indexes:
        n_splits = cd.num_splits
        out_indexes = [i for i in args.val_split_indexes if i > (n_splits - 1)]
        if out_indexes:
            print("Not valid validation split index: %r" % out_indexes)
            sys.exit(-1)

        val_splits = args.val_split_indexes
        test_splits = args.test_split_indexes
        train_splits = [
            i for i in range(n_splits)
            if (i not in val_splits) and (i not in test_splits)
        ]
        num_batches_tr = np.sum([cd.num_batches[i] for i in train_splits])
        num_batches_val = np.sum([cd.num_batches[i] for i in val_splits])

        print("Train splits: %r" % train_splits)
        print("Val splits: %r" % val_splits)
        print("Test splits: %r" % test_splits)

    else:
        num_batches_tr = cd.num_batches[0]
        num_batches_val = cd.num_batches[1]

    ################################
    #### Training and evaluation ###
    ################################

    print("Defining metric...", flush=True)

    metric_fn = eddl.getMetric("categorical_accuracy")
    loss_fn = eddl.getLoss("soft_cross_entropy")

    print("Starting training", flush=True)

    loss_l = []
    acc_l = []
    val_loss_l = []
    val_acc_l = []

    patience_cnt = 0
    val_acc_max = 0.0

    #### Code used to find best learning rate. Comment it to perform an actual training
    if args.find_opt_lr:
        max_epochs = args.epochs
        lr_start = args.lr
        lr_end = args.lr_end
        lr_f = lambda x: 10**(np.log10(lr_start) + (
            (np.log10(lr_end) - np.log10(lr_start)) / max_epochs) * x)
    ####

    ### Main loop across epochs
    for e in range(args.epochs):
        ## SET LT
        if args.find_opt_lr:
            eddl.setlr(net, [lr_f(e)])

        ### Training
        cd.current_split = 0  ## Set the training split as the current one
        print("Epoch {:d}/{:d} - Training".format(e + 1, args.epochs),
              flush=True)

        cd.rewind_splits(shuffle=True)
        eddl.reset_loss(net)
        total_metric = []
        total_loss = []

        ### Looping across batches of training data
        pbar = tqdm(range(num_batches_tr))

        for b_index, b in enumerate(pbar):
            if args.val_split_indexes:
                x, y = cd.load_batch_cross(not_splits=val_splits + test_splits)
            else:
                x, y = cd.load_batch()

            x.div_(255.0)
            tx, ty = [x], [y]
            eddl.train_batch(net, tx, ty)

            #print bratch train results
            instances = (b_index + 1) * args.batch_size
            loss = eddl.get_losses(net)[0]
            metr = eddl.get_metrics(net)[0]
            msg = "Epoch {:d}/{:d} (batch {:d}/{:d}) - loss: {:.3f}, acc: {:.3f}".format(
                e + 1, args.epochs, b + 1, num_batches_tr, loss, metr)
            pbar.set_postfix_str(msg)
            total_loss.append(loss)
            total_metric.append(metr)

        loss_l.append(np.mean(total_loss))
        acc_l.append(np.mean(total_metric))

        pbar.close()

        ### Evaluation on validation set batches
        cd.current_split = 1  ## Set validation split as the current one
        total_metric = []
        total_loss = []

        print("Epoch %d/%d - Evaluation" % (e + 1, args.epochs), flush=True)

        pbar = tqdm(range(num_batches_val))

        for b_index, b in enumerate(pbar):
            if args.val_split_indexes:
                x, y = cd.load_batch_cross(not_splits=train_splits +
                                           test_splits)
            else:
                x, y = cd.load_batch()

            x.div_(255.0)
            eddl.forward(net, [x])
            output = eddl.getOutput(out)
            sum_ca = 0.0  ## sum of samples accuracy within a batch
            sum_ce = 0.0  ## sum of losses within a batch

            n = 0
            for k in range(x.getShape()[0]):
                result = output.select([str(k)])
                target = y.select([str(k)])
                ca = metric_fn.value(target, result)
                ce = loss_fn.value(target, result)
                total_metric.append(ca)
                total_loss.append(ce)
                sum_ca += ca
                sum_ce += ce
                n += 1

            msg = "Epoch {:d}/{:d} (batch {:d}/{:d}) loss: {:.3f}, acc: {:.3f} ".format(
                e + 1, args.epochs, b + 1, num_batches_val, (sum_ce / n),
                (sum_ca / n))
            pbar.set_postfix_str(msg)

        pbar.close()
        val_batch_acc_avg = np.mean(total_metric)
        val_batch_loss_avg = np.mean(total_loss)
        val_loss_l.append(val_batch_loss_avg)
        val_acc_l.append(val_batch_acc_avg)

        print("loss: {:.3f}, acc: {:.3f}, val_loss: {:.3f}, val_acc: {:.3f}\n".
              format(loss_l[-1], acc_l[-1], val_loss_l[-1], val_acc_l[-1]))

        ## Save weights
        if args.save_weights:
            print("Saving weights")
            path = os.path.join(
                res_dir, "promort_%s_weights_ep_%s_vacc_%.2f.bin" %
                (net_name, e, val_acc_l[-1]))
            eddl.save(net, path, "bin")

        # Dump history at the end of each epoch so if the job is interrupted data are not lost.
        if args.out_dir:
            history = {
                'loss': loss_l,
                'acc': acc_l,
                'val_loss': val_loss_l,
                'val_acc': val_acc_l
            }
            pickle.dump(history,
                        open(os.path.join(res_dir, 'history.pickle'), 'wb'))

        ### Patience check
        if val_acc_l[-1] > val_acc_max:
            val_acc_max = val_acc_l[-1]
            patience_cnt = 0
        else:
            patience_cnt += 1

        if patience_cnt > args.patience:
            ## Exit and complete the training
            print("Got maximum patience... training completed")
            break
Exemple #5
0
def main(args):
    num_classes = 1
    size = [512, 512]  # size of images
    thresh = 0.5
    best_dice = -1

    if args.out_dir:
        os.makedirs(args.out_dir, exist_ok=True)

    in_ = eddl.Input([1, size[0], size[1]])
    out = SegNetBN(in_, num_classes)
    out_sigm = eddl.Sigmoid(out)
    net = eddl.Model([in_], [out_sigm])
    eddl.build(net, eddl.adam(0.0001), ["cross_entropy"],
               ["mean_squared_error"],
               eddl.CS_GPU([1], mem='low_mem') if args.gpu else eddl.CS_CPU())
    eddl.summary(net)
    eddl.setlogfile(net, "pneumothorax_segmentation_training")

    if args.ckpts and os.path.exists(args.ckpts):
        print("Loading checkpoints '{}'".format(args.ckpts))
        eddl.load(net, args.ckpts, 'bin')

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(size),
        ecvl.AugMirror(0.5),
        ecvl.AugRotate([-10, 10]),
        ecvl.AugBrightness([0, 30]),
        ecvl.AugGammaContrast([0, 3]),
    ])
    validation_augs = ecvl.SequentialAugmentationContainer(
        [ecvl.AugResizeDim(size)])
    dataset_augs = ecvl.DatasetAugmentations(
        [training_augs, validation_augs, None])

    print("Reading dataset")
    d = ecvl.DLDataset(args.in_ds, args.batch_size, dataset_augs,
                       ecvl.ColorType.GRAY)
    # Prepare tensors which store batch
    x = Tensor([args.batch_size, d.n_channels_, size[0], size[1]])
    y = Tensor([args.batch_size, d.n_channels_gt_, size[0], size[1]])

    # Retrieve indices of images with a black ground truth
    # which are not include in a split
    train_split = d.GetSplit(ecvl.SplitType.training)
    val_split = d.GetSplit(ecvl.SplitType.validation)
    test_split = d.GetSplit(ecvl.SplitType.test)
    all_split = set(train_split + val_split + test_split)

    images_list = set(range(len(d.samples_)))

    # Obtain images with black ground truth
    black_images = images_list - all_split

    # Add a 25% of training samples with black ground truth.
    num_samples_train = math.floor(len(train_split) * 1.25)
    num_batches_train = num_samples_train // args.batch_size

    # Add a 25% of validation samples with black ground truth.
    num_samples_validation = math.floor(len(val_split) * 1.25)
    num_batches_validation = num_samples_validation // args.batch_size

    black_images = list(black_images)
    black_training = black_images[0:-(num_samples_validation - len(val_split))]
    black_validation = black_images[-(num_samples_validation -
                                      len(val_split)):]
    indices = list(range(args.batch_size))

    evaluator = utils.Evaluator()
    print("Starting training")
    for e in range(args.epochs):
        print("Epoch {:d}/{:d} - Training".format(e + 1, args.epochs),
              flush=True)
        d.SetSplit(ecvl.SplitType.training)
        eddl.reset_loss(net)
        s = d.GetSplit()
        random.shuffle(s)
        d.split_.training_ = s
        random.shuffle(black_training)

        d.ResetAllBatches()
        # Indices to track mask and black vector in PneumothoraxLoadBatch
        m_i = 0
        b_i = 0
        for i, b in enumerate(range(num_batches_train)):
            d, images, labels, _, m_i, b_i = PneumothoraxLoadBatch(
                d, black_training, m_i, b_i)
            x, y = fill_tensors(images, labels, x, y)
            x.div_(255.0)
            y.div_(255.0)
            eddl.train_batch(net, [x], [y], indices)
            if i % args.log_interval == 0:
                print("Epoch {:d}/{:d} (batch {:d}/{:d}) - ".format(
                    e + 1, args.epochs, b + 1, num_batches_train),
                      end="",
                      flush=True)
                eddl.print_loss(net, b)
                print()

        d.SetSplit(ecvl.SplitType.validation)
        evaluator.ResetEval()
        print("Epoch %d/%d - Evaluation" % (e + 1, args.epochs), flush=True)
        m_i = 0
        b_i = 0
        for b in range(num_batches_validation):
            n = 0
            print("Epoch {:d}/{:d} (batch {:d}/{:d}) ".format(
                e + 1, args.epochs, b + 1, num_batches_validation),
                  end="",
                  flush=True)
            d, images, labels, names, m_i, b_i = PneumothoraxLoadBatch(
                d, black_validation, m_i, b_i)
            x, y = fill_tensors(images, labels, x, y)
            x.div_(255.0)
            y.div_(255.0)
            eddl.forward(net, [x])
            output = eddl.getOutput(out_sigm)

            # Compute Dice metric and optionally save the output images
            for k in range(args.batch_size):
                pred = output.select([str(k)])
                gt = y.select([str(k)])
                pred_np = np.array(pred, copy=False)
                gt_np = np.array(gt, copy=False)
                # DiceCoefficient modifies image as a side effect
                dice = evaluator.DiceCoefficient(pred_np, gt_np, thresh=thresh)
                print("- Dice: {:.6f} ".format(dice), end="", flush=True)

                if args.out_dir:
                    # Save original image fused together with prediction and
                    # ground truth
                    pred_np *= 255
                    pred_ecvl = ecvl.TensorToImage(pred)
                    pred_ecvl.colortype_ = ecvl.ColorType.GRAY
                    pred_ecvl.channels_ = "xyc"
                    ecvl.ResizeDim(pred_ecvl, pred_ecvl, (1024, 1024),
                                   ecvl.InterpolationType.nearest)

                    filename_gt = names[n + 1]
                    gt_ecvl = ecvl.ImRead(filename_gt,
                                          ecvl.ImReadMode.GRAYSCALE)

                    filename = names[n]

                    # Image as BGR
                    img_ecvl = ecvl.ImRead(filename)
                    ecvl.Stack([img_ecvl, img_ecvl, img_ecvl], img_ecvl)
                    img_ecvl.channels_ = "xyc"
                    img_ecvl.colortype_ = ecvl.ColorType.BGR
                    image_np = np.array(img_ecvl, copy=False)
                    pred_np = np.array(pred_ecvl, copy=False)
                    gt_np = np.array(gt_ecvl, copy=False)

                    pred_np = pred_np.squeeze()
                    gt_np = gt_np.squeeze()
                    # Prediction summed in R channel
                    image_np[:, :, -1] = np.where(pred_np == 255, pred_np,
                                                  image_np[:, :, -1])
                    # Ground truth summed in G channel
                    image_np[:, :, 1] = np.where(gt_np == 255, gt_np,
                                                 image_np[:, :, 1])

                    n += 2
                    head, tail = os.path.splitext(os.path.basename(filename))
                    bname = "{}.png".format(head)
                    filepath = os.path.join(args.out_dir, bname)
                    ecvl.ImWrite(filepath, img_ecvl)

            print()

        mean_dice = evaluator.MeanMetric()
        if mean_dice > best_dice:
            print("Saving weights")
            eddl.save(
                net, "pneumothorax_segnetBN_adam_lr_0.0001_"
                "loss_ce_size_512_{}.bin".format(e + 1), "bin")
            best_dice = mean_dice
        print("Mean Dice Coefficient: {:.6g}".format(mean_dice))
    dataset.split_.training_ = split

    # Training
    for batch_idx in range(n_train_batches):
        stdout.write(
            f"Epoch {epoch}/{epochs} (batch {batch_idx:>4}/{n_train_batches}) - "
        )
        stdout.flush()

        start_time = time()

        dataset.LoadBatch(x, y)  # Load data

        eddlT.div_(x, 255.0)  # Preprocessing

        eddl.train_batch(net, [x], [y])  # Perform training

        eddl.print_loss(net, batch_idx)

        stdout.write(f"- Elapsed time: {time()-start_time:.2f} seconds\n")
        stdout.flush()

    print("Saving model...")
    eddl.save_net_to_onnx_file(net, "padchest_VGG16_adam_lr-0.0001.onnx")

    # Validation
    dataset.SetSplit(ecvl.SplitType.validation)  # Set validation split
    eddl.reset_loss(net)  # Reset errors
    print("Starting validation:")
    for batch_idx in range(n_validation_batches):
        stdout.write(
Exemple #7
0
def classificate(args):
    args = dotdict(args)

    ckpts_dir = opjoin(settings.TRAINING_DIR, 'ckpts')
    outputfile = None
    inference = None

    train = True if args.mode == 'training' else False
    batch_size = args.batch_size if args.mode == 'training' else args.test_batch_size
    weight_id = args.weight_id
    weight = dj_models.ModelWeights.objects.get(id=weight_id)
    if train:
        pretrained = None
        if weight.pretrained_on:
            pretrained = weight.pretrained_on.location
    else:
        inference_id = args.inference_id
        inference = dj_models.Inference.objects.get(id=inference_id)
        pretrained = weight.location
    save_stdout = sys.stdout
    size = [args.input_h, args.input_w]  # Height, width
    try:
        model = bindings.models_binding[args.model_id]
    except KeyError:
        raise Exception(
            f'Model with id: {args.model_id} not found in bindings.py')
    try:
        dataset_path = str(
            dj_models.Dataset.objects.get(id=args.dataset_id).path)
    except KeyError:
        raise Exception(
            f'Dataset with id: {args.dataset_id} not found in bindings.py')
    dataset = bindings.dataset_binding.get(args.dataset_id)

    if dataset is None and not train:
        # Binding does not exist. it's a single image dataset
        # Use as dataset "stub" the dataset on which model has been trained
        dataset = bindings.dataset_binding.get(weight.dataset_id.id)
    elif dataset is None and train:
        raise Exception(
            f'Dataset with id: {args.dataset_id} not found in bindings.py')

    basic_augs = ecvl.SequentialAugmentationContainer(
        [ecvl.AugResizeDim(size)])
    train_augs = basic_augs
    val_augs = basic_augs
    test_augs = basic_augs
    if args.train_augs:
        train_augs = ecvl.SequentialAugmentationContainer([
            ecvl.AugResizeDim(size),
            ecvl.AugmentationFactory.create(args.train_augs)
        ])
    if args.val_augs:
        val_augs = ecvl.SequentialAugmentationContainer([
            ecvl.AugResizeDim(size),
            ecvl.AugmentationFactory.create(args.val_augs)
        ])
    if args.test_augs:
        test_augs = ecvl.SequentialAugmentationContainer([
            ecvl.AugResizeDim(size),
            ecvl.AugmentationFactory.create(args.test_augs)
        ])

    logging.info('Reading dataset')
    print('Reading dataset', flush=True)

    dataset = dataset(
        dataset_path, batch_size,
        ecvl.DatasetAugmentations([train_augs, val_augs, test_augs]))
    d = dataset.d
    num_classes = dataset.num_classes
    in_ = eddl.Input([d.n_channels_, size[0], size[1]])
    out = model(in_,
                num_classes)  # out is already softmaxed in classific models
    net = eddl.Model([in_], [out])

    if train:
        logfile = open(Path(weight.logfile), 'w')
    else:
        logfile = open(inference.logfile, 'w')
        outputfile = open(inference.outputfile, 'w')
    with redirect_stdout(logfile):
        # Save args to file
        print('args: ' + json.dumps(args, indent=2, sort_keys=True),
              flush=True)
        logging.info('args: ' + json.dumps(args, indent=2, sort_keys=True))

        eddl.build(
            net, eddl.sgd(args.lr,
                          0.9), [bindings.losses_binding.get(args.loss)],
            [bindings.metrics_binding.get(args.metric)],
            eddl.CS_GPU([1], mem='low_mem') if args.gpu else eddl.CS_CPU())
        eddl.summary(net)

        if pretrained and os.path.exists(pretrained):
            eddl.load(net, pretrained)
            logging.info('Weights loaded')

        # Create tensor for images and labels
        images = eddlT.create([batch_size, d.n_channels_, size[0], size[1]])
        labels = eddlT.create([batch_size, num_classes])

        logging.info(f'Starting {args.mode}')
        print(f'Starting {args.mode}', flush=True)
        if train:
            num_samples_train = len(d.GetSplit(ecvl.SplitType.training))
            num_batches_train = num_samples_train // batch_size
            num_samples_val = len(d.GetSplit(ecvl.SplitType.validation))
            num_batches_val = num_samples_val // batch_size

            indices = list(range(batch_size))

            for e in range(args.epochs):
                eddl.reset_loss(net)
                d.SetSplit(ecvl.SplitType.training)
                s = d.GetSplit()
                random.shuffle(s)
                d.split_.training_ = s
                d.ResetCurrentBatch()
                # total_loss = 0.
                # total_metric = 0.
                for i in range(num_batches_train):
                    d.LoadBatch(images, labels)
                    images.div_(255.0)
                    eddl.train_batch(net, [images], [labels], indices)
                    total_loss = net.fiterr[0]
                    total_metric = net.fiterr[1]
                    print(
                        f'Train Epoch: {e + 1}/{args.epochs} [{i + 1}/{num_batches_train}] {net.lout[0].name}'
                        f'({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                        f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})',
                        flush=True)

                    logging.info(
                        f'Train Epoch: {e + 1}/{args.epochs} [{i + 1}/{num_batches_train}] {net.lout[0].name}'
                        f'({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                        f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})'
                    )

                eddl.save(net, opjoin(ckpts_dir, f'{weight_id}.bin'))
                logging.info('Weights saved')
                print('Weights saved', flush=True)

                if len(d.split_.validation_) > 0:

                    logging.info(f'Validation {e}/{args.epochs}')
                    print(f'Validation {e}/{args.epochs}', flush=True)

                    d.SetSplit(ecvl.SplitType.validation)
                    d.ResetCurrentBatch()

                    for i in range(num_batches_val):
                        d.LoadBatch(images, labels)
                        images.div_(255.0)
                        eddl.eval_batch(net, [images], [labels], indices)
                        # eddl.evaluate(net, [images], [labels])

                        total_loss = net.fiterr[0]
                        total_metric = net.fiterr[1]
                        print(
                            f'Val Epoch: {e + 1}/{args.epochs}  [{i + 1}/{num_batches_val}] {net.lout[0].name}'
                            f'({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                            f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})',
                            flush=True)
                        logging.info(
                            f'Val Epoch: {e + 1}/{args.epochs}  [{i + 1}/{num_batches_val}] {net.lout[0].name}'
                            f'({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                            f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})'
                        )
        else:
            d.SetSplit(ecvl.SplitType.test)
            num_samples_test = len(d.GetSplit())
            num_batches_test = num_samples_test // batch_size
            preds = np.empty((0, num_classes), np.float64)

            for b in range(num_batches_test):
                d.LoadBatch(images)
                images.div_(255.0)
                eddl.forward(net, [images])

                print(f'Infer Batch {b + 1}/{num_batches_test}', flush=True)
                logging.info(f'Infer Batch {b + 1}/{num_batches_test}')

                # print(
                #     f'Evaluation {b + 1}/{num_batches} {net.lout[0].name}({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                #     f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})')
                # logging.info(
                #     f'Evaluation {b + 1}/{num_batches} {net.lout[0].name}({net.losses[0].name}={total_loss / net.inferenced_samples:1.3f},'
                #     f'{net.metrics[0].name}={total_metric / net.inferenced_samples:1.3f})')
                # Save network predictions
                for i in range(batch_size):
                    pred = np.array(eddlT.select(eddl.getTensor(out), i),
                                    copy=False)
                    # gt = np.argmax(np.array(labels)[indices])
                    # pred = np.append(pred, gt).reshape((1, num_classes + 1))
                    preds = np.append(preds, pred, axis=0)
                    pred_name = d.samples_[d.GetSplit()[b * batch_size +
                                                        i]].location_
                    # print(f'{pred_name};{pred}')
                    outputfile.write(f'{pred_name};{pred.tolist()}\n')
            outputfile.close()
        print('<done>')
    logfile.close()
    del net
    del out
    del in_
    return
Exemple #8
0
def main(args):
    num_classes = 8
    size = [224, 224]  # size of images

    in_ = eddl.Input([3, size[0], size[1]])
    out = VGG16(in_, num_classes)
    net = eddl.Model([in_], [out])
    eddl.build(net, eddl.sgd(0.001, 0.9), ["soft_cross_entropy"],
               ["categorical_accuracy"],
               eddl.CS_GPU([1]) if args.gpu else eddl.CS_CPU())
    eddl.summary(net)
    eddl.setlogfile(net, "skin_lesion_classification")

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(size),
        ecvl.AugMirror(.5),
        ecvl.AugFlip(.5),
        ecvl.AugRotate([-180, 180]),
        ecvl.AugAdditivePoissonNoise([0, 10]),
        ecvl.AugGammaContrast([0.5, 1.5]),
        ecvl.AugGaussianBlur([0, 0.8]),
        ecvl.AugCoarseDropout([0, 0.3], [0.02, 0.05], 0.5)
    ])
    validation_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(size),
    ])
    dataset_augs = ecvl.DatasetAugmentations(
        [training_augs, validation_augs, None])

    print("Reading dataset")
    d = ecvl.DLDataset(args.in_ds, args.batch_size, dataset_augs)
    x = Tensor([args.batch_size, d.n_channels_, size[0], size[1]])
    y = Tensor([args.batch_size, len(d.classes_)])
    num_samples_train = len(d.GetSplit())
    num_batches_train = num_samples_train // args.batch_size
    d.SetSplit(ecvl.SplitType.validation)
    num_samples_val = len(d.GetSplit())
    num_batches_val = num_samples_val // args.batch_size
    indices = list(range(args.batch_size))
    metric = eddl.getMetric("categorical_accuracy")

    print("Starting training")
    for e in range(args.epochs):
        print("Epoch {:d}/{:d} - Training".format(e + 1, args.epochs),
              flush=True)
        if args.out_dir:
            current_path = os.path.join(args.out_dir, "Epoch_%d" % e)
            for c in d.classes_:
                c_dir = os.path.join(current_path, c)
                os.makedirs(c_dir, exist_ok=True)
        d.SetSplit(ecvl.SplitType.training)
        eddl.reset_loss(net)
        total_metric = []
        s = d.GetSplit()
        random.shuffle(s)
        d.split_.training_ = s
        d.ResetAllBatches()
        for b in range(num_batches_train):
            print("Epoch {:d}/{:d} (batch {:d}/{:d}) - ".format(
                e + 1, args.epochs, b + 1, num_batches_train),
                  end="",
                  flush=True)
            d.LoadBatch(x, y)
            x.div_(255.0)
            tx, ty = [x], [y]
            eddl.train_batch(net, tx, ty, indices)
            eddl.print_loss(net, b)
            print()

        print("Saving weights")
        eddl.save(net, "isic_classification_checkpoint_epoch_%s.bin" % e,
                  "bin")

        print("Epoch %d/%d - Evaluation" % (e + 1, args.epochs), flush=True)
        d.SetSplit(ecvl.SplitType.validation)
        for b in range(num_batches_val):
            n = 0
            print("Epoch {:d}/{:d} (batch {:d}/{:d}) - ".format(
                e + 1, args.epochs, b + 1, num_batches_val),
                  end="",
                  flush=True)
            d.LoadBatch(x, y)
            x.div_(255.0)
            eddl.forward(net, [x])
            output = eddl.getOutput(out)
            sum_ = 0.0
            for k in range(args.batch_size):
                result = output.select([str(k)])
                target = y.select([str(k)])
                ca = metric.value(target, result)
                total_metric.append(ca)
                sum_ += ca
                if args.out_dir:
                    result_a = np.array(result, copy=False)
                    target_a = np.array(target, copy=False)
                    classe = np.argmax(result_a).item()
                    gt_class = np.argmax(target_a).item()
                    single_image = x.select([str(k)])
                    img_t = ecvl.TensorToView(single_image)
                    img_t.colortype_ = ecvl.ColorType.BGR
                    single_image.mult_(255.)
                    filename = d.samples_[d.GetSplit()[n]].location_[0]
                    head, tail = os.path.splitext(os.path.basename(filename))
                    bname = "%s_gt_class_%s.png" % (head, gt_class)
                    cur_path = os.path.join(current_path, d.classes_[classe],
                                            bname)
                    ecvl.ImWrite(cur_path, img_t)
                n += 1
            print("categorical_accuracy:", sum_ / args.batch_size)
        total_avg = sum(total_metric) / len(total_metric)
        print("Total categorical accuracy:", total_avg)
Exemple #9
0
def main(args):
    num_classes = 10
    size = [28, 28]  # size of images
    ctype = ecvl.ColorType.GRAY

    in_ = eddl.Input([1, size[0], size[1]])
    out = LeNet(in_, num_classes)
    net = eddl.Model([in_], [out])
    eddl.build(net, eddl.sgd(0.001, 0.9), ["soft_cross_entropy"],
               ["categorical_accuracy"],
               eddl.CS_GPU([1]) if args.gpu else eddl.CS_CPU())
    eddl.summary(net)
    eddl.setlogfile(net, "mnist")

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugRotate([-5, 5]),
        ecvl.AugAdditivePoissonNoise([0, 10]),
        ecvl.AugGaussianBlur([0, 0.8]),
        ecvl.AugCoarseDropout([0, 0.3], [0.02, 0.05], 0),
    ])
    dataset_augs = ecvl.DatasetAugmentations([training_augs, None, None])

    print("Reading dataset")
    d = ecvl.DLDataset(args.in_ds, args.batch_size, dataset_augs, ctype)
    x_train = Tensor([args.batch_size, d.n_channels_, size[0], size[1]])
    y_train = Tensor([args.batch_size, len(d.classes_)])
    num_samples = len(d.GetSplit())
    num_batches = num_samples // args.batch_size
    indices = list(range(args.batch_size))

    print("Training")
    for i in range(args.epochs):
        eddl.reset_loss(net)
        s = d.GetSplit()
        random.shuffle(s)
        d.split_.training_ = s
        d.ResetCurrentBatch()
        for j in range(num_batches):
            print("Epoch %d/%d (batch %d/%d) - " %
                  (i + 1, args.epochs, j + 1, num_batches),
                  end="",
                  flush=True)
            d.LoadBatch(x_train, y_train)
            x_train.div_(255.0)
            tx, ty = [x_train], [y_train]
            eddl.train_batch(net, tx, ty, indices)
            eddl.print_loss(net, j)
            print()

    print("Saving weights")
    eddl.save(net, "mnist_checkpoint.bin", "bin")

    print("Evaluation")
    d.SetSplit(ecvl.SplitType.test)
    num_samples = len(d.GetSplit())
    num_batches = num_samples // args.batch_size
    for i in range(num_batches):
        print("batch %d / %d - " % (i, num_batches), end="", flush=True)
        d.LoadBatch(x_train, y_train)
        x_train.div_(255.0)
        eddl.evaluate(net, [x_train], [y_train])
Exemple #10
0
def main(args):
    eddl.download_mnist()

    num_classes = 10

    in_ = eddl.Input([784])
    layer = in_
    layer = eddl.ReLu(eddl.Dense(layer, 1024))
    layer = eddl.ReLu(eddl.Dense(layer, 1024))
    layer = eddl.ReLu(eddl.Dense(layer, 1024))
    out = eddl.Softmax(eddl.Dense(layer, num_classes))
    net = eddl.Model([in_], [out])

    eddl.build(
        net, eddl.sgd(0.001, 0.9), ["softmax_cross_entropy"],
        ["categorical_accuracy"],
        eddl.CS_GPU(mem=args.mem) if args.gpu else eddl.CS_CPU(mem=args.mem))

    eddl.summary(net)
    eddl.plot(net, "model.pdf")
    eddl.setlogfile(net, "mnist")

    x_train = Tensor.load("mnist_trX.bin")
    y_train = Tensor.load("mnist_trY.bin")
    x_test = Tensor.load("mnist_tsX.bin")
    y_test = Tensor.load("mnist_tsY.bin")
    if args.small:
        x_train = x_train.select([":6000"])
        y_train = y_train.select([":6000"])
        x_test = x_test.select([":1000"])
        y_test = y_test.select([":1000"])

    x_train.div_(255.0)
    x_test.div_(255.0)

    s = x_train.shape
    num_batches = s[0] // args.batch_size
    for i in range(args.epochs):
        eddl.reset_loss(net)
        print("Epoch %d/%d (%d batches)" % (i + 1, args.epochs, num_batches))
        for j in range(num_batches):
            indices = np.random.randint(0, s[0], args.batch_size)
            eddl.train_batch(net, [x_train], [y_train], indices)

    losses1 = eddl.get_losses(net)
    metrics1 = eddl.get_metrics(net)
    for l, m in zip(losses1, metrics1):
        print("Loss: %.6f\tMetric: %.6f" % (l, m))

    s = x_test.shape
    num_batches = s[0] // args.batch_size
    for j in range(num_batches):
        indices = np.arange(j * args.batch_size,
                            j * args.batch_size + args.batch_size)
        eddl.eval_batch(net, [x_test], [y_test], indices)

    losses2 = eddl.get_losses(net)
    metrics2 = eddl.get_metrics(net)
    for l, m in zip(losses2, metrics2):
        print("Loss: %.6f\tMetric: %.6f" % (l, m))

    last_batch_size = s[0] % args.batch_size
    if last_batch_size:
        indices = np.arange(j * args.batch_size,
                            j * args.batch_size + args.batch_size)
        eddl.eval_batch(net, [x_test], [y_test], indices)

    losses3 = eddl.get_losses(net)
    metrics3 = eddl.get_metrics(net)
    for l, m in zip(losses3, metrics3):
        print("Loss: %.6f\tMetric: %.6f" % (l, m))

    print("All done")
Exemple #11
0
def main(args):
    batch_size = args.batch_size
    image_size = args.size, args.size
    thresh = 0.5

    if args.weights:
        os.makedirs(args.weights, exist_ok=True)

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(image_size,
                          ecvl.InterpolationType.cubic,
                          gt_interp=ecvl.InterpolationType.nearest),
        ecvl.AugMirror(.5),
        ecvl.AugFlip(.5),
        ecvl.AugRotate([-180, 180]),
        ecvl.AugAdditivePoissonNoise([0, 10]),
        ecvl.AugGammaContrast([0.5, 1.5]),
        ecvl.AugGaussianBlur([0, 0.8]),
        ecvl.AugCoarseDropout([0, 0.03], [0.02, 0.05], 0.25),
        ecvl.AugToFloat32(255, divisor_gt=255),
        ecvl.AugNormalize([0.6681, 0.5301, 0.5247],
                          [0.1337, 0.1480, 0.1595]),  # isic stats
    ])
    validation_test_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(image_size,
                          ecvl.InterpolationType.cubic,
                          gt_interp=ecvl.InterpolationType.nearest),
        ecvl.AugToFloat32(255, divisor_gt=255),
        ecvl.AugNormalize([0.6681, 0.5301, 0.5247],
                          [0.1337, 0.1480, 0.1595]),  # isic stats
    ])
    dataset_augs = ecvl.DatasetAugmentations(
        [training_augs, validation_test_augs, validation_test_augs])

    print('Reading dataset')
    d = ecvl.DLDataset(args.in_ds,
                       args.batch_size,
                       dataset_augs,
                       ctype=ecvl.ColorType.RGB)
    num_classes = len(d.classes_) or d.n_channels_gt_
    size = d.n_channels_, args.size, args.size

    if args.ckpts:
        net = eddl.import_net_from_onnx_file(args.ckpts, size)
    else:
        in_ = eddl.Input(size)
        out = Unet(in_, num_classes)
        out_sigm = eddl.Sigmoid(out)
        net = eddl.Model([in_], [out_sigm])

        # model_path = utils.DownloadModel(segmentation_zoo[args.model]['url'], f'{args.model}.onnx', 'model_onnx')
        # net = eddl.import_net_from_onnx_file(model_path, size)
        # eddl.removeLayer(net, segmentation_zoo[args.model]['to_remove'])
        # top = eddl.getLayer(net, segmentation_zoo[args.model]['top'])
        #
        # out = eddl.Sigmoid(eddl.Conv(top, num_classes, [3, 3], name='last_layer'))
        # data_input = eddl.getLayer(net, segmentation_zoo[args.model]['input'])  # input of the onnx
        # net = eddl.Model([data_input], [out])

    loss_name = 'binary_cross_entropy'
    metric_name = 'mean_squared_error'
    eddl.build(
        net, eddl.adam(args.learning_rate), [loss_name], [metric_name],
        eddl.CS_GPU(args.gpu, mem="low_mem") if args.gpu else eddl.CS_CPU(),
        True)
    out = eddl.getOut(net)[0]

    # if not args.ckpts:
    #     eddl.initializeLayer(net, "last_layer")

    eddl.summary(net)
    eddl.setlogfile(net, 'skin_lesion_segmentation')

    x = Tensor([args.batch_size, *size])
    y = Tensor([args.batch_size, d.n_channels_gt_, size[1], size[2]])

    miou = 0.
    if args.train:
        num_samples_train = len(d.GetSplit())
        num_batches_train = num_samples_train // args.batch_size
        num_samples_val = len(d.GetSplit(ecvl.SplitType.validation))
        num_batches_val = num_samples_val // args.batch_size
        evaluator = utils.Evaluator()

        print('Starting training')
        for e in range(args.epochs):
            d.SetSplit(ecvl.SplitType.training)
            eddl.reset_loss(net)
            s = d.GetSplit()
            random.shuffle(s)
            d.split_.training_ = s
            d.ResetAllBatches()
            for b in range(num_batches_train):
                d.LoadBatch(x, y)
                # x_ = x.select(["0"])
                # x_.normalize_(0, 1)
                # x_.mult_(255.)
                # x_.save(f'images/train_{e}_{b}.png')
                #
                # y_ = y.select(["0"])
                # # y_.mult_(255.)
                # y_.save(f'images/train_gt_{e}_{b}.png')

                eddl.train_batch(net, [x], [y])
                losses = eddl.get_losses(net)
                metrics = eddl.get_metrics(net)

                print(
                    f'Train - epoch [{e + 1}/{args.epochs}] - batch [{b + 1}/{num_batches_train}]'
                    f' - {loss_name}={losses[0]:.3f} - {metric_name}={metrics[0]:.3f}',
                    flush=True)

            d.SetSplit(ecvl.SplitType.validation)
            evaluator.ResetEval()
            eddl.reset_loss(net)

            for b in range(num_batches_val):
                n = 0
                print(
                    f'Validation - epoch [{e + 1}/{args.epochs}] - batch [{b + 1}/{num_batches_val}]'
                )
                d.LoadBatch(x, y)
                eddl.forward(net, [x])
                output = eddl.getOutput(out)
                for bs in range(args.batch_size):
                    img = output.select([str(bs)])
                    gt = y.select([str(bs)])
                    img_np = np.array(img, copy=False)
                    gt_np = np.array(gt, copy=False)
                    iou = evaluator.BinaryIoU(img_np, gt_np, thresh=thresh)
                    print(f' - IoU: {iou:.3f}', end="", flush=True)
                    if args.out_dir:
                        # C++ BinaryIoU modifies image as a side effect
                        img_np[img_np >= thresh] = 1
                        img_np[img_np < thresh] = 0
                        img_t = ecvl.TensorToView(img)
                        img_t.colortype_ = ecvl.ColorType.GRAY
                        img_t.channels_ = "xyc"
                        img.mult_(255.)
                        # orig_img
                        orig_img = x.select([str(bs)])
                        orig_img.mult_(255.)
                        orig_img_t = ecvl.TensorToImage(orig_img)
                        orig_img_t.colortype_ = ecvl.ColorType.BGR
                        orig_img_t.channels_ = "xyc"

                        tmp, labels = ecvl.Image.empty(), ecvl.Image.empty()
                        ecvl.CopyImage(img_t, tmp, ecvl.DataType.uint8)
                        ecvl.ConnectedComponentsLabeling(tmp, labels)
                        ecvl.CopyImage(labels, tmp, ecvl.DataType.uint8)
                        contours = ecvl.FindContours(tmp)
                        ecvl.CopyImage(orig_img_t, tmp, ecvl.DataType.uint8)
                        tmp_np = np.array(tmp, copy=False)
                        for cseq in contours:
                            for c in cseq:
                                tmp_np[c[0], c[1], 0] = 0
                                tmp_np[c[0], c[1], 1] = 0
                                tmp_np[c[0], c[1], 2] = 255
                        filename = d.samples_[d.GetSplit()[n]].location_[0]
                        head, tail = os.path.splitext(
                            os.path.basename(filename))
                        bname = "%s.png" % head
                        output_fn = os.path.join(args.out_dir, bname)
                        ecvl.ImWrite(output_fn, tmp)
                        if e == 0:
                            gt_t = ecvl.TensorToView(gt)
                            gt_t.colortype_ = ecvl.ColorType.GRAY
                            gt_t.channels_ = "xyc"
                            gt.mult_(255.)
                            gt_filename = d.samples_[d.GetSplit()
                                                     [n]].label_path_
                            gt_fn = os.path.join(args.out_dir,
                                                 os.path.basename(gt_filename))
                            ecvl.ImWrite(gt_fn, gt_t)
                    n += 1
                print()

            last_miou = evaluator.MIoU()
            print(
                f'Validation - epoch [{e + 1}/{args.epochs}] - Total MIoU: {last_miou:.3f}'
            )

            if last_miou > miou:
                miou = last_miou
                eddl.save_net_to_onnx_file(
                    net,
                    os.path.join(args.weights,
                                 f'isic_segm_{args.model}_epoch_{e + 1}.onnx'))
                print('Weights saved')
    elif args.test:
        evaluator = utils.Evaluator()
        evaluator.ResetEval()

        d.SetSplit(ecvl.SplitType.test)
        num_samples_test = len(d.GetSplit())
        num_batches_test = num_samples_test // batch_size
        for b in range(num_batches_test):
            n = 0
            print(f'Test - batch [{b + 1}/{num_batches_test}]')
            d.LoadBatch(x, y)
            eddl.forward(net, [x])
            output = eddl.getOutput(out)
            for bs in range(args.batch_size):
                img = output.select([str(bs)])
                gt = y.select([str(bs)])
                img_np, gt_np = np.array(img, copy=False), np.array(gt,
                                                                    copy=False)
                iou = evaluator.BinaryIoU(img_np, gt_np, thresh=thresh)
                print(f' - IoU: {iou:.3f}', end="", flush=True)
                if args.out_dir:
                    # C++ BinaryIoU modifies image as a side effect
                    img_np[img_np >= thresh] = 1
                    img_np[img_np < thresh] = 0
                    img_t = ecvl.TensorToView(img)
                    img_t.colortype_ = ecvl.ColorType.GRAY
                    img_t.channels_ = "xyc"
                    img.mult_(255.)
                    # orig_img
                    orig_img = x.select([str(bs)])
                    orig_img.mult_(255.)
                    orig_img_t = ecvl.TensorToImage(orig_img)
                    orig_img_t.colortype_ = ecvl.ColorType.BGR
                    orig_img_t.channels_ = "xyc"

                    tmp, labels = ecvl.Image.empty(), ecvl.Image.empty()
                    ecvl.CopyImage(img_t, tmp, ecvl.DataType.uint8)
                    ecvl.ConnectedComponentsLabeling(tmp, labels)
                    ecvl.CopyImage(labels, tmp, ecvl.DataType.uint8)
                    contours = ecvl.FindContours(tmp)
                    ecvl.CopyImage(orig_img_t, tmp, ecvl.DataType.uint8)
                    tmp_np = np.array(tmp, copy=False)
                    for cseq in contours:
                        for c in cseq:
                            tmp_np[c[0], c[1], 0] = 0
                            tmp_np[c[0], c[1], 1] = 0
                            tmp_np[c[0], c[1], 2] = 255
                    filename = d.samples_[d.GetSplit()[n]].location_[0]
                    head, tail = os.path.splitext(os.path.basename(filename))
                    bname = "%s.png" % head
                    output_fn = os.path.join(args.out_dir, bname)
                    ecvl.ImWrite(output_fn, tmp)

                    gt_t = ecvl.TensorToView(gt)
                    gt_t.colortype_ = ecvl.ColorType.GRAY
                    gt_t.channels_ = "xyc"
                    gt.mult_(255.)
                    gt_filename = d.samples_[d.GetSplit()[n]].label_path_
                    gt_fn = os.path.join(args.out_dir,
                                         os.path.basename(gt_filename))
                    ecvl.ImWrite(gt_fn, gt_t)
                n += 1
        miou = evaluator.MIoU()
        print(f'Test - Total MIoU: {miou:.3f}')
def main(args):
    batch_size = args.batch_size
    image_size = args.size, args.size

    if args.weights:
        os.makedirs(args.weights, exist_ok=True)

    training_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(image_size, ecvl.InterpolationType.cubic),
        ecvl.AugMirror(.5),
        ecvl.AugFlip(.5),
        ecvl.AugRotate([-180, 180]),
        ecvl.AugAdditivePoissonNoise([0, 10]),
        ecvl.AugGammaContrast([0.5, 1.5]),
        ecvl.AugGaussianBlur([0, 0.8]),
        ecvl.AugCoarseDropout([0, 0.03], [0.02, 0.05], 0.25),
        ecvl.AugToFloat32(255),
    ])
    validation_test_augs = ecvl.SequentialAugmentationContainer([
        ecvl.AugResizeDim(image_size),
        ecvl.AugToFloat32(255),
    ])
    dataset_augs = ecvl.DatasetAugmentations(
        [training_augs, validation_test_augs, validation_test_augs])

    print('Reading dataset')
    d = ecvl.DLDataset(args.in_ds,
                       args.batch_size,
                       dataset_augs,
                       ctype=ecvl.ColorType.RGB)
    num_classes = len(d.classes_)
    size = d.n_channels_, args.size, args.size

    if args.ckpts:
        net = eddl.import_net_from_onnx_file(args.ckpts, size)
    else:
        model_path = utils.DownloadModel(classification_zoo[args.model]['url'],
                                         f'{args.model}.onnx', 'model_onnx')
        net = eddl.import_net_from_onnx_file(model_path, size)
        eddl.removeLayer(net, classification_zoo[args.model]
                         ['to_remove'])  # remove last Linear of resnet
        top = eddl.getLayer(
            net,
            classification_zoo[args.model]['top'])  # get flatten of resnet

        out = eddl.Softmax(eddl.Dense(top, num_classes, True,
                                      'classifier'))  # true is for the bias
        data_input = eddl.getLayer(
            net, classification_zoo[args.model]['input'])  # input of the onnx
        net = eddl.Model([data_input], [out])

    eddl.build(
        net, eddl.adam(args.learning_rate), ['softmax_cross_entropy'],
        ['accuracy'],
        eddl.CS_GPU(args.gpu, mem="low_mem") if args.gpu else eddl.CS_CPU(),
        False)
    out = eddl.getOut(net)[0]

    if not args.ckpts:
        eddl.initializeLayer(net, "classifier")

    eddl.summary(net)
    eddl.setlogfile(net, 'skin_lesion_classification')

    x = Tensor([batch_size, *size])
    y = Tensor([batch_size, num_classes])

    metric_fn = eddl.getMetric('accuracy')
    best_accuracy = 0.
    if args.train:
        num_samples_train = len(d.GetSplit())
        num_batches_train = num_samples_train // args.batch_size
        num_samples_val = len(d.GetSplit(ecvl.SplitType.validation))
        num_batches_val = num_samples_val // args.batch_size

        print('Starting training')
        for e in range(args.epochs):
            if args.out_dir:
                current_path = os.path.join(args.out_dir, f'Epoch_{e}')
                for c in d.classes_:
                    c_dir = os.path.join(current_path, c)
                    os.makedirs(c_dir, exist_ok=True)
            d.SetSplit(ecvl.SplitType.training)
            eddl.reset_loss(net)
            s = d.GetSplit()
            random.shuffle(s)
            d.split_.training_ = s
            d.ResetAllBatches()
            for b in range(num_batches_train):
                d.LoadBatch(x, y)
                eddl.train_batch(net, [x], [y])
                losses = eddl.get_losses(net)
                metrics = eddl.get_metrics(net)

                print(
                    f'Train - epoch [{e + 1}/{args.epochs}] - batch [{b + 1}/{num_batches_train}]'
                    f' - loss={losses[0]:.3f} - accuracy={metrics[0]:.3f}',
                    flush=True)

            d.SetSplit(ecvl.SplitType.validation)
            values = np.zeros(num_batches_val)
            eddl.reset_loss(net)

            for b in range(num_batches_val):
                n = 0
                d.LoadBatch(x, y)
                eddl.forward(net, [x])
                output = eddl.getOutput(out)
                value = metric_fn.value(y, output)
                values[b] = value
                if args.out_dir:
                    for k in range(args.batch_size):
                        result = output.select([str(k)])
                        target = y.select([str(k)])
                        result_a = np.array(result, copy=False)
                        target_a = np.array(target, copy=False)
                        classe = np.argmax(result_a).item()
                        gt_class = np.argmax(target_a).item()
                        single_image = x.select([str(k)])
                        img_t = ecvl.TensorToView(single_image)
                        img_t.colortype_ = ecvl.ColorType.BGR
                        single_image.mult_(255.)
                        filename = d.samples_[d.GetSplit()[n]].location_[0]
                        head, tail = os.path.splitext(
                            os.path.basename(filename))
                        bname = '{}_gt_class_{}.png'.format(head, gt_class)
                        cur_path = os.path.join(current_path,
                                                d.classes_[classe], bname)
                        ecvl.ImWrite(cur_path, img_t)
                    n += 1

                print(
                    f'Validation - epoch [{e + 1}/{args.epochs}] - batch [{b + 1}/{num_batches_val}] -'
                    f' accuracy={np.mean(values[:b + 1] / batch_size):.3f}')

            last_accuracy = np.mean(values / batch_size)
            print(
                f'Validation - epoch [{e + 1}/{args.epochs}] - total accuracy={last_accuracy:.3f}'
            )
            if last_accuracy > best_accuracy:
                best_accuracy = last_accuracy
                print('Saving weights')
                eddl.save_net_to_onnx_file(
                    net,
                    f'isic_classification_{args.model}_epoch_{e + 1}.onnx')

    elif args.test:
        d.SetSplit(ecvl.SplitType.test)
        num_samples_test = len(d.GetSplit())
        num_batches_test = num_samples_test // batch_size
        values = np.zeros(num_batches_test)
        eddl.reset_loss(net)

        for b in range(num_batches_test):
            d.LoadBatch(x, y)
            eddl.forward(net, [x])
            output = eddl.getOutput(out)
            value = metric_fn.value(y, output)
            values[b] = value
            if args.out_dir:
                n = 0
                for k in range(args.batch_size):
                    result = output.select([str(k)])
                    target = y.select([str(k)])
                    result_a = np.array(result, copy=False)
                    target_a = np.array(target, copy=False)
                    classe = np.argmax(result_a).item()
                    gt_class = np.argmax(target_a).item()
                    single_image = x.select([str(k)])
                    img_t = ecvl.TensorToView(single_image)
                    img_t.colortype_ = ecvl.ColorType.BGR
                    single_image.mult_(255.)
                    filename = d.samples_[d.GetSplit()[n]].location_[0]
                    head, tail = os.path.splitext(os.path.basename(filename))
                    bname = "%s_gt_class_%s.png" % (head, gt_class)
                    cur_path = os.path.join(args.out_dir, d.classes_[classe],
                                            bname)
                    ecvl.ImWrite(cur_path, img_t)
                    n += 1

            print(
                f'Test - batch [{b + 1}/{num_batches_test}] - accuracy={np.mean(values[:b + 1] / batch_size):.3f}'
            )
        print(f'Test - total accuracy={np.mean(values / batch_size):.3f}')
def main(args):
    """
    Train a model on epilepsy detection with recurrent neural networks.
    """

    index_training = [args.index]
    index_validation = [args.index_val]
    patient_id = args.id
    model_id = args.model
    epochs = args.epochs
    batch_size = args.batch_size
    resume_dir = args.resume
    starting_epoch = args.starting_epoch
    gpus = args.gpus

    model_checkpoint = None

    # Create dirs for the experiment
    if resume_dir is None:
        os.makedirs('experiments', exist_ok=True)
        exp_name = f'detection_recurrent_{patient_id}_LSTM'
        exp_dir = f'experiments/{exp_name}'
        os.makedirs(exp_dir, exist_ok=False)
        os.makedirs(exp_dir + '/models')
    else:
        exp_dir = resume_dir
        model_dir = exp_dir + '/models'
        for f in os.listdir(model_dir):
            if 'last' in f:
                model_checkpoint = os.path.join(model_dir, f)
        #
        if model_checkpoint is None:
            raise Exception(f'Last model not found in {model_dir}')
        #

    log_file = open(f'{exp_dir}/training_log.txt', 'w')
    log_file.write('epoch, train_loss, train_acc, val_acc_single_channel,' +
                   ' val_f1score_single_channel, val_acc, val_f1score\n')
    log_file.flush()

    # Data Generator Object for training
    print('\n\nCreating Training Data Generator...', file=sys.stderr)
    dg = RawRecurrentDataGenerator(
        index_filenames=index_training,
        window_length=args.window_length,  # in seconds
        shift=args.shift,  # in seconds
        timesteps=args.timesteps,  # in seconds
        sampling_rate=256,  # in Hz
        batch_size=batch_size,
        in_training_mode=True,
        balance_batches=True,
        patient_id=patient_id)
    #

    print('\n\nCreating Validation Data Generator...', file=sys.stderr)
    dg_val = RawRecurrentDataGenerator(
        index_filenames=index_validation,
        window_length=args.window_length,
        shift=args.shift,
        timesteps=args.timesteps,
        sampling_rate=256,  # in Hz
        batch_size=batch_size,
        in_training_mode=False,
        patient_id=patient_id)

    net = create_model(model_id,
                       dg.input_shape,
                       num_classes=2,
                       filename=model_checkpoint,
                       gpus=gpus)
    #

    best_val_acc = 0.0

    for epoch in range(starting_epoch, epochs):

        print(f'\nTraining epoch {epoch+1} of {epochs}...', file=sys.stderr)
        dg.shuffle_data()
        # TRAINING STAGE
        eddl.reset_loss(net)

        # Set a progress bar for the training loop
        pbar = tqdm(range(len(dg)))

        for i in pbar:
            # Load batch of data
            x, y = dg[i]

            _y_ = numpy.zeros([len(y), 2])
            for i in range(2):
                _y_[y == i, i] = 1
            _y_ = _y_.reshape((len(y), 1, 2))
            y = Tensor.fromarray(_y_)

            for channel in range(x.shape[3]):
                x_channel = x[:, :, :, channel]

                channel_tensor_batch = Tensor.fromarray(x_channel)
                # Forward and backward of the channel through the net
                eddl.train_batch(net, [channel_tensor_batch], [y])

                losses = eddl.get_losses(net)
                #metrics = eddl.get_metrics(net)

                pbar.set_description(
                    f'Training[loss={losses[0]:.5f}, acc=Not Available]')

        print()

        # VALIDATION
        print(f'\nValidation epoch {epoch+1}', file=sys.stderr)

        Y_true_single_channel = list()
        Y_pred_single_channel = list()
        Y_true = list()
        Y_pred = list()

        for j in tqdm(range(len(dg_val))):
            x, y = dg_val[j]

            channels_y_pred = list()
            for channel in range(x.shape[3]):
                x_channel = x[:, :, :, channel]

                channel_tensor_batch = Tensor.fromarray(x_channel)
                # Forward and backward of the channel through the net
                (y_pred, ) = eddl.predict(net, [channel_tensor_batch])

                y_pred = y_pred.getdata()

                channels_y_pred.append(y_pred)
                Y_pred_single_channel += y_pred.argmax(axis=1).tolist()
                Y_true_single_channel += y.tolist()

            channels_y_pred = numpy.array(channels_y_pred)
            # (23, batch_size, 2)
            channels_y_pred = numpy.sum(channels_y_pred, axis=0)
            channels_y_pred = channels_y_pred / 23.0
            # print(channels_y_pred.shape) -> (batch_size, 2)

            Y_true += y.tolist()
            Y_pred += channels_y_pred.argmax(axis=1).tolist()
        #

        y_true = numpy.array(Y_true) * 1.0
        y_pred = numpy.array(Y_pred) * 1.0
        y_true_single_channel = numpy.array(Y_true_single_channel) * 1.0
        y_pred_single_channel = numpy.array(Y_pred_single_channel) * 1.0

        val_accuracy_single_channel = sum(
            y_true_single_channel == y_pred_single_channel) / len(
                y_true_single_channel)
        cnf_matrix = confusion_matrix(y_true_single_channel,
                                      y_pred_single_channel)
        report = classification_report(y_true_single_channel,
                                       y_pred_single_channel)
        fscore_single_channel = f1_score(y_true_single_channel,
                                         y_pred_single_channel,
                                         labels=[0, 1],
                                         average='macro')

        print(
            '***************************************************************\n',
            file=sys.stderr)
        print(f'Epoch {epoch + 1}: Validation results\n', file=sys.stderr)
        print(' -- Single channel results (no combination of channels) --\n',
              file=sys.stderr)
        print(f'Validation acc : {val_accuracy_single_channel}',
              file=sys.stderr)
        print(f'Validation macro f1-score : {fscore_single_channel}',
              file=sys.stderr)
        print('Confussion matrix:', file=sys.stderr)
        print(f'{cnf_matrix}\n', file=sys.stderr)
        print('Classification report:', file=sys.stderr)
        print(report, file=sys.stderr)

        print(
            '\n--------------------------------------------------------------\n',
            file=sys.stderr)

        val_accuracy = sum(y_true == y_pred) / len(y_true)
        cnf_matrix = confusion_matrix(y_true, y_pred)
        report = classification_report(y_true, y_pred)
        fscore = f1_score(y_true, y_pred, labels=[0, 1], average='macro')

        print(' -- All channels involved (combined for each timestamp) --\n',
              file=sys.stderr)
        print(f'Validation acc : {val_accuracy}', file=sys.stderr)
        print(f'Validation macro f1-score : {fscore}', file=sys.stderr)
        print('Confussion matrix:', file=sys.stderr)
        print(f'{cnf_matrix}\n', file=sys.stderr)
        print('Classification report:', file=sys.stderr)
        print(report, file=sys.stderr)
        print(
            '***************************************************************\n\n',
            file=sys.stderr)

        log_file.write('%d,%d,%g,%g,%g,%g,%g\n' %
                       (epoch, -1, losses[0], val_accuracy_single_channel,
                        fscore_single_channel, val_accuracy, fscore))

        log_file.flush()

        # Save best model
        if (val_accuracy > best_val_acc):
            best_val_acc = val_accuracy
            eddl.save_net_to_onnx_file(
                net,
                f'{exp_dir}/models/best_model_epoch_{epoch:04d}_val_acc_{val_accuracy:.4f}.onnx'
            )

        eddl.save_net_to_onnx_file(net, f'{exp_dir}/models/last.onnx')

    #
    log_file.close()
Exemple #14
0
def main(args):
    eddl.download_drive()

    in_1 = eddl.Input([3, 584, 584])
    in_2 = eddl.Input([1, 584, 584])
    layer = eddl.Concat([in_1, in_2])

    layer = eddl.RandomCropScale(layer, [0.9, 1.0])
    layer = eddl.CenteredCrop(layer, [512, 512])
    img = eddl.Select(layer, ["0:3"])
    mask = eddl.Select(layer, ["3"])

    # DA net
    danet = eddl.Model([in_1, in_2], [])
    eddl.build(danet)
    if args.gpu:
        eddl.toGPU(danet, mem="low_mem")
    eddl.summary(danet)

    # SegNet
    in_ = eddl.Input([3, 512, 512])
    out = eddl.Sigmoid(UNetWithPadding(in_))
    segnet = eddl.Model([in_], [out])
    eddl.build(
        segnet,
        eddl.adam(0.00001),  # Optimizer
        ["mse"],  # Losses
        ["mse"],  # Metrics
        eddl.CS_GPU(mem=args.mem) if args.gpu else eddl.CS_CPU(mem=args.mem)
    )
    eddl.summary(segnet)

    print("Reading training data")
    # x_train_f = Tensor.fromarray(np.load("drive_trX.npy").astype(np.float32))
    x_train_f = Tensor.load("drive_trX.bin")
    x_train = x_train_f.permute([0, 3, 1, 2])
    x_train.info()
    x_train.div_(255.0)

    print("Reading test data")
    # y_train = Tensor.fromarray(np.load("drive_trY.npy").astype(np.float32))
    y_train = Tensor.load("drive_trY.bin")
    y_train.info()
    y_train.reshape_([20, 1, 584, 584])
    y_train.div_(255.0)

    xbatch = Tensor([args.batch_size, 3, 584, 584])
    ybatch = Tensor([args.batch_size, 1, 584, 584])

    print("Starting training")
    for i in range(args.epochs):
        print("\nEpoch %d/%d" % (i + 1, args.epochs))
        eddl.reset_loss(segnet)
        for j in range(args.num_batches):
            eddl.next_batch([x_train, y_train], [xbatch, ybatch])
            # DA net
            eddl.forward(danet, [xbatch, ybatch])
            xbatch_da = eddl.getOutput(img)
            ybatch_da = eddl.getOutput(mask)
            # SegNet
            eddl.train_batch(segnet, [xbatch_da], [ybatch_da])
            eddl.print_loss(segnet, j)
            if i == args.epochs - 1:
                yout = eddl.getOutput(out).select(["0"])
                yout.save("./out_%d.jpg" % j)
            print()
    print("All done")