def batch_act(self, observations): batchsize = len(observations) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # `labels` stores the true labels returned in the `ys` vector # `valid_inds` tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field xs, ys, labels, valid_inds, is_training = self.vectorize(observations) if xs is None: # no valid examples, just return empty responses return batch_reply predictions = self.predict(xs, ys, is_training) # maps returns predictions back to the right `valid_inds` # in the example above, a prediction `world` should reply to `hello` PaddingUtils.map_predictions(predictions.cpu().data, valid_inds, batch_reply, observations, self.dict, self.END_IDX, labels=labels, answers=labels, ys=ys.data if ys is not None else None, report_freq=self.opt.get( 'report_freq', 0)) return batch_reply
def batch_act(self, observations): batchsize = len(observations) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # valid_inds tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field xs, ys, labels, valid_inds, is_training = self.vectorize(observations) if xs is None: # no valid examples, just return empty responses return batch_reply # produce predictions, train on targets if availables predictions = self.predict(xs, ys, is_training) if is_training: report_freq = 0 else: report_freq = 0.01 PaddingUtils.map_predictions(predictions, valid_inds, batch_reply, observations, self.dict, self.END_IDX, report_freq=report_freq, labels=labels, answers=self.answers, ys=ys.data) return batch_reply
def batch_act(self, observations): batch_reply = [{'id': self.getID()} for _ in range(len(observations))] if any(['labels' in obs for obs in observations]): # if we are starting a new training epoch, reinitialize hidden if not self.is_training: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = True data_list, targets_list, _c, _v, y_lens = self.vectorize( observations, self.opt['seq_len'], self.is_training) else: # if we just finished training, reinitialize hidden if self.is_training: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = False data_list, targets_list, labels, valid_inds, y_lens = self.vectorize( observations, self.opt['seq_len'], self.is_training) if data_list is None: # not enough data to batch act yet, return empty responses return batch_reply batch_reply = [] # during evaluation, len(data_list) is always 1 # during training, len(dat_list) >= 0: vectorize returns a list # containing all batches available at the time it is called for i in range(len(data_list)): temp_dicts = [{ 'id': self.getID() } for _ in range(len(observations))] # ignore case when we do not return any valid indices if data_list[i] is not None: output, hidden, predictions = self.predict( data_list[i], self.hidden, targets_list[i], self.is_training, y_lens) self.hidden = self.repackage_hidden(hidden) if predictions is not None: # map predictions back to the right order PaddingUtils.map_predictions( predictions.cpu(), valid_inds, temp_dicts, observations, self.dict, self.END_IDX, report_freq=self.opt['report_freq'], ) batch_reply += temp_dicts # for prediction metrics computations, we get rid of PERSON1 and PERSON2 tokens if not self.is_training: for reply in batch_reply: if 'text' in reply: reply['text'] = reply['text'].replace('PERSON1 ', '') reply['text'] = reply['text'].replace('PERSON2 ', '') return batch_reply
def batch_act(self, observations): batchsize = len(observations) self.init_cuda_buffer(batchsize) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # valid_inds tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field print(observations) xs, ys, labels, valid_inds, cands, valid_cands, is_training = self.vectorize( observations) print(xs) if xs is None: # no valid examples, just return empty responses return batch_reply # produce predictions, train on targets if availables cand_inds = [i[0] for i in valid_cands] if valid_cands is not None else None predictions, cand_preds = self.predict(xs, ys, cands, cand_inds, is_training) if is_training: report_freq = 0 else: report_freq = self.report_freq if predictions is not None: PaddingUtils.map_predictions( predictions, valid_inds, batch_reply, observations, self.dict, self.END_IDX, report_freq=report_freq, labels=labels, answers=self.answers, ys=ys.data if ys is not None else None) if cand_preds is not None: if valid_cands is None: valid_cands = [(None, i, labels) for i in valid_inds] for i in range(len(valid_cands)): order = cand_preds[i] _, batch_idx, curr_cands = valid_cands[i] curr = batch_reply[batch_idx] curr['text_candidates'] = [ curr_cands[idx] for idx in order if idx < len(curr_cands) ] return batch_reply
def vectorize(self, observations): """Convert a list of observations into input & target tensors.""" is_training = any(['labels' in obs for obs in observations]) xs, ys, labels, valid_inds, _, _ = PaddingUtils.pad_text( observations, self.dict, end_idx=self.END_IDX, null_idx=self.NULL_IDX, dq=True, eval_labels=True, truncate=self.truncate) if xs is None: return None, None, None, None, None, None, None xs = torch.LongTensor(xs) if ys is not None: ys = torch.LongTensor(ys) if self.use_cuda: # copy to gpu self.xs.resize_(xs.size()) self.xs.copy_(xs) xs = Variable(self.xs) if ys is not None: self.ys.resize_(ys.size()) self.ys.copy_(ys) ys = Variable(self.ys) else: xs = Variable(xs) if ys is not None: ys = Variable(ys) cands = None valid_cands = None if not is_training and self.rank: # set up candidates cands = [] valid_cands = [] for i, v in enumerate(valid_inds): if 'label_candidates' in observations[v]: curr_lcs = list(observations[v]['label_candidates']) curr_cands = [{'text': c} for c in curr_lcs] cs, _, _, valid_c_inds, *_ = PaddingUtils.pad_text( curr_cands, self.dict, null_idx=self.NULL_IDX, dq=True, truncate=self.truncate) valid_cands.append( (i, v, [curr_lcs[j] for j in valid_c_inds])) cs = torch.LongTensor(cs) if self.use_cuda: cs = cs.cuda() cands.append(cs) return xs, ys, labels, valid_inds, cands, valid_cands, is_training
def batch_act(self, observations): batch_reply = [{'id': self.getID()} for _ in range(len(observations))] if any(['labels' in obs for obs in observations]): # if we are starting a new training epoch, reinitialize hidden if self.is_training == False: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = True data_list, targets_list, _, _, y_lens = self.vectorize( observations, self.opt['seq_len'], self.is_training) else: # if we just finished training, reinitialize hidden if self.is_training == True: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = False data_list, targets_list, labels, valid_inds, y_lens = self.vectorize( observations, self.opt['seq_len'], self.is_training) if data_list is None: # not enough data to batch act yet, return empty responses return batch_reply batch_reply = [] # during evaluation, len(data_list) is always 1 # during training, len(dat_list) >= 0: vectorize returns a list containing all batches available at the time it is called for i in range(len(data_list)): temp_dicts = [{ 'id': self.getID() } for _ in range(len(observations))] output, hidden, loss_dict, predictions = self.predict( data_list[i], self.hidden, targets_list[i], self.is_training, y_lens) self.hidden = self.repackage_hidden(hidden) if predictions is not None: # map predictions back to the right order PaddingUtils.map_predictions( predictions.cpu(), valid_inds, temp_dicts, observations, self.dict, self.END_IDX, report_freq=self.opt['report_freq']) if loss_dict is not None: if 'metrics' in temp_dicts[0]: for k, v in loss_dict.items(): temp_dicts[0]['metrics'][k] = v else: temp_dicts[0]['metrics'] = loss_dict batch_reply += temp_dicts return batch_reply
def batch_act(self, observations): batchsize = len(observations) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # valid_inds tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field xs, ys, labels, valid_inds, cands, valid_cands = self.vectorize( observations) if xs is None: # no valid examples, just return empty responses return batch_reply # produce predictions, train on targets if availables predictions, text_cand_inds, loss = self.predict( xs, ys, cands, valid_cands) if loss is not None: if 'metrics' in batch_reply[0]: for k, v in loss.items(): batch_reply[0]['metrics'][k] = v else: batch_reply[0]['metrics'] = loss if ys is not None: report_freq = 0 else: report_freq = 0.1 PaddingUtils.map_predictions(predictions, valid_inds, batch_reply, observations, self.dict, self.END_IDX, report_freq=report_freq, labels=labels, answers=self.answers, ys=ys) if text_cand_inds is not None: text_cand_inds = text_cand_inds.cpu().data for i in range(len(valid_cands)): order = text_cand_inds[i] _, batch_idx, curr_cands = valid_cands[i] curr = batch_reply[batch_idx] curr['text_candidates'] = [ curr_cands[idx] for idx in order if idx < len(curr_cands) ] return batch_reply
def batch_act(self, observations): batchsize = len(observations) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # valid_inds tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field xs, ys, labels, valid_inds, cands, valid_cands, is_training = self.vectorize(observations) if xs is None: # no valid examples, just return empty responses return batch_reply # produce predictions, train on targets if availables predictions, text_cand_inds = self.predict(xs, ys, cands, valid_cands, is_training) self.distinct_ngrams(predictions) if is_training: report_freq = 0 else: report_freq = self.report_freq PaddingUtils.map_predictions( predictions.cpu().data, valid_inds, batch_reply, observations, self.dict, self.END_IDX, report_freq=report_freq, labels=labels, answers=self.answers, ys=ys.data if ys is not None else None) # tensor to list list_ref = ys.cpu().data.numpy().tolist() list_hypo = predictions.cpu().data.numpy().tolist() # cut off from self.END_IDX for ref in list_ref: ind = self.end_idx(ref) self.refs.append([ref[:ind]]) for hypo in list_hypo: ind = self.end_idx(hypo) self.hypos.append(hypo[:ind]) if text_cand_inds is not None: text_cand_inds = text_cand_inds.cpu().data for i in range(len(valid_cands)): order = text_cand_inds[i] _, batch_idx, curr_cands = valid_cands[i] curr = batch_reply[batch_idx] curr['text_candidates'] = [curr_cands[idx] for idx in order if idx < len(curr_cands)] return batch_reply
def vectorize(self, observations): """Convert a list of observations into input & target tensors.""" is_training = any(['labels' in obs for obs in observations]) xs, ys, labels, valid_inds, _, _ = PaddingUtils.pad_text( observations, self.dict, end_idx=None, null_idx=self.NULL_IDX, dq=True, eval_labels=True, truncate=self.truncate) if xs is None: return None, None, None, None, None, None, None xs = torch.LongTensor(xs) ys = torch.LongTensor(ys) if self.use_cuda: # copy to gpu self.xs.resize_(xs.size()) self.xs.copy_(xs) xs = Variable(self.xs) if ys is not None: self.ys.resize_(ys.size()) self.ys.copy_(ys) ys = Variable(self.ys) else: xs = Variable(xs) if ys is not None: ys = Variable(ys) return xs, ys, labels, valid_inds, is_training
def vectorize(self, observations): """Convert a list of observations into input & target tensors.""" is_training = any(('labels' in obs for obs in observations)) # utility function for padding text and returning lists of indices # parsed using the provided dictionary xs, ys, labels, valid_inds, _, _ = PaddingUtils.pad_text( observations, self.dict, end_idx=self.END_IDX, null_idx=self.NULL_IDX, dq=False, eval_labels=True) if xs is None: return None, None, None, None, None # move lists of indices returned above into tensors xs = torch.LongTensor(xs) if self.use_cuda: xs = xs.cuda() xs = Variable(xs) if ys is not None: ys = torch.LongTensor(ys) if self.use_cuda: ys = ys.cuda() ys = Variable(ys) return xs, ys, labels, valid_inds, is_training
def vectorize(self, observations): """Convert a list of observations into input & target tensors.""" ys = None xs, ys, labels, valid_inds, _, _ = PaddingUtils.pad_text( observations, self.dict, self.END_IDX, self.NULL_IDX, dq=True, eval_labels=False, truncate=self.truncate) if xs is None: return None, None, None, None, None, None if self.use_cuda: # copy to gpu self.xs.resize_(xs.size()) self.xs.copy_(xs, async=True) xs = Variable(self.xs) if ys is not None: self.ys.resize_(ys.size()) self.ys.copy_(ys, async=True) ys = Variable(self.ys) else: xs = Variable(xs) if ys is not None: ys = Variable(ys) # set up candidates cands = None valid_cands = None if ys is None and self.rank: # only do ranking when no targets available and ranking flag set parsed_cs = [] valid_cands = [] for i, v in enumerate(valid_inds): if 'label_candidates' in observations[v]: # each candidate tuple is a pair of the parsed version and # the original full string cs = list(observations[v]['label_candidates']) curr_dqs = [deque(maxlen=self.truncate) for _ in cs] for dq, c in zip(curr_dqs, cs): dq.extendleft(reversed(self.parse(c))) parsed_cs.append(curr_dqs) valid_cands.append((i, v, cs)) if len(parsed_cs) > 0: # TODO: store lengths of cands separately, so don't have zero # padding for varying number of cands per example # found cands, pack them into tensor max_c_len = max(max(len(c) for c in cs) for cs in parsed_cs) max_c_cnt = max(len(cs) for cs in parsed_cs) for cs in parsed_cs: for c in cs: c += [self.NULL_IDX] * (max_c_len - len(c)) cs += [self.NULL_IDX] * (max_c_cnt - len(cs)) cands = torch.LongTensor(parsed_cs) if self.use_cuda: # copy to gpu self.cands.resize_(cands.size()) self.cands.copy_(cands, async=True) cands = Variable(self.cands) else: cands = Variable(cands) return xs, ys, labels, valid_inds, cands, valid_cands
def batch_act(self, observations): batchsize = len(observations) # initialize a table of replies with this agent's id batch_reply = [{'id': self.getID()} for _ in range(batchsize)] # convert the observations into batches of inputs and targets # valid_inds tells us the indices of all valid examples # e.g. for input [{}, {'text': 'hello'}, {}, {}], valid_inds is [1] # since the other three elements had no 'text' field xs, ys, labels, valid_inds, cands, valid_cands = self.vectorize(observations) if xs is None: # no valid examples, just return empty responses return batch_reply # produce predictions, train on targets if availables predictions, text_cand_inds, loss = self.predict(xs, ys, cands, valid_cands) if loss is not None: if 'metrics' in batch_reply[0]: for k, v in loss.items(): batch_reply[0]['metrics'][k] = v else: batch_reply[0]['metrics'] = loss if ys is not None: report_freq = 0 else: report_freq = 0.1 PaddingUtils.map_predictions( predictions, valid_inds, batch_reply, observations, self.dict, self.END_IDX, report_freq=report_freq, labels=labels, answers=self.answers, ys=ys) if text_cand_inds is not None: text_cand_inds = text_cand_inds.cpu().data for i in range(len(valid_cands)): order = text_cand_inds[i] _, batch_idx, curr_cands = valid_cands[i] curr = batch_reply[batch_idx] curr['text_candidates'] = [curr_cands[idx] for idx in order if idx < len(curr_cands)] return batch_reply
def batch_act(self, observations): batch_reply = [{'id': self.getID()} for _ in range(len(observations))] if any(['labels' in obs for obs in observations]): # if we are starting a new training epoch, reinitialize hidden if self.is_training == False: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = True data_list, targets_list, _, _, y_lens = self.vectorize(observations, self.opt['seq_len'], self.is_training) else: # if we just finished training, reinitialize hidden if self.is_training == True: self.hidden = self.model.init_hidden(self.batchsize) self.is_training = False data_list, targets_list, labels, valid_inds, y_lens = self.vectorize(observations, self.opt['seq_len'], self.is_training) if data_list is None: # not enough data to batch act yet, return empty responses return batch_reply batch_reply = [] # during evaluation, len(data_list) is always 1 # during training, len(dat_list) >= 0: vectorize returns a list containing all batches available at the time it is called for i in range(len(data_list)): temp_dicts = [{'id': self.getID()} for _ in range(len(observations))] output, hidden, loss_dict, predictions = self.predict(data_list[i], self.hidden, targets_list[i], self.is_training, y_lens) self.hidden = self.repackage_hidden(hidden) if predictions is not None: # map predictions back to the right order PaddingUtils.map_predictions( predictions, valid_inds, temp_dicts, observations, self.dict, self.END_IDX, report_freq=self.opt['report_freq']) if loss_dict is not None: if 'metrics' in temp_dicts[0]: for k, v in loss_dict.items(): temp_dicts[0]['metrics'][k] = v else: temp_dicts[0]['metrics'] = loss_dict batch_reply += temp_dicts return batch_reply
def vectorize(self, observations, seq_len, is_training): """Convert a list of observations into input & target tensors.""" labels = None valid_inds = None y_lens = None if is_training: for obs in observations: if obs: if 'text2vec' in obs: self.next_batch += obs['text2vec'] if len(self.next_batch) <= self.batchsize: return None, None, None, None, None else: data_list = [] targets_list = [] # total is the number of batches total = len(self.next_batch) // self.batchsize for _ in range(total): batch = self.next_batch[:self.batchsize] self.next_batch = self.next_batch[self.batchsize:] source = torch.LongTensor(batch).t().contiguous() data = Variable(source[:seq_len]) targets = Variable(source[1:]) if self.use_cuda: data = data.cuda() targets = targets.cuda() data_list.append(data) targets_list.append(targets) else: # here we get valid examples and pad them with zeros xs, ys, labels, valid_inds, _, y_lens = PaddingUtils.pad_text( observations, self.dict, end_idx=self.END_IDX, null_idx=self.NULL_IDX) if self.use_cuda: if xs is not None: xs = Variable(torch.LongTensor(xs)).cuda() if ys is not None: ys = Variable(torch.LongTensor(ys)).cuda() else: if xs is not None: xs = Variable(torch.LongTensor(xs)) if ys is not None: ys = Variable(torch.LongTensor(ys)) data_list = [xs] targets_list = [ys] return data_list, targets_list, labels, valid_inds, y_lens
def vectorize(self, observations, seq_len, is_training): """Convert a list of observations into input & target tensors.""" labels = None valid_inds = None y_lens = None if is_training: for obs in observations: if obs: if 'text2vec' in obs: self.next_batch += obs['text2vec'] if len(self.next_batch) <= self.batchsize: return None, None, None, None, None else: data_list = [] targets_list = [] # total is the number of batches total = len(self.next_batch)//self.batchsize for i in range(total): batch = self.next_batch[:self.batchsize] self.next_batch = self.next_batch[self.batchsize:] source = torch.LongTensor(batch).t().contiguous() data = Variable(source[:seq_len]) targets = Variable(source[1:]) if self.use_cuda: data = data.cuda() targets = targets.cuda() data_list.append(data) targets_list.append(targets) else: # here we get valid examples and pad them with zeros xs, ys, labels, valid_inds, _, y_lens = PaddingUtils.pad_text( observations, self.dict, self.END_IDX, self.NULL_IDX) if self.use_cuda: xs = Variable(xs).cuda() ys = Variable(ys).cuda() else: xs = Variable(xs) ys = Variable(ys) data_list = [xs] targets_list = [ys] return data_list, targets_list, labels, valid_inds, y_lens
def vectorize(self, observations): """Convert a list of observations into input & target tensors.""" ys = None xs, ys, labels, valid_inds, _, _ = PaddingUtils.pad_text( observations, self.dict, self.END_IDX, self.NULL_IDX, dq=True, eval_labels=False, truncate=self.truncate) if xs is None: return None, None, None, None, None, None if self.use_cuda: # copy to gpu self.xs.resize_(xs.size()) self.xs.copy_(xs, async=True) xs = Variable(self.xs) if ys is not None: self.ys.resize_(ys.size()) self.ys.copy_(ys, async=True) ys = Variable(self.ys) else: xs = Variable(xs) if ys is not None: ys = Variable(ys) # set up candidates cands = None valid_cands = None if ys is None and self.rank: # only do ranking when no targets available and ranking flag set parsed_cs = [] valid_cands = [] for i, v in enumerate(valid_inds): if 'label_candidates' in observations[v]: # each candidate tuple is a pair of the parsed version and # the original full string cs = list(observations[v]['label_candidates']) curr_dqs = [deque(maxlen=self.truncate) for _ in cs] for dq, c in zip(curr_dqs, cs): dq.extendleft(reversed(self.parse(c))) parsed_cs.append(curr_dqs) valid_cands.append((i, v, cs)) if len(parsed_cs) > 0: # TODO: store lengths of cands separately, so don't have zero # padding for varying number of cands per example # found cands, pack them into tensor max_c_len = max(max(len(c) for c in cs) for cs in parsed_cs) max_c_cnt = max(len(cs) for cs in parsed_cs) for cs in parsed_cs: for c in cs: c += [self.NULL_IDX] * (max_c_len - len(c)) cs += [self.NULL_IDX] * (max_c_cnt - len(cs)) cands = torch.LongTensor(parsed_cs) if self.use_cuda: # copy to gpu self.cands.resize_(cands.size()) self.cands.copy_(cands, async=True) cands = Variable(self.cands) else: cands = Variable(cands) return xs, ys, labels, valid_inds, cands, valid_cands