Пример #1
0
class Predictor():
    def __init__(self):
        try:
            f = open("params.json", "r", encoding='utf8')
            self.params = json.loads(f.read())
        except FileNotFoundError:
            self.params = save_corpus()
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.device = device
        self.model = BiGRU(torch.zeros((len(self.params['tbl']) + 1, 300)),
                           MODEL_PARAMS['gru_hidden_dim'],
                           MODEL_PARAMS['gru_num_layers'],
                           len(self.params['tagset']),
                           MODEL_PARAMS['concat']).to(device)
        self.model.load_state_dict(
            torch.load('trained_model.pt',
                       map_location=lambda storage, loc: storage))
        self.model.eval()

    def predict(self, sentence):
        words = sentence.split()

        lis = []
        new_words = []
        for word in words:
            symbol = None
            if not word[-1].isalnum():
                symbol = word[-1]
                word = word[:-1]
            if word.lower() in self.params['tbl']:
                lis.append(self.params['tbl'][word.lower()])
            else:
                lis.append(0)
            new_words.append(word)
            if symbol != None:
                if symbol in self.params['tbl']:
                    lis.append(self.params['tbl'][symbol])
                else:
                    lis.append(0)
                new_words.append(symbol)

        x = torch.LongTensor(lis).to(self.device)
        x = x.unsqueeze(0)
        y_raw = self.model(x)
        y_pred = torch.argmax(y_raw, dim=2).view(-1)
        tagged_sent = ''
        for i in range(len(y_pred)):
            tagged_sent += new_words[i]
            tagged_sent += ' '
            tagged_sent += self.params['reverse_tagset'][y_pred[i]]
            tagged_sent += ' '
        print(tagged_sent)

    def tag_lookup(self, tag):
        try:
            print('TAG:', tag)
            print('Definition:', self.params['tag_definition'][tag][0])
        except:
            print('Error: Tag not found.')
Пример #2
0
def main(options):

    use_cuda = (len(options.gpuid) >= 1)
    if options.gpuid:
        cuda.set_device(options.gpuid[0])

    train, dev, test, vocab = torch.load(open(options.data_file, 'rb'),
                                         pickle_module=dill)

    batched_train, batched_train_mask, _ = utils.tensor.advanced_batchize(
        train, options.batch_size, vocab.stoi["<pad>"])
    batched_dev, batched_dev_mask, _ = utils.tensor.advanced_batchize(
        dev, options.batch_size, vocab.stoi["<pad>"])

    vocab_size = len(vocab)

    rnnlm = BiGRU(vocab_size, use_cuda=use_cuda)
    if use_cuda > 0:
        rnnlm.cuda()
    else:
        rnnlm.cpu()

    criterion = torch.nn.NLLLoss()
    optimizer = eval("torch.optim." + options.optimizer)(rnnlm.parameters(),
                                                         options.learning_rate)

    # main training loop
    last_dev_avg_loss = float("inf")
    rnnlm.train()
    for epoch_i in range(options.epochs):
        logging.info("At {0}-th epoch.".format(epoch_i))
        # srange generates a lazy sequence of shuffled range
        for i, batch_i in enumerate(utils.rand.srange(len(batched_train))):
            train_batch = Variable(
                batched_train[batch_i])  # of size (seq_len, batch_size)
            train_mask = Variable(batched_train_mask[batch_i])
            train_in_mask = train_mask.view(-1)
            train_out_mask = train_mask.view(-1)
            if use_cuda:
                train_batch = train_batch.cuda()
                train_mask = train_mask.cuda()
                train_in_mask = train_in_mask.cuda()
                train_out_mask = train_out_mask.cuda()

            sys_out_batch = rnnlm(
                train_batch
            )  # (seq_len, batch_size, vocab_size) # TODO: substitute this with your module
            train_in_mask = train_in_mask.unsqueeze(1).expand(
                len(train_in_mask), vocab_size)
            sys_out_batch = sys_out_batch.view(-1, vocab_size)
            train_out_batch = train_batch.view(-1)
            sys_out_batch = sys_out_batch.masked_select(train_in_mask).view(
                -1, vocab_size)
            train_out_batch = train_out_batch.masked_select(train_out_mask)
            loss = criterion(sys_out_batch, train_out_batch)
            logging.debug("loss at batch {0}: {1}".format(i, loss.data[0]))
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        # validation -- this is a crude esitmation because there might be some paddings at the end
        dev_loss = 0.0
        rnnlm.eval()
        for batch_i in range(len(batched_dev)):
            dev_batch = Variable(batched_dev[batch_i], volatile=True)
            dev_mask = Variable(batched_dev_mask[batch_i], volatile=True)
            dev_in_mask = dev_mask.view(-1)
            dev_out_batch = dev_batch.view(-1)
            if use_cuda:
                dev_batch = dev_batch.cuda()
                dev_mask = dev_mask.cuda()
                dev_in_mask = dev_in_mask.cuda()
                dev_out_batch = dev_out_batch.cuda()

            sys_out_batch = rnnlm(dev_batch)
            dev_in_mask = dev_in_mask.unsqueeze(1).expand(
                len(dev_in_mask), vocab_size)
            dev_out_mask = dev_mask.view(-1)
            sys_out_batch = sys_out_batch.view(-1, vocab_size)
            sys_out_batch = sys_out_batch.masked_select(dev_in_mask).view(
                -1, vocab_size)
            dev_out_batch = dev_out_batch.masked_select(dev_out_mask)
            loss = criterion(sys_out_batch, dev_out_batch)
            dev_loss += loss
        dev_avg_loss = dev_loss / len(batched_dev)
        logging.info(
            "Average loss value per instance is {0} at the end of epoch {1}".
            format(dev_avg_loss.data[0], epoch_i))

        if (last_dev_avg_loss - dev_avg_loss).data[0] < options.estop:
            logging.info(
                "Early stopping triggered with threshold {0} (previous dev loss: {1}, current: {2})"
                .format(epoch_i, last_dev_avg_loss.data[0],
                        dev_avg_loss.data[0]))
            break
        torch.save(
            rnnlm,
            open(
                options.model_file +
                ".nll_{0:.2f}.epoch_{1}".format(dev_avg_loss.data[0], epoch_i),
                'wb'),
            pickle_module=dill)
        last_dev_avg_loss = dev_avg_loss