Ejemplo n.º 1
0
def save_best_model(encoder_model, decoder_model, encoder_optimizer,
                    decoder_optimizer, hidden_size, layers, epoch, file_name):
    """
    Save the best model
    :param encoder_model: A trained encoder model
    :param decoder_model: A trained decoder model
    :param encoder_optimizer: Encoder optimizer
    :param decoder_optimizer: Decoder optimizer
    :param file_name: Output file name
    :return:
    """
    if os.path.isfile(file_name):
        os.remove(file_name)
    ModelHandler.save_checkpoint(
        {
            'encoder_state_dict': encoder_model.state_dict(),
            'decoder_state_dict': decoder_model.state_dict(),
            'encoder_optimizer': encoder_optimizer.state_dict(),
            'decoder_optimizer': decoder_optimizer.state_dict(),
            'hidden_size': hidden_size,
            'gru_layers': layers,
            'epochs': epoch,
        }, file_name)
    sys.stderr.write(TextColor.RED + "\nMODEL SAVED SUCCESSFULLY.\n" +
                     TextColor.END)
Ejemplo n.º 2
0
def do_test(test_file, batch_size, gpu_mode, num_workers, model_path,
            output_directory, print_details):
    """
    Train a model and save
    :param test_file: A CSV file containing test image information
    :param batch_size: Batch size for training
    :param gpu_mode: If true the model will be trained on GPU
    :param num_workers: Number of workers for data loading
    :param model_path: Path to a saved model
    :param num_classes: Number of output classes
    :return:
    """
    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)

    if os.path.isfile(model_path) is False:
        sys.stderr.write(TextColor.RED + "ERROR: INVALID PATH TO MODEL\n")
        exit(1)

    sys.stderr.write(TextColor.GREEN + "INFO: MODEL LOADING\n" + TextColor.END)

    transducer_model, hidden_size, gru_layers, prev_ite = \
        ModelHandler.load_simple_model(model_path,
                                       input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                       image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                       seq_len=ImageSizeOptions.SEQ_LENGTH,
                                       num_base_classes=ImageSizeOptions.TOTAL_BASE_LABELS,
                                       num_rle_classes=ImageSizeOptions.TOTAL_RLE_LABELS)

    sys.stderr.write(TextColor.GREEN + "INFO: MODEL LOADED\n" + TextColor.END)

    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()

    stats_dictionary = test(
        test_file,
        batch_size,
        gpu_mode,
        transducer_model,
        num_workers,
        gru_layers,
        hidden_size,
        num_base_classes=ImageSizeOptions.TOTAL_BASE_LABELS,
        num_rle_classes=ImageSizeOptions.TOTAL_RLE_LABELS,
        output_directory=output_directory,
        print_details=print_details)

    save_rle_confusion_matrix(stats_dictionary)
    save_base_confusion_matrix(stats_dictionary)

    sys.stderr.write(TextColor.PURPLE + 'DONE\n' + TextColor.END)
Ejemplo n.º 3
0
def save_best_model(transducer_model, model_optimizer, hidden_size, layers,
                    epoch, file_name):
    """
    Save the best model
    :param transducer_model: A trained model
    :param model_optimizer: Model optimizer
    :param hidden_size: Number of hidden layers
    :param layers: Number of GRU layers to use
    :param epoch: Epoch/iteration number
    :param file_name: Output file name
    :return:
    """
    if os.path.isfile(file_name):
        os.remove(file_name)
    ModelHandler.save_checkpoint(
        {
            'model_state_dict': transducer_model.state_dict(),
            'model_optimizer': model_optimizer.state_dict(),
            'hidden_size': hidden_size,
            'gru_layers': layers,
            'epochs': epoch,
        }, file_name)
    sys.stderr.write(TextColor.RED + "\nMODEL SAVED SUCCESSFULLY.\n" +
                     TextColor.END)
Ejemplo n.º 4
0
def train(train_file, test_file, batch_size, epoch_limit, gpu_mode,
          num_workers, retrain_model, retrain_model_path, gru_layers,
          hidden_size, lr, decay, model_dir, stats_dir, train_mode):

    if train_mode is True:
        train_loss_logger = open(stats_dir + "train_loss.csv", 'w')
        test_loss_logger = open(stats_dir + "test_loss.csv", 'w')
        confusion_matrix_logger = open(stats_dir + "confusion_matrix.txt", 'w')
    else:
        train_loss_logger = None
        test_loss_logger = None
        confusion_matrix_logger = None

    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)
    train_data_set = SequenceDataset(train_file)
    train_loader = DataLoader(train_data_set,
                              batch_size=batch_size,
                              shuffle=True,
                              num_workers=num_workers,
                              pin_memory=gpu_mode)
    num_classes = ImageSizeOptions.TOTAL_LABELS

    if retrain_model is True:
        if os.path.isfile(retrain_model_path) is False:
            sys.stderr.write(
                TextColor.RED +
                "ERROR: INVALID PATH TO RETRAIN PATH MODEL --retrain_model_path\n"
            )
            exit(1)
        sys.stderr.write(TextColor.GREEN + "INFO: RETRAIN MODEL LOADING\n" +
                         TextColor.END)
        transducer_model, hidden_size, gru_layers, prev_ite = \
            ModelHandler.load_simple_model_for_training(retrain_model_path,
                                                        input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                                        image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                                        seq_len=ImageSizeOptions.SEQ_LENGTH,
                                                        num_classes=num_classes)

        if train_mode is True:
            epoch_limit = prev_ite + epoch_limit

        sys.stderr.write(TextColor.GREEN + "INFO: RETRAIN MODEL LOADED\n" +
                         TextColor.END)
    else:
        transducer_model = ModelHandler.get_new_gru_model(
            input_channels=ImageSizeOptions.IMAGE_CHANNELS,
            image_features=ImageSizeOptions.IMAGE_HEIGHT,
            gru_layers=gru_layers,
            hidden_size=hidden_size,
            num_classes=num_classes)
        prev_ite = 0

    param_count = sum(p.numel() for p in transducer_model.parameters()
                      if p.requires_grad)
    sys.stderr.write(TextColor.RED + "INFO: TOTAL TRAINABLE PARAMETERS:\t" +
                     str(param_count) + "\n" + TextColor.END)

    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()

    class_weights = torch.Tensor(CLASS_WEIGHTS)
    # Loss
    criterion = nn.CrossEntropyLoss(class_weights)

    if gpu_mode is True:
        criterion = criterion.cuda()

    model_optimizer = torch.optim.Adam(transducer_model.parameters(),
                                       lr=lr,
                                       weight_decay=decay)
    lr_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
        model_optimizer, 'min')

    if retrain_model is True:
        sys.stderr.write(TextColor.GREEN + "INFO: OPTIMIZER LOADING\n" +
                         TextColor.END)
        model_optimizer = ModelHandler.load_simple_optimizer(
            model_optimizer, retrain_model_path, gpu_mode)
        sys.stderr.write(TextColor.GREEN + "INFO: OPTIMIZER LOADED\n" +
                         TextColor.END)

    start_epoch = prev_ite

    # Train the Model
    sys.stderr.write(TextColor.PURPLE + 'Training starting\n' + TextColor.END)
    stats = dict()
    stats['loss_epoch'] = []
    stats['accuracy_epoch'] = []
    sys.stderr.write(TextColor.BLUE + 'Start: ' + str(start_epoch + 1) +
                     ' End: ' + str(epoch_limit) + "\n")
    for epoch in range(start_epoch, epoch_limit, 1):
        total_loss = 0
        total_images = 0
        sys.stderr.write(TextColor.BLUE + 'Train epoch: ' + str(epoch + 1) +
                         "\n")
        # make sure the model is in train mode. BN is different in train and eval.

        batch_no = 1
        with tqdm(total=len(train_loader), desc='Loss', leave=True,
                  ncols=100) as progress_bar:
            transducer_model.train()
            for images, labels in train_loader:
                labels = labels.type(torch.LongTensor)
                images = images.type(torch.FloatTensor)

                if gpu_mode:
                    # encoder_hidden = encoder_hidden.cuda()
                    images = images.cuda()
                    labels = labels.cuda()

                hidden = torch.zeros(images.size(0),
                                     2 * TrainOptions.GRU_LAYERS,
                                     TrainOptions.HIDDEN_SIZE)

                if gpu_mode:
                    hidden = hidden.cuda()

                for i in range(0, ImageSizeOptions.SEQ_LENGTH,
                               TrainOptions.WINDOW_JUMP):
                    model_optimizer.zero_grad()

                    if i + TrainOptions.TRAIN_WINDOW > ImageSizeOptions.SEQ_LENGTH:
                        break
                    image_chunk = images[:, i:i + TrainOptions.TRAIN_WINDOW]
                    label_chunk = labels[:, i:i + TrainOptions.TRAIN_WINDOW]

                    output_, hidden = transducer_model(image_chunk, hidden)

                    loss = criterion(
                        output_.contiguous().view(-1, num_classes),
                        label_chunk.contiguous().view(-1))

                    loss.backward()
                    model_optimizer.step()

                    total_loss += loss.item()
                    total_images += image_chunk.size(0)

                    hidden = hidden.detach()

                # update the progress bar
                avg_loss = (total_loss / total_images) if total_images else 0
                progress_bar.set_description("Loss: " + str(avg_loss))

                if train_mode is True:
                    train_loss_logger.write(
                        str(epoch + 1) + "," + str(batch_no) + "," +
                        str(avg_loss) + "\n")
                progress_bar.refresh()
                progress_bar.update(1)
                batch_no += 1

            progress_bar.close()

        stats_dictioanry = test(test_file,
                                batch_size,
                                gpu_mode,
                                transducer_model,
                                num_workers,
                                gru_layers,
                                hidden_size,
                                num_classes=ImageSizeOptions.TOTAL_LABELS)
        stats['loss'] = stats_dictioanry['loss']
        stats['accuracy'] = stats_dictioanry['accuracy']
        stats['loss_epoch'].append((epoch, stats_dictioanry['loss']))
        stats['accuracy_epoch'].append((epoch, stats_dictioanry['accuracy']))

        lr_scheduler.step(stats['loss'])

        # update the loggers
        if train_mode is True:
            # save the model after each epoch
            # encoder_model, decoder_model, encoder_optimizer, decoder_optimizer, hidden_size, layers, epoch,
            # file_name
            save_best_model(
                transducer_model, model_optimizer, hidden_size, gru_layers,
                epoch,
                model_dir + "_epoch_" + str(epoch + 1) + '_checkpoint.pkl')

            test_loss_logger.write(
                str(epoch + 1) + "," + str(stats['loss']) + "," +
                str(stats['accuracy']) + "\n")
            confusion_matrix_logger.write(
                str(epoch + 1) + "\n" +
                str(stats_dictioanry['confusion_matrix']) + "\n")
            train_loss_logger.flush()
            test_loss_logger.flush()
            confusion_matrix_logger.flush()
        else:
            # this setup is for hyperband
            if epoch + 1 >= 10 and stats['accuracy'] < 98:
                sys.stderr.write(
                    TextColor.PURPLE +
                    'EARLY STOPPING AS THE MODEL NOT DOING WELL\n' +
                    TextColor.END)
                return transducer_model, model_optimizer, stats

    sys.stderr.write(TextColor.PURPLE + 'Finished training\n' + TextColor.END)

    return transducer_model, model_optimizer, stats
Ejemplo n.º 5
0
def predict(test_file, output_filename, model_path, batch_size, threads, num_workers, gpu_mode):
    """
    Create a prediction table/dictionary of an images set using a trained model.
    :param test_file: File to predict on
    :param batch_size: Batch size used for prediction
    :param model_path: Path to a trained model
    :param gpu_mode: If true, predictions will be done over GPU
    :param threads: Number of threads to set for pytorch
    :param num_workers: Number of workers to be used by the dataloader
    :return: Prediction dictionary
    """
    prediction_data_file = DataStore(output_filename, mode='w')
    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)

    torch.set_num_threads(threads)
    sys.stderr.write(TextColor.GREEN + 'INFO: TORCH THREADS SET TO: ' + str(torch.get_num_threads()) + ".\n"
                     + TextColor.END)
    sys.stderr.flush()

    # data loader
    test_data = SequenceDataset(test_file, load_labels=True)
    test_loader = DataLoader(test_data,
                             batch_size=batch_size,
                             shuffle=False,
                             num_workers=num_workers)

    transducer_model, hidden_size, gru_layers, prev_ite = \
        ModelHandler.load_simple_model_for_training(model_path,
                                                    input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                                    image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                                    seq_len=ImageSizeOptions.SEQ_LENGTH,
                                                    num_classes=ImageSizeOptions.TOTAL_LABELS)
    transducer_model.eval()

    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()
    sys.stderr.write(TextColor.CYAN + 'MODEL LOADED\n')

    with torch.no_grad():
        for contig, contig_start, contig_end, chunk_id, images, position, index, ref_seq, coverage, labels in tqdm(test_loader, ncols=50):
            sys.stderr.flush()
            images = images.type(torch.FloatTensor)
            if gpu_mode:
                images = images.cuda()

            prediction_base_counter_h1 = np.zeros((images.size(0), ImageSizeOptions.SEQ_LENGTH, ImageSizeOptions.TOTAL_LABELS))
            prediction_base_counter_h2 = np.zeros((images.size(0), ImageSizeOptions.SEQ_LENGTH, ImageSizeOptions.TOTAL_LABELS))

            prediction_base_probs_h1 = np.zeros((images.size(0), ImageSizeOptions.SEQ_LENGTH, ImageSizeOptions.TOTAL_LABELS))
            prediction_base_probs_h2 = np.zeros((images.size(0), ImageSizeOptions.SEQ_LENGTH, ImageSizeOptions.TOTAL_LABELS))

            for i in range(0, ImageSizeOptions.SEQ_LENGTH, TrainOptions.WINDOW_JUMP):
                if i + TrainOptions.TRAIN_WINDOW > ImageSizeOptions.SEQ_LENGTH:
                    break
                chunk_start = i
                chunk_end = i + TrainOptions.TRAIN_WINDOW
                # chunk all the data
                label_chunk_h1 = labels[:, 0, i:i+TrainOptions.TRAIN_WINDOW]
                label_chunk_h2 = labels[:, 1, i:i+TrainOptions.TRAIN_WINDOW]

                predicted_base_label_h1 = label_chunk_h1.numpy().tolist()
                predicted_base_label_h2 = label_chunk_h2.numpy().tolist()

                for ii in range(0, len(predicted_base_label_h1)):
                    chunk_pos = chunk_start
                    for base in predicted_base_label_h1[ii]:
                        prediction_base_counter_h1[ii][chunk_pos][base] += 1
                        chunk_pos += 1

                for ii in range(0, len(predicted_base_label_h2)):
                    chunk_pos = chunk_start
                    for base in predicted_base_label_h2[ii]:
                        prediction_base_counter_h2[ii][chunk_pos][base] += 1
                        chunk_pos += 1

            predicted_base_labels_h1 = np.argmax(np.array(prediction_base_counter_h1), axis=2)
            predicted_base_labels_h2 = np.argmax(np.array(prediction_base_counter_h2), axis=2)

            for i in range(images.size(0)):
                prediction_data_file.write_prediction(contig[i], contig_start[i], contig_end[i], chunk_id[i],
                                                      position[i], index[i],
                                                      ref_seq[i],
                                                      coverage[i],
                                                      prediction_base_probs_h1[i],
                                                      prediction_base_probs_h2[i],
                                                      predicted_base_labels_h1[i],
                                                      predicted_base_labels_h2[i])
Ejemplo n.º 6
0
def predict(test_file, output_filename, model_path, batch_size, num_workers,
            gpu_mode):
    """
    Create a prediction table/dictionary of an images set using a trained model.
    :param test_file: File to predict on
    :param batch_size: Batch size used for prediction
    :param model_path: Path to a trained model
    :param gpu_mode: If true, predictions will be done over GPU
    :param num_workers: Number of workers to be used by the dataloader
    :return: Prediction dictionary
    """
    prediction_data_file = DataStore(output_filename, mode='w')
    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)

    # data loader
    test_data = SequenceDataset(test_file)
    test_loader = DataLoader(test_data,
                             batch_size=batch_size,
                             shuffle=False,
                             num_workers=num_workers)

    transducer_model, hidden_size, gru_layers, prev_ite = \
        ModelHandler.load_simple_model_for_training(model_path,
                                                    input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                                    image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                                    seq_len=ImageSizeOptions.SEQ_LENGTH,
                                                    num_classes=ImageSizeOptions.TOTAL_LABELS)
    transducer_model.eval()

    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()
    sys.stderr.write(TextColor.CYAN + 'MODEL LOADED\n')

    with torch.no_grad():
        for contig, contig_start, contig_end, chunk_id, images, position, index in tqdm(
                test_loader, ncols=50):
            images = images.type(torch.FloatTensor)
            if gpu_mode:
                # encoder_hidden = encoder_hidden.cuda()
                images = images.cuda()

            hidden = torch.zeros(images.size(0), 2 * TrainOptions.GRU_LAYERS,
                                 TrainOptions.HIDDEN_SIZE)

            if gpu_mode:
                hidden = hidden.cuda()

            prediction_base_dict = np.zeros((images.size(0), images.size(1),
                                             ImageSizeOptions.TOTAL_LABELS))

            for i in range(0, ImageSizeOptions.SEQ_LENGTH,
                           TrainOptions.WINDOW_JUMP):
                if i + TrainOptions.TRAIN_WINDOW > ImageSizeOptions.SEQ_LENGTH:
                    break
                chunk_start = i
                chunk_end = i + TrainOptions.TRAIN_WINDOW
                # chunk all the data
                image_chunk = images[:, chunk_start:chunk_end]

                # run inference
                output_base, hidden = transducer_model(image_chunk, hidden)

                # do softmax and get prediction
                m = nn.Softmax(dim=2)
                soft_probs = m(output_base)
                output_preds = soft_probs.cpu()
                base_max_value, predicted_base_label = torch.max(output_preds,
                                                                 dim=2)

                # convert everything to list
                base_max_value = base_max_value.numpy().tolist()
                predicted_base_label = predicted_base_label.numpy().tolist()

                assert (len(base_max_value) == len(predicted_base_label))

                for ii in range(0, len(predicted_base_label)):
                    chunk_pos = chunk_start
                    for p_base, base in zip(base_max_value[ii],
                                            predicted_base_label[ii]):
                        prediction_base_dict[ii][chunk_pos][base] += p_base
                        chunk_pos += 1
            predicted_base_labels = np.argmax(np.array(prediction_base_dict),
                                              axis=2)

            for i in range(images.size(0)):
                prediction_data_file.write_prediction(
                    contig[i], contig_start[i], contig_end[i], chunk_id[i],
                    position[i], index[i], predicted_base_labels[i])
Ejemplo n.º 7
0
def train(train_file, test_file, batch_size, epoch_limit, gpu_mode,
          num_workers, retrain_model, retrain_model_path, gru_layers,
          hidden_size, encoder_lr, encoder_decay, decoder_lr, decoder_decay,
          model_dir, stats_dir, train_mode):

    if train_mode is True:
        train_loss_logger = open(stats_dir + "train_loss.csv", 'w')
        test_loss_logger = open(stats_dir + "test_loss.csv", 'w')
        confusion_matrix_logger = open(stats_dir + "confusion_matrix.txt", 'w')
    else:
        train_loss_logger = None
        test_loss_logger = None
        confusion_matrix_logger = None

    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)
    train_data_set = SequenceDataset(train_file)
    train_loader = DataLoader(train_data_set,
                              batch_size=batch_size,
                              shuffle=True,
                              num_workers=num_workers,
                              pin_memory=gpu_mode)
    if retrain_model is True:
        if os.path.isfile(retrain_model_path) is False:
            sys.stderr.write(
                TextColor.RED +
                "ERROR: INVALID PATH TO RETRAIN PATH MODEL --retrain_model_path\n"
            )
            exit(1)
        sys.stderr.write(TextColor.GREEN + "INFO: RETRAIN MODEL LOADING\n" +
                         TextColor.END)
        encoder_model, decoder_model, hidden_size, gru_layers, prev_ite = \
            ModelHandler.load_model_for_training(retrain_model_path,
                                                 input_channels=5,
                                                 seq_len=ImageSizeOptions.SEQ_LENGTH,
                                                 num_classes=3)

        if train_mode is True:
            epoch_limit = prev_ite + epoch_limit

        sys.stderr.write(TextColor.GREEN + "INFO: RETRAIN MODEL LOADED\n" +
                         TextColor.END)
    else:
        encoder_model, decoder_model = ModelHandler.get_new_model(
            input_channels=5,
            gru_layers=gru_layers,
            hidden_size=hidden_size,
            seq_len=ImageSizeOptions.SEQ_LENGTH,
            num_classes=3)
        prev_ite = 0

    encoder_optimizer = torch.optim.Adam(encoder_model.parameters(),
                                         lr=encoder_lr,
                                         weight_decay=encoder_decay)
    decoder_optimizer = torch.optim.Adam(decoder_model.parameters(),
                                         lr=decoder_lr,
                                         weight_decay=decoder_decay)

    if retrain_model is True:
        sys.stderr.write(TextColor.GREEN + "INFO: OPTIMIZER LOADING\n" +
                         TextColor.END)
        encoder_optimizer, decoder_optimizer = ModelHandler.load_optimizer(
            encoder_optimizer, decoder_optimizer, retrain_model_path, gpu_mode)
        sys.stderr.write(TextColor.GREEN + "INFO: OPTIMIZER LOADED\n" +
                         TextColor.END)

    if gpu_mode:
        encoder_model = torch.nn.DataParallel(encoder_model).cuda()
        decoder_model = torch.nn.DataParallel(decoder_model).cuda()

    class_weights = torch.FloatTensor(CLASS_WEIGHTS)
    # Loss
    criterion = nn.CrossEntropyLoss(weight=class_weights)

    if gpu_mode is True:
        criterion = criterion.cuda()

    start_epoch = prev_ite

    # Train the Model
    sys.stderr.write(TextColor.PURPLE + 'Training starting\n' + TextColor.END)
    stats = dict()
    stats['loss_epoch'] = []
    stats['accuracy_epoch'] = []
    sys.stderr.write(TextColor.PURPLE + 'Start: ' + str(start_epoch + 1) +
                     ' End: ' + str(epoch_limit + 1) + "\n")
    for epoch in range(start_epoch, epoch_limit, 1):
        total_loss = 0
        total_images = 0
        sys.stderr.write(TextColor.BLUE + 'Train epoch: ' + str(epoch + 1) +
                         "\n")
        # make sure the model is in train mode. BN is different in train and eval.
        encoder_model.train()
        decoder_model.train()
        batch_no = 1
        with tqdm(total=len(train_loader), desc='Loss', leave=True,
                  ncols=100) as progress_bar:
            for images, labels in train_loader:
                # print(images.size(), labels.size())

                # from modules.python.helper.tensor_analyzer import analyze_tensor
                # for label in labels[0].data:
                #     print(label.item(), end='')
                # print()
                # analyze_tensor(images[0])
                # exit()
                if gpu_mode:
                    # encoder_hidden = encoder_hidden.cuda()
                    images = images.cuda()
                    labels = labels.cuda()

                encoder_hidden = torch.FloatTensor(images.size(0),
                                                   gru_layers * 2,
                                                   hidden_size).zero_()

                if gpu_mode:
                    encoder_hidden = encoder_hidden.cuda()

                encoder_optimizer.zero_grad()
                decoder_optimizer.zero_grad()

                loss = 0
                total_seq_length = images.size(2)
                start_index = 0
                end_index = images.size(2)

                # from analysis.analyze_png_img import analyze_tensor
                # print(labels[0, :].data.numpy())
                # analyze_tensor(images[0, :, :, :])
                # exit()
                context_vector, hidden_encoder = encoder_model(
                    images, encoder_hidden)

                for seq_index in range(start_index, end_index):
                    current_batch_size = images.size(0)
                    y = labels[:, seq_index - start_index]
                    attention_index = torch.from_numpy(
                        np.asarray([seq_index] * current_batch_size)).view(
                            -1, 1)

                    attention_index_onehot = torch.FloatTensor(
                        current_batch_size, total_seq_length)

                    attention_index_onehot.zero_()
                    attention_index_onehot.scatter_(1, attention_index, 1)
                    # print("\n", seq_index, attention_index_onehot)
                    # exit()

                    output_dec, decoder_hidden, attn = decoder_model(
                        attention_index_onehot,
                        context_vector=context_vector,
                        encoder_hidden=hidden_encoder)
                    # loss
                    loss += criterion(output_dec, y)

                loss.backward()
                encoder_optimizer.step()
                decoder_optimizer.step()

                total_loss += loss.item()
                total_images += labels.size(0)

                # update the progress bar
                avg_loss = (total_loss / total_images) if total_images else 0
                progress_bar.set_description("Loss: " + str(avg_loss))
                if train_mode is True:
                    train_loss_logger.write(
                        str(epoch + 1) + "," + str(batch_no) + "," +
                        str(avg_loss) + "\n")
                progress_bar.refresh()
                progress_bar.update(1)
                batch_no += 1

            progress_bar.close()

        stats_dictioanry = test(test_file,
                                batch_size,
                                gpu_mode,
                                encoder_model,
                                decoder_model,
                                num_workers,
                                gru_layers,
                                hidden_size,
                                num_classes=3)
        stats['loss'] = stats_dictioanry['loss']
        stats['accuracy'] = stats_dictioanry['accuracy']
        stats['loss_epoch'].append((epoch, stats_dictioanry['loss']))
        stats['accuracy_epoch'].append((epoch, stats_dictioanry['accuracy']))

        # update the loggers
        if train_mode is True:
            # save the model after each epoch
            # encoder_model, decoder_model, encoder_optimizer, decoder_optimizer, hidden_size, layers, epoch,
            # file_name
            save_best_model(
                encoder_model, decoder_model, encoder_optimizer,
                decoder_optimizer, hidden_size, gru_layers, epoch,
                model_dir + "_epoch_" + str(epoch + 1) + '_checkpoint.pkl')

            test_loss_logger.write(
                str(epoch + 1) + "," + str(stats['loss']) + "," +
                str(stats['accuracy']) + "\n")
            confusion_matrix_logger.write(
                str(epoch + 1) + "\n" +
                str(stats_dictioanry['confusion_matrix']) + "\n")
            train_loss_logger.flush()
            test_loss_logger.flush()
            confusion_matrix_logger.flush()
        else:
            # this setup is for hyperband
            if epoch + 1 >= 2 and stats['accuracy'] < 90:
                sys.stderr.write(
                    TextColor.PURPLE +
                    'EARLY STOPPING AS THE MODEL NOT DOING WELL\n' +
                    TextColor.END)
                return encoder_model, decoder_model, encoder_optimizer, decoder_optimizer, stats

    sys.stderr.write(TextColor.PURPLE + 'Finished training\n' + TextColor.END)

    return encoder_model, decoder_model, encoder_optimizer, decoder_optimizer, stats
Ejemplo n.º 8
0
def predict(test_file, output_filename, model_path, batch_size, num_workers,
            threads, gpu_mode):
    """
    The predict method loads images generated by MarginPolish and produces base predictions using a
    sequence transduction model based deep neural network. This method loads the model and iterates over
    minibatch images to generate the predictions and saves the predictions to a hdf5 file.

    :param test_file: File to predict on
    :param output_filename: Name and path to the output file
    :param batch_size: Batch size used for minibatch prediction
    :param model_path: Path to a trained model
    :param gpu_mode: If true, predictions will be done over GPU
    :param num_workers: Number of workers to be used by the dataloader
    :param threads: Number of threads to use with pytorch
    :return: Prediction dictionary
    """
    # create the output hdf5 file where all the predictions will be saved
    prediction_data_file = DataStore(output_filename, mode='w')
    torch.set_num_threads(threads)
    sys.stderr.write(TextColor.GREEN + 'INFO: TORCH THREADS SET TO: ' +
                     str(torch.get_num_threads()) + ".\n" + TextColor.END)

    # notify that the process has started and loading data
    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)

    # create a pytorch dataset and dataloader that loads the data in mini_batches
    test_data = SequenceDataset(test_file)
    test_loader = DataLoader(test_data,
                             batch_size=batch_size,
                             shuffle=False,
                             num_workers=num_workers)

    # load the model using the model path
    transducer_model, hidden_size, gru_layers, prev_ite = \
        ModelHandler.load_simple_model(model_path,
                                       input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                       image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                       seq_len=ImageSizeOptions.SEQ_LENGTH,
                                       num_base_classes=ImageSizeOptions.TOTAL_BASE_LABELS,
                                       num_rle_classes=ImageSizeOptions.TOTAL_RLE_LABELS)

    # set the model to evaluation mode.
    transducer_model.eval()

    # if gpu mode is True, then load the model in the GPUs
    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()

    # notify that the model has loaded successfully
    sys.stderr.write(TextColor.CYAN + 'MODEL LOADED\n')

    # iterate over the data in minibatches
    with torch.no_grad():
        # the dataloader loop, iterates in minibatches. tqdm is the progress logger.
        for contig, contig_start, contig_end, chunk_id, images, position, filename in tqdm(
                test_loader, ncols=50):
            # the images are usually in uint8, convert them to FloatTensor
            images = images.type(torch.FloatTensor)
            # initialize the first hidden input as all zeros
            hidden = torch.zeros(images.size(0), 2 * TrainOptions.GRU_LAYERS,
                                 TrainOptions.HIDDEN_SIZE)

            # if gpu_mode is True, transfer the image and hidden tensors to the GPU
            if gpu_mode:
                images = images.cuda()
                hidden = hidden.cuda()

            # this is a multi-task neural network where we predict a base and a run-length. We use two dictionaries
            # to keep track of predictions.
            # these two dictionaries save predictions for each of the chunks and later we aggregate all the predictions
            # over the entire sequence to get a sequence prediction for the whole sequence.
            prediction_base_tensor = torch.zeros(
                (images.size(0), images.size(1),
                 ImageSizeOptions.TOTAL_BASE_LABELS))
            prediction_rle_tensor = torch.zeros(
                (images.size(0), images.size(1),
                 ImageSizeOptions.TOTAL_RLE_LABELS))

            if gpu_mode:
                prediction_base_tensor = prediction_base_tensor.cuda()
                prediction_rle_tensor = prediction_rle_tensor.cuda()

            # now the images usually contain 1000 bases, we iterate on a sliding window basis where we process
            # the window size then jump to the next window
            for i in range(0, ImageSizeOptions.SEQ_LENGTH,
                           TrainOptions.WINDOW_JUMP):
                # if current position + window size goes beyond the size of the window, that means we've reached the end
                if i + TrainOptions.TRAIN_WINDOW > ImageSizeOptions.SEQ_LENGTH:
                    break
                chunk_start = i
                chunk_end = i + TrainOptions.TRAIN_WINDOW

                # get the image chunk
                image_chunk = images[:, chunk_start:chunk_end]

                # run inference
                output_base, output_rle, hidden = transducer_model(
                    image_chunk, hidden)

                # now calculate how much padding is on the top and bottom of this chunk so we can do a simple
                # add operation
                top_zeros = chunk_start
                bottom_zeros = ImageSizeOptions.SEQ_LENGTH - chunk_end

                # we run a softmax a padding to make the output tensor compatible for adding
                inference_layers = nn.Sequential(
                    nn.Softmax(dim=2),
                    nn.ZeroPad2d((0, 0, top_zeros, bottom_zeros)))
                if gpu_mode:
                    inference_layers = inference_layers.cuda()

                # run the softmax and padding layers
                base_prediction = inference_layers(output_base)
                rle_prediction = inference_layers(output_rle)

                # now simply add the tensor to the global counter
                prediction_base_tensor = torch.add(prediction_base_tensor,
                                                   base_prediction)
                prediction_rle_tensor = torch.add(prediction_rle_tensor,
                                                  rle_prediction)

            # all done now create a SEQ_LENGTH long prediction list
            prediction_base_tensor = prediction_base_tensor.cpu()
            prediction_rle_tensor = prediction_rle_tensor.cpu()

            base_values, base_labels = torch.max(prediction_base_tensor, 2)
            rle_values, rle_labels = torch.max(prediction_rle_tensor, 2)

            predicted_base_labels = base_labels.cpu().numpy()
            predicted_rle_labels = rle_labels.cpu().numpy()

            # go to each of the images and save the predictions to the file
            for i in range(images.size(0)):
                prediction_data_file.write_prediction(
                    contig[i], contig_start[i], contig_end[i], chunk_id[i],
                    position[i], predicted_base_labels[i],
                    predicted_rle_labels[i], filename[i])
Ejemplo n.º 9
0
def predict(test_file, output_filename, model_path, batch_size, threads,
            num_workers, gpu_mode):
    """
    Create a prediction table/dictionary of an images set using a trained model.
    :param test_file: File to predict on
    :param batch_size: Batch size used for prediction
    :param model_path: Path to a trained model
    :param gpu_mode: If true, predictions will be done over GPU
    :param threads: Number of threads to set for pytorch
    :param num_workers: Number of workers to be used by the dataloader
    :return: Prediction dictionary
    """
    prediction_data_file = DataStore(output_filename, mode='w')
    sys.stderr.write(TextColor.PURPLE + 'Loading data\n' + TextColor.END)

    torch.set_num_threads(threads)
    sys.stderr.write(TextColor.GREEN + 'INFO: TORCH THREADS SET TO: ' +
                     str(torch.get_num_threads()) + ".\n" + TextColor.END)
    sys.stderr.flush()

    # data loader
    test_data = SequenceDataset(test_file)
    test_loader = DataLoader(test_data,
                             batch_size=batch_size,
                             shuffle=False,
                             num_workers=num_workers)

    transducer_model, hidden_size, gru_layers, prev_ite = \
        ModelHandler.load_simple_model_for_training(model_path,
                                                    input_channels=ImageSizeOptions.IMAGE_CHANNELS,
                                                    image_features=ImageSizeOptions.IMAGE_HEIGHT,
                                                    seq_len=ImageSizeOptions.SEQ_LENGTH,
                                                    num_classes=ImageSizeOptions.TOTAL_LABELS)
    transducer_model.eval()

    if gpu_mode:
        transducer_model = torch.nn.DataParallel(transducer_model).cuda()
    sys.stderr.write(TextColor.CYAN + 'MODEL LOADED\n')

    with torch.no_grad():
        for contig, contig_start, contig_end, chunk_id, images, position, index, ref_seq, labels in tqdm(
                test_loader, ncols=50):
            sys.stderr.flush()
            images = images.type(torch.FloatTensor)

            hidden = torch.zeros(images.size(0), 2 * TrainOptions.LSTM_LAYERS,
                                 TrainOptions.HIDDEN_SIZE)

            prediction_base_counter = torch.zeros(
                (images.size(0), ImageSizeOptions.SEQ_LENGTH,
                 ImageSizeOptions.TOTAL_LABELS))

            if gpu_mode:
                images = images.cuda()
                hidden = hidden.cuda()
                prediction_base_counter = prediction_base_counter.cuda()

            for i in range(0, ImageSizeOptions.SEQ_LENGTH,
                           TrainOptions.WINDOW_JUMP):
                if i + TrainOptions.TRAIN_WINDOW > ImageSizeOptions.SEQ_LENGTH:
                    break
                chunk_start = i
                chunk_end = i + TrainOptions.TRAIN_WINDOW

                # chunk all the data
                image_chunk = images[:, i:i + TrainOptions.TRAIN_WINDOW]

                # run inference
                out, hidden = transducer_model(image_chunk, hidden)

                # now calculate how much padding is on the top and bottom of this chunk so we can do a simple
                # add operation
                top_zeros = chunk_start
                bottom_zeros = ImageSizeOptions.SEQ_LENGTH - chunk_end

                # do softmax and get prediction
                # we run a softmax a padding to make the output tensor compatible for adding
                inference_layers = nn.Sequential(
                    nn.Softmax(dim=2),
                    nn.ZeroPad2d((0, 0, top_zeros, bottom_zeros)))
                if gpu_mode:
                    inference_layers = inference_layers.cuda()

                # run the softmax and padding layers
                if gpu_mode:
                    base_prediction = (inference_layers(out) * 10).type(
                        torch.IntTensor).cuda()
                else:
                    base_prediction = (inference_layers(out) * 10).type(
                        torch.IntTensor)

                # now simply add the tensor to the global counter
                prediction_base_counter = torch.add(prediction_base_counter,
                                                    base_prediction)

            base_values, base_labels = torch.max(prediction_base_counter, 2)

            predicted_base_labels = base_labels.cpu().numpy()

            for i in range(images.size(0)):
                prediction_data_file.write_prediction(contig[i],
                                                      contig_start[i],
                                                      contig_end[i],
                                                      chunk_id[i], position[i],
                                                      index[i], ref_seq[i],
                                                      predicted_base_labels[i])