def beam_search(self, seqs, lens, B, L, vocab):
        n_best = 1
        K = constant.beam_size
        beam = [Beam(K, 
                     n_best=n_best,
                     global_scorer=GNMTGlobalScorer(),)
                     # min_length=self.min_length,                                               
                     # stepwise_penalty=self.stepwise_penalty,                                                       
                     # block_ngram_repeat=self.block_ngram_repeat,                                                            
                     # exclusion_tokens=exclusion_tokens)                                         
                for _ in range(B)]

        # (1) Run the encoder on the src.
        src_h, dec_h_t = self.encode(seqs, lens)

        # (2) Repeat src objects `beam_size` times.
        # Tile states and inputs K times
        dec_h_t = tile(dec_h_t, K, dim=1)
        
        if self.use_attn:
            src_h = tile(src_h.contiguous(), K, dim=0)
        
        # We use now  batch_size x beam_size (same as fast mode)

        # (3) run the decoder to generate sentences, using beam search.
        for t in range(L):
            if all((b.done() for b in beam)):
                break

            # (a) Construct batch x beam_size nxt words.
            # Get all the pending current beam words and arrange for forward.
            x_t = torch.stack([b.get_current_state() for b in beam])#.t().contiguous()
            x_t = x_t.view(-1)

            # (b) Decode and forward
            y_t, dec_h_t = self.decoder(x_t, dec_h_t, src_h)
            y_t = y_t.view(B, K, -1) # B, K, V
            y_t = F.log_softmax(y_t, dim=2)

            # (c) Advance each beam.
            select_indices_array = []
            # Loop over the batch_size number of beams (beam search per sequence)
            for j, b in enumerate(beam):
                b.advance(y_t[j], None)
                select_indices_array.append(
                    b.get_current_origin() + j * K)
            
            select_indices = torch.cat(select_indices_array)
            dec_h_t = dec_h_t.index_select(1, select_indices) # select correct nodes

        # (4) Extract sentences from beam.
        preds = []
        for b in beam:
            scores, ks = b.sort_finished(minimum=n_best)
            hyps = []
            for times, k in ks[:n_best]:
                hyp, _ = b.get_hyp(times, k)
                hyps.append(" ".join([vocab.index2word[word.item()] for word in hyp if word.item() not in [constant.eou_idx, constant.pad_idx]]))
            preds.append(hyps[0])
        return preds
Example #2
0
    def __getitem__(self, idx):
        img_name = os.path.join(
            os.path.join(self.data_dir, 'train_images/'),
            self.data.loc[idx, 'image_id'] + '.' + self.image_format)
        data_provider = self.data.loc[idx, 'data_provider']
        gleason_score = self.data.loc[idx, 'gleason_score']
        isup_grade = label = self.data.loc[idx, 'isup_grade']

        if self.image_format == 'tiff':
            image = skimage.io.MultiImage(img_name)[self.layer]
        elif self.image_format == 'png':
            image = cv2.imread(img_name)
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        if self.tile == 1:
            try:
                image = crop_tile(image)
            except ZeroDivisionError:
                print(img_name)
        elif self.tile == 2:
            image = tile(image, sz=512, N=16)
            #image = np.random.shuffle(image))
            image = cv2.hconcat([
                cv2.vconcat([image[0], image[1], image[2], image[3]]),
                cv2.vconcat([image[4], image[5], image[6], image[7]]),
                cv2.vconcat([image[8], image[9], image[10], image[11]]),
                cv2.vconcat([image[12], image[13], image[14], image[15]])
            ])

        if self.transform:
            image = self.transform(image=image)
            image = torch.from_numpy(image['image'].transpose(2, 0, 1))
        return image, isup_grade
def rpn_loss_regr(y_true,
                  y_pred,
                  y_is_box_label,
                  lambda_rpn_regr=1.0,
                  epsilon=1e-6,
                  device='cpu'):
    # Smooth L1 loss function
    #                    0.5*x*x (if x_abs < 1)
    #                    x_abx - 0.5 (otherwise)

    # y_true [: , : , : , 36]: 4 values per 9 anchor boxes
    # y_is_box_label [: , : , : , 9] tilled on the last dimension 4 times. label 1 propogated through all 4 values ,
    # similarly other labels replicated 4 times
    b = y_true.size(0)
    x_abs = y_true - y_pred
    x_abs = torch.abs(x_abs)
    index_small = torch.where(x_abs <= 1)

    x_abs[index_small] = torch.pow(x_abs[index_small], 2) / 2 + 0.5
    x_abs = x_abs - 0.5
    # label 1 means positive box, label 0 means neutral and -1 means negative box
    # clamp min= 0, removes negative box error
    y_is_box_label = tile(y_is_box_label, -1, 4, device=device).clamp(min=0)

    loss = (y_is_box_label * x_abs).view(
        b, -1).sum(1) / (epsilon + y_is_box_label.view(b, -1).sum(1))
    # loss = (y_is_box_label * x_abs).sum() / (epsilon + y_is_box_label.sum() )
    return lambda_rpn_regr * loss.mean()
Example #4
0
    def forward(self,
                x,
                action,
                with_encode=False,
                hidden=None,
                cell=None,
                training=True,
                action_var=None):
        output_dict = dict()
        if not with_encode:
            x, hidden, output_dict['seg_current'] = self.get_feature(x)
            if torch.cuda.is_available():
                action_var = action_var.cuda()
            x = tile_first(x, action_var)

        x[-1] = tile(x[-1], action)
        hx = self.feature_map_predictor(x)
        rx, output_dict['seg_pred'] = self.dlaseg.infer(hx)
        nx_feature_enc = x[1:] + [hx]
        hidden = torch.cat([hidden[:, self.args.classes:, :, :], rx], dim=1)

        output_dict['coll_prob'] = self.coll_layer(rx.detach())
        output_dict['offroad_prob'] = self.off_layer(rx.detach())
        output_dict['speed'] = self.speed_layer(hidden.detach())

        return output_dict, nx_feature_enc, hidden, None
Example #5
0
File: made.py Project: yyht/lfi
    def _get_mask_and_degrees(cls, in_degrees, out_features,
                              autoregressive_features, random_mask, is_output):
        if is_output:
            out_degrees = utils.tile(
                _get_input_degrees(autoregressive_features),
                out_features // autoregressive_features,
            )
            mask = (out_degrees[..., None] > in_degrees).float()

        else:
            if random_mask:
                min_in_degree = torch.min(in_degrees).item()
                min_in_degree = min(min_in_degree, autoregressive_features - 1)
                out_degrees = torch.randint(
                    low=min_in_degree,
                    high=autoregressive_features,
                    size=[out_features],
                    dtype=torch.long,
                )
            else:
                max_ = max(1, autoregressive_features - 1)
                min_ = min(1, autoregressive_features - 1)
                out_degrees = torch.arange(out_features) % max_ + min_
            mask = (out_degrees[..., None] >= in_degrees).float()

        return mask, out_degrees
Example #6
0
    def initialize(self, memory_bank, src_lengths, field_signals, device=None):
        """Initialize search state for each batch input"""

        # Repeat state in beam_size
        def fn_map_state(state, dim):
            return tile(state, self.beam_size, dim=dim)

        src_max_len = memory_bank.size(1)
        memory_bank = tile(memory_bank, self.beam_size)
        memory_pad_mask = tile(~sequence_mask(src_lengths, src_max_len),
                               self.beam_size)
        self.memory_lengths = tile(src_lengths, self.beam_size)
        mb_device = memory_bank.device
        if device is None:
            self.device = mb_device
        self.field_signals = field_signals
        self.alive_seq = field_signals.repeat_interleave(self.beam_size)\
            .unsqueeze(-1).to(self.device)
        self.is_finished = torch.zeros([self.batch_size, self.beam_size],
                                       dtype=torch.uint8,
                                       device=self.device)
        self.best_scores = torch.full([self.batch_size],
                                      -1e10,
                                      dtype=torch.float,
                                      device=self.device)
        self._beam_offset = torch.arange(0,
                                         self.batch_size * self.beam_size,
                                         step=self.beam_size,
                                         dtype=torch.long,
                                         device=self.device)
        # Give full probability to the first beam on the first step; with no
        # prior information, choose any (the first beam)
        self.topk_log_probs = torch.tensor(
            [0.0] + [float("-inf")] * (self.beam_size - 1),
            device=self.device).repeat(self.batch_size)
        # buffers for the topk scores and 'backpointer'
        self.topk_scores = torch.empty((self.batch_size, self.beam_size),
                                       dtype=torch.float,
                                       device=self.device)
        self.topk_ids = torch.empty((self.batch_size, self.beam_size),
                                    dtype=torch.long,
                                    device=self.device)
        self._batch_index = torch.empty([self.batch_size, self.beam_size],
                                        dtype=torch.long,
                                        device=self.device)
        return fn_map_state, memory_bank, memory_pad_mask
Example #7
0
def do_tile(input_task):
    sample, img_path, cm_path = input_task
    if ATM_PATH:
        atm_file = open(ATM_PATH, "r")
        atm = atm_file.read().split(" ")
    else:
        atm = None
    img = Image.open(img_path)
    
    # img normalization
    img_uncast = remove_colour_cast(img)
    img_std = LuminosityStandardizer.standardize(np.array(img_uncast))
    transformed = normalizer.transform(img_std)
    img = Image.fromarray(transformed)
    
    cm = pd.read_csv(cm_path, header=0, sep='\t', index_col=0)
    cm = cm.transpose()
    spots_center_gen = spot_gen(cm)
    tile_out = os.path.join(TILE_PATH, sample)
    mkdirs(tile_out)
    tile(img, spots_center_gen, tile_out, atm)
Example #8
0
    def __getitem__(self, idx):
        file_name = self.df['image_id'].values[idx]
        file_path = f'{self.data_dir}/{file_name}.tiff'
        image = skimage.io.MultiImage(file_path)[-1]
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        # split image
        image = utils.tile(image, tile_size=128, num_tiles=12)
        image = torch.from_numpy(1.0 - image / 255.0).float()
        image = (image - mean) / std
        image = image.permute(0, 3, 1, 2)

        return image
Example #9
0
 def output_examples(self):
     cols = self.output_cols
     rows = self.output_rows
     nimgs = cols * rows
     zfeed = self.example_noise.eval(
     )  # need to eval to get value since it's a tf variable
     imgs = self.sess.run(self.Gz,
                          feed_dict={
                              self.Z: zfeed,
                              self.is_training: False
                          })
     imgs = imgs[:nimgs]
     # conver [-1,1] back to [0,1] before saving
     imgs = pixels01(imgs)
     path = os.path.join(self.dirs['output'],
                         '%06d.jpg' % self.output_img_idx)
     tiled = tile(imgs, (rows, cols))
     as_ints = (tiled * 255.0).astype('uint8')
     Image.fromarray(as_ints).save(path)
     self.output_img_idx += 1
Example #10
0
    def forward_next_step(self,
                          fms_seq,
                          action,
                          with_encode=False,
                          hidden=None,
                          cell=None,
                          training=True,
                          action_var=None):
        # given the predicted feature maps for the next frame, do:
        # 1. detect vehicles on the feature maps
        # 2. infer semantic segmentation on the feature maps
        # 3. infer feature maps for the following frame
        # 4. predct events on the feature maps
        output_dict = dict()
        fms_seq[-1] = tile(fms_seq[-1], action)
        pred_fms = self.feature_map_predictor(fms_seq)

        output_dict['seg_pred'], rx, output_dict['depth_pred'] = self.fm_infer(
            pred_fms)
        if self.args.use_detection:
            output_dict['loc_pred'], output_dict['cls_pred'], output_dict[
                'colls_with_prob'], output_dict["residual_pred"], output_dict[
                    "conf_pred"], output_dict["dim_pred"], output_dict[
                        "center_pred"] = self.detector(pred_fms)

        nx_feature_enc = fms_seq[1:] + [pred_fms]
        hidden = torch.cat([hidden[:, self.args.classes:, :, :], rx], dim=1)

        if self.args.use_collision:
            output_dict['coll_prob'] = self.coll_layer(rx.detach())
            # output_dict['coll_other_prob'] = self.coll_other_layer(rx.detach())
            # output_dict['coll_vehicles_prob'] = self.coll_vehicle_layer(rx.detach())
        if self.args.use_offroad:
            output_dict['offroad_prob'] = self.offroad_layer(rx.detach())
        if self.args.use_offlane:
            output_dict['offlane_prob'] = self.offlane_layer(rx.detach())
        if self.args.use_speed:
            output_dict['speed'] = self.speed_layer(hidden.detach())

        return output_dict, nx_feature_enc, hidden, None
Example #11
0
    def _beam_search_decoding(self, imgs, beam_size):
        B = imgs.size(0)
        # use batch_size*beam_size as new Batch
        imgs = tile(imgs, beam_size, dim=0)
        enc_outs, hiddens = self.model.encode(imgs)
        dec_states, O_t = self.model.init_decoder(enc_outs, hiddens)

        new_B = imgs.size(0)
        # first decoding step's input
        tgt = torch.ones(new_B, 1).long() * START_TOKEN
        beam = BeamSearch(beam_size, B)
        for t in range(self.max_len):
            tgt = beam.current_predictions.unsqueeze(1)
            dec_states, O_t, probs = self.step_decoding(
                dec_states, O_t, enc_outs, tgt)
            log_probs = torch.log(probs)

            beam.advance(log_probs)
            any_beam_is_finished = beam.is_finished.any()
            if any_beam_is_finished:
                beam.update_finished()
                if beam.done:
                    break

            select_indices = beam.current_origin
            if any_beam_is_finished:
                # Reorder states
                h, c = dec_states
                h = h.index_select(0, select_indices)
                c = c.index_select(0, select_indices)
                dec_states = (h, c)
                O_t = O_t.index_select(0, select_indices)
        # get results
        formulas_idx = torch.stack([hyps[1] for hyps in beam.hypotheses],
                                   dim=0)
        results = self._idx2formulas(formulas_idx)
        return results
def get_mask(in_features,
             out_features,
             autoregressive_features,
             mask_type=None):
    max_ = max(1, autoregressive_features - 1)
    min_ = min(1, autoregressive_features - 1)

    if mask_type == 'input':
        in_degrees = torch.arange(1, autoregressive_features + 1)
        out_degrees = torch.arange(out_features) % max_ + min_
        mask = (out_degrees[..., None] >= in_degrees).float()

    elif mask_type == 'output':
        in_degrees = torch.arange(in_features) % max_ + min_
        out_degrees = utils.tile(torch.arange(1, autoregressive_features + 1),
                                 out_features // autoregressive_features)
        mask = (out_degrees[..., None] > in_degrees).float()

    else:
        in_degrees = torch.arange(in_features) % max_ + min_
        out_degrees = torch.arange(out_features) % max_ + min_
        mask = (out_degrees[..., None] >= in_degrees).float()

    return mask
import numpy as np
import pandas as pd
import cv2
import matplotlib.pyplot as plt
from utils import tile, get_HOG_image
from skimage.feature import hog
from feature_expansion import feature_threshold, feature_sobel

X_tr_orig = np.load("../other/X_tr_orig.npy")
X_te_orig = np.load("../other/X_te_orig.npy")
y_tr_orig = np.load("../other/y_tr_orig.npy")
labels_string = np.load("../other/labels_string.npy")
sorted_files_tr_orig = np.load("../other/sorted_files_tr_orig.npy")
sorted_files_te_orig = np.load("../other/sorted_files_te_orig.npy")

out = tile(300, 600, 3, 10, "../data/train", y_tr_orig, labels_string, 1, 42, 1)
cv2.imwrite("../other/figures/visual_small.png", out)

img = cv2.imread("../data/train/1.Bmp", 0)
h, h_img = hog(img, orientations=8, pixels_per_cell=(15, 15), cells_per_block=(2, 2), visualise=True, normalise=True)
a = h_img.min()
b = h_img.max()
h_img = (h_img - a) / (b - a) * 255
h_img_1 = h_img.astype("uint8")

cv2.imwrite("../other/figures/hog_full.png", h_img_1)

img = cv2.resize(img, (img.shape[1] / 2, img.shape[0] / 2), interpolation=cv2.INTER_CUBIC)

h, h_img = hog(img, orientations=8, pixels_per_cell=(15, 15), cells_per_block=(2, 2), visualise=True, normalise=True)
a = h_img.min()
Example #14
0
 def fn_map_state(state, dim):
     return tile(state, self.beam_size, dim=dim)
Example #15
0
    def adapt_with_jigsaw(self, x):
        # input data
        if self.n_support == 1:
            self.repeat_time = 5  # repeat support data if shot =1
        x_support = x[:, :self.n_support]
        x_support = tile(x_support, dim=1, n_tile=self.repeat_time)
        x_support = x_support.contiguous().view(
            self.n_way * self.n_support * self.repeat_time,
            *x.size()[2:])
        y_support = torch.from_numpy(
            np.repeat(range(self.n_way),
                      self.n_support * self.repeat_time)).long().cuda()

        x_query = x[:, self.n_support:(self.n_support + self.n_query)]
        x_query = x_query.contiguous().view(self.n_way * self.n_query,
                                            *x.size()[2:])

        x_unlabeled = x[:, (self.n_support + self.n_query):]
        x_unlabeled = x_unlabeled.contiguous().view(
            self.n_way * self.n_unlabeled,
            *x.size()[2:])

        # calculate feature before hand since backbone won't be updated
        self.eval()
        with torch.no_grad():
            z_query = self.feature(x_query)
            z_unlabeled = self.feature(x_unlabeled)

        # classifier + opt
        classifier = nn.Linear(self.feature_dim, self.n_way).cuda()
        optimizer = torch.optim.Adam(classifier.parameters())

        batch_size = 4
        support_size = y_support.size(0)

        x_support_aug = x_support
        for epoch in range(100):
            rand_id = np.random.permutation(support_size)
            # rand_id = np.array([i for i in range(support_size)])
            for i in range(0, support_size, batch_size):
                selected_id = torch.from_numpy(
                    rand_id[i:min(i +
                                  batch_size, support_size)]).long().cuda()
                x_batch = x_support_aug[selected_id]
                y_batch = y_support[selected_id]

                with torch.no_grad():
                    z = self.feature(x_batch)  # backbone is fixed

                logits = classifier(z)
                loss = self.ceLoss(logits, y_batch)

                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

            if epoch < 99:  # no aug in last epoch
                # different data selection strategies for ablation study
                label2idx, topk_labels = self.selected_by_pseudo_labels(
                    classifier, z_unlabeled)

                selected_idx = torch.cat(label2idx, dim=0)
                selected_unlabel_img = x_unlabeled[selected_idx]

                # local block replacement
                x_support_aug = self.jigsaw_aug(
                    x_support,
                    selected_unlabel_img,
                    min_replace_block_num=self.jig_replace_min_num,
                    max_replace_block_num=self.jig_replace_max_num)
                ####################

        # test on query set after adaptation
        scores = classifier(z_query)
        """Get the accuracy"""
        # query labels
        y_query = np.repeat(range(self.n_way), self.n_query)

        topk_scores, topk_labels = scores.data.topk(1, 1, True, True)
        topk_ind = topk_labels.cpu().numpy()
        correct = np.sum(topk_ind[:, 0] == y_query)
        count = len(y_query)

        return correct, count
def collate_fn(batch):
    """This function takes list of samples and assembles a batch. 
    It is intended to used in PyTorch DataLoader."""

    mfccs, ivectors, embeddings, transcripts, accents = list(zip(*batch))

    def exists(list_):
        """Checks if we are not getting a list of None"""
        return list_[0] is not None

    ## Lens
    if exists(mfccs):
        inputs_lens = torch.IntTensor([len(m) for m in mfccs])
    elif exists(ivectors):
        inputs_lens = torch.IntTensor([len(i) for i in ivectors])
    else:
        inputs_lens = torch.IntTensor([1] * len(batch))

    # Sorting order (needs to be descending in lens for the padder)
    inputs_lens, sorted_idx = inputs_lens.sort(descending=True)

    if exists(transcripts):
        transcripts_lens = torch.IntTensor([len(t) for t in transcripts])
        transcripts_lens = transcripts_lens[sorted_idx]
    else:
        transcripts_lens = None

    ## Inputs
    inputs = []
    if exists(mfccs):
        inputs.append(nn.utils.rnn.pad_sequence(mfccs, batch_first=True))

    if exists(ivectors):
        ivect = nn.utils.rnn.pad_sequence(ivectors, batch_first=True)
        if exists(
                mfccs
        ):  # The ivector resolution is 10 times lower than the mfccs', so we expand them.
            ivect = tile(ivect, 1, 10)
            ivect = ivect[:, :inputs[0].size(1), :]
        inputs.append(ivect)

    if exists(embeddings):
        emb = torch.cat(embeddings)
        emb = emb.view(emb.size(0), 1, emb.size(1))
        if exists(mfccs) or exists(ivectors):
            # tile embeddings to fit either mfccs or ivectors size if they are present
            emb = tile(emb, 1, inputs[0].size(1))
        inputs.append(emb)

    inputs = torch.cat(inputs, dim=2)
    inputs = inputs[sorted_idx]

    ## Outputs
    if exists(transcripts):
        if inputs.size(0) == 1:  # bugfix for when only one sample
            transcripts = [transcripts]
        transcripts = np.asarray(
            transcripts
        )[sorted_idx]  # dtype=object because some transcripts were loaded with wrong type (Int64). TODO fix.
        transcripts = torch.IntTensor([t for trs in transcripts for t in trs])
        # we need text targets as one concatenated vector

    if exists(accents):
        accents = torch.cat(accents)[sorted_idx]
    else:
        accents = None

    return inputs, inputs_lens, transcripts, transcripts_lens, accents
Example #17
0
    def _fast_translate_batch(self, batch, max_length, min_length=0):
        # TODO: faster code path for beam_size == 1.

        # TODO: support these blacklisted features.
        assert not self.dump_beam

        beam_size = self.beam_size
        batch_size = batch.batch_size
        src = batch.src
        segs = batch.segs
        mask_src = batch.mask_src
        # pdb.set_trace()
        tgt = batch.tgt

        src_features = self.model.bert_model(input_ids=src,
                                             attention_mask=mask_src,
                                             token_type_ids=segs)

        dec_states = self.model.decoder.init_decoder_state(src,
                                                           src_features,
                                                           with_cache=True)
        device = src_features.device

        # Tile states and memory beam_size times.
        dec_states.map_batch_fn(
            lambda state, dim: tile(state, beam_size, dim=dim))

        src_features = tile(src_features, beam_size, dim=0)
        batch_offset = torch.arange(batch_size,
                                    dtype=torch.long,
                                    device=device)
        beam_offset = torch.arange(0,
                                   batch_size * beam_size,
                                   step=beam_size,
                                   dtype=torch.long,
                                   device=device)
        alive_seq = torch.full([batch_size * beam_size, 1],
                               self.start_token,
                               dtype=torch.long,
                               device=device)

        # Give full probability to the first beam on the first step.
        topk_log_probs = (torch.tensor([0.0] + [float("-inf")] *
                                       (beam_size - 1),
                                       device=device).repeat(batch_size))

        # Structure that holds finished hypotheses.
        hypotheses = [[] for _ in range(batch_size)]  # noqa: F812

        results = {}
        results["predictions"] = [[] for _ in range(batch_size)]  # noqa: F812
        results["scores"] = [[] for _ in range(batch_size)]  # noqa: F812
        results["gold_score"] = [0] * batch_size
        results["batch"] = batch

        for step in range(max_length):
            # pdb.set_trace()
            decoder_input = alive_seq[:, -1].view(1, -1)

            # Decoder forward.
            decoder_input = decoder_input.transpose(0, 1)
            # pdb.set_trace()
            decoder_outputs = self.decoder(
                tgt=output.view(output.shape[1], output.shape[0], -1),
                memory=top_vec[0].view(top_vec[0].shape[1],
                                       top_vec[0].shape[0], -1),
                tgt_mask=tgt_mask,
                memory_mask=None,
                tgt_key_padding_mask=tgt_pad_mask,
                memory_key_padding_mask=src_pad_mask)

            dec_out, dec_states = self.model.decoder(decoder_input,
                                                     src_features,
                                                     dec_states,
                                                     step=step)  #, edit_vec=z)
            # pdb.set_trace()

            # Generator forward.
            log_probs = self.generator.forward(
                dec_out.transpose(0, 1).squeeze(0))
            vocab_size = log_probs.size(-1)

            if step < min_length:
                log_probs[:, self.end_token] = -1e20

            # Multiply probs by the beam probability.
            log_probs += topk_log_probs.view(-1).unsqueeze(1)

            alpha = 0.6  # TODO: change if necessary - self.global_scorer.alpha
            length_penalty = ((5.0 + (step + 1)) / 6.0)**alpha

            # Flatten probs into a list of possibilities.
            curr_scores = log_probs / length_penalty

            if self.args.block_trigram:
                cur_len = alive_seq.size(1)
                if (cur_len > 3):
                    for i in range(alive_seq.size(0)):
                        fail = False
                        words = [int(w) for w in alive_seq[i]]
                        words = [self.vocab.ids_to_tokens[w] for w in words]
                        words = ' '.join(words).replace(' ##', '').split()
                        if (len(words) <= 3):
                            continue
                        trigrams = [(words[i - 1], words[i], words[i + 1])
                                    for i in range(1,
                                                   len(words) - 1)]
                        trigram = tuple(trigrams[-1])
                        if trigram in trigrams[:-1]:
                            fail = True
                        if fail:
                            curr_scores[i] = -10e20

            curr_scores = curr_scores.reshape(-1, beam_size * vocab_size)
            topk_scores, topk_ids = curr_scores.topk(beam_size, dim=-1)

            # Recover log probs.
            topk_log_probs = topk_scores * length_penalty

            # Resolve beam origin and true word ids.
            topk_beam_index = topk_ids.div(vocab_size)
            topk_ids = topk_ids.fmod(vocab_size)

            # Map beam_index to batch_index in the flat representation.
            batch_index = (topk_beam_index +
                           beam_offset[:topk_beam_index.size(0)].unsqueeze(1))
            select_indices = batch_index.view(-1)

            # Append last prediction.
            alive_seq = torch.cat([
                alive_seq.index_select(0, select_indices),
                topk_ids.view(-1, 1)
            ], -1)

            is_finished = topk_ids.eq(self.end_token)
            if step + 1 == max_length:
                is_finished.fill_(1)
            # End condition is top beam is finished.
            end_condition = is_finished[:, 0].eq(1)
            # Save finished hypotheses.
            if is_finished.any():
                predictions = alive_seq.view(-1, beam_size, alive_seq.size(-1))
                for i in range(is_finished.size(0)):
                    b = batch_offset[i]
                    if end_condition[i]:
                        is_finished[i].fill_(1)
                    finished_hyp = is_finished[i].nonzero().view(-1)
                    # Store finished hypotheses for this batch.
                    for j in finished_hyp:
                        hypotheses[b].append(
                            (topk_scores[i, j], predictions[i, j, 1:]))
                    # If the batch reached the end, save the n_best hypotheses.
                    if end_condition[i]:
                        best_hyp = sorted(hypotheses[b],
                                          key=lambda x: x[0],
                                          reverse=True)
                        score, pred = best_hyp[0]

                        results["scores"][b].append(score)
                        results["predictions"][b].append(pred)
                non_finished = end_condition.eq(0).nonzero().view(-1)
                # If all sentences are translated, no need to go further.
                if len(non_finished) == 0:
                    break
                # Remove finished batches for the next step.
                topk_log_probs = topk_log_probs.index_select(0, non_finished)
                batch_index = batch_index.index_select(0, non_finished)
                batch_offset = batch_offset.index_select(0, non_finished)
                alive_seq = predictions.index_select(0, non_finished) \
                    .view(-1, alive_seq.size(-1))
            # Reorder states.
            select_indices = batch_index.view(-1)
            src_features = src_features.index_select(0, select_indices)

            dec_states.map_batch_fn(
                lambda state, dim: state.index_select(dim, select_indices))

        return results
Example #18
0
def train_rl(model, dataloaders):
    train_dataloader, dev_dataloader, test_dataloader = dataloaders

    clf_criterion = nn.BCEWithLogitsLoss()
    mle_criterion = nn.CrossEntropyLoss(ignore_index=constant.pad_idx)
    baseline_criterion = nn.MSELoss()

    if constant.optim == 'Adam':
        opt = torch.optim.Adam(model.parameters(), lr=constant.lr)
    elif constant.optim == 'SGD':
        opt = torch.optim.SGD(model.parameters(), lr=constant.lr)
    else:
        print("Optim is not defined")
        exit(1)

    start_epoch = 1
    if constant.restore:
        model, opt, start_epoch = load_ckpt(model, opt, constant.restore_path)

    if constant.USE_CUDA:
        model.cuda()

    best_dev = 0
    best_path = ''
    patience = 3
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(opt,
                                                           'max',
                                                           factor=0.5,
                                                           patience=0,
                                                           min_lr=1e-6)
    tau = constant.tau
    tau_min = 0.2
    tau_dec = 0.2
    pretrain_curiosity = constant.lambda_aux
    if constant.pretrain_curiosity:
        pretrain_curiosity = 0.0

    try:
        for e in range(start_epoch, constant.epochs):
            model.train()
            reward_log = []
            ori_reward_log = []
            aux_reward_log = []  # for sentiment agreement / curiosity
            inv_loss_log = []  # for curiosity
            f1_log = []

            # pretrain curiosity only for first epoch
            if e > start_epoch:
                pretrain_curiosity = constant.lambda_aux

            # temperature annealing
            if constant.use_tau_anneal and e > start_epoch and constant.tau > tau_min:
                constant.tau -= tau_dec

            if constant.grid_search:
                pbar = enumerate(train_dataloader)
            else:
                pbar = tqdm(enumerate(train_dataloader),
                            total=len(train_dataloader))

            for b, (dialogs, lens, targets, _, _, sentiments, sentiments_b, _,
                    _) in pbar:
                if len(train_dataloader) % (b + 1) == 10:
                    torch.cuda.empty_cache()
                opt.zero_grad()
                try:
                    B, T = targets.shape

                    if constant.use_self_critical:
                        step_loss, dec_lens_var, R_g, R, greedy_sents, sampled_sents = model(
                            dialogs, lens, targets)
                        # (R_s - R_g) * step_loss
                        rl_loss = torch.mean(
                            torch.sum((R.detach() - R_g.detach()) * step_loss,
                                      dim=1) / dec_lens_var.float())
                    elif constant.use_arl:
                        step_loss, dec_lens_var, rs, R, arl, sampled_sents = model(
                            dialogs, lens, targets)
                        rs = rs.transpose(0, 1).contiguous()

                        rl_loss = (R.detach() - rs.detach()) * step_loss
                        rl_loss = torch.mean(
                            torch.sum(rl_loss * arl, dim=1) /
                            dec_lens_var.float())
                    else:
                        # probs: (B, T, V), xs: (B, T), R: (B, 1), rs: (B, T)
                        if constant.use_sentiment and constant.aux_reward_model != '':
                            step_loss, dec_lens_var, rs, R_l, R_s, sampled_sents, clf_logits = model(
                                dialogs, lens, targets, sentiments=sentiments)
                            R = constant.lambda_aux * R_l + R_s
                            clf_loss = clf_criterion(clf_logits, sentiments_b)
                            preds = torch.sigmoid(clf_logits.squeeze()) > 0.5
                            f1 = f1_score(sentiments_b.cpu().numpy(),
                                          preds.detach().cpu().numpy(),
                                          average='weighted')
                            f1_log.append(f1)
                        elif constant.use_sentiment and constant.use_sentiment_agreement:
                            step_loss, dec_lens_var, rs, R, sampled_sents, clf_logits = model(
                                dialogs, lens, targets, sentiments=sentiments)
                            clf_loss = clf_criterion(clf_logits, sentiments_b)
                            preds = torch.sigmoid(clf_logits.squeeze()) > 0.5
                            f1 = f1_score(sentiments_b.cpu().numpy(),
                                          preds.detach().cpu().numpy(),
                                          average='weighted')
                            f1_log.append(f1)
                        elif constant.use_sentiment_agreement:
                            step_loss, dec_lens_var, rs, R, sampled_sents = model(
                                dialogs, lens, targets, sentiments=sentiments)
                        elif constant.use_sentiment:
                            step_loss, dec_lens_var, rs, R, sampled_sents, clf_logits = model(
                                dialogs, lens, targets, sentiments=sentiments)
                            clf_loss = clf_criterion(clf_logits, sentiments_b)
                            preds = torch.sigmoid(clf_logits.squeeze()) > 0.5
                            f1 = f1_score(sentiments_b.cpu().numpy(),
                                          preds.detach().cpu().numpy(),
                                          average='weighted')
                            f1_log.append(f1)
                        elif constant.use_curiosity:
                            step_loss, dec_lens_var, rs, R, R_i, L_i, sampled_sents = model(
                                dialogs, lens, targets)
                            rs = rs.transpose(0, 1).contiguous()
                            R_i = R_i.transpose(0, 1).contiguous()
                            baseline_target = R.detach() * R_i.detach()
                            rl_loss = torch.mean(
                                torch.sum(
                                    (R.detach() * R_i.detach() - rs.detach()) *
                                    step_loss,
                                    dim=1) / dec_lens_var.float())
                            R_i = torch.mean(
                                torch.sum(R_i, dim=1) / dec_lens_var.float())
                        else:
                            step_loss, dec_lens_var, rs, R, sampled_sents = model(
                                dialogs, lens, targets)

                        if not constant.use_curiosity:
                            # probs = probs.transpose(0, 1).cntiguous()
                            # xs = xs.transpose(0, 1).contiguous()
                            # # (B, T, V) => (B, T) => (B,)
                            # probs = torch.gather(probs, dim=2, index=xs.unsqueeze(2)).squeeze()
                            # probs = -torch.log(probs)
                            rs = rs.transpose(0, 1).contiguous()
                            rl_loss = torch.mean(
                                torch.sum(
                                    (R.detach() - rs.detach()) * step_loss,
                                    dim=1) / dec_lens_var.float())

                    if constant.use_hybrid:
                        probs, _ = model(dialogs, lens, targets, use_mle=True)
                        mle_loss = mle_criterion(
                            probs.transpose(0, 1).contiguous().view(B * T, -1),
                            targets.contiguous().view(B * T))
                        loss = constant.lambda_mle * rl_loss + (
                            1 - constant.lambda_mle) * mle_loss
                    elif constant.use_arl:
                        probs, _ = model(dialogs, lens, targets, use_mle=True)
                        arl_c = torch.ones(arl.size()).to(arl.device) - arl
                        mle_criterion.reduction = 'none'
                        mle_loss = mle_criterion(
                            probs.transpose(0, 1).contiguous().view(B * T, -1),
                            targets.contiguous().view(B * T))
                        mle_loss = torch.mean(
                            torch.sum(mle_loss * arl_c, dim=1))
                        loss = rl_loss + mle_loss
                    else:
                        loss = rl_loss

                    if constant.use_sentiment:
                        loss = constant.lambda_emo * clf_loss + (
                            1 - constant.lambda_emo) * loss

                    if constant.use_curiosity:
                        loss = pretrain_curiosity * loss + (
                            1 - constant.beta) * L_i + constant.beta * R_i

                    loss.backward()
                    opt.step()

                    if constant.use_baseline:
                        if constant.use_curiosity:
                            baseline_loss = baseline_criterion(
                                rs, baseline_target)
                        else:
                            # rs (32, T) <==> R (32, 1)
                            baseline_loss = baseline_criterion(
                                rs, tile(R, T, dim=1))
                        baseline_loss.backward()
                        opt.step()

                    ## logging
                    reward_log.append(torch.mean(R).item())
                    if constant.use_sentiment and constant.aux_reward_model != '':
                        ori_reward_log.append(torch.mean(R_l).item())
                        aux_reward_log.append(torch.mean(R_s).item())

                    if constant.use_curiosity:
                        aux_reward_log.append(torch.mean(R_i).item())
                        inv_loss_log.append(L_i.item())

                    if not constant.grid_search:
                        if constant.use_sentiment:
                            if constant.aux_reward_model != '':
                                pbar.set_description(
                                    "(Epoch {}) TRAIN R: {:.3f} R_l: {:.3f} R_s: {:.3f} F1: {:.3f}"
                                    .format(e, np.mean(reward_log),
                                            np.mean(ori_reward_log),
                                            np.mean(aux_reward_log),
                                            np.mean(f1_log)))
                            else:
                                pbar.set_description(
                                    "(Epoch {}) TRAIN REWARD: {:.4f} TRAIN F1: {:.4f}"
                                    .format(e, np.mean(reward_log),
                                            np.mean(f1_log)))
                        elif constant.use_curiosity:
                            pbar.set_description(
                                "(Epoch {}) TRAIN R: {:.3f} R_i: {:.3f} L_i: {:.3f}"
                                .format(e, np.mean(reward_log),
                                        np.mean(aux_reward_log),
                                        np.mean(inv_loss_log)))
                        else:
                            pbar.set_description(
                                "(Epoch {}) TRAIN REWARD: {:.4f}".format(
                                    e, np.mean(reward_log)))

                    if b % 100 == 0 and b > 0:
                        # if not constant.use_self_critical:
                        #     _, greedy_sents = model(dialogs, lens, targets, test=True, use_mle=True)
                        corrects = [
                            " ".join([
                                train_dataloader.dataset.lang.index2word[x_t]
                                for x_t in iter(lambda x=iter(gens): next(x),
                                                constant.eou_idx)
                            ]) for gens in targets.cpu().data.numpy()
                        ]
                        contexts = [
                            " ".join([
                                train_dataloader.dataset.lang.index2word[x_t]
                                for x_t in iter(lambda x=iter(gens): next(x),
                                                constant.pad_idx)
                            ]) for gens in dialogs.cpu().data.numpy()
                        ]
                        for d, c, s, r in zip(contexts, corrects,
                                              sampled_sents,
                                              R.detach().cpu().numpy()):
                            print('reward: ', r)
                            print('dialog: ', d)
                            print('sample: ', s)
                            print('golden: ', c)
                            print()
                except RuntimeError as err:
                    if 'out of memory' in str(err):
                        print('| WARNING: ran out of memory, skipping batch')
                        torch.cuda.empty_cache()
                    else:
                        print(err)
                        traceback.print_exc()
                        raise err

            ## LOG
            if constant.use_sentiment and not constant.use_sentiment_agreement:
                dev_reward, dev_f1 = eval_rl(model, dev_dataloader, bleu=False)
                print("(Epoch {}) DEV REWARD: {:.4f}".format(e, dev_reward))
            elif constant.use_curiosity:
                dev_reward, dev_Ri, dev_Li = eval_rl(model,
                                                     dev_dataloader,
                                                     bleu=False)
                print("(Epoch {}) DEV REWARD: {:.3f} R_i: {:.3f} L_i: {:.3f}".
                      format(e, dev_reward, dev_Ri, dev_Li))
            else:
                dev_reward = eval_rl(model, dev_dataloader, bleu=False)
                print("(Epoch {}) DEV REWARD: {:.4f}".format(e, dev_reward))

            scheduler.step(dev_reward)
            if (dev_reward > best_dev):
                best_dev = dev_reward
                # save best model
                path = 'trained/data-{}.task-rlseq.lr-{}.tau-{}.lambda-{}.reward-{}.{}'
                path = path.format(constant.data, constant.lr, tau,
                                   constant.lambda_mle, best_dev,
                                   constant.reward_model.split('/')[1])
                if constant.use_curiosity:
                    path += '.curiosity'
                if constant.aux_reward_model != '':
                    path += '.' + constant.aux_reward_model.split('/')[1]
                    path += '.lambda_aux-{}'.format(constant.lambda_aux)
                if constant.use_tau_anneal:
                    path += '.tau_anneal'
                if constant.use_self_critical:
                    path += '.self_critical'
                if constant.use_current:
                    path += '.current'
                if constant.use_sentiment:
                    path += '.sentiment'
                if constant.use_sentiment_agreement:
                    path += '.agreement'
                if constant.use_context:
                    path += '.context'
                if constant.topk:
                    path += '.topk-{}'.format(constant.topk_size)
                if constant.use_arl:
                    path += '.arl'
                if constant.grid_search:
                    path += '.grid'
                best_path = save_model(model, 'reward', best_dev, path)
                patience = 3
            else:
                patience -= 1
            if patience == 0: break
            if constant.aux_reward_model == '' and best_dev == 0.0: break

    except KeyboardInterrupt:
        if not constant.grid_search:
            print("KEYBOARD INTERRUPT: Save CKPT and Eval")
            save = True if input('Save ckpt? (y/n)\t') in [
                'y', 'Y', 'yes', 'Yes'
            ] else False
            if save:
                save_path = save_ckpt(model, opt, e)
                print("Saved CKPT path: ", save_path)
            # ask if eval
            do_eval = True if input('Proceed with eval? (y/n)\t') in [
                'y', 'Y', 'yes', 'Yes'
            ] else False
            if do_eval:
                if constant.use_sentiment:
                    if constant.aux_reward_model != '':
                        dev_rewards, dev_f1, dev_bleu, dev_bleus = eval_rl(
                            model, dev_dataloader, bleu=True)
                        print(
                            "DEV R: {:.3f} R_l: {:.3f} R_s: {:.3f} DEV F1: {:.3f} DEV B: {:.3f}"
                            .format(dev_rewards[0], dev_rewards[1],
                                    dev_rewards[2], dev_f1, dev_bleu))
                    else:
                        dev_reward, dev_f1, dev_bleu, dev_bleus = eval_rl(
                            model, dev_dataloader, bleu=True)
                        print(
                            "DEV REWARD: {:.4f}, DEV F1: {:.4f}, DEV BLEU: {:.4f}"
                            .format(dev_reward, dev_f1, dev_bleu))
                elif constant.use_curiosity:
                    dev_reward, dev_Ri, dev_Li, dev_bleu, dev_bleus = eval_rl(
                        model, dev_dataloader, bleu=True)
                    print(
                        "BEST DEV REWARD: {:.4f} R_i: {:.3f} L_i: {:.3f} BLEU: {:.4f}"
                        .format(dev_reward, dev_Ri, dev_Li, dev_bleu))
                else:
                    dev_reward, dev_bleu, dev_bleus = eval_rl(model,
                                                              dev_dataloader,
                                                              bleu=True)
                    print("DEV REWARD: {:.4f}, DEV BLEU: {:.4f}".format(
                        dev_reward, dev_bleu))
                print(
                    "BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}"
                    .format(dev_bleus[0], dev_bleus[1], dev_bleus[2],
                            dev_bleus[3]))
        exit(1)

    # load and report best model on test
    torch.cuda.empty_cache()
    model = load_model(model, best_path)
    if constant.USE_CUDA:
        model.cuda()

    if constant.use_sentiment and not constant.use_sentiment_agreement:
        if constant.aux_reward_model != '':
            dev_rewards, dev_f1, dev_bleu, dev_bleus = eval_rl(model,
                                                               dev_dataloader,
                                                               bleu=True)
            test_rewards, test_f1, test_bleu, test_bleus = eval_rl(
                model, test_dataloader, bleu=True)
            print(
                "DEV R: {:.3f} R_l: {:.3f} R_s: {:.3f} DEV F1: {:.3f} DEV B: {:.3f}"
                .format(dev_rewards[0], dev_rewards[1], dev_rewards[2], dev_f1,
                        dev_bleu))
            print(
                "BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}"
                .format(dev_bleus[0], dev_bleus[1], dev_bleus[2],
                        dev_bleus[3]))
            print(
                "TEST R: {:.3f} R_l: {:.3f} R_s: {:.3f} TEST F1: {:.3f} TEST B: {:.3f}"
                .format(test_rewards[0], test_rewards[1], test_rewards[2],
                        test_f1, test_bleu))
            print(
                "BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}"
                .format(test_bleus[0], test_bleus[1], test_bleus[2],
                        test_bleus[3]))
        else:
            dev_reward, dev_f1, dev_bleu, dev_bleus = eval_rl(model,
                                                              dev_dataloader,
                                                              bleu=True)
            test_reward, test_f1, test_bleu, test_bleus = eval_rl(
                model, test_dataloader, bleu=True)
            print(
                "DEV REWARD: {:.4f}, DEV F1: {:.4f}, DEV BLEU: {:.4f}".format(
                    dev_reward, dev_f1, dev_bleu))
            print(
                "BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}"
                .format(dev_bleus[0], dev_bleus[1], dev_bleus[2],
                        dev_bleus[3]))
            print("TEST REWARD: {:.4f}, TEST F1: {:.4f}, TEST BLEU: {:.4f}".
                  format(test_reward, test_f1, test_bleu))
            print(
                "BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}"
                .format(test_bleus[0], test_bleus[1], test_bleus[2],
                        test_bleus[3]))
    elif constant.use_curiosity:
        dev_reward, dev_Ri, dev_Li, dev_bleu, dev_bleus = eval_rl(
            model, dev_dataloader, bleu=True)
        test_reward, test_Ri, test_Li, test_bleu, test_bleus = eval_rl(
            model, test_dataloader, bleu=True)
        print("BEST DEV REWARD: {:.4f} R_i: {:.3f} L_i: {:.3f} BLEU: {:.4f}".
              format(dev_reward, dev_Ri, dev_Li, dev_bleu))
        print("BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}".
              format(dev_bleus[0], dev_bleus[1], dev_bleus[2], dev_bleus[3]))
        print("BEST TEST REWARD: {:.4f} R_i: {:.3f} L_i: {:.3f} BLEU: {:.4f}".
              format(test_reward, test_Ri, test_Li, test_bleu))
        print("BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}".
              format(test_bleus[0], test_bleus[1], test_bleus[2],
                     test_bleus[3]))
    else:
        dev_reward, dev_bleu, dev_bleus = eval_rl(model,
                                                  dev_dataloader,
                                                  bleu=True)
        test_reward, test_bleu, test_bleus = eval_rl(model,
                                                     test_dataloader,
                                                     bleu=True)
        print("BEST DEV REWARD: {:.4f}, BLEU: {:.4f}".format(
            dev_reward, dev_bleu))
        print("BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}".
              format(dev_bleus[0], dev_bleus[1], dev_bleus[2], dev_bleus[3]))
        print("BEST TEST REWARD: {:.4f}, BLEU: {:.4f}".format(
            test_reward, test_bleu))
        print("BLEU 1: {:.4f}, BLEU 2: {:.4f}, BLEU 3: {:.4f}, BLEU 4: {:.4f}".
              format(test_bleus[0], test_bleus[1], test_bleus[2],
                     test_bleus[3]))