def train_fold(i_fold, trn_tp, model, criterion, optimizer, scheduler, config):
    mixup = config['globals']['mixup']
    device = torch.device(('cuda' if torch.cuda.is_available() else 'cpu'))
    (trn_idxs, val_idxs) = C.get_index_fold(trn_tp, i_fold, config)
    trn_tp_trn = trn_tp.iloc[trn_idxs].reset_index(drop=True)
    trn_tp_val = trn_tp.iloc[val_idxs].reset_index(drop=True)
    trn_loader = C.get_trn_val_loader(trn_tp_trn, 'train', config)
    val_loader = C.get_trn_val_loader(trn_tp_val, 'valid', config)
    model.train()
    epoch_train_loss = 0
    for (batch_idx, (data, target)) in enumerate(trn_loader):
        (data, target) = (data.to(device), target.to(device))
        if mixup:
            (data, targets_a, targets_b, lam) = U.mixup_data(data, target, alpha=1.0)
        optimizer.zero_grad()
        output = model(data)
        if mixup:
            loss = mixup_criterion(criterion, output, targets_a, targets_b, lam)
        else:
            loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        epoch_train_loss += (loss.item() * data.size(0))
    scheduler.step()
    loss_trn = (epoch_train_loss / len(trn_loader.dataset))
    del data
    (loss_val, acc_val, lwlrap_val, output_sig) = get_loss_score(model, val_loader, criterion, device)
    result_dict = {'model': model, 'val_idxs': val_idxs, 'output_sig': output_sig, 'loss_trn': loss_trn, 'loss_val': loss_val, 'acc_val': acc_val, 'lwlrap_val': lwlrap_val}
    return result_dict
def train_fold(i_fold, trn_tp, model, criterion, optimizer, scheduler, config):
    mixup = config['globals']['mixup']
    device = torch.device(('cuda' if torch.cuda.is_available() else 'cpu'))
    (trn_idxs, val_idxs) = C.get_index_fold(trn_tp, i_fold, config)
    trn_tp_trn = trn_tp.iloc[trn_idxs].reset_index(drop=True)
    trn_tp_val = trn_tp.iloc[val_idxs].reset_index(drop=True)
    trn_loader = C.get_trn_val_loader(trn_tp_trn, 'train', config)
    val_loader = C.get_trn_val_loader(trn_tp_val, 'valid', config)
    model.train()
    epoch_train_loss = 0
    for (batch_idx, (data, target)) in enumerate(trn_loader):
        (data, target) = (data.to(device), target.to(device))
        if mixup:
            (data, targets_a, targets_b, lam) = U.mixup_data(data, target, alpha=1.0)
        optimizer.zero_grad()
        output = model(data)
        if mixup:
            loss = mixup_criterion(criterion, output, targets_a, targets_b, lam)
        else:
            loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        epoch_train_loss += (loss.item() * data.size(0))
    scheduler.step()
    loss_trn = (epoch_train_loss / len(trn_loader.dataset))
    del data
    (loss_val, acc_val, lwlrap_val, output_sig) = get_loss_score(model, val_loader, criterion, device)
    result_dict = {'model': model, 'val_idxs': val_idxs, 'output_sig': output_sig, 'loss_trn': loss_trn, 'loss_val': loss_val, 'acc_val': acc_val, 'lwlrap_val': lwlrap_val}
    return result_dict