def prepare_batch(batch, voc): # index_seqs = [indexesFromSentence(voc, normalizeString(u)) + indexesFromSentence(voc, normalizeString(r)) for u, r in # zip(batch.utterance, batch.response)] index_seqs = [ indexesFromSentence(voc, u) + indexesFromSentence(voc, r) for u, r in zip(batch.utterance, batch.response) ] lengths = torch.tensor([len(s) for s in index_seqs], device=device, dtype=torch.long) #, device=device) seq_tensor = torch.zeros((len(index_seqs), lengths.max()), device=device, dtype=torch.long) for idx, (seq, seq_len) in enumerate(zip(index_seqs, lengths)): # seq_tensor[idx, :seq_len] = torch.LongTensor(seq) seq_tensor[idx, :seq_len] = torch.tensor(seq, device=device, dtype=torch.long) lengths, perm_idx = lengths.sort(0, descending=True) seq_tensor = seq_tensor[perm_idx] target = batch.rating target = target[perm_idx].to(device) return seq_tensor, target
def sentence2tensor(self, sentence): ### Format input sentence as a batch # words -> indexes indexes_batch = [indexesFromSentence(self.voc, sentence)] seq = torch.tensor(indexes_batch, device=device, dtype=torch.long) # Use appropriate device seq = seq.to(device) return seq
def prepare_batch(batch, voc): index_seqs = [ indexesFromSentence(voc, u) + indexesFromSentence(voc, r) for u, r in zip(batch.utterance, batch.response) ] lengths = torch.LongTensor([len(s) for s in index_seqs], device=device) seq_tensor = torch.zeros((len(index_seqs), lengths.max()), device=device).long() for idx, (seq, seq_len) in enumerate(zip(index_seqs, lengths)): seq_tensor[idx, :seq_len] = torch.LongTensor(seq, device=device) lengths, perm_idx = lengths.sort(0, descending=True) seq_tensor = seq_tensor[perm_idx] target = batch.reward target = target[perm_idx] return seq_tensor, target
def test_AdversarialDiscriminatorOnLatestSeq2Seq(model, searcher, data_loader, voc): print("evaluating trained model ...") correctlyHuman = 0 correctlyBot = 0 test_data_size = len(data_loader.dataset) for batch in data_loader: seq, target = prepare_batch(batch, voc) target[:] = 1 pred = model(seq) correctlyHuman = sum(pred >= 0.5).item() # input_sentence_tokens = [indexesFromSentence(voc, normalizeString(u)) for u in batch.utterance] input_sentence_tokens = [ indexesFromSentence(voc, u) for u in batch.utterance ] input_sentence_tokens.sort(key=len, reverse=True) lengths = torch.tensor( [len(indexes) for indexes in input_sentence_tokens], dtype=torch.long, device=device) maxLength = max(lengths) padded_input_sentence_tokens = [ indexes + list(itertools.repeat(PAD_token, maxLength - len(indexes))) for indexes in input_sentence_tokens ] input_batch = torch.tensor(padded_input_sentence_tokens, device=device, dtype=torch.long) output_sentence_tokens, scores = searcher(input_batch) compiledSequence = torch.cat([input_batch, output_sentence_tokens], dim=1).to(device) target[:] = 0 pred = model(compiledSequence) correctlyBot = sum(pred < 0.5).item() # print('test batch {}\n'.format(i)) print( '\nTest set accuracy: correctly guess human: {}/{} ({:.0f}%) ; correctly guess bot: {}/{} ({:.0f}%)' .format(correctlyHuman, batch_size, (100. * correctlyHuman / batch_size), correctlyBot, batch_size, (100. * correctlyBot / batch_size)))
def trainAdversarialDiscriminatorOnLatestSeq2Seq(model, searcher, voc, data_loader, criterion, optimizer, embedding, save_dir, epoch): # Evaluating the searcher total_loss = 0 for i, batch in enumerate(data_loader, 1): seq, target = prepare_batch(batch, voc) output = model(seq) try: target = torch.ones([len(seq), 1], dtype=torch.float, device=device) loss = criterion(output, target) except: target = torch.ones([len(seq), 1], dtype=torch.long, device=device) loss = criterion(output, target) total_loss += loss.item() model.zero_grad() loss.backward() optimizer.step() input_sentence_tokens = [ indexesFromSentence(voc, u) for u in batch.utterance ] input_sentence_tokens.sort(key=len, reverse=True) lengths = torch.tensor( [len(indexes) for indexes in input_sentence_tokens], dtype=torch.long, device=device) maxLength = max(lengths) padded_input_sentence_tokens = [ indexes + list(itertools.repeat(PAD_token, maxLength - len(indexes))) for indexes in input_sentence_tokens ] #input_sentence_tokens # # Transpose dimensions of batch to match models' expectations input_batch = torch.tensor(padded_input_sentence_tokens, device=device, dtype=torch.long) # Use appropriate device input_batch = input_batch.to(device) # Decode sentence with searcher output_sentence_tokens, scores = searcher(input_batch, MAX_LENGTH) compiledSequence = torch.cat([input_batch, output_sentence_tokens], dim=1).to(device) output = model(compiledSequence) try: target = torch.zeros([len(seq), 1], dtype=torch.float, device=device) loss = criterion(output, target) except: target = torch.zeros([len(seq), 1], dtype=torch.long, device=device) loss = criterion(output, target) total_loss += loss.item() model.zero_grad() loss.backward() optimizer.step() # print('batch {}\n'.format(i)) if i % 1 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.2f}'.format( epoch, i * len(batch[0]), len(data_loader.dataset), 100. * i * len(batch[0]) / len(data_loader.dataset), total_loss / i * len(batch))) # if(i % 100 == 0): # torch.save({ # 'iteration': i+epoch, # 'model': model.state_dict(), # 'opt': optimizer.state_dict(), # 'loss': loss, # 'voc_dict': voc.__dict__, # 'embedding': embedding.state_dict() # }, os.path.join(save_dir, '{}_{}.tar'.format(i+epoch, 'batches'))) return total_loss