Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
  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
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
  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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
  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
Ejemplo n.º 14
0
 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
Ejemplo n.º 15
0
    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()}
Ejemplo n.º 16
0
 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)
Ejemplo n.º 17
0
 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)
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
 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
Ejemplo n.º 20
0
 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))
Ejemplo n.º 21
0
 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()
Ejemplo n.º 22
0
 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))
Ejemplo n.º 23
0
 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
Ejemplo n.º 24
0
    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()
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
    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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
    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))
Ejemplo n.º 29
0
    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)
Ejemplo n.º 30
0
    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})
Ejemplo n.º 31
0
    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)