Spaces:
Running
Running
| import torch | |
| import numpy as np | |
| from data import Dataset, make_data_iter | |
| from helpers import calculate_dtw | |
| from batch import Batch | |
| from model import Model | |
| from constants import PAD_TOKEN | |
| # Validate epoch given a dataset | |
| # def validate_on_data(model: Model, | |
| # data: Dataset, | |
| # batch_size: int, | |
| # max_output_length: int, | |
| # eval_metric: str, | |
| # loss_function: torch.nn.Module = None, | |
| # batch_type: str = "sentence", | |
| # type = "val", | |
| # BT_model = None): | |
| # valid_iter = make_data_iter( | |
| # dataset=data, batch_size=batch_size, | |
| # shuffle=True, train=False) | |
| # pad_index = model.src_vocab.stoi[PAD_TOKEN] | |
| # # disable dropout | |
| # model.eval() | |
| # # don't track gradients during validation | |
| # with torch.no_grad(): | |
| # valid_hypotheses = [] | |
| # valid_references = [] | |
| # valid_inputs = [] | |
| # file_paths = [] | |
| # all_dtw_scores = [] | |
| # valid_loss = 0 | |
| # total_ntokens = 0 | |
| # total_nseqs = 0 | |
| # batches = 0 | |
| # for valid_batch in iter(valid_iter): | |
| # # Extract batch | |
| # batch = Batch(torch_batch=valid_batch, | |
| # pad_index=pad_index, | |
| # model=model) | |
| # targets = batch.trg_input | |
| # # run as during training with teacher forcing | |
| # if loss_function is not None and batch.trg is not None: | |
| # # Get the loss for this batch | |
| # batch_loss = model.get_loss_for_batch(is_train=True, | |
| # batch=batch, | |
| # loss_function=loss_function) | |
| # valid_loss += batch_loss | |
| # total_ntokens += batch.ntokens | |
| # total_nseqs += batch.nseqs | |
| # output = model.forward(src=batch.src, | |
| # trg_input=batch.trg_input[:, :, :150], | |
| # src_mask=batch.src_mask, | |
| # src_lengths=batch.src_lengths, | |
| # trg_mask=batch.trg_mask, | |
| # is_train=False) | |
| # output = torch.cat((output, batch.trg_input[:, :, 150:]), dim=-1) | |
| # # Add references, hypotheses and file paths to list | |
| # valid_references.extend(targets) | |
| # valid_hypotheses.extend(output) | |
| # file_paths.extend(batch.file_paths) | |
| # # Add the source sentences to list, by using the model source vocab and batch indices | |
| # valid_inputs.extend([[model.src_vocab.itos[batch.src[i][j]] for j in range(len(batch.src[i]))] for i in | |
| # range(len(batch.src))]) | |
| # # Calculate the full Dynamic Time Warping score - for evaluation | |
| # dtw_score = calculate_dtw(targets, output) | |
| # all_dtw_scores.extend(dtw_score) | |
| # # Can set to only run a few batches | |
| # # if batches == math.ceil(20/batch_size): | |
| # # break | |
| # batches += 1 | |
| # # Dynamic Time Warping scores | |
| # current_valid_score = np.mean(all_dtw_scores) | |
| # return current_valid_score, valid_loss, valid_references, valid_hypotheses, \ | |
| # valid_inputs, all_dtw_scores, file_paths | |
| def validate_on_data(model: Model, | |
| data: Dataset, | |
| batch_size: int, | |
| max_output_length: int, | |
| eval_metric: str, | |
| loss_function: torch.nn.Module = None, | |
| vocab=None, | |
| # tok_fun=None, | |
| trg_size: int = 150, | |
| BT_model=None): | |
| # Build validation DataLoader | |
| valid_iter = make_data_iter( | |
| dataset=data, | |
| batch_size=batch_size, | |
| vocab=vocab, | |
| # tok_fun=tok_fun, | |
| trg_size=trg_size, | |
| shuffle=False | |
| ) | |
| pad_index = model.src_vocab.stoi[PAD_TOKEN] | |
| model.eval() | |
| with torch.no_grad(): | |
| valid_hypotheses = [] | |
| valid_references = [] | |
| valid_inputs = [] | |
| file_paths = [] | |
| all_dtw_scores = [] | |
| valid_loss = 0 | |
| total_ntokens = 0 | |
| total_nseqs = 0 | |
| batches = 0 | |
| for valid_batch in iter(valid_iter): | |
| # Wrap into Batch | |
| batch = Batch(torch_batch=valid_batch, | |
| pad_index=pad_index, | |
| model=model) | |
| targets = batch.trg_input | |
| # Compute loss if available | |
| if loss_function is not None and batch.trg is not None: | |
| batch_loss = model.get_loss_for_batch( | |
| is_train=True, | |
| batch=batch, | |
| loss_function=loss_function | |
| ) | |
| valid_loss += batch_loss | |
| total_ntokens += batch.ntokens | |
| total_nseqs += batch.nseqs | |
| # Forward pass | |
| output = model.forward( | |
| src=batch.src, | |
| trg_input=batch.trg_input[:, :, :trg_size], | |
| src_mask=batch.src_mask, | |
| src_lengths=batch.src_lengths, | |
| trg_mask=batch.trg_mask, | |
| is_train=False | |
| ) | |
| # Concatenate remainder of target | |
| output = torch.cat((output, batch.trg_input[:, :, trg_size:]), dim=-1) | |
| # Collect results | |
| valid_references.extend(targets) | |
| valid_hypotheses.extend(output) | |
| file_paths.extend(batch.file_paths) | |
| valid_inputs.extend([ | |
| [model.src_vocab.itos[batch.src[i][j]] for j in range(len(batch.src[i]))] | |
| for i in range(len(batch.src)) | |
| ]) | |
| # Dynamic Time Warping score | |
| dtw_score = calculate_dtw(targets, output) | |
| all_dtw_scores.extend(dtw_score) | |
| batches += 1 | |
| # Clean up memory periodically during validation | |
| if batches % 10 == 0: | |
| torch.cuda.empty_cache() | |
| current_valid_score = np.mean(all_dtw_scores) | |
| return ( | |
| current_valid_score, | |
| valid_loss, | |
| valid_references, | |
| valid_hypotheses, | |
| valid_inputs, | |
| all_dtw_scores, | |
| file_paths | |
| ) | |