def get_nobp_state(self, state): output_state = state.rnn_state.output() if type(output_state) == EnsembleListDelegate: for i in range(len(output_state)): output_state[i] = dy.nobackprop(output_state[i]) else: output_state = dy.nobackprop(output_state) return output_state
def get_nobp_state( self, state: decoders.AutoRegressiveDecoderState) -> dy.Expression: output_state = state.rnn_state.output() if type(output_state) == EnsembleListDelegate: for i in range(len(output_state)): output_state[i] = dy.nobackprop(output_state[i]) else: output_state = dy.nobackprop(output_state) return output_state
def on_calc_additional_loss(self, translator_loss): if not self.learn_segmentation or self.segment_decisions is None: return None reward = -translator_loss["mle"] if not self.log_reward: reward = dy.exp(reward) reward = dy.nobackprop(reward) # Make sure that reward is not scalar, but rather based on the each batch item assert reward.dim()[1] == len(self.src_sent) # Mask enc_mask = self.enc_mask.get_active_one_mask().transpose() if self.enc_mask is not None else None # Compose the lose ret = LossBuilder() ## Length prior alpha = self.length_prior_alpha.value() if self.length_prior_alpha is not None else 0 if alpha > 0: reward += self.segment_length_prior * alpha # reward z-score normalization if self.z_normalization: reward = dy.cdiv(reward-dy.mean_batches(reward), dy.std_batches(reward) + EPS) ## Baseline Loss if self.use_baseline: baseline_loss = [] for i, baseline in enumerate(self.bs): loss = dy.squared_distance(reward, baseline) if enc_mask is not None: loss = dy.cmult(dy.inputTensor(enc_mask[i], batched=True), loss) baseline_loss.append(loss) ret.add_loss("Baseline", dy.esum(baseline_loss)) if self.print_sample: print(dy.exp(self.segment_logsoftmaxes[i]).npvalue().transpose()[0]) ## Reinforce Loss lmbd = self.lmbd.value() if lmbd > 0.0: reinforce_loss = [] # Calculating the loss of the baseline and reinforce for i in range(len(self.segment_decisions)): ll = dy.pick_batch(self.segment_logsoftmaxes[i], self.segment_decisions[i]) if self.use_baseline: r_i = reward - dy.nobackprop(self.bs[i]) else: r_i = reward if enc_mask is not None: ll = dy.cmult(dy.inputTensor(enc_mask[i], batched=True), ll) reinforce_loss.append(r_i * -ll) loss = dy.esum(reinforce_loss) * lmbd ret.add_loss("Reinforce", loss) if self.confidence_penalty: ls_loss = self.confidence_penalty(self.segment_logsoftmaxes, enc_mask) ret.add_loss("Confidence Penalty", ls_loss) # Total Loss return ret
def calc_baseline_loss(self, reward, only_final_reward): pred_rewards = [] cur_losses = [] for i, state in enumerate(self.states): pred_reward = self.baseline.transform(dy.nobackprop(state)) pred_rewards.append(dy.nobackprop(pred_reward)) seq_reward = reward if only_final_reward else reward[i] if self.valid_pos is not None: pred_reward = dy.pick_batch_elems(pred_reward, self.valid_pos[i]) act_reward = dy.pick_batch_elems(seq_reward, self.valid_pos[i]) else: act_reward = seq_reward cur_losses.append(dy.sum_batches(dy.squared_distance(pred_reward, dy.nobackprop(act_reward)))) return pred_rewards, dy.esum(cur_losses)
def calc_reinforce_loss(words, tags, delta): dy.renew_cg() # Transduce all batch elements with an LSTM word_reps = LSTM.transduce([LOOKUP[x] for x in words]) # Softmax scores W = dy.parameter(W_sm) b = dy.parameter(b_sm) #calculate the probability distribution scores = [dy.affine_transform([b, W, x]) for x in word_reps] losses = [ dy.pickneglogsoftmax(score, tag) for score, tag in zip(scores, tags) ] probs = [-dy.exp(loss).as_array() for loss in losses] #then take samples from the probability distribution samples = [np.random.choice(range(len(x)), p=x) for x in probs] #calculate accuracy=reward correct = [sample == tag for sample, tag in zip(samples, tags)] r_i = float(sum(correct)) / len(correct) r = dy.constant((1), r_i) # Reward baseline for each word W_bl = dy.parameter(W_bl_p) b_bl = dy.parameter(b_bl_p) r_b = [ dy.affine_transform([b_bl, W_bl, dy.nobackprop(x)]) for x in word_reps ] #we need to take the value in order to break the computation graph #as the reward portion is trained seperatley and not backpropogated through during the overall score rewards_over_baseline = [(r - dy.nobackprop(x)) for x in r_b] #the scores for training the baseline baseline_scores = [dy.square(r - x) for x in r_b] #then calculate the reinforce scores using reinforce reinforce_scores = [ r_s * score for r_s, score in zip(rewards_over_baseline, scores) ] #we want the first len(sent)-delta scores from xent then delta scores from reinforce #for mixer if len(scores) > delta: mixer_scores = scores[:len(scores) - delta] + reinforce_scores[delta - 1:] else: mixer_scores = reinforce_scores return dy.esum(mixer_scores), dy.esum(baseline_scores)
def BuildLMGraph(self, sent, sent_args=None): dynet.renew_cg() init_state = self.rnn.initial_state() R = dynet.parameter(self.R) bias = dynet.parameter(self.bias) errs = [] # will hold expressions state = init_state for (cw, nw) in zip(sent, sent[1:]): cw = self.vocab[cw] nw = self.vocab[nw] #print "before if" if cw.s in self.pron_dict.pdict: #print "string in pron dict" fpv = self.pron_dict.pdict[cw.s] fpv = dynet.inputVector(fpv) else: #print "string not in pron dict" spelling = [ self.s2s.src_vocab[letter] for letter in cw.s.upper() ] embedded_spelling = self.s2s.embed_seq(spelling) pron_vector = self.s2s.encode_seq(embedded_spelling)[-1] fpv = dynet.nobackprop(pron_vector) x_t = dynet.concatenate([self.lookup[cw.i], fpv]) state = state.add_input(x_t) y_t = state.output() r_t = bias + (R * y_t) err = dynet.pickneglogsoftmax(r_t, int(nw.i)) errs.append(err) nerr = dynet.esum(errs) return nerr
def training_step(self, src, trg): """ Performs forward pass, backward pass, parameter update for the given minibatch """ loss_builder = LossBuilder() standard_loss = self.model.calc_loss(src, trg, self.loss_calculator) if standard_loss.__class__ == LossBuilder: loss = None for loss_name, loss_expr in standard_loss.loss_nodes: loss_builder.add_loss(loss_name, loss_expr) loss = loss_expr if not loss else loss + loss_expr standard_loss = loss else: loss_builder.add_loss("loss", standard_loss) additional_loss = self.model.calc_additional_loss( dy.nobackprop(-standard_loss)) if additional_loss != None: loss_builder.add_loss("additional_loss", additional_loss) loss_value = loss_builder.compute() self.logger.update_epoch_loss(src, trg, loss_builder) self.logger.report_train_process() return loss_value
def calc_loss(self, model: 'model_base.ConditionedModel', src: Union[sent.Sentence, 'batchers.Batch'], trg: Union[sent.Sentence, 'batchers.Batch']) -> losses.FactoredLossExpr: search_outputs = model.generate_search_output(src, self.search_strategy) sign = -1 if self.inv_eval else 1 total_loss = losses.FactoredLossExpr() for search_output in search_outputs: # Calculate rewards eval_score = [] for trg_i, sample_i in zip(trg, search_output.word_ids): # Removing EOS sample_i = self.remove_eos(sample_i.tolist()) ref_i = trg_i.words[:trg_i.len_unpadded()] score = self.evaluation_metric.evaluate_one_sent(ref_i, sample_i) eval_score.append(sign * score) reward = dy.inputTensor(eval_score, batched=True) # Composing losses loss = losses.FactoredLossExpr() baseline_loss = [] cur_losses = [] for state, mask in zip(search_output.state, search_output.mask): bs_score = self.baseline.transform(dy.nobackprop(state.as_vector())) baseline_loss.append(dy.squared_distance(reward, bs_score)) logsoft = model.decoder.scorer.calc_log_probs(state.as_vector()) loss_i = dy.cmult(logsoft, reward - bs_score) cur_losses.append(dy.cmult(loss_i, dy.inputTensor(mask, batched=True))) loss.add_loss("reinforce", dy.sum_elems(dy.esum(cur_losses))) loss.add_loss("reinf_baseline", dy.sum_elems(dy.esum(baseline_loss))) # Total losses total_loss.add_factored_loss_expr(loss) return loss
def decode(self, input_vectors, output): tgt_toks = [self.tgt_vocab[tok] for tok in output] w = dynet.parameter(self.decoder_w) b = dynet.parameter(self.decoder_b) s = self.dec_lstm.initial_state() s = s.add_input( dynet.concatenate([ input_vectors[-1], dynet.vecInput(self.args.hidden_dim * 2), dynet.vecInput(self.pronouncer.args.hidden_dim * 2) ])) loss = [] for tok in tgt_toks: out_vector = w * s.output() + b probs = dynet.softmax(out_vector) loss.append(-dynet.log(dynet.pick(probs, tok.i))) embed_vector = self.tgt_lookup[tok.i] attn_vector = self.attend(input_vectors, s) spelling = [ self.pronouncer.src_vocab[letter] for letter in tok.s.upper() ] embedded_spelling = self.pronouncer.embed_seq(spelling) pron_vector = self.pronouncer.encode_seq(embedded_spelling)[-1] fpv = dynet.nobackprop(pron_vector) inp = dynet.concatenate([embed_vector, attn_vector, fpv]) s = s.add_input(inp) loss = dynet.esum(loss) return loss
def encode_seq(self, src_seq): src_seq, raw_words = src_seq spellings = [[ self.pronouncer.src_vocab[letter] for letter in self.src_vocab[tok].s.upper() ] for tok in raw_words] embedded_spellings = [ self.pronouncer.embed_seq(spelling) for spelling in spellings ] pron_vectors = [ self.pronouncer.encode_seq(embedded_spelling)[-1] for embedded_spelling in embedded_spellings ] fpvs = [dynet.nobackprop(pron_vector) for pron_vector in pron_vectors] src_seq_rev = list(reversed(src_seq)) fwd_vectors = self.enc_fwd_lstm.initial_state().transduce(src_seq) bwd_vectors = self.enc_bwd_lstm.initial_state().transduce(src_seq_rev) bwd_vectors = list(reversed(bwd_vectors)) vectors = [ dynet.concatenate(list(p)) for p in zip(fwd_vectors, bwd_vectors, fpvs) ] return vectors
def BuildLMGraph(self, sent, sent_args=None): dynet.renew_cg() init_state = self.rnn.initial_state() R = dynet.parameter(self.R) bias = dynet.parameter(self.bias) errs = [] # will hold expressions state = init_state for (cw, nw) in zip(sent, sent[1:]): cw = self.vocab[cw] nw = self.vocab[nw] spelling = [self.s2s.src_vocab[letter] for letter in cw.s.upper()] embedded_spelling = self.s2s.embed_seq(spelling) pron_vector = self.s2s.encode_seq(embedded_spelling)[-1] fpv = dynet.nobackprop(pron_vector) x_t = fpv state = state.add_input(x_t) y_t = state.output() r_t = bias + (R * y_t) err = dynet.pickneglogsoftmax(r_t, int(nw.i)) errs.append(err) nerr = dynet.esum(errs) return nerr
def _next_action(self, state, src_len, force_action=None) -> PolicyAction: # Sanity Check here: if force_action is None: force_action = self.Action.READ.value if state.has_been_read == 0 else force_action # No writing at the beginning. force_action = self.Action.WRITE.value if state.has_been_read == src_len else force_action # No reading at the end. if self.read_before_write: force_action = self.Action.READ.value if state.has_been_read < src_len else self.Action.WRITE.value # Compose inputs from 3 states if self.policy_network is not None: enc_dim = self.src_encoding[0].dim() encoder_state = state.encoder_state if state.encoder_state is not None else dy.zeros( *enc_dim) decoder_state = state.decoder_state.as_vector( ) if state.decoder_state is not None else dy.zeros(*enc_dim) policy_input = dy.nobackprop( dy.concatenate([encoder_state, decoder_state])) predefined_action = [force_action ] if force_action is not None else None # Sample / Calculate a single action policy_action = self.policy_network.sample_action( policy_input, predefined_actions=predefined_action, argmax=not (self.train and self.policy_sample)) policy_action.single_action() else: policy_action = PolicyAction(force_action) # TODO(philip30): Update this value when you add more actions if policy_action.content > 2: import random policy_action.content = random.randint(0, 1) return policy_action
def __call__(self, translator, dec_state, src, trg): # TODO: apply trg.mask ? samples = [] logsofts = [] self.bs = [] done = [False for _ in range(len(trg))] for _ in range(self.sample_length): dec_state.context = translator.attender.calc_context(dec_state.rnn_state.output()) if self.use_baseline: h_t = dy.tanh(translator.decoder.context_projector(dy.concatenate([dec_state.rnn_state.output(), dec_state.context]))) self.bs.append(self.baseline(dy.nobackprop(h_t))) logsoft = dy.log_softmax(translator.decoder.get_scores(dec_state)) sample = logsoft.tensor_value().categorical_sample_log_prob().as_numpy()[0] # Keep track of previously sampled EOS sample = [sample_i if not done_i else Vocab.ES for sample_i, done_i in zip(sample, done)] # Appending and feeding in the decoder logsoft = dy.pick_batch(logsoft, sample) logsofts.append(logsoft) samples.append(sample) dec_state = translator.decoder.add_input(dec_state, translator.trg_embedder.embed(xnmt.batcher.mark_as_batch(sample))) # Check if we are done. done = list(six.moves.map(lambda x: x == Vocab.ES, sample)) if all(done): break samples = np.stack(samples, axis=1).tolist() self.eval_score = [] for trg_i, sample_i in zip(trg, samples): # Removing EOS try: idx = sample_i.index(Vocab.ES) sample_i = sample_i[:idx] except ValueError: pass try: idx = trg_i.words.index(Vocab.ES) trg_i.words = trg_i.words[:idx] except ValueError: pass # Calculate the evaluation score score = 0 if not len(sample_i) else self.evaluation_metric.evaluate_fast(trg_i.words, sample_i) self.eval_score.append(score) self.true_score = dy.inputTensor(self.eval_score, batched=True) loss = LossBuilder() if self.use_baseline: for i, (score, _) in enumerate(zip(self.bs, logsofts)): logsofts[i] = dy.cmult(logsofts[i], score - self.true_score) loss.add_loss("Reinforce", dy.sum_elems(dy.esum(logsofts))) else: loss.add_loss("Reinforce", dy.sum_elems(dy.cmult(-self.true_score, dy.esum(logsofts)))) if self.use_baseline: baseline_loss = [] for bs in self.bs: baseline_loss.append(dy.squared_distance(self.true_score, bs)) loss.add_loss("Baseline", dy.sum_elems(dy.esum(baseline_loss))) return loss
def get_span_expr(start, end): ret = span_exprs_cache.get((start, end)) if not ret: ret = span_features[start, end] if getattr(self.options, "no_backprop", False): ret = dn.nobackprop(ret) span_exprs_cache[start, end] = ret return ret
def get_nobackprop_loss(self) -> Dict[str, dy.Expression]: """ Get dictionary of named non-backpropagating loss expressions Returns: Loss expressions """ return {k: dy.nobackprop(v) for k, v in self.expr_factors.items()}
def calc_baseline_loss(self, rewards): avg_rewards = dy.average( rewards) # Taking average of the rewards accross multiple samples pred_rewards = [] loss = [] for i, state in enumerate(self.states): pred_reward = self.baseline(dy.nobackprop(state)) pred_rewards.append(dy.nobackprop(pred_reward)) if self.valid_pos is not None: pred_reward = dy.pick_batch_elems(pred_reward, self.valid_pos[i]) avg_reward = dy.pick_batch_elems(avg_rewards, self.valid_pos[i]) else: avg_reward = avg_rewards loss.append( dy.sum_batches(dy.squared_distance(pred_reward, avg_reward))) return pred_rewards, dy.esum(loss)
def calculate_baseline( self, input_states: expr_seq.ExpressionSequence ) -> expr_seq.ExpressionSequence: transform_seq = [] for input_state in input_states: transform_seq.append( self.transform.transform(dy.nobackprop(input_state))) return expr_seq.ExpressionSequence(expr_list=transform_seq, mask=input_states.mask)
def calc_reinforce_loss(words, tags, delta): dy.renew_cg() # Transduce all batch elements with an LSTM word_reps = LSTM.transduce([LOOKUP[x] for x in words]) # Softmax scores W = dy.parameter(W_sm) b = dy.parameter(b_sm) #calculate the probability distribution scores = [dy.affine_transform([b, W, x]) for x in word_reps] losses = [dy.pickneglogsoftmax(score, tag) for score, tag in zip(scores, tags)] probs = [-dy.exp(loss).as_array() for loss in losses] #then take samples from the probability distribution samples = [np.random.choice(range(len(x)), p=x) for x in probs] #calculate accuracy=reward correct = [sample == tag for sample, tag in zip(samples, tags)] r_i = float(sum(correct))/len(correct) r = dy.constant((1), r_i) # Reward baseline for each word W_bl = dy.parameter(W_bl_p) b_bl = dy.parameter(b_bl_p) r_b = [dy.affine_transform([b_bl, W_bl, dy.nobackprop(x)]) for x in word_reps] #we need to take the value in order to break the computation graph #as the reward portion is trained seperatley and not backpropogated through during the overall score rewards_over_baseline = [(r - dy.nobackprop(x)) for x in r_b] #the scores for training the baseline baseline_scores = [dy.square(r - x) for x in r_b] #then calculate the reinforce scores using reinforce reinforce_scores = [r_s*score for r_s, score in zip(rewards_over_baseline, scores)] #we want the first len(sent)-delta scores from xent then delta scores from reinforce #for mixer if len(scores) > delta: mixer_scores = scores[:len(scores)-delta] + reinforce_scores[delta-1:] else: mixer_scores = reinforce_scores return dy.esum(mixer_scores), dy.esum(baseline_scores)
def MakeInputs(self, text): words = self.get_words(text) vecs = [] wds = [] for w in words: if w in self.wv: vec = dy.inputVector(self.wv[w]) vecs.append(dy.nobackprop(vec)) wds.append(w) conv = self.Conv(vecs) return wds, vecs, conv
def on_start_sent(self, src): batch_size = len(src) col_size = len(src[0]) # Make this faster with dy.sparse_inputTensor? lexicon_prob = np.dstack([ np.vstack([self.dense_prob(src[i][j]) for j in range(col_size)]) for i in range(batch_size) ]) lexicon_prob = np.swapaxes(lexicon_prob, 0, 1) self.lexicon_prob = dy.nobackprop( dy.inputTensor(lexicon_prob, batched=True))
def add_prons(self, data): for item in data: for token in item: if not (token in self.pdict): dynet.renew_cg() spelling = [ self.s2s.src_vocab[letter] for letter in token.upper() ] embedded_spelling = self.s2s.embed_seq(spelling) pron_vector = self.s2s.encode_seq(embedded_spelling)[-1] fpv = dynet.nobackprop(pron_vector) self.pdict[token] = fpv.vec_value()
def on_start_sent(self, src): self.coeff = None self.dict_prob = None batch_size = src.batch_size() col_size = src.sent_len() idxs = [(x, j, i) for i in range(batch_size) for j in range(col_size) for x in self.lexicon[src[i][j]].keys()] idxs = tuple(map(list, list(zip(*idxs)))) values = [x for i in range(batch_size) for j in range(col_size) for x in self.lexicon[src[i][j]].values()] dim = len(self.trg_vocab), col_size, batch_size self.lexicon_prob = dy.nobackprop(dy.sparse_inputTensor(idxs, values, dim, batched=True))
def MakeInputs(self, text, train=False): words = self.get_words(text) wds = [] vecs = [] for w in words: if w in self.wv: vec = dy.inputVector(self.wv[w]) vecs.append(dy.nobackprop(vec)) wds.append(w) cont_sen = self.biRNN.transduce([self.pad[0]] + vecs + [self.pad[1]])[1:-1] cont_sen = [dy.esum([v, c]) for v, c in zip(vecs, cont_sen)] return wds, vecs, cont_sen
def one_epoch(self, update_weights=True): """ :param update_weights: Whether to perform backward pass & update weights (useful for debugging) """ self.logger.new_epoch() if self.args["reload_command"] is not None: self._augment_data_next_epoch() self.model.set_train(update_weights) order = list(range(0, len(self.train_src))) np.random.shuffle(order) for batch_num in order: src = self.train_src[batch_num] trg = self.train_trg[batch_num] # Loss calculation dy.renew_cg() loss_builder = LossBuilder() standard_loss = self.model.calc_loss(src, trg) if standard_loss.__class__ == LossBuilder: loss = None for loss_name, loss_expr in standard_loss.loss_nodes: loss_builder.add_loss(loss_name, loss_expr) loss = loss_expr if not loss else loss + loss_expr standard_loss = loss else: loss_builder.add_loss("loss", standard_loss) additional_loss = self.model.calc_additional_loss( dy.nobackprop(-standard_loss)) if additional_loss != None: loss_builder.add_loss("additional_loss", additional_loss) # Log the loss sum loss_value = loss_builder.compute() self.logger.update_epoch_loss(src, trg, loss_builder) if update_weights: loss_value.backward() self.trainer.update() # Devel reporting self.logger.report_train_process() if self.logger.should_report_dev(): self.dev_evaluation() self.model.new_epoch()
def calc_nll(self, src_batch, trg_batch) -> dy.Expression: self.actions.clear() self.outputs.clear() event_trigger.start_sent(src_batch) batch_loss = [] # For every item in the batch for src, trg in zip(src_batch, trg_batch): # Initial state with no read/write actions being taken current_state = self._initial_state(src) src_len = src.sent_len() # Reading + Writing src_encoding = [] loss_exprs = [] now_action = [] outputs = [] # Simultaneous greedy search while not self._stoping_criterions_met(current_state, trg): # Define action based on state action = self.next_action(current_state, src_len, len(src_encoding)) if action == self.Action.READ: # Reading + Encoding current_state = current_state.read(src) src_encoding.append(current_state.encoder_state.output()) else: # Predicting next word current_state = current_state.calc_context(src_encoding) current_output = self.add_input( current_state.prev_written_word, current_state) # Calculating losses ground_truth = self._select_ground_truth( current_state, trg) loss_exprs.append( self.decoder.calc_loss(current_output.state, ground_truth)) # Use word from ref/model depeding on settings next_word = self._select_next_word(ground_truth, current_output.state) # The produced words outputs.append(next_word) current_state = current_state.write(next_word) now_action.append(action.value) self.actions.append(now_action) self.outputs.append(outputs) # Accumulate loss batch_loss.append(dy.esum(loss_exprs)) dy.forward(batch_loss) loss = dy.esum(batch_loss) return loss if not self.freeze_decoder_param else dy.nobackprop(loss)
def generate(self, src_seq, sampled=False): def sample(probs): rnd = random.random() for i, p in enumerate(probs): rnd -= p if rnd <= 0: break return i dynet.renew_cg() embedded = self.embed_seq(src_seq) input_vectors = self.encode_seq(embedded) w = dynet.parameter(self.decoder_w) b = dynet.parameter(self.decoder_b) s = self.dec_lstm.initial_state() s = s.add_input( dynet.concatenate([ input_vectors[-1], dynet.vecInput(self.args.hidden_dim * 2), dynet.vecInput(self.pronouncer.args.hidden_dim * 2) ])) out = [] for i in range(1 + len(src_seq) * 5): out_vector = w * s.output() + b probs = dynet.softmax(out_vector) probs = probs.vec_value() next_symbol = sample(probs) if sampled else max( enumerate(probs), key=lambda x: x[1])[0] out.append(self.tgt_vocab[next_symbol]) if self.tgt_vocab[next_symbol] == self.tgt_vocab.END_TOK: break embed_vector = self.tgt_lookup[out[-1].i] attn_vector = self.attend(input_vectors, s) spelling = [ self.pronouncer.src_vocab[letter] for letter in out[-1].s.upper() ] embedded_spelling = self.pronouncer.embed_seq(spelling) pron_vector = self.pronouncer.encode_seq(embedded_spelling)[-1] fpv = dynet.nobackprop(pron_vector) inp = dynet.concatenate([embed_vector, attn_vector, fpv]) s = s.add_input(inp) return out
def get_base_embeddings(trainmode, unkdtokens, tg_start, sentence): sentlen = len(unkdtokens) if trainmode: emb_x = [dy.noise(v_x[tok], 0.1) for tok in unkdtokens] else: emb_x = [v_x[tok] for tok in unkdtokens] pos_x = [p_x[pos] for pos in sentence.postags] dist_x = [dy.scalarInput(i - tg_start + 1) for i in range(sentlen)] baseinp_x = [(w_i * dy.concatenate([emb_x[j], pos_x[j], dist_x[j]]) + b_i) for j in range(sentlen)] if USE_WV: for j in range(sentlen): if unkdtokens[j] in wvs: nonupdatedwv = dy.nobackprop(e_x[unkdtokens[j]]) baseinp_x[j] = baseinp_x[j] + w_e * nonupdatedwv + b_e embposdist_x = [dy.rectify(baseinp_x[j]) for j in range(sentlen)] if USE_DROPOUT: basefwdlstm.set_dropout(DROPOUT_RATE) baserevlstm.set_dropout(DROPOUT_RATE) bfinit = basefwdlstm.initial_state() basefwd = bfinit.transduce(embposdist_x) brinit = baserevlstm.initial_state() baserev = brinit.transduce(reversed(embposdist_x)) basebi_x = [ dy.rectify( w_bi * dy.concatenate([basefwd[eidx], baserev[sentlen - eidx - 1]]) + b_bi) for eidx in range(sentlen) ] if USE_DEPS: dhead_x = [embposdist_x[dephead] for dephead in sentence.depheads] dheadp_x = [pos_x[dephead] for dephead in sentence.depheads] drel_x = [dr_x[deprel] for deprel in sentence.deprels] baseinp_x = [ dy.rectify(w_di * dy.concatenate( [dhead_x[j], dheadp_x[j], drel_x[j], basebi_x[j]]) + b_di) for j in range(sentlen) ] basebi_x = baseinp_x return basebi_x
def on_start_sent(self, src): batch_size = len(src) col_size = len(src[0]) idxs = [(x, j, i) for i in range(batch_size) for j in range(col_size) for x in self.lexicon[src[i][j]].keys()] idxs = tuple(map(list, list(zip(*idxs)))) values = [ x for i in range(batch_size) for j in range(col_size) for x in self.lexicon[src[i][j]].values() ] self.lexicon_prob = dy.nobackprop( dy.sparse_inputTensor(idxs, values, (len(self.trg_vocab), col_size, batch_size), batched=True))
def __init__(self, model, dim, input_dim, W, minibatch_size, dropout, device, nobackprop=False, init_h_t=None, init_c_t=None): self.model = model self.dim = dim self.input_dim = input_dim self.W = dynet.parameter(W) self.nobackprop = nobackprop if nobackprop: self.W = dynet.nobackprop(self.W) self.W_param = W self.minibatch_size = minibatch_size self.dropout = dropout self.device = device self.next_layer = None if init_h_t is None: self.h_t = dynet.inputVector([0] * self.dim, device=self.device) else: self.h_t = init_h_t if init_c_t is None: self.c_t = dynet.inputVector([0] * dim, device=self.device) else: self.c_t = init_c_t self.bias = dynet.inputVector([1], device=self.device) if self.dropout is not None: mask = (1. / (1. - self.dropout)) * (numpy.random.uniform( size=[self.input_dim, self.minibatch_size]) > self.dropout) self.dropout_mask_x = dynet.inputTensor(mask, batched=True, device=self.device) mask = (1. / (1. - self.dropout)) * (numpy.random.uniform( size=[self.dim, self.minibatch_size]) > self.dropout) self.dropout_mask_h = dynet.inputTensor(mask, batched=True, device=self.device)
def _perform_calc_loss( self, model: 'model_base.ConditionedModel', src: Union[sent.Sentence, 'batchers.Batch'], trg: Union[sent.Sentence, 'batchers.Batch']) -> losses.FactoredLossExpr: search_outputs = model.generate_search_output(src, self.search_strategy) sign = -1 if self.inv_eval else 1 # TODO: Fix units total_loss = collections.defaultdict(int) for search_output in search_outputs: # Calculate rewards eval_score = [] for trg_i, sample_i in zip(trg, search_output.word_ids): # Removing EOS sample_i = utils.remove_eos(sample_i.tolist(), vocabs.Vocab.ES) ref_i = trg_i.words[:trg_i.len_unpadded()] score = self.evaluation_metric.evaluate_one_sent( ref_i, sample_i) eval_score.append(sign * score) reward = dy.inputTensor(eval_score, batched=True) # Composing losses baseline_loss = [] cur_losses = [] for state, mask in zip(search_output.state, search_output.mask): bs_score = self.baseline.transform( dy.nobackprop(state.as_vector())) baseline_loss.append(dy.squared_distance(reward, bs_score)) logsoft = model.decoder.scorer.calc_log_probs( state.as_vector()) loss_i = dy.cmult(logsoft, reward - bs_score) cur_losses.append( dy.cmult(loss_i, dy.inputTensor(mask, batched=True))) total_loss["polc_loss"] += dy.sum_elems(dy.esum(cur_losses)) total_loss["base_loss"] += dy.sum_elems(dy.esum(baseline_loss)) units = [t.len_unpadded() for t in trg] total_loss = losses.FactoredLossExpr( {k: losses.LossExpr(v, units) for k, v in total_loss.items()}) return losses.FactoredLossExpr({"risk": total_loss})
def init(self, H, y, usr, test=True, update=True): bs = len(y[0]) if not test: self.lstm.set_dropout(self.dr) else: self.lstm.disable_dropout() # Initialize first state of the decoder with the last state of the encoder self.Wp = self.Wp_p.expr(update) self.bp = self.bp_p.expr(update) self.Wu = self.Wu_p.expr(update) last_enc = dy.pick(H, index=H.dim()[0][-1] - 1, dim=1) init_state = dy.affine_transform([self.bp, self.Wp, last_enc, self.Wu, dy.nobackprop(usr)]) init_state = [init_state, dy.zeroes((self.dh,), batch_size=bs)] self.ds = self.lstm.initial_state(init_state, update=update) # Initialize dropout masks if not test: self.lstm.set_dropout_masks(bs) self.Wo = self.Wo_p.expr(update) self.bo = self.bo_p.expr(update) self.E = self.E_p.expr(update) self.b = self.b_p.expr(update)