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)
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)
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)]
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)