def train(self, reader: DataReader, reader_dev: DataReader = None):
        """
        Trains the model on the given reader.

        NOTE: If no development reader is given, autostopping will be disabled!

        :param reader: The DataReader object which contains the training data
        :param reader_dev: The DataReader object for evaluation and auto stopping
        :return:
        """

        xs = []
        ys = []

        new_xs, new_ys = get_dataset(reader)
        xs += new_xs
        ys += new_ys

        shuffle_concurrent_lists([xs, ys])

        # Zip datasets and generate complete dictionary
        examples = [
            data.Example.fromlist([x, y], self.data_fields) for x, y in zip(xs, ys)
        ]

        dataset = data.Dataset(examples, fields=self.data_fields)

        self.input_field.build_vocab(dataset)
        self.output_field.build_vocab(dataset)

        dataset_size = len(xs)

        train_iter = self.prepare_dataset(xs, ys)

        dev_iter = self.get_iter(reader_dev)

        self.input_field.vocab.load_vectors("glove.6B.300d")

        num_classes = len(self.output_field.vocab)

        embed = nn.Embedding.from_pretrained(self.input_field.vocab.vectors)

        self.network = FrameIDNetwork(self.cM, embed, num_classes)

        if dev_iter is None:
            logging.info(
                f"NOTE: Beginning training w/o a development set! Autostopper deactivated!"
            )

        self.network.train_model(dataset_size, train_iter, dev_iter)
示例#2
0
    def train(self, mReader, mReaderDev):
        """
        Trains the model on all of the given annotations.

        :param annotations: A list of all annotations to train the model from
        :return:
        """

        embed = self.gen_embedding_layer(mReader)

        xs, ys = self.get_dataset_comb(mReader)

        dev_xs, dev_ys = self.get_dataset_comb(mReaderDev)

        shuffle_concurrent_lists([xs, ys])

        num_classes = 3

        self.network = SpanIdNetwork(self.cM, num_classes, embed)

        self.network.train_model(xs, ys, dev_xs, dev_ys)
示例#3
0
def test_shuffle(testdata: List[object], expected: List[object]):
    """
    Test the correctness of the shuffling function in utils

    NOTE: Each shuffling is required to keep concurrency!

    :param testdata: A list of objects
    :param expected: A list of objects
    :return:
    """

    testdata2 = testdata.copy()
    expected2 = expected.copy()

    shuffle_concurrent_lists([testdata, expected])

    for i in range(len(testdata)):
        x = testdata[i]
        y = expected[i]

        assert (x, y) in [(s, t) for s, t in zip(testdata2, expected2)]
示例#4
0
    def gen_embedding_layer(self, reader: DataReader):
        """

        :param reader:
        :return:
        """

        input_field = data.Field(
            dtype=torch.long, use_vocab=True, preprocessing=None
        )  # , fix_length= max_length) #No padding necessary anymore, since avg
        output_field = data.Field(dtype=torch.long)
        data_fields = [("Sentence", input_field), ("Frame", output_field)]

        xs = []
        ys = []

        new_xs, new_ys = get_dataset(reader)
        xs += new_xs
        ys += new_ys

        shuffle_concurrent_lists([xs, ys])

        examples = [
            data.Example.fromlist([x, y], data_fields) for x, y in zip(xs, ys)
        ]

        dataset = data.Dataset(examples, fields=data_fields)

        input_field.build_vocab(dataset)
        output_field.build_vocab(dataset)

        input_field.vocab.load_vectors("glove.6B.300d")

        embed = torch.nn.Embedding.from_pretrained(input_field.vocab.vectors)

        self.input_field = input_field

        return embed
    def train_model(
        self,
        xs: List[torch.tensor],
        ys: List[List[int]],
        dev_xs: List[torch.tensor] = None,
        dev_ys: List[List[int]] = None,
    ):
        """
        Trains the model with the given dataset
        Uses the model specified in net

        :param xs: The training sequences, given as a list of tensors
        :param ys: The labels of the sequences
        :param dev_xs: The development sequences, given as a list of tensors
        :param dev_ys: The labels of the sequences
        :return:
        """

        dataset_size = len(xs)

        for epoch in range(self.cM.span_num_epochs):

            total_loss = 0
            total_hits = 0
            perf_match = 0
            count = 0
            occ = 0

            shuffle_concurrent_lists([xs, ys])

            with tqdm(
                    zip(xs, ys),
                    position=0,
                    desc=
                    f"[Epoch: {epoch+1}/{self.cM.span_num_epochs}] Iteration",
            ) as progress_bar:

                for x, y in progress_bar:

                    output_dim = len(x)

                    labels = Variable(torch.tensor(y)).to(self.device)
                    labels = torch.reshape(labels, (1, output_dim))

                    self.reset_hidden()

                    # Forward + Backward + Optimize
                    self.optimizer.zero_grad()  # zero the gradient buffer
                    outputs = self.net(x)

                    outputs = torch.reshape(outputs, (1, 3, output_dim))

                    loss = self.criterion(outputs, labels)
                    loss.backward()
                    self.optimizer.step()
                    total_loss += loss.item()
                    _, predicted = torch.max(outputs.data, 1)

                    su = sum(predicted[0])

                    occ += su
                    total_hits += (predicted == labels).sum().item() / len(
                        predicted[0])
                    if (predicted == labels).sum().item() == len(predicted[0]):
                        perf_match += 1

                    count += 1

                    # Just update every 20 iterations
                    if count % 20 == 0:
                        train_loss = round((total_loss / count), 4)
                        train_acc = round((total_hits / count), 4)
                        perf_acc = round((perf_match / count), 4)
                        progress_bar.set_postfix(
                            Loss=train_loss,
                            Acc=train_acc,
                            Perfect=perf_acc,
                            Frames=f"{count}/{dataset_size}",
                            OccSpans=occ,
                        )

            self.eval_dev(dev_xs, dev_ys)