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))
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
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
def evalucate(results, targets, train_labels, a=0.55, b=1.5): 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))
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))
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}')
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