Exemple #1
0
def train_for_epoch(parser, train_data, dev_data, optimizer, loss_func,
                    batch_size):
    """ Train the neural dependency parser for single epoch.
    @return dev_UAS (float): Unlabeled Attachment Score (UAS) for dev data
    """
    parser.model.train(
    )  # Places model in "train" mode, i.e. apply dropout layer
    n_minibatches = math.ceil(len(train_data) / batch_size)
    loss_meter = AverageMeter()

    with tqdm(total=(n_minibatches)) as prog:
        for i, (train_x,
                train_y) in enumerate(minibatches(train_data, batch_size)):
            optimizer.zero_grad()  # remove any baggage in the optimizer
            loss = 0.  # store loss for this batch here
            train_x = torch.from_numpy(train_x).long()
            train_y = torch.from_numpy(train_y.nonzero()[1]).long()
            output_y = parser.model(train_x)
            loss = loss_func(output_y, train_y)
            loss.backward()
            optimizer.step()
            prog.update(1)
            loss_meter.update(loss.item())

    print("Average Train Loss: {}".format(loss_meter.avg))

    print("Evaluating on dev set", )
    parser.model.eval(
    )  # Places model in "eval" mode, i.e. don't apply dropout layer
    dev_UAS = parser.evaluate(dev_data)
    print("- dev UAS: {:.2f}".format(dev_UAS * 100.0))
    return dev_UAS
Exemple #2
0
    def learn(self, dataset, n_iters=100):
        train_data = self.create_instances([{
            'word': x.sentence,
            'head': x.head
        } for x in dataset])

        batch_size = 1024
        n_epochs = int(math.ceil(batch_size * n_iters / len(train_data)))
        n_epochs = max(n_epochs, 5)  # run at least 5 epochs
        print(n_epochs, "epochs, ", end='')
        self.model.train(
        )  # Places model in "train" mode, i.e. apply dropout layer
        for epoch in range(n_epochs):
            for i, (train_x,
                    train_y) in enumerate(minibatches(train_data, batch_size)):
                train_x = torch.from_numpy(train_x).long()
                train_y = torch.from_numpy(train_y.nonzero()[1]).long()
                train_x = train_x.to(self.device)
                train_y = train_y.to(self.device)
                output_y = self.model(train_x)
                loss = self.criterion(output_y, train_y)

                self.optimizer.zero_grad(
                )  # remove any baggage in the optimizer
                loss.backward()
                self.optimizer.step()
    def run_epoch(self, sess, train, dev, epoch):
        '''
        Performs one complete pass over the train set and evaluates on dev

        Args:
            sess: tensorflow session
            train: large BIODataSentence list (training set)
            dev: large BIODataSentence list (dev set)
            epoch: (int) number of the epoch
        '''
        nbatches = len(train) // self.config.batch_size
        if len(train) % self.config.batch_size != 0:
            nbatches += 1

        prog = Progbar(target=nbatches)
        for i, sent_batch in enumerate(
                minibatches(train, self.config.batch_size)):
            fd, _ = self.prepare_feed_dict_optimized( \
                        bio_data_sentence_batch=sent_batch, \
                        dropout_keep_prob=self.config.dropout_keep_prob, \
                        learning_rate=self.config.learning_rate)

            #_, train_loss, summary = sess.run([self.train_op, self.loss, self.merged], feed_dict=fd)
            _, train_loss = sess.run([self.train_op, self.loss], feed_dict=fd)

            prog.update(i + 1, [('train loss', train_loss)])

            # tensorboard
            #if i % 10 == 0:
            #self.file_writer.add_summary(summary, epoch*nbatches + i)

        acc, f1, mod_p = self.run_evaluate(sess, dev)
        self.logger.info(
            '- dev acc {:04.2f} - f1 {:04.2f} - mod prec {:04.2f}'.format(
                100 * acc, 100 * f1, 100 * mod_p))
        return acc, f1
    def run_evaluate(self, sess, test):
        '''
        Evaluates performance on specified test/dev set

        Args:
            sess: tensorflow session
            test: large BIODataSentence list (dev/test set)
        '''

        #nbatches = len(test) // self.config.batch_size
        #if len(test) % self.config.batch_size != 0:
        #    nbatches += 1

        correct_preds = 0
        total_preds = 0
        total_correct = 0
        correct_mod = 0
        total_mod = 0
        accs = []

        #prog = Progbar(target=nbatches)
        for i, gold_sent_batch in enumerate(
                minibatches(test, self.config.batch_size)):
            pred_sent_batch = self.predict_batch(sess, gold_sent_batch)

            assert len(gold_sent_batch) == len(pred_sent_batch)

            for sidx in range(len(gold_sent_batch)):
                gold_chunks = gold_sent_batch[sidx].get_label_chunks()
                pred_chunks = pred_sent_batch[sidx].get_label_chunks()
                correct_chunks = gold_chunks & pred_chunks

                self.logger.debug('gold_chunks: ' + str(sorted(gold_chunks)))
                self.logger.debug('pred_chunks: ' + str(sorted(pred_chunks)))

                for (chunk_idx, chunk_label) in gold_chunks:
                    if chunk_label.startswith('MOD') or chunk_label.startswith(
                            'B-MOD') or chunk_label.startswith('I-MOD'):
                        total_mod += 1

                for (chunk_idx, chunk_label) in correct_chunks:
                    if chunk_label.startswith('MOD') or chunk_label.startswith(
                            'B-MOD') or chunk_label.startswith('I-MOD'):
                        correct_mod += 1

                correct_preds += len(correct_chunks)
                total_preds += len(pred_chunks)
                total_correct += len(gold_chunks)
                accs += map(
                    lambda items: items[0] == items[1],
                    list(
                        zip(gold_sent_batch[sidx].labels,
                            pred_sent_batch[sidx].labels)))

        self.logger.info('correct_preds: ' + str(correct_preds))
        self.logger.info('total_preds: ' + str(total_preds))
        self.logger.info('total_correct: ' + str(total_correct))

        p = correct_preds / total_preds if correct_preds > 0 else 0
        r = correct_preds / total_correct if correct_preds > 0 else 0
        mod_p = correct_mod / total_mod if correct_mod > 0 else 0
        f1 = 2 * p * r / (p + r) if correct_preds > 0 else 0
        acc = np.mean(accs)
        return acc, f1, mod_p