Exemple #1
0
    def train(self, train_loader: DataLoader, valid_loader: DataLoader, opt_params: Optional[Mapping] = None,
              nb_epoch=100, step=100, k=5, early=50, verbose=True, swa_warmup=None, **kwargs):
        self.get_optimizer(**({} if opt_params is None else opt_params))
        global_step, best_n5, e = 0, 0.0, 0
        for epoch_idx in range(nb_epoch):
            if epoch_idx == swa_warmup:
                self.swa_init()
            for i, (train_x, train_y) in enumerate(train_loader, 1):
#                print("train loop")
#                print(i,train_x.size(),train_y.size())
                global_step += 1
                loss = self.train_step(train_x, train_y.cuda())
                if global_step % step == 0:
                    self.swa_step()
                    self.swap_swa_params()
                    labels = np.concatenate([self.predict_step(valid_x, k)[1] for valid_x in valid_loader])
                    targets = valid_loader.dataset.data_y
                    p5, n5 = get_p_5(labels, targets), get_n_5(labels, targets)
                    if n5 > best_n5:
                        self.save_model()
                        best_n5, e = n5, 0
                    else:
                        e += 1
                        if early is not None and e > early:
                            return
                    self.swap_swa_params()
                    if verbose:
                        logger.info('{} {} train loss: {} P@5: {} nDCG@5: {} early stop: {}'.format(epoch_idx,i*train_loader.batch_size,round(loss,5),round(p5,5),round(n5,5),e))
Exemple #2
0
 def train(self,
           train_loader: DataLoader,
           valid_loader: DataLoader,
           opt_params: Optional[Mapping] = None,
           nb_epoch=100,
           step=100,
           k=5,
           early=100,
           verbose=True,
           swa_warmup=None,
           **kwargs):
     self.get_optimizer(**({} if opt_params is None else opt_params))
     global_step, best_n5, e = 0, 0.0, 0
     print_loss = 0.0  #
     for epoch_idx in range(nb_epoch):
         if epoch_idx == swa_warmup:
             self.swa_init()
         for i, (train_x, train_y) in enumerate(train_loader, 1):
             global_step += 1
             loss = self.train_step(
                 train_x.to(self.in_device, non_blocking=True),
                 train_y.to(self.out_device, non_blocking=True))
             print_loss += loss  #
             if global_step % step == 0:
                 self.swa_step()
                 self.swap_swa_params()
                 ##
                 labels = []
                 valid_loss = 0.0
                 self.model.eval()
                 with torch.no_grad():
                     for (valid_x, valid_y) in valid_loader:
                         logits = self.model(
                             valid_x.to(self.in_device, non_blocking=True))
                         valid_loss += self.loss_fn(
                             logits,
                             valid_y.to(self.out_device,
                                        non_blocking=True)).item()
                         scores, tmp = torch.topk(logits, k)
                         labels.append(tmp.cpu())
                 valid_loss /= len(valid_loader)
                 labels = np.concatenate(labels)
                 ##
                 #                    labels = np.concatenate([self.predict_step(valid_x, k)[1] for valid_x in valid_loader])
                 targets = valid_loader.dataset.data_y
                 p5, n5 = get_p_5(labels, targets), get_n_5(labels, targets)
                 if n5 > best_n5:
                     self.save_model(epoch_idx > 3 * swa_warmup)
                     best_n5, e = n5, 0
                 else:
                     e += 1
                     if early is not None and e > early:
                         return
                 self.swap_swa_params()
                 if verbose:
                     log_msg = '%d %d train loss: %.7f valid loss: %.7f P@5: %.5f N@5: %.5f early stop: %d' % \
                     (epoch_idx, i * train_loader.batch_size, print_loss / step, valid_loss, round(p5, 5), round(n5, 5), e)
                     logger.info(log_msg)
                     print_loss = 0.0
Exemple #3
0
 def train(self,
           train_loader: DataLoader,
           valid_loader: DataLoader,
           opt_params: Optional[Mapping] = None,
           nb_epoch=1,
           step=10,
           k=5,
           early=50,
           verbose=True,
           **kwargs):
     print("train")  # {'batch_size': 40, 'nb_epoch': 30, 'swa_warmup': 10}
     nb_epoch = 5
     self.get_optimizer(**({} if opt_params is None else opt_params))
     global_step, best_n5, e = 0, 0.0, 0
     print_loss = 0.0  #
     print("len(train_loader) = %d, len(valid_loader) = %d" %
           (len(train_loader), len(valid_loader)))
     for epoch_idx in range(nb_epoch):
         for i, (train_x, train_y) in enumerate(train_loader, 1):
             # train_x: 40 x 500, train_y: 40 x 3801
             global_step += 1
             loss = self.train_step(train_x, train_y.to(device))
             # print("return loss =", loss)
             print_loss += loss  #
             if global_step % step == 0:
                 print("detail: epoch_idx = %s, i = %s" % (epoch_idx, i))
                 labels = []
                 valid_loss = 0.0
                 self.model.eval()  # 從訓練模式轉為評估模式
                 with torch.no_grad():  # 不需要計算導數
                     for (valid_x, valid_y) in valid_loader:
                         logits = self.model(valid_x)
                         valid_loss += self.loss_fn(
                             logits, valid_y.to(device)).item()
                         scores, tmp = torch.topk(logits, k)  # (40, 5)
                         labels.append(tmp.cpu())
                 valid_loss /= len(valid_loader)
                 labels = np.concatenate(labels)
                 # print(labels[0])  # (200, 5)
                 targets = valid_loader.dataset.data_y
                 p5, n5 = get_p_5(labels,
                                  targets), get_n_5(labels, targets)  # ndcg
                 print(p5, n5)
                 if n5 > best_n5:
                     self.save_model()  # epoch_idx > 1 * swa_warmup)
                     best_n5, e = n5, 0
                 else:
                     e += 1
                     if early is not None and e > early:
                         return
                 if True:
                     log_msg = '%d %d train loss: %.7f valid loss: %.7f P@5: %.5f N@5: %.5f early stop: %d' % \
                               (epoch_idx, i * train_loader.batch_size, print_loss / step,
                                valid_loss, round(p5, 5), round(n5, 5), e)
                     logger.info(log_msg)
                     print_loss = 0.0
Exemple #4
0
def main(results, targets, train_labels):
    res, targets = np.load(results,
                           allow_pickle=True), np.load(targets,
                                                       allow_pickle=True)

    topk = 5
    with open('predictions.txt', 'w') as fout:
        for labels in res:
            fout.write(' '.join(labels[:topk]) + '\n')

    mlb = MultiLabelBinarizer(sparse_output=True)
    targets = mlb.fit_transform(targets)
    print('Precision@1,3,5:', get_p_1(res, targets, mlb),
          get_p_3(res, targets, mlb), get_p_5(res, targets, mlb))
    print('nDCG@1,3,5:', get_n_1(res, targets, mlb),
          get_n_3(res, targets, mlb), get_n_5(res, targets, mlb))
Exemple #5
0
def main(results, targets, train_labels, a, b):
    res, targets = np.load(results,
                           allow_pickle=True), np.load(targets,
                                                       allow_pickle=True)
    mlb = MultiLabelBinarizer(sparse_output=True)
    targets = mlb.fit_transform(targets)
    print('Precision@1,3,5:', get_p_1(res, targets, mlb),
          get_p_3(res, targets, mlb), get_p_5(res, targets, mlb))
    print('nDCG@1,3,5:', get_n_1(res, targets, mlb),
          get_n_3(res, targets, mlb), get_n_5(res, targets, mlb))
    if train_labels is not None:
        train_labels = np.load(train_labels, allow_pickle=True)
        inv_w = get_inv_propensity(mlb.transform(train_labels), a, b)
        print('PSPrecision@1,3,5:', get_psp_1(res, targets, inv_w, mlb),
              get_psp_3(res, targets, inv_w, mlb),
              get_psp_5(res, targets, inv_w, mlb))
        print('PSnDCG@1,3,5:', get_psndcg_1(res, targets, inv_w, mlb),
              get_psndcg_3(res, targets, inv_w, mlb),
              get_psndcg_5(res, targets, inv_w, mlb))
Exemple #6
0
    def train(self,
              train_loader: DataLoader,
              valid_loader: DataLoader,
              opt_params: Optional[Mapping] = None,
              nb_epoch=100,
              step=100,
              k=5,
              early=50,
              verbose=True,
              swa_warmup=None,
              inv_w=None,
              mlb=None,
              criterion='ndcg5',
              **kwargs):
        self.nb_epoch = 100
        self.n_steps = len(train_loader)

        if inv_w is not None and mlb is not None:
            train_labels = mlb.inverse_transform(train_loader.dataset.data_y)
            valid_labels = mlb.inverse_transform(valid_loader.dataset.data_y)
            valid_mlb = MultiLabelBinarizer(
                sparse_output=True).fit(valid_labels)
            valid_targets = valid_mlb.transform(valid_labels)
            with contextlib.redirect_stderr(None):
                inv_w = get_inv_propensity(valid_mlb.transform(train_labels),
                                           inv_w.get('a', 0.55),
                                           inv_w.get('b', 1.5))
        else:
            valid_targets = None
            valid_mlb = None

        if criterion not in ['p5', 'ndcg5', 'psp5']:
            raise ValueError(
                f'criterion {criterion} is invalid. (p5, ndcg5, psp5)')

        self.get_optimizer(**({} if opt_params is None else opt_params))
        global_step, best, e = 0, 0.0, 0
        self.save_model()
        for epoch_idx in range(nb_epoch):
            if epoch_idx == swa_warmup:
                self.swa_init()
            for i, train_inputs in enumerate(train_loader, 1):
                global_step += 1
                loss = self.train_step(epoch_idx, *train_inputs)
                if global_step % step == 0:
                    self.swa_step()
                    self.swap_swa_params()
                    labels = []
                    for valid_x in valid_loader:
                        if isinstance(valid_x, (list, tuple)):
                            labels.append(self.predict_step(*valid_x, k)[1])
                        else:
                            labels.append(self.predict_step(valid_x, k)[1])
                    labels = np.concatenate(labels)
                    targets = valid_loader.dataset.data_y
                    p5, n5 = get_p_5(labels, targets), get_n_5(labels, targets)
                    if inv_w is not None and mlb is not None:
                        with contextlib.redirect_stderr(None):
                            psp5 = get_psp_5(mlb.classes_[labels],
                                             valid_targets, inv_w, valid_mlb)
                    else:
                        psp5 = None

                    if criterion == 'p5':
                        cur = p5
                    elif criterion == 'ndcg5':
                        cur = n5
                    else:
                        cur = psp5

                    if cur > best:
                        self.save_model()
                        best, e = cur, 0
                    else:
                        e += 1
                        if early is not None and e > early:
                            return
                    self.swap_swa_params()
                    if verbose:
                        logger.info(
                            F'{epoch_idx} {i * train_loader.batch_size} train loss: {round(loss, 5)} '
                            F'P@5: {round(p5, 5)} nDCG@5: {round(n5, 5)} PSP@5: {round(psp5, 5)} '
                            F'early stop: {e}')
Exemple #7
0
    def train(self, train_loader: DataLoader, valid_loader: DataLoader, opt_params: Optional[Mapping] = None,
              nb_epoch=100, step=100, k=5, early=100, verbose=True, swa_warmup=None, **kwargs):
        self.get_optimizer(**({} if opt_params is None else opt_params))
        global_step, best_n5, e = 0, 0.0, 0
        print_loss = 0.0  #
        epoch_loss = np.zeros((1, nb_epoch), dtype=np.float)
        np_p1 = np.zeros((1, nb_epoch), dtype=np.float)
        np_p5 = np.zeros((1, nb_epoch), dtype=np.float)
        for epoch_idx in range(nb_epoch):
            print_epoch_loss = 0.0
            if epoch_idx == swa_warmup:
                self.swa_init()
            p1_tmp = 0.0
            p5_tmp = 0.0
            for i, (train_x, train_y) in enumerate(train_loader, 1):
                global_step += 1
                loss = self.train_step(train_x, train_y.cuda())
                print_loss += loss
                print_epoch_loss += loss
                if global_step % step == 0:
                    self.swa_step()
                    self.swap_swa_params()
                    ##
                    labels = []
                    valid_loss = 0.0
                    self.model.eval()
                    with torch.no_grad():
                        for (valid_x, valid_y) in valid_loader:
                            # 原始寫法
                            # logits = self.model(valid_x)
                            logits = self.model(valid_x.long())
                            valid_loss += self.loss_fn(logits, valid_y.cuda()).item()
                            scores, tmp = torch.topk(logits, k)
                            labels.append(tmp.cpu())
                    valid_loss /= len(valid_loader)
                    labels = np.concatenate(labels)
                    ##
                    #                    labels = np.concatenate([self.predict_step(valid_x, k)[1] for valid_x in valid_loader])
                    targets = valid_loader.dataset.data_y
                    p5, n5 = get_p_5(labels, targets), get_n_5(labels, targets)
                    p1, n1 = get_p_1(labels, targets), get_n_1(labels, targets)
                    p5_tmp = p5
                    p1_tmp = p1
                    if n5 > best_n5:
                        self.save_model(True)  # epoch_idx > 1 * swa_warmup)
                        best_n5, e = n5, 0
                    else:
                        e += 1
                        if early is not None and e > early:
                            return
                    self.swap_swa_params()
                    if verbose:
                        log_msg = '%d %d train loss: %.7f valid loss: %.7f P@5: %.5f N@5: %.5f P@1: %.5f N@1: %.5f early stop: %d' % \
                                  (epoch_idx, i * train_loader.batch_size, print_loss / step, valid_loss, round(p5, 5),
                                   round(n5, 5), round(p1, 5), round(n1, 5), e)
                        logger.info(log_msg)
                        print_loss = 0.0

            epoch_loss[0, epoch_idx] = print_epoch_loss / 15249
            print_epoch_loss = 0.0
            np_p1[0, epoch_idx] = p1_tmp
            np_p5[0, epoch_idx] = p5_tmp
        return epoch_loss, np_p1, np_p5