Exemplo n.º 1
0
        def matching_to_labeled_hypothesis(self, hypothesis, matching):
            """ Helper function for constructing the GT for a given input. """
            # matching is a list of (gt_idx, iou_list, bbox_list, label_list)
            labeled_hypothesis = Hypothesis(tracklet=hypothesis.tracklet)

            if len(matching) == 0:
                labeled_hypothesis.labels =\
                    np.zeros((self.scene_size,), dtype=np.float32)
                labeled_hypothesis.bboxes = \
                    np.zeros((self.scene_size, 4), dtype=np.float32)
                labeled_hypothesis.ious = \
                    np.zeros((self.scene_size,), dtype=np.float32)
                labeled_hypothesis.gt_idx = -1
                return labeled_hypothesis

            idfs = [sum(m[1]) for m in matching]

            best_match = np.argmax(np.asarray(idfs))
            gt_idx = matching[best_match][0]

            labeled_hypothesis.ious = matching[best_match][1]
            labeled_hypothesis.bboxes = matching[best_match][2]
            labeled_hypothesis.labels = matching[best_match][3]
            labeled_hypothesis.gt_idx = gt_idx

            return labeled_hypothesis
Exemplo n.º 2
0
def convert_hypothesis(pred_sent, vocab, score):
    tgt_sent = []
    for word_id in pred_sent[1:-1]:
        tgt_sent.append(vocab.tgt.id2word[word_id.item()])
    if decoder_config.greedy_search:
        score = (score - np.log(len(pred_sent)))
    return Hypothesis(tgt_sent, score)
Exemplo n.º 3
0
    def beam_search(self,
                    src_sent,
                    key,
                    max_step=None,
                    replace=False) -> List[Hypothesis]:
        src_sent, key
        np_sent = np.array([self.vocab_src[key][word] for word in src_sent])
        # if config.flip_source:
        #    np_sent = np.flip(np_sent, axis=0).copy()
        tensor_sent = torch.LongTensor(np_sent)
        if self.gpu:
            tensor_sent = tensor_sent.cuda()
        src_encoding, decoder_init_state = self.encoder[key].encode_one_sent(
            tensor_sent)
        if config.greedy_search:
            tgt_tensor, score = self.decoder.greedy_search(src_encoding,
                                                           decoder_init_state,
                                                           max_step,
                                                           replace=replace)
            tgt_np = tgt_tensor.cpu().detach().numpy()
            tgt_sent = []
            for i in tgt_np[1:-1]:
                if i >= 0:
                    tgt_sent.append(self.vocab_tgt.id2word[i])
                else:
                    tgt_sent.append(src_sent[-i])
            hypotheses = [Hypothesis(tgt_sent, score)]

        else:
            l = self.decoder.beam_search(src_encoding,
                                         decoder_init_state,
                                         max_step,
                                         replace=replace)
            hypotheses = []
            for tgt_tensor, score in l:
                tgt_np = tgt_tensor.cpu().detach().numpy()
                tgt_sent = []
                for i in tgt_np[1:-1]:
                    if i > 0:
                        tgt_sent.append(self.vocab_tgt.id2word[i])
                    else:
                        tgt_sent.append(src_sent[-i])
                hypotheses.append(Hypothesis(tgt_sent, score))
        return hypotheses
Exemplo n.º 4
0
    def beam_search(self,
                    src_sent: List[str],
                    max_step=None,
                    replace=False,
                    **kwargs) -> List[Hypothesis]:
        np_sent = np.array([self.vocab.src[word] for word in src_sent])
        tensor_sent = torch.LongTensor(np_sent)
        if self.gpu:
            tensor_sent = tensor_sent.cuda()
        src_encoding, decoder_init_state = self.encoder.encode_one_sent(
            tensor_sent)
        #print(src_sent, np_sent, src_encoding.size())
        if dconfig.greedy_search:
            tgt_tensor, score = self.decoder.greedy_search(src_encoding,
                                                           decoder_init_state,
                                                           max_step,
                                                           replace=replace)
            tgt_np = tgt_tensor.cpu().detach().numpy()
            tgt_sent = []
            for i in tgt_np[1:-1]:
                if i >= 0:
                    tgt_sent.append(self.vocab.tgt.id2word[i])
                else:
                    tgt_sent.append(src_sent[-i])
            hypotheses = [Hypothesis(tgt_sent, score)]

        else:
            l = self.decoder.beam_search(src_encoding,
                                         decoder_init_state,
                                         max_step,
                                         replace=replace)
            hypotheses = []
            for tgt_tensor, score in l:
                tgt_np = tgt_tensor.cpu().detach().numpy()
                tgt_sent = []
                for i in tgt_np[1:-1]:
                    if i > 0:
                        tgt_sent.append(self.vocab.tgt.id2word[i])
                    else:
                        tgt_sent.append(src_sent[-i])
                hypotheses.append(Hypothesis(tgt_sent, score))
        return hypotheses
Exemplo n.º 5
0
    def create_pairwise_hypotheses(self, detections, scene_start, scene_end):
        # This simply creates pairwise hypotheses for all pairs
        # of detections that are at most dt apart, and between
        # which we can interpolate so that IoU of hypotheses
        # is > 0. This is obviously an overcomplete set.
        self.logger.info("Creating pairwise hypotheses...")

        pairwise_hypothesis = []
        if len(detections) == 0:
            return pairwise_hypothesis

        detections = sorted(detections, key=lambda detection: detection.time)
        detections_by_time = [[detections[0]]]
        for detection in detections[1:]:
            if detection.time == detections_by_time[-1][0].time:
                detections_by_time[-1].append(detection)
            else:
                detections_by_time.append([detection])

        for idx_now, detections_now in enumerate(detections_by_time):
            for detections_nxt in detections_by_time[idx_now + 1:]:
                if len(detections_now) == 0 or len(detections_nxt) == 0:
                    continue
                if detections_nxt[0].time - detections_now[0].time >\
                        self.pairwise_max_dt:
                    break
                for detection_now in detections_now:
                    for detection_nxt in detections_nxt:

                        tracklet = interpolate_tracklet(
                            detection_now, detection_nxt)

                        bboxes = np.vstack(
                            [detection.bbox for detection in tracklet])

                        ious = IoU(bboxes[:-1], bboxes[1:])
                        if np.min(ious) >= self.pairwise_min_iou:
                            tracklet_fin = [
                                None for when in range(scene_start, scene_end)
                            ]
                            for did, det in enumerate(tracklet):
                                tracklet_fin[det.time - scene_start] = det
                                if did > 0 and did < len(tracklet) - 1:
                                    det.confidence = \
                                        LabelStorage.instance.min_det_confidence
                            pairwise_hypothesis.append(
                                Hypothesis(tracklet=tracklet_fin))

        self.logger.info("Done: total %d", len(pairwise_hypothesis))
        return pairwise_hypothesis
Exemplo n.º 6
0
    def create_merged_hypotheses(self, hypotheses, active_pairwise, track_len):
        # Merge hypotheses of current length with all possible pairwise hypotheses
        # to create candidates of hypotheses of longer lengths.
        # To do that, we consider hypotheses A----B, and pairwise hypotheses B--C,
        # to create A---B--C.
        self.logger.info("Creating merged hypotheses")
        out = []

        heads = [{} for _ in range(track_len)]

        for cur_len in range(1, track_len):
            for h in hypotheses[cur_len]:
                ptr = -1
                while h.tracklet[ptr] is None:
                    ptr -= 1
                detection = h.tracklet[ptr]

                if detection not in heads[cur_len].keys():
                    heads[cur_len][detection] = []
                heads[cur_len][detection].append(h)

        for h in active_pairwise:
            ptr = 0
            while h.tracklet[ptr] is None:
                ptr += 1
            detection = h.tracklet[ptr]
            tail_ptr = len(h.tracklet) - 1
            while h.tracklet[tail_ptr] is None:
                tail_ptr -= 1
            need_len = track_len - (tail_ptr - ptr + 1) + 1
            if detection in heads[need_len].keys():
                for head in heads[need_len][detection]:
                    new_tracklet = [det for det in head.tracklet]
                    for did, d in enumerate(h.tracklet):
                        if d is not None:
                            try:
                                new_tracklet[did] = d
                            except:
                                print("Here")
                    out.append(Hypothesis(new_tracklet))

        self.logger.info("Done: total %d", len(out))
        return out
    def do(self, hypotheses, previous_batch=[]):
        self.logger.info("Doing action")

        good_h = []
        for h in hypotheses:
            new_tracklet = [d for d in h.tracklet if d is not None]
            int_tracklet = [new_tracklet[0]]
            for d in new_tracklet[1:]:
                int_tracklet += interpolate_tracklet(int_tracklet[-1], d)[1:]
            good_h.append(Hypothesis(int_tracklet, h.score))
            good_h[-1].outputs = deepcopy(h.outputs)

        if len(good_h) == 0:
            return [], []

        tracks = []
        hypos = []
        goodhs = []

        scores = np.asarray([hypothesis.score for hypothesis in good_h])
        prev_ctr = 0
        while True:
            # First find the best match to anything in the previous batch
            # as these are the ones that must be there.
            if prev_ctr < len(previous_batch):
                new_scores = []
                for hid, h in enumerate(good_h):
                    matched = True
                    for did, det in enumerate(h.tracklet):
                        if did >= len(previous_batch[prev_ctr]):
                            break
                        if det is None:
                            matched = False
                            break
                        if det != previous_batch[prev_ctr][did]:
                            matched = False
                    if matched:
                        val = h.score
                        for track, hypo in zip(tracks, hypos):
                            if hypotheses_IoU(hypo, hypotheses[hid]) >=\
                                    self.iou_cutoff:
                                val = -1e9
                        new_scores.append(val)
                    else:
                        new_scores.append(-2e9)

                best_idx = np.argmax(new_scores)
                self.logger.debug("Matching previous batch with track %d"
                                 " with score %0.3f",
                                 best_idx, new_scores[best_idx])
                prev_ctr += 1
            else:
                # Otherwise simply pick the one with the best score
                best_idx = np.argmax(scores)
                if scores[best_idx] <= self.score_cutoff:
                    break
                self.logger.info("Selecting track %d with score %0.3f",
                                 best_idx, scores[best_idx])

            tracks.append(good_h[best_idx].tracklet)

            # Now put score of anything which overlaps with the selected
            # track to -infty
            hypos.append(hypotheses[best_idx])
            goodhs.append(good_h[best_idx])

            for hid, hypothesis in enumerate(hypotheses):
                if hid == best_idx or\
                                hypotheses_IoU(hypos[-1], hypothesis) >=\
                                self.iou_cutoff:
                    scores[hid] = -1e9
        return tracks, hypos
Exemplo n.º 8
0
    def beam_search(self,
                    input_tensor,
                    input_lengths=None,
                    ext_vocab_size=None,
                    beam_size=4,
                    *,
                    min_out_len=1,
                    max_out_len=None,
                    len_in_words=True) -> List[Hypothesis]:
        """
    :param input_tensor: tensor of word indices, (src seq len, batch size); for now, batch size has
                         to be 1
    :param input_lengths: see explanation in `EncoderRNN`
    :param ext_vocab_size: see explanation in `DecoderRNN`
    :param beam_size: the beam size
    :param min_out_len: required minimum output length
    :param max_out_len: required maximum output length (if None, use the model's own value)
    :param len_in_words: if True, count output length in words instead of tokens (i.e. do not count
                         punctuations)
    :return: list of the best decoded sequences, in descending order of probability

    Use beam search to generate summaries.
    """
        batch_size = input_tensor.size(1)
        assert batch_size == 1
        if max_out_len is None:
            max_out_len = self.max_dec_steps - 1  # max_out_len doesn't count EOS

        # encode
        encoder_hidden = self.encoder.init_hidden(batch_size)
        # encoder_embedded: (input len, batch size, embed size)
        encoder_embedded = self.embedding(
            self.filter_oov(input_tensor, ext_vocab_size))
        encoder_outputs, encoder_hidden = \
          self.encoder(encoder_embedded, encoder_hidden, input_lengths)
        if self.enc_dec_adapter is None:
            decoder_hidden = encoder_hidden
        else:
            decoder_hidden = self.enc_dec_adapter(encoder_hidden)
        # turn batch size from 1 to beam size (by repeating)
        # if we want dynamic batch size, the following must be created for all possible batch sizes
        encoder_outputs = encoder_outputs.expand(-1, beam_size,
                                                 -1).contiguous()
        input_tensor = input_tensor.expand(-1, beam_size).contiguous()

        # decode
        hypos = [Hypothesis([self.vocab.SOS], [], decoder_hidden, [], [], 1)]
        complete_results = []
        step = 0
        while hypos and step < 2 * max_out_len:  # prevent infinitely generating punctuations
            # make batch size equal to beam size (n_hypos <= beam size)
            n_hypos = len(hypos)
            if n_hypos < beam_size:
                hypos.extend(hypos[-1] for _ in range(beam_size - n_hypos))
            # assemble existing hypotheses into a batch
            decoder_input = torch.tensor([h.tokens[-1] for h in hypos],
                                         device=DEVICE)
            decoder_hidden = torch.cat([h.dec_hidden for h in hypos], 1)
            if self.dec_attn:  # dim 0 is decoding step, dim 1 is beam batch
                decoder_states = torch.cat(
                    [torch.cat(h.dec_states, 0) for h in hypos], 1)
            else:
                decoder_states = None
            if self.enc_attn_cover:
                enc_attn_weights = [
                    torch.cat([h.enc_attn_weights[i] for h in hypos], 1)
                    for i in range(step)
                ]
            else:
                enc_attn_weights = []
            if enc_attn_weights:
                coverage_vector = self.get_coverage_vector(
                    enc_attn_weights)  # shape: (beam size, src len)
            else:
                coverage_vector = None
            # run the decoder over the assembled batch
            decoder_embedded = self.embedding(
                self.filter_oov(decoder_input, ext_vocab_size))
            decoder_output, decoder_hidden, dec_enc_attn, dec_prob_ptr = \
              self.decoder(decoder_embedded, decoder_hidden, encoder_outputs,
                           decoder_states, coverage_vector,
                           encoder_word_idx=input_tensor, ext_vocab_size=ext_vocab_size)
            top_v, top_i = decoder_output.data.topk(
                beam_size)  # shape of both: (beam size, beam size)
            # create new hypotheses
            new_hypos = []
            for in_idx in range(n_hypos):
                for out_idx in range(beam_size):
                    new_tok = top_i[in_idx][out_idx].item()
                    new_prob = top_v[in_idx][out_idx].item()
                    if len_in_words:
                        if new_tok < 3:
                            non_word = True
                        elif new_tok < self.vocab_size:
                            token_str = self.vocab[new_tok]
                            non_word = word_detector.search(
                                token_str) is None or token_str == '<P>'
                        else:  # OOV is assumed to be word-only, not punctuation
                            non_word = False
                    else:
                        non_word = new_tok == self.vocab.EOS  # only SOS & EOS don't count
                    new_hypo = hypos[in_idx].create_next(
                        new_tok, new_prob,
                        decoder_hidden[0][in_idx].unsqueeze(0).unsqueeze(0),
                        self.dec_attn,
                        dec_enc_attn[in_idx].unsqueeze(0).unsqueeze(0)
                        if dec_enc_attn is not None else None, non_word)
                    new_hypos.append(new_hypo)
            # process the new hypotheses
            new_hypos = sorted(new_hypos, key=lambda h: -h.avg_log_prob)
            hypos = []
            new_complete_results = []
            for nh in new_hypos:
                if nh.tokens[-1] == self.vocab.EOS:  # a complete hypothesis
                    if len(new_complete_results
                           ) < beam_size and min_out_len <= len(
                               nh) <= max_out_len:
                        new_complete_results.append(nh)
                elif len(hypos) < beam_size and len(
                        nh) <= max_out_len:  # an incomplete hypothesis
                    hypos.append(nh)
                if len(hypos) >= beam_size and len(
                        new_complete_results) >= beam_size:
                    break  # neither of the lists accept new items
            complete_results.extend(new_complete_results)
            step += 1
        if complete_results:
            return sorted(complete_results,
                          key=lambda h: -h.avg_log_prob)[:beam_size]
        else:
            return hypos
Exemplo n.º 9
0
    def beam_search(self,
                    input_tensor,
                    input_lengths=None,
                    ext_vocab_size=None,
                    beam_size=4,
                    *,
                    min_out_len=1,
                    max_out_len=None,
                    len_in_words=True,
                    mask=None) -> List[Hypothesis]:
        """
        :param input_tensor: tensor of word indices, (src seq len, batch size); for now, batch size has
                             to be 1
        :param input_lengths: see explanation in `EncoderRNN`
        :param ext_vocab_size: see explanation in `DecoderRNN`
        :param beam_size: the beam size
        :param min_out_len: required minimum output length
        :param max_out_len: required maximum output length (if None, use the model's own value)
        :param len_in_words: if True, count output length in words instead of tokens (i.e. do not count
                             punctuations)
        :return: list of the best decoded sequences, in descending order of probability

        Use beam search to generate summaries.
        """
        batch_size = input_tensor.size(1)  # 1
        assert batch_size == 1
        if max_out_len is None:
            max_out_len = self.max_dec_steps - 1  # max_out_len doesn't count EOS

        # encode
        encoder_hidden = self.encoder.init_hidden(batch_size)
        # encoder_embedded: (input len, batch size, embed size)
        encoder_embedded = self.embedding(
            self.filter_oov(input_tensor, ext_vocab_size))
        # output: [input_length, 1, hidden]
        # hidden: [1, 1, hidden]
        encoder_outputs, encoder_hidden = \
            self.encoder(encoder_embedded, encoder_hidden, input_lengths)
        if self.enc_dec_adapter is None:
            decoder_hidden = encoder_hidden
        else:
            decoder_hidden = self.enc_dec_adapter(encoder_hidden)

        # turn batch size from 1 to beam size (by repeating)
        # if we want dynamic batch size, the following must be created for all possible batch sizes
        # encoder_outputs:[src_len, beam_size, hidden_size] 相当于复制了四套encoder的状态
        encoder_outputs = encoder_outputs.expand(-1, beam_size,
                                                 -1).contiguous()
        # input_tensor:[src_len, beam_size] 将输入tensor复制四份
        input_tensor = input_tensor.expand(-1, beam_size).contiguous()

        # decode
        # 一个Hypothesis是一个预测,最后返回beam size大小的Hypothesis列表
        # 初始化一个hypos,其中tokens以SOS开始,表示句子开始,
        hypos = [Hypothesis([self.vocab.SOS], [], decoder_hidden, [], [], 1)]
        results, backup_results = [], []
        step = 0
        while hypos and step < 2 * max_out_len:  # prevent infinitely generating punctuations(标点)
            # make batch size equal to beam size (n_hypos <= beam size)
            n_hypos = len(hypos)  # 最开始是1
            if n_hypos < beam_size:
                # 最后结果是一个长度为beam size的列表list,应该只会在第一次循环执行这个,相当于初始化
                hypos.extend(hypos[-1] for _ in range(beam_size - n_hypos))
            # assemble existing hypotheses into a batch [1, beam_size]
            # 取每一个hypo最后一个词
            decoder_input = torch.tensor([h.tokens[-1] for h in hypos],
                                         device=DEVICE)
            # decoder_hidden:[1, beam_size, hidden_size]
            decoder_hidden = torch.cat([h.dec_hidden for h in hypos], 1)
            if self.dec_attn and step > 0:  # dim 0 is decoding step, dim 1 is beam batch
                decoder_states = torch.cat(
                    [torch.cat(h.dec_states, 0) for h in hypos], 1)
            else:
                decoder_states = None
            if self.enc_attn_cover:
                # 获得encoder attention
                enc_attn_weights = [
                    torch.cat([h.enc_attn_weights[i] for h in hypos], 1)
                    for i in range(step)
                ]
            else:
                enc_attn_weights = []
            if enc_attn_weights:
                coverage_vector = self.get_coverage_vector(
                    enc_attn_weights)  # shape: (beam size, src len)
            else:
                coverage_vector = None
            # run the decoder over the assembled batch
            decoder_embedded = self.embedding(
                self.filter_oov(decoder_input, ext_vocab_size))
            decoder_output, decoder_hidden, dec_enc_attn, dec_prob_ptr = \
                self.decoder(decoder_embedded, decoder_hidden, encoder_outputs,
                             decoder_states, coverage_vector,
                             encoder_word_idx=input_tensor, ext_vocab_size=ext_vocab_size, mask=mask)
            # (beam size, beam size) 相当于是 (batch_size, beam size)
            # top_v : value
            # top_i : index
            top_v, top_i = decoder_output.data.topk(
                beam_size)  # shape of both: (beam size, beam size)
            # create new hypotheses
            new_hypos = []
            for in_idx in range(n_hypos):
                for out_idx in range(beam_size):
                    new_tok = top_i[in_idx][out_idx].item()
                    new_prob = top_v[in_idx][out_idx].item()
                    if len_in_words:
                        non_word = not self.vocab.is_word(new_tok)
                    else:
                        non_word = new_tok == self.vocab.EOS  # only SOS & EOS don't count
                    new_hypo = hypos[in_idx].create_next(
                        new_tok, new_prob,
                        decoder_hidden[0][in_idx].unsqueeze(0).unsqueeze(0),
                        self.dec_attn,
                        dec_enc_attn[in_idx].unsqueeze(0).unsqueeze(0)
                        if dec_enc_attn is not None else None, non_word)
                    new_hypos.append(new_hypo)

            # process the new hypotheses
            # 降序排序
            new_hypos = sorted(new_hypos, key=lambda h: -h.avg_log_prob)
            hypos = []
            new_complete_results, new_incomplete_results = [], []
            for nh in new_hypos:
                length = len(nh)
                if nh.tokens[-1] == self.vocab.EOS:  # a complete hypothesis
                    if len(
                            new_complete_results
                    ) < beam_size and min_out_len <= length <= max_out_len:
                        new_complete_results.append(nh)
                elif len(
                        hypos
                ) < beam_size and length < max_out_len:  # an incomplete hypothesis
                    hypos.append(nh)
                elif length == max_out_len and len(
                        new_incomplete_results) < beam_size:
                    new_incomplete_results.append(nh)
            if new_complete_results:
                results.extend(new_complete_results)
            elif new_incomplete_results:
                backup_results.extend(new_incomplete_results)
            step += 1

        if not results:  # if no sequence ends with EOS within desired length, fallback to sequences
            results = backup_results  # that are "truncated" at the end to max_out_len
        return sorted(results, key=lambda h: -h.avg_log_prob)[:beam_size]
Exemplo n.º 10
0
    def do(self,
           detections,
           model,
           previous_batch,
           scene_start,
           scene_end,
           temp=1e-6):
        self.logger.info("Doing action")

        _detections = [det for det in detections]

        # Hypotheses containing only one detection
        unitary = []
        for d in _detections:
            tracklet = [None for _ in range(scene_start, scene_end)]
            tracklet[d.time - scene_start] = d
            h = Hypothesis(tracklet=tracklet)
            unitary.append(h)
        model.score(unitary)

        # During inference we can try to ignore hypothesis with very low scores
        # to speed up the process.
        if self.nms_option.endswith("ignore"):
            ignore_cutoff = float(self.nms_option.split('-')[-2])
        else:
            ignore_cutoff = -1e9

        # That includes ignoring very low quality detections.

        detections = []
        for did in range(len(unitary)):
            if unitary[did].score * (scene_end - scene_start) < ignore_cutoff:
                pass
            else:
                detections.append(_detections[did])

        # Creating pairwise hypotheses by interpolating between pairs of detections.

        pairwise_hypotheses = self.create_pairwise_hypotheses(
            detections, scene_start, scene_end)

        # Populating hypotheses array.
        # Hypotheses[1] = unitary detections
        # Hypotheses[l] = pairwise hypotheses between detections l-1 frames apart

        if len(detections) > 0:
            t_min = min([detection.time for detection in detections])
            t_max = max([detection.time for detection in detections])
            max_track_len = t_max - t_min + 1
        else:
            max_track_len = scene_end - scene_start + 1
        hypotheses = [[] for _ in range(max_track_len + 1)]

        for detection in detections:
            tracklet = [None for when in range(scene_start, scene_end)]
            tracklet[detection.time - scene_start] = detection
            hypotheses[1].append(Hypothesis(tracklet))

        for hypothesis in pairwise_hypotheses:
            h_start = min(
                [det.time for det in hypothesis.tracklet if det is not None])
            h_end = max(
                [det.time for det in hypothesis.tracklet if det is not None])
            hypotheses[h_end - h_start + 1].append(hypothesis)

        active_pairwise = []

        all_hypos = []

        for track_len in range(1, len(hypotheses)):
            self.logger.info("Working with track_len %d", track_len)

            # Compute scores for all hypotheses of the current length

            model.score(hypotheses[track_len])
            all_hypos += hypotheses[track_len]
            # Run NMS - having at most 1 hypothesis of every length
            # with every starting point.
            hypotheses[track_len] = self.nms(hypotheses[track_len],
                                             scene_start, scene_end, temp)

            # After NMS, let's add the forced hypotheses from the prev batch:
            # This is required to make sure that we can at least somehow link
            # our current hypotheses to the ones in the previous batch.
            push_force = []
            for tracklet in previous_batch:
                if len(tracklet) == track_len:
                    full_tracklet = [
                        None for when in range(scene_start, scene_end)
                    ]
                    for detection in tracklet:
                        full_tracklet[detection.time - scene_start] = detection
                    push_force.append(Hypothesis(full_tracklet))
            model.score(push_force)
            hypotheses[track_len] += push_force

            # Consider pairwise hypotheses which we will use to grow further.
            # In particular, if we have two pairwise hypotheses A---B and B---C,
            # they could be used to grow into A---B---C.
            for hypothesis in hypotheses[track_len]:
                sum_non_intp = 0
                for detection in hypothesis.tracklet:
                    if detection is None: continue
                    if not hasattr(detection, "interpolated"):
                        sum_non_intp += 1
                    elif not detection.interpolated:
                        sum_non_intp += 1
                if sum_non_intp == 2:
                    active_pairwise.append(hypothesis)

            # Create additional candidates for longer hypotheses. We will NMS then
            # when we process the hypotheses of that length in this loop.

            if track_len < max_track_len:
                merged = self.create_merged_hypotheses(hypotheses,
                                                       active_pairwise,
                                                       track_len + 1)
                for hypothesis in merged:
                    hypotheses[track_len + 1].append(hypothesis)

        return [
            hypothesis for track_len in range(1, max_track_len + 1)
            for hypothesis in hypotheses[track_len]
        ], all_hypos
    def generate_beam(self, src1, src2):
        src1_mat, src2_mat, src1_w1dt, src2_w1dt, decoder_state = self.encoder_forward(
            src1, src2
        )

        hypothesis_list = [
            Hypothesis(
                text_list=[self.tgt_vocab.str2int(EOS)],
                decoder_state=decoder_state,
                c1_t=dy.vecInput(2 * HIDDEN_DIM),
                c2_t=dy.vecInput(2 * HIDDEN_DIM),
                prev_coverage=self.get_coverage(
                    a_t=dy.vecInput(len(src1)),
                    training=False,
                    prev_coverage=dy.vecInput(len(src1)),
                ),
                score=0.0,
                p_gens=[],
            )
        ]
        completed_list = []

        for t in range(int(len(src1) * 1.1)):
            new_hyp_list = []
            new_hyp_scores = []
            for hyp in hypothesis_list:
                last_output_embeddings = self.tgt_lookup[hyp.text_list[-1]]

                a_t, c1_t = self.attend(
                    src1_mat,
                    hyp.decoder_state,
                    src1_w1dt,
                    self.att1_w2,
                    self.att1_v,
                    hyp.prev_coverage,
                )
                if not self.single_source:
                    _, c2_t = self.attend(
                        src2_mat,
                        hyp.decoder_state,
                        src2_w1dt,
                        self.att2_w2,
                        self.att2_v,
                        None,
                    )
                else:
                    c2_t = dy.vecInput(2 * HIDDEN_DIM)

                x_t = dy.concatenate([c1_t, c2_t, last_output_embeddings])
                decoder_state = hyp.decoder_state.add_input(x_t)

                probs = dy.softmax(self.dec_w * decoder_state.output() + self.dec_b)
                probs, cur_p_gen = self.get_pointergen_probs(
                    c1_t, decoder_state, x_t, a_t, probs, src1
                )
                probs = probs.npvalue()

                for ind in range(len(probs)):
                    text_list = hyp.text_list + [ind]
                    p_gens = hyp.p_gens + [cur_p_gen]
                    score = (hyp.score + math.log(probs[ind])) / (len(text_list) ** 0.0)
                    coverage = self.get_coverage(a_t, hyp.prev_coverage, training=False)
                    new_hyp_list.append(
                        Hypothesis(
                            text_list=text_list,
                            decoder_state=decoder_state,
                            c1_t=c1_t,
                            c2_t=c2_t,
                            prev_coverage=coverage,
                            score=score,
                            p_gens=p_gens,
                        )
                    )
                    new_hyp_scores.append(score)

            top_inds = np.argpartition(np.array(new_hyp_scores), -self.beam_size)[
                -self.beam_size :
            ]
            new_hyp_list = np.array(new_hyp_list)[top_inds]

            hypothesis_list = []

            for new_hyp in new_hyp_list:
                if new_hyp.text_list[-1] == self.tgt_vocab.str2int(EOS) and t > 0:
                    completed_list.append(new_hyp)
                else:
                    hypothesis_list.append(new_hyp)

            if len(completed_list) >= self.beam_size:
                break

        if len(completed_list) == 0:
            sorted(hypothesis_list, key=lambda x: x.score, reverse=True)
            completed_list = [hypothesis_list[0]]

        for hyp in completed_list:
            hyp.text_list = [self.tgt_vocab.int2str(i) for i in hyp.text_list]

        top_hyp = sorted(completed_list, key=lambda x: x.score, reverse=True)[0]
        return "".join(top_hyp.text_list).replace(EOS, "").strip(), top_hyp.p_gens[1:-1]