Ejemplo n.º 1
0
def test_borders():
    """Tests printing of the top and bottom borders"""

    # top
    assert top(5, width=2, style='round') == '╭──┬──┬──┬──┬──╮'
    assert top(1, width=6, style='grid') == '+------+'

    # bottom
    assert bottom(3, width=1, style='fancy_grid') == '╘═╧═╧═╛'
    assert bottom(3, 4, style='clean') == ' ──── ──── ──── '
Ejemplo n.º 2
0
        def minimize(self, f_df, x0, display=sys.stdout, maxiter=1e3):

            self.display = display
            self.theta = x0

            # setup
            xk = self.algorithm.send(destruct(x0).copy())
            store = defaultdict(list)
            runtimes = []
            if len(self.operators) == 0:
                self.operators = [proxops.identity()]

            # setup
            obj, grad = wrap(f_df, x0)
            transform = compose(destruct, *reversed(self.operators), self.restruct)

            self.optional_print(tp.header(['Iteration', 'Objective', '||Grad||', 'Runtime']))
            try:
                for k in count():

                    # setup
                    tstart = perf_counter()
                    f = obj(xk)
                    df = grad(xk)
                    xk = transform(self.algorithm.send(df))
                    runtimes.append(perf_counter() - tstart)
                    store['f'].append(f)

                    # Update display
                    self.optional_print(tp.row([k,
                                                f,
                                                np.linalg.norm(destruct(df)),
                                                tp.humantime(runtimes[-1])]))

                    if k >= maxiter:
                        break

            except KeyboardInterrupt:
                pass

            self.optional_print(tp.bottom(4))

            # cleanup
            self.optional_print(u'\u279b Final objective: {}'.format(store['f'][-1]))
            self.optional_print(u'\u279b Total runtime: {}'.format(tp.humantime(sum(runtimes))))
            self.optional_print(u'\u279b Per iteration runtime: {} +/- {}'.format(
                tp.humantime(np.mean(runtimes)),
                tp.humantime(np.std(runtimes)),
            ))

            # result
            return OptimizeResult({
                'x': self.restruct(xk),
                'f': f,
                'df': self.restruct(df),
                'k': k,
                'obj': np.array(store['f']),
            })
Ejemplo n.º 3
0
def sample(data_path: str,
           encoder_path: str,
           vocab_path: str,
           sample_length: int = 30,
           output: str = None):
    dump = torch.load(encoder_path, map_location=lambda storage, loc: storage)
    encodermodel = dump['encodermodel']
    decodermodel = dump['decodermodel']
    # Some scaler (sklearn standardscaler)
    scaler = dump['scaler']
    # Also load previous training config
    config_parameters = dump['config']

    vocab = torch.load(vocab_path)
    print(encodermodel)
    print(decodermodel)
    # load images from previous
    encodermodel = encodermodel.to(DEVICE).eval()
    decodermodel = decodermodel.to(DEVICE).eval()

    kaldi_string = parsecopyfeats(data_path,
                                  **config_parameters['feature_args'])
    width_length = sample_length * 4
    with stdout_or_file(output) as writer:
        writer.write(
            tp.header(["InputUtterance", "Output Sentence"],
                      style='grid',
                      width=width_length))
        writer.write('\n')
        for k, features in kaldi_io.read_mat_ark(kaldi_string):
            features = scaler.transform(features)
            # Add single batch dimension
            features = torch.from_numpy(features).to(DEVICE).unsqueeze(0)
            # Generate an caption embedding
            encoded_feature, hiddens = encodermodel(features)
            sampled_ids = decodermodel.sample(encoded_feature,
                                              states=hiddens,
                                              maxlength=sample_length)
            # (1, max_seq_length) -> (max_seq_length)
            sampled_ids = sampled_ids[0].cpu().numpy()

            # Convert word_ids to words
            sampled_caption = []
            for word_id in sampled_ids:
                word = vocab.idx2word[word_id]
                sampled_caption.append(word)
                if word == '<end>':
                    break
            sentence = ''.join(sampled_caption)

            # Print out the image and the generated caption
            writer.write(
                tp.row([k, sentence], style='grid', width=width_length))
            writer.write('\n')
            writer.flush()
        writer.write(tp.bottom(2, style='grid', width=width_length))
Ejemplo n.º 4
0
    def update_display(self,
                       iteration,
                       disp_level,
                       col_width=12):  # pragma: no cover
        """
        Prints information about the optimization procedure to standard output

        Parameters
        ----------
        iteration : int
            The current iteration. Must either a positive integer or -1, which indicates the end of the algorithm

        disp_level : int
            An integer which controls how much information to display, ranging from 0 (nothing) to 3 (lots of stuff)

        col_width : int
            The width of each column in the data table, used if disp_level > 1
        """

        # exit and print nothing if disp_level is zero
        if disp_level == 0:
            return

        else:

            # simple update, no table
            if disp_level == 1 and iteration >= 0:
                print('[Iteration %i]' % iteration)

            # fancy table updates
            if disp_level > 1:

                # get the metadata from this iteration
                data = valmap(last, self.metadata)

                # choose what keys to use
                keys = ['Time (s)', 'Primal resid', 'Dual resid', 'rho']

                # initial update. print out table headers
                if iteration == 1:
                    print(tableprint.header(keys, width=col_width))

                # print data
                print(
                    tableprint.row([data[k] for k in keys],
                                   width=col_width,
                                   format_spec='4g'))

                if iteration == -1:
                    print(tableprint.bottom(len(keys), width=col_width) + '\n')

            # print convergence statement
            if iteration == -1 and self.converged:
                print('Converged after %i iterations!' %
                      len(self.metadata['Primal resid']))
Ejemplo n.º 5
0
def buildTable(a, b, c, d):
    n = len(a)
    print(tp.header(['i', 'ai', 'bi', 'ci', 'di'], 10))
    num = 1
    for i in range(1, n - 1):
        print(tp.row([num, "{:.3f}".format(a[i]), "{:.3f}".format(b[i]), \
            "{:.3f}".format(c[i]), "{:.3f}".format(d[i-1])], 10))
        num += 1
    print(tp.row([num, "{:.3f}".format(a[n-1]), "{:.3f}".format(b[0]), \
        "{:.3f}".format(c[n-1]), "{:.3f}".format(d[n-1])], 10))
    print(tp.bottom(5, 10))
Ejemplo n.º 6
0
def printTable(ax):
    a = []
    for i in ax:
        a.append(i[:])

    for i in range(6):
        a[i].insert(0, i)
    print(tp.top(7, 3))
    print(tp.row(["x/y", 0, 1, 2, 3, 4, 5], 3))
    print(tp.bottom(7, 3))
    print("\r", end='\r\r\r')
    tp.table(a, None, '5g', 5, 'fancy_grid')
Ejemplo n.º 7
0
def geocode_crime_data(data_entries):
    """ Geocodes a list of crime data entries """

    print(tableprint.header(['City Name', 'Lat', 'Long'], width=30))
    for entry in data_entries:
        coords = geocode_city_name(entry['city_name'])
        entry['coords'] = coords

        # Add a delay for API limiting
        time.sleep(0.1)

    print(tableprint.bottom(3, width=30))

    return data_entries
Ejemplo n.º 8
0
def main(config='config/ReLU/0Pool/crnn_maxpool.yaml', **kwargs):
    """Trains a model on the given features and vocab.

    :features: str: Input features. Needs to be kaldi formatted file
    :config: A training configuration. Note that all parameters in the config can also be manually adjusted with --ARG=VALUE
    :returns: None
    """

    config_parameters = parse_config_or_kwargs(config, **kwargs)
    outputdir = os.path.join(
        config_parameters['outputpath'],
        config_parameters['model'],
        datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%f'))
    try:
        os.makedirs(outputdir)
    except IOError:
        pass
    logger = genlogger(outputdir, 'train.log')
    logger.info("Storing data at: {}".format(outputdir))
    logger.info("<== Passed Arguments ==>")
    # Print arguments into logs
    for line in pformat(config_parameters).split('\n'):
        logger.info(line)

    kaldi_string = parsecopyfeats(
        config_parameters['features'], **config_parameters['feature_args'])

    scaler = getattr(
        pre, config_parameters['scaler'])(
        **config_parameters['scaler_args'])
    inputdim = -1
    logger.info(
        "<== Estimating Scaler ({}) ==>".format(
            scaler.__class__.__name__))
    for kid, feat in kaldi_io.read_mat_ark(kaldi_string):
        scaler.partial_fit(feat)
        inputdim = feat.shape[-1]
    assert inputdim > 0, "Reading inputstream failed"
    logger.info(
        "Features: {} Input dimension: {}".format(
            config_parameters['features'],
            inputdim))
    logger.info("<== Labels ==>")
    label_df = pd.read_csv(config_parameters['labels'], sep='\t')
    label_df.event_labels = label_df.event_labels.str.split(',')
    label_df = label_df.set_index('filename')
    uniquelabels = list(np.unique(
        [item
         for row in label_df.event_labels.values
         for item in row]))
    many_hot_encoder = ManyHotEncoder(
        label_list=uniquelabels,
        time_resolution=1
    )
    label_df['manyhot'] = label_df['event_labels'].apply(
        lambda x: many_hot_encoder.encode(x, 1).data.flatten())

    utt_labels = label_df.loc[:, 'manyhot'].to_dict()

    train_dataloader, cv_dataloader = create_dataloader_train_cv(
        kaldi_string,
        utt_labels,
        transform=scaler.transform,
        **config_parameters['dataloader_args'])
    model = getattr(
        models,
        config_parameters['model'])(
        inputdim=inputdim,
        output_size=len(uniquelabels),
        **config_parameters['model_args'])
    logger.info("<== Model ==>")
    for line in pformat(model).split('\n'):
        logger.info(line)
    optimizer = getattr(
        torch.optim, config_parameters['optimizer'])(
        model.parameters(),
        **config_parameters['optimizer_args'])

    scheduler = getattr(
        torch.optim.lr_scheduler,
        config_parameters['scheduler'])(
        optimizer,
        **config_parameters['scheduler_args'])
    criterion = getattr(losses, config_parameters['loss'])(
        **config_parameters['loss_args'])

    trainedmodelpath = os.path.join(outputdir, 'model.th')

    model = model.to(device)
    criterion_improved = criterion_improver(
        config_parameters['improvecriterion'])
    header = [
        'Epoch',
        'UttLoss(T)',
        'UttLoss(CV)',
        "UttAcc(T)",
        "UttAcc(CV)",
        "mAUC(CV)"]
    for line in tp.header(
        header,
            style='grid').split('\n'):
        logger.info(line)

    poolingfunction_name = config_parameters['poolingfunction']
    pooling_function = parse_poolingfunction(poolingfunction_name)
    for epoch in range(1, config_parameters['epochs']+1):
        train_utt_loss_mean_std, train_utt_acc, train_auc_utt = runepoch(
            train_dataloader, model, criterion, optimizer, dotrain=True, poolfun=pooling_function)
        cv_utt_loss_mean_std, cv_utt_acc, cv_auc_utt = runepoch(
            cv_dataloader, model,  criterion, dotrain=False, poolfun=pooling_function)
        logger.info(
            tp.row(
                (epoch,) +
                (train_utt_loss_mean_std[0],
                 cv_utt_loss_mean_std[0],
                 train_utt_acc, cv_utt_acc, cv_auc_utt),
                style='grid'))
        epoch_meanloss = cv_utt_loss_mean_std[0]
        if epoch % config_parameters['saveinterval'] == 0:
            torch.save({'model': model,
                        'scaler': scaler,
                        'encoder': many_hot_encoder,
                        'config': config_parameters},
                       os.path.join(outputdir, 'model_{}.th'.format(epoch)))
        # ReduceOnPlateau needs a value to work
        schedarg = epoch_meanloss if scheduler.__class__.__name__ == 'ReduceLROnPlateau' else None
        scheduler.step(schedarg)
        if criterion_improved(epoch_meanloss):
            torch.save({'model': model,
                        'scaler': scaler,
                        'encoder': many_hot_encoder,
                        'config': config_parameters},
                       trainedmodelpath)
        if optimizer.param_groups[0]['lr'] < 1e-7:
            break
    logger.info(tp.bottom(len(header), style='grid'))
    logger.info("Results are in: {}".format(outputdir))
    return outputdir
Ejemplo n.º 9
0
 def table_bottom(self, n_columns, *args, **kwargs):
     self.write(tableprint.bottom(n_columns, *args, **kwargs))
Ejemplo n.º 10
0
def train(model, experiment, monitor, num_epochs, augment=False):
    """Train the given network against the given data

    Parameters
    ----------
    model : keras.models.Model or glms.GLM
        A GLM or Keras Model object

    experiment : experiments.Experiment
        An Experiment object

    monitor : io.Monitor
        Saves the model parameters and plots of performance progress

    num_epochs : int
        Number of epochs to train for

    reduce_lr_every : int
        How often to reduce the learning rate

    reduce_rate : float
        A fraction (constant) to multiply the learning rate by

    """
    assert isinstance(model, (Model, GLM)), "'model' must be a GLM or Keras model"

    # initialize training iteration
    iteration = 0
    train_start = time()

    # loop over epochs
    try:
        for epoch in range(num_epochs):
            tp.banner('Epoch #{} of {}'.format(epoch + 1, num_epochs))
            print(tp.header(["Iteration", "Loss", "Runtime"]), flush=True)

            # loop over data batches for this epoch
            for X, y in experiment.train(shuffle=True):

                # update on save_every, assuming it is positive
                if (monitor is not None) and (iteration % monitor.save_every == 0):

                    # performs validation, updates performance plots, saves results to dropbox
                    monitor.save(epoch, iteration, X, y, model.predict)

                # train on the batch
                tstart = time()
                loss = model.train_on_batch({'stim':X, 'loss':y})[0]
                elapsed_time = time() - tstart

                # update
                iteration += 1
                print(tp.row([iteration, float(loss), tp.humantime(elapsed_time)]), flush=True)

            print(tp.bottom(3))

    except KeyboardInterrupt:
        print('\nCleaning up')

    # allows the monitor to perform any post-training visualization
    if monitor is not None:
        elapsed_time = time() - train_start
        monitor.cleanup(iteration, elapsed_time)

    tp.banner('Training complete!')
Ejemplo n.º 11
0
def main(features: str, vocab_file: str,
         config='config/trainconfig.yaml', **kwargs):
    """Trains a model on the given features and vocab.

    :features: str: Input features. Needs to be kaldi formatted file
    :vocab_file:str: Vocabulary generated by using build_vocab.py
    :config: A training configuration. Note that all parameters in the config can also be manually adjusted with --ARG=VALUE
    :returns: None
    """

    config_parameters = parse_config_or_kwargs(config, **kwargs)
    outputdir = os.path.join(
        config_parameters['encodermodel'] + '_' +
        config_parameters['decodermodel'],
        datetime.datetime.now().strftime('%Y-%m-%d_%H-%M'))
    try:
        os.makedirs(outputdir)
    except IOError:
        pass
    logger = genlogger(outputdir, 'train.log')
    logger.info("Storing data at: {}".format(outputdir))
    logger.info("<== Passed Arguments ==>")
    # Print arguments into logs
    for line in pformat(config_parameters).split('\n'):
        logger.info(line)

    kaldi_string = parsecopyfeats(
        features, **config_parameters['feature_args'])

    scaler = getattr(
        pre, config_parameters['scaler'])(
        **config_parameters['scaler_args'])
    inputdim = -1
    logger.info(
        "<== Estimating Scaler ({}) ==>".format(
            scaler.__class__.__name__))
    for kid, feat in kaldi_io.read_mat_ark(kaldi_string):
        scaler.partial_fit(feat)
        inputdim = feat.shape[-1]
    assert inputdim > 0, "Reading inputstream failed"
    vocabulary = torch.load(vocab_file)
    vocab_size = len(vocabulary)
    logger.info(
        "Features: {} Input dimension: {} Vocab Size: {}".format(
            features, inputdim, vocab_size))
    if 'load_pretrained' in config_parameters and config_parameters['load_pretrained']:
        encodermodeldump = torch.load(
            config_parameters['load_pretrained'],
            map_location=lambda storage, loc: storage)
        pretrainedmodel = encodermodeldump['encodermodel']
        encodermodel = models.PreTrainedCNN(
            inputdim=inputdim, pretrained_model=pretrainedmodel, **
            config_parameters['encodermodel_args'])
    else:
        encodermodel = getattr(
            models, config_parameters['encodermodel'])(
            inputdim=inputdim, **config_parameters['encodermodel_args'])
    decodermodel = getattr(
        models, config_parameters['decodermodel'])(
        vocab_size=vocab_size, **config_parameters['decodermodel_args'])
    logger.info("<== EncoderModel ==>")
    for line in pformat(encodermodel).split('\n'):
        logger.info(line)
    logger.info("<== DecoderModel ==>")
    for line in pformat(decodermodel).split('\n'):
        logger.info(line)

    params = list(encodermodel.parameters()) + list(decodermodel.parameters())

    train_dataloader, cv_dataloader = create_dataloader_train_cv(
        kaldi_string,
        config_parameters['captions_file'],
        vocab_file,
        transform=scaler.transform,
        **config_parameters['dataloader_args'])
    optimizer = getattr(
        torch.optim, config_parameters['optimizer'])(
        params,
        **config_parameters['optimizer_args'])

    scheduler = getattr(
        torch.optim.lr_scheduler,
        config_parameters['scheduler'])(
        optimizer,
        **config_parameters['scheduler_args'])
    criterion = torch.nn.CrossEntropyLoss()
    trainedmodelpath = os.path.join(outputdir, 'model.th')

    encodermodel = encodermodel.to(device)
    decodermodel = decodermodel.to(device)

    criterion_improved = criterion_improver(
        config_parameters['improvecriterion'])
    for line in tp.header(
        ['Epoch', 'MeanLoss(T)', 'StdLoss(T)', 'Loss(CV)', 'StdLoss(CV)',
         "Acc(T)", "Acc(CV)", "Forcing?"],
            style='grid').split('\n'):
        logger.info(line)
    teacher_forcing_ratio = config_parameters['teacher_forcing_ratio']
    for epoch in range(1, config_parameters['epochs']+1):
        use_teacher_forcing = True if random.random() < teacher_forcing_ratio else False
        train_loss_mean_std, train_acc = trainepoch(
            train_dataloader, encodermodel, decodermodel, criterion, optimizer,
            vocabulary, use_teacher_forcing)
        cv_loss_mean_std, cv_acc = sample_cv(
            cv_dataloader, encodermodel, decodermodel, criterion)
        logger.info(
            tp.row(
                (epoch,) + train_loss_mean_std + cv_loss_mean_std +
                (train_acc, cv_acc, use_teacher_forcing),
                style='grid'))
        epoch_meanloss = cv_loss_mean_std[0]
        if epoch % config_parameters['saveinterval'] == 0:
            torch.save({'encodermodel': encodermodel,
                        'decodermodel': decodermodel, 'scaler': scaler,
                        'config': config_parameters},
                       os.path.join(outputdir, 'model_{}.th'.format(epoch)))
        # ReduceOnPlateau needs a value to work
        schedarg = epoch_meanloss if scheduler.__class__.__name__ == 'ReduceLROnPlateau' else None
        scheduler.step(schedarg)
        if criterion_improved(epoch_meanloss):
            torch.save({'encodermodel': encodermodel,
                        'decodermodel': decodermodel, 'scaler': scaler,
                        'config': config_parameters},
                       trainedmodelpath)
        else:
            dump = torch.load(trainedmodelpath)
            encodermodel.load_state_dict(dump['encodermodel'].state_dict())
            decodermodel.load_state_dict(dump['decodermodel'].state_dict())
        if optimizer.param_groups[0]['lr'] < 1e-6:
            break
    logger.info(tp.bottom(8, style='grid'))
    # Sample results
    from sample import sample

    sample(
        data_path=features,
        encoder_path=trainedmodelpath,
        vocab_path=vocab_file,
        output=os.path.join(
            outputdir,
            'output_word.txt'))
Ejemplo n.º 12
0
    def sample(self,
               experiment_path: str,
               feature_file: str,
               feature_scp: str,
               output: str = "output_word.txt",
               **kwargs):
        """Generate captions given experiment model"""
        """kwargs: {'max_length': int, 'method': str, 'beam_size': int}"""
        import tableprint as tp

        dump = torch.load(os.path.join(experiment_path, "saved.pth"),
                          map_location="cpu")
        # Load previous training config
        config = dump["config"]

        vocab_size = len(torch.load(config["vocab_file"]))
        model = self._get_model(config, vocab_size)
        model.load_state_dict(dump["model"])
        # Some scaler (sklearn standardscaler)
        scaler = dump["scaler"]
        vocabulary = torch.load(config["vocab_file"])
        zh = config["zh"]
        model = model.to(self.device)
        dataset = SJTUDatasetEval(feature=feature_file,
                                  eval_scp=feature_scp,
                                  transform=scaler.transform)
        dataloader = torch.utils.data.DataLoader(dataset,
                                                 shuffle=False,
                                                 collate_fn=collate_fn((1, )),
                                                 batch_size=16,
                                                 num_workers=0)

        width_length = 80
        pbar = ProgressBar(persist=False, ascii=True)
        writer = open(os.path.join(experiment_path, output), "w")
        writer.write(
            tp.header(["InputUtterance", "Output Sentence"],
                      width=[len("InputUtterance"), width_length]))
        writer.write('\n')

        sentences = []

        def _sample(engine, batch):
            # batch: [keys, feats, feat_lens]
            with torch.no_grad():
                model.eval()
                keys = batch[0]
                output = self._forward(model, batch, mode="sample", **kwargs)
                seqs = output["seqs"].cpu().numpy()
                for idx, seq in enumerate(seqs):
                    caption = self._convert_idx2sentence(seq,
                                                         vocabulary,
                                                         zh=zh)
                    if zh:
                        sentence = " ".join(caption)
                    else:
                        sentence = caption
                    writer.write(
                        tp.row([keys[idx], sentence],
                               width=[len("InputUtterance"), width_length]) +
                        "\n")
                    sentences.append(sentence)

        sample_engine = Engine(_sample)
        pbar.attach(sample_engine)
        sample_engine.run(dataloader)
        writer.write(
            tp.bottom(2, width=[len("InputUtterance"), width_length]) + "\n")
        writer.write("Unique sentence number: {}\n".format(len(
            set(sentences))))
        writer.close()
Ejemplo n.º 13
0
def on_training_ended(engine, n, outputfun=sys.stdout.write):
    outputfun(tp.bottom(n, style="grid"))
Ejemplo n.º 14
0
def main(config='config/train.yaml', **kwargs):
    """Trains a model on the given features and vocab.

    :config: A training configuration. Note that all parameters in the config can also be manually adjusted with --ARG VALUE
    :returns: None
    """

    config_parameters = parse_config_or_kwargs(config, **kwargs)
    outputdir = os.path.join(
        config_parameters['outputpath'],
        config_parameters['model'],
        datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f'))
    try:
        os.makedirs(outputdir)
    except IOError:
        pass
    logger = genlogger(outputdir, 'train.log')
    logger.info("Storing data at: {}".format(outputdir))
    logger.info("<== Passed Arguments ==>")
    # Print arguments into logs
    for line in pformat(config_parameters).split('\n'):
        logger.info(line)

    # seed setting
    seed=config_parameters['seed'] # 1~5
    np.random.seed(seed)
    torch.manual_seed(seed)

    kaldi_string = parsecopyfeats(
        config_parameters['features'], **config_parameters['feature_args'])

    scaler = getattr(pre, config_parameters['scaler'])(**config_parameters['scaler_args'])
    logger.info("<== Estimating Scaler ({}) ==>".format(scaler.__class__.__name__))
    inputdim = -1
    for kid, feat in kaldi_io.read_mat_ark(kaldi_string):
        scaler.partial_fit(feat)
        inputdim = feat.shape[-1]
    assert inputdim > 0, "Reading inputstream failed"
    logger.info(
        "Features: {} Input dimension: {}".format(
            config_parameters['features'],
            inputdim))
    
    logger.info("<== Labels ==>")
    # Can be label, DAT, DADA ... default is 'label'
    target_label_name = config_parameters.get('label_type', 'label')
    if target_label_name == 'label':
        label_df = pd.read_csv(config_parameters['labels'], sep=' ', names=['speaker', 'filename', 'physical', 'system', 'label'])
    else: # 'DAT' or 'DADA'
        label_df = pd.read_csv(config_parameters['labels'], sep=' ', names=['speaker', 'filename', 'physical', 'system', 'label', 'domain'])
    label_encoder = pre.LabelEncoder()
    if target_label_name == 'label':
        label_encoder.fit(label_df[target_label_name].values.astype(str))
        # Labelencoder needs an iterable to work, so just put a list around it and fetch again the 0-th element ( just the encoded string )
        label_df['class_encoded'] = label_df[target_label_name].apply(lambda x: label_encoder.transform([x])[0])
        train_labels = label_df[['filename', 'class_encoded']].set_index('filename').loc[:, 'class_encoded'].to_dict()
    else: # 'DAT' or 'DADA'
        label_encoder_sub = pre.LabelEncoder()
        label_encoder.fit(label_df['label'].values.astype(str))
        label_df['lab_encoded'] = label_df['label'].apply(lambda x: label_encoder.transform([x])[0])
        label_encoder_sub.fit(label_df['domain'].values.astype(str))
        label_df['domain_encoded'] = label_df['domain'].apply(lambda x: label_encoder_sub.transform([x])[0])
        train_labels = label_df[['filename', 'lab_encoded', 'domain_encoded']].set_index('filename').to_dict('index')
        train_labels = {k:np.array(list(v.values())) for k, v in train_labels.items()}
        # outdomain
        outdomain = config_parameters['outdomain']
        outdomain_label = label_encoder_sub.transform([outdomain])[0]
        logger.info("Outdomain: {}, Outdomain label: {}".format(outdomain, outdomain_label))
    
    if target_label_name == 'label':
        train_dataloader, cv_dataloader = create_dataloader_train_cv(kaldi_string, train_labels, transform=scaler.transform, target_label_name=target_label_name, **config_parameters['dataloader_args'])
    else: #'DAT' or 'DADA' 
        outdomain_train_dataloader, indomain_train_dataloader, cv_dataloader = create_dataloader_train_cv(kaldi_string, train_labels, transform=scaler.transform, target_label_name=target_label_name, outdomain_label=outdomain_label, **config_parameters['dataloader_args'])

    if target_label_name == 'label':
        model = getattr(models, config_parameters['model'])(inputdim=inputdim, outputdim=len(label_encoder.classes_), **config_parameters['model_args'])
    else: # 'DAT' or 'DADA'
        model = getattr(models, config_parameters['model'])(inputdim=inputdim, outputdim1=len(label_encoder.classes_), outputdim2=len(label_encoder_sub.classes_), **config_parameters['model_args'])
    logger.info("<== Model ==>")
    for line in pformat(model).split('\n'):
        logger.info(line)
    optimizer = getattr(torch.optim, config_parameters['optimizer'])(model.parameters(), **config_parameters['optimizer_args'])

    scheduler = getattr(torch.optim.lr_scheduler, config_parameters['scheduler'])(optimizer, **config_parameters['scheduler_args'])
    criterion = getattr(loss, config_parameters['loss'])(**config_parameters['loss_args'])
    trainedmodelpath = os.path.join(outputdir, 'model.th')

    model = model.to(device)
    criterion_improved = criterion_improver(config_parameters['improvecriterion'])
    header = [
        'Epoch',
        'Lr',
        'Loss(T)',
        'Loss(CV)',
        "Acc(T)",
        "Acc(CV)",
    ]
    for line in tp.header(header, style='grid').split('\n'):
        logger.info(line)

    for epoch in range(1, config_parameters['epochs']+1):
        if target_label_name == 'label':
            train_loss, train_acc = runepoch(train_dataloader, None, model, criterion, target_label_name, optimizer, dotrain=True, epoch=epoch)
        else: # 'DAT' or 'DADA'
            train_loss, train_acc = runepoch(outdomain_train_dataloader, indomain_train_dataloader, model, criterion, target_label_name, optimizer, dotrain=True, epoch=epoch)
        cv_loss, cv_acc = runepoch(cv_dataloader, None, model, criterion, target_label_name, dotrain=False, epoch=epoch)
        logger.info(
            tp.row(
                (epoch,) + (optimizer.param_groups[0]['lr'],) +
                (str(train_loss), str(cv_loss), str(train_acc), str(cv_acc)),
                style='grid'))
        epoch_meanloss = cv_loss[0] if type(cv_loss)==tuple else cv_loss
        if epoch % config_parameters['saveinterval'] == 0:
            torch.save({'model': model,
                        'scaler': scaler,
                        'encoder': label_encoder,
                        'config': config_parameters},
                        os.path.join(outputdir, 'model_{}.th'.format(epoch)))
        # ReduceOnPlateau needs a value to work
        schedarg = epoch_meanloss if scheduler.__class__.__name__ == 'ReduceLROnPlateau' else None
        scheduler.step(schedarg)
        if criterion_improved(epoch_meanloss):
            torch.save({'model': model,
                        'scaler': scaler,
                        'encoder': label_encoder,
                        'config': config_parameters},
                        trainedmodelpath)
        if optimizer.param_groups[0]['lr'] < 1e-7:
            break
    logger.info(tp.bottom(len(header), style='grid'))
    logger.info("Results are in: {}".format(outputdir))
Ejemplo n.º 15
0
def check_grad(f_df, xref, stepsize=1e-6, tol=1e-6, width=15, style='round', out=sys.stdout):
    """
    Compares the numerical gradient to the analytic gradient

    Parameters
    ----------
    f_df : function
        The analytic objective and gradient function to check

    x0 : array_like
        Parameter values to check the gradient at

    stepsize : float, optional
        Stepsize for the numerical gradient. Too big and this will poorly estimate the gradient.
        Too small and you will run into precision issues (default: 1e-6)

    tol : float, optional
        Tolerance to use when coloring correct/incorrect gradients (default: 1e-5)

    width : int, optional
        Width of the table columns (default: 15)

    style : string, optional
        Style of the printed table, see tableprint for a list of styles (default: 'round')
    """
    CORRECT = u'\x1b[32m\N{CHECK MARK}\x1b[0m'
    INCORRECT = u'\x1b[31m\N{BALLOT X}\x1b[0m'

    obj, grad = wrap(f_df, xref, size=0)
    x0 = destruct(xref)
    df = grad(x0)

    # header
    out.write(tp.header(["Numerical", "Analytic", "Error"], width=width, style=style) + "\n")
    out.flush()

    # helper function to parse a number
    def parse_error(number):

        # colors
        failure = "\033[91m"
        passing = "\033[92m"
        warning = "\033[93m"
        end = "\033[0m"
        base = "{}{:0.3e}{}"

        # correct
        if error < 0.1 * tol:
            return base.format(passing, error, end)

        # warning
        elif error < tol:
            return base.format(warning, error, end)

        # failure
        else:
            return base.format(failure, error, end)

    # check each dimension
    num_errors = 0
    for j in range(x0.size):

        # take a small step in one dimension
        dx = np.zeros(x0.size)
        dx[j] = stepsize

        # compute the centered difference formula
        df_approx = (obj(x0 + dx) - obj(x0 - dx)) / (2 * stepsize)
        df_analytic = df[j]

        # absolute error
        abs_error = np.linalg.norm(df_approx - df_analytic)

        # relative error
        error = abs_error if np.allclose(abs_error, 0) else abs_error / \
            (np.linalg.norm(df_analytic) + np.linalg.norm(df_approx))

        num_errors += error >= tol
        errstr = CORRECT if error < tol else INCORRECT
        out.write(tp.row([df_approx, df_analytic, parse_error(error) + ' ' + errstr],
                         width=width, style=style) + "\n")
        out.flush()

    out.write(tp.bottom(3, width=width, style=style) + "\n")
    return num_errors
Ejemplo n.º 16
0
def check_grad(f_df,
               xref,
               stepsize=1e-6,
               tol=1e-6,
               width=15,
               style='round',
               out=sys.stdout):
    """
    Compares the numerical gradient to the analytic gradient

    Parameters
    ----------
    f_df : function
        The analytic objective and gradient function to check

    x0 : array_like
        Parameter values to check the gradient at

    stepsize : float, optional
        Stepsize for the numerical gradient. Too big and this will poorly estimate the gradient.
        Too small and you will run into precision issues (default: 1e-6)

    tol : float, optional
        Tolerance to use when coloring correct/incorrect gradients (default: 1e-5)

    width : int, optional
        Width of the table columns (default: 15)

    style : string, optional
        Style of the printed table, see tableprint for a list of styles (default: 'round')
    """
    CORRECT = u'\x1b[32m\N{CHECK MARK}\x1b[0m'
    INCORRECT = u'\x1b[31m\N{BALLOT X}\x1b[0m'

    obj, grad = wrap(f_df, xref, size=0)
    x0 = destruct(xref)
    df = grad(x0)

    # header
    out.write(
        tp.header(["Numerical", "Analytic", "Error"], width=width, style=style)
        + "\n")
    out.flush()

    # helper function to parse a number
    def parse_error(number):

        # colors
        failure = "\033[91m"
        passing = "\033[92m"
        warning = "\033[93m"
        end = "\033[0m"
        base = "{}{:0.3e}{}"

        # correct
        if error < 0.1 * tol:
            return base.format(passing, error, end)

        # warning
        elif error < tol:
            return base.format(warning, error, end)

        # failure
        else:
            return base.format(failure, error, end)

    # check each dimension
    num_errors = 0
    for j in range(x0.size):

        # take a small step in one dimension
        dx = np.zeros(x0.size)
        dx[j] = stepsize

        # compute the centered difference formula
        df_approx = (obj(x0 + dx) - obj(x0 - dx)) / (2 * stepsize)
        df_analytic = df[j]

        # absolute error
        abs_error = np.linalg.norm(df_approx - df_analytic)

        # relative error
        error = abs_error if np.allclose(abs_error, 0) else abs_error / \
            (np.linalg.norm(df_analytic) + np.linalg.norm(df_approx))

        num_errors += error >= tol
        errstr = CORRECT if error < tol else INCORRECT
        out.write(
            tp.row([df_approx, df_analytic,
                    parse_error(error) + ' ' + errstr],
                   width=width,
                   style=style) + "\n")
        out.flush()

    out.write(tp.bottom(3, width=width, style=style) + "\n")
    return num_errors
Ejemplo n.º 17
0
 def on_epoch_end(self, epoch, logs={}):
     print(tp.bottom(2))
     print(logs)