Пример #1
0
def train_epoch_wo_outlier(model, optimizer, in_loader, loss_func, cur_epoch, op_cfg, writer):
    global global_cfg
    model.train()
    avg_loss = 0
    correct = 0
    in_data_size = len(in_loader.dataset)
    for cur_iter, in_set in enumerate(in_loader):
        #TODO: Dimension of in_set and out_set should be checked!
        # Data to GPU
        data = in_set[0]
        targets = in_set[1]
        if cur_iter == 0:
            writer.add_image('in_dist target {}'.format(targets[0]), data[0], cur_epoch)
        data, targets = data.cuda(), targets.cuda()

        # Adjust Learning rate
        lr = optim.get_lr_at_epoch(op_cfg, cur_epoch + float(cur_iter) / in_data_size)
        optim.set_lr(optimizer, lr)
        
        # Foward propagation and Calculate loss
        logits = model(data)
        
        (ava_logits, ova_logits) = logits
        
        #print(logits.size())
        global_cfg['loss']['model'] = model
        global_cfg['loss']['data'] = data
        loss_dict = loss_func(logits, targets, global_cfg['loss'])
        loss = loss_dict['loss']
        
        logits = F.softmax(ava_logits, dim=1)     
        
        # Back propagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        
        
        # Calculate classifier error about in-distribution sample
        num_topks_correct = metrics.topks_correct(logits[:len(targets)], targets, (1,))
        [top1_correct] = [x for x in num_topks_correct]
        
        # Add additional metrics!!!
        
        loss, top1_correct = loss.item(), top1_correct.item()
        avg_loss += loss
        correct += top1_correct
    
    summary = {
        'avg_loss': avg_loss / in_data_size,
        'classifier_acc': correct / in_data_size,
        'lr': optim.get_lr_at_epoch(op_cfg, cur_epoch),
        'epoch': cur_epoch,
    }
    
    return summary
Пример #2
0
def train_epoch_wo_outlier(model, optimizer, in_loader, attack_in, cur_epoch, op_cfg, writer):
    global global_cfg
    model.train()
    avg_loss = 0
    correct = 0
    in_data_size = len(in_loader.dataset)
    for cur_iter, (x_tf_0, x_tf_90, x_tf_180, x_tf_270, targets) in enumerate(in_loader):
        
        batch_size = x_tf_0.shape[0]
        
        assert x_tf_0.shape[0] == \
            x_tf_90.shape[0] == \
            x_tf_180.shape[0] == \
            x_tf_270.shape[0] == \
            targets.shape[0]
            #x_tf_trans.shape[0] == \
            #target_trans_x.shape[0] == \
            #target_trans_y.shape[0] == \
            
        batch = np.concatenate((
            x_tf_0,
            x_tf_90,
            x_tf_180,
            x_tf_270
        ), 0)
        batch = torch.FloatTensor(batch).cuda()
        
        target_rots = torch.cat((
            torch.zeros(batch_size),
            torch.ones(batch_size),
            2 * torch.ones(batch_size),
            3 * torch.ones(batch_size)
        ), 0).long()
        
        if attack_in is not None:
            # Process PGD attack
            batch = attack_in.perturb(batch, batch_size, torch.cat((targets, target_rots), 0).cuda())
            batch = batch.cuda()
        
        if cur_iter == 0:
            writer.add_image('Original', batch[0], cur_epoch)
            writer.add_image('Rot90', batch[batch_size], cur_epoch)
            writer.add_image('Rot180', batch[batch_size * 2], cur_epoch)
            writer.add_image('Rot270', batch[batch_size * 3], cur_epoch)
        
         # Adjust Learning rate
        lr = optim.get_lr_at_epoch(op_cfg, cur_epoch + float(cur_iter) / in_data_size)
        optim.set_lr(optimizer, lr)
        
        logits, pen = model(batch)
        
        classification_logits = logits[:batch_size]
        rot_logits            = model.rot_head(pen[:4*batch_size])
        #x_trans_logits        = model.x_trans_head(pen[4*batch_size:])
        #y_trans_logits        = model.y_trans_head(pen[4*batch_size:])
        
        
        classification_loss = F.cross_entropy(classification_logits, targets.cuda())
        rot_loss = F.cross_entropy(rot_logits, target_rots.cuda()) * global_cfg['loss']['rot_weight']
#         x_trans_loss = F.cross_entropy(x_trans_logits, target_trans_x.cuda()) * global_cfg['loss']['trans_weight']
#         y_trans_loss = F.cross_entropy(y_trans_logits, target_trans_y.cuda()) * global_cfg['loss']['trans_weight']
        
        
        #loss = classification_loss + ((rot_loss + x_trans_loss + y_trans_loss) / 3.0)
        loss = classification_loss + rot_loss
        
        # Back propagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        # Calculate classifier error about in-distribution sample
        num_topks_correct = metrics.topks_correct(logits[:batch_size], targets.cuda(), (1,))
        [top1_correct] = [x for x in num_topks_correct]
        
        # Add additional metrics!!!
        
        loss, top1_correct = loss.item(), top1_correct.item()
        avg_loss += loss
        correct += top1_correct
    
    summary = {
        'avg_loss': avg_loss / in_data_size,
        'classifier_acc': correct / in_data_size,
        'lr': optim.get_lr_at_epoch(op_cfg, cur_epoch),
        'epoch': cur_epoch,
    }
    
    return summary
Пример #3
0
def train_epoch_w_outlier(model, optimizer, in_loader, out_loader, loss_func, detector_func, cur_epoch, op_cfg, writer):
    global global_cfg
    model.train()
    avg_loss = 0
    correct = 0
    total = 0
    in_data_size = len(in_loader.dataset)
    out_loader.dataset.offset = np.random.randint(len(out_loader.dataset))
    for cur_iter, (in_set, out_set) in enumerate(zip(in_loader, out_loader)):
        #TODO: Dimension of in_set and out_set should be checked!
        
        # Data to GPU
        data = torch.cat((in_set[0], out_set[0]), 0)
        targets = in_set[1]
        if cur_iter == 0:
            writer.add_image('in_dist sample, target:[{}]'.format(targets[0]), in_set[0][0], cur_epoch)
            writer.add_image('out_dist sample', out_set[0][0], cur_epoch)
        data, targets = data.cuda(), targets.cuda()
        
        # Adjust Learning rate
        lr = optim.get_lr_at_epoch(op_cfg, cur_epoch + float(cur_iter) / in_data_size)
        optim.set_lr(optimizer, lr)
        
        # Foward propagation and Calculate loss and confidence
        logits = model(data)
        global_cfg['loss']['model'] = model
        global_cfg['loss']['data'] = data
        global_cfg['detector']['model'] = model
        global_cfg['detector']['data'] = data
        loss_dict = loss_func(logits, targets, global_cfg['loss'])
        loss = loss_dict['loss']
        confidences_dict = detector_func(logits, targets, global_cfg['detector'])
        confidences = confidences_dict['confidences']

        
        # Back propagation 
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        ## METRICS ##
        # Calculate classifier error about in-distribution sample
        num_topks_correct = metrics.topks_correct(logits[:len(targets)], targets, (1,))
        [top1_correct] = [x for x in num_topks_correct]
        
        # Calculate OOD metrics (auroc, aupr, fpr)
        #(auroc, aupr, fpr) = metrics.get_ood_measures(confidences, targets)
        
        # Add additional metrics!!!
        
        
        ## UDATE STATS ##
        loss, top1_correct = loss.item(), top1_correct.item()
        avg_loss += loss
        correct += top1_correct
        total += targets.size(0)
    
    summary = {
        'avg_loss': avg_loss / total,
        'classifier_acc': correct / total,
        'lr': optim.get_lr_at_epoch(op_cfg, cur_epoch),
        'epoch': cur_epoch,
    }
    
    return summary
Пример #4
0
def train_epoch_wo_outlier(model, optimizer, in_loader, loss_func, cur_epoch,
                           op_cfg, writer):
    global global_cfg
    model.train()
    avg_loss = 0
    avg_sup_loss = 0
    avg_con_loss = 0
    correct = 0
    in_data_size = len(in_loader.dataset)
    for cur_iter, in_set in enumerate(in_loader):
        #TODO: Dimension of in_set and out_set should be checked!

        # Data to GPU
        data = in_set[0]
        if cur_iter == 0:
            writer.add_image('Original', data[0], cur_epoch)

        # Transform imgs
        data = np.transpose((data.numpy() * 255).round().astype(np.uint8),
                            (0, 2, 3, 1))
        images_aug = seq0(images=data)
        data0 = torch.from_numpy(
            np.transpose((np.stack(images_aug, 0).astype(np.float32) / 255.),
                         (0, 3, 1, 2)))
        images_aug = seq1(images=data)
        data1 = torch.from_numpy(
            np.transpose((np.stack(images_aug, 0).astype(np.float32) / 255.),
                         (0, 3, 1, 2)))
        if cur_iter == 0:
            writer.add_image('Transform0', data0[0], cur_epoch)
            writer.add_image('Transform1', data1[0], cur_epoch)

        data = torch.cat((data0, data1), 0)
        targets = in_set[1]
        data, targets = data.cuda(), targets.cuda()

        # Adjust Learning rate
        lr = optim.get_lr_at_epoch(op_cfg,
                                   cur_epoch + float(cur_iter) / in_data_size)
        optim.set_lr(optimizer, lr)

        # Foward propagation and Calculate loss
        (g_logits, h_logits, f_logits) = model(data, cur_epoch)
        # logits: (g, h)
        logits = (g_logits, h_logits)
        global_cfg['loss']['model'] = model
        global_cfg['loss']['data'] = data
        loss_dict = loss_func(logits, targets, global_cfg['loss'])
        loss = loss_dict['loss']
        sup_loss = loss_dict['sup_loss']
        con_loss = loss_dict['con_loss']

        # Back propagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # Calculate classifier error about in-distribution sample
        num_topks_correct = metrics.topks_correct(g_logits[:len(targets)],
                                                  targets, (1, ))
        [top1_correct] = [x for x in num_topks_correct]

        # Add additional metrics!!!

        loss, top1_correct = loss.item(), top1_correct.item()
        avg_loss += loss
        avg_sup_loss += sup_loss
        avg_con_loss += con_loss
        correct += top1_correct

    summary = {
        'avg_loss': avg_loss / in_data_size,
        'avg_sup_loss': avg_sup_loss / in_data_size,
        'avg_con_loss': avg_con_loss / in_data_size,
        'classifier_acc': correct / in_data_size,
        'lr': optim.get_lr_at_epoch(op_cfg, cur_epoch),
        'epoch': cur_epoch,
    }

    return summary
Пример #5
0
def train_epoch_wo_outlier(feature_extractor, G, D, G_optimizer, D_optimizer,
                           in_loader, cur_epoch, op_cfg, writer):
    global global_cfg
    D.train()
    G.train()
    feature_extractor.eval()
    avg_loss = 0
    correct = 0
    in_data_size = len(in_loader.dataset)
    real_feature = None
    real_target = None
    for cur_iter, in_set in enumerate(in_loader):
        #TODO: Dimension of in_set and out_set should be checked!

        # Data to GPU
        real_data = in_set[0]
        targets = in_set[1]
        if cur_iter == 0:
            writer.add_image('in_dist target {}'.format(targets[0]),
                             real_data[0], cur_epoch)
        real_data, targets = real_data.cuda(), targets.cuda()

        _, real_features = feature_extractor(real_data, -1)
        if cur_iter == 0:
            real_feature = real_features[0].unsqueeze(0)
            real_target = targets[0]
        # Adjust Learning rate
        lr = optim.get_lr_at_epoch(op_cfg,
                                   cur_epoch + float(cur_iter) / in_data_size)
        optim.set_lr(G_optimizer, lr)
        optim.set_lr(D_optimizer, lr)

        ###
        d_out_real, dr1, dr2 = D(real_data, real_features)
        if global_cfg['loss']['adv_loss'] == 'wgan-gp':
            d_loss_real = -torch.mean(d_out_real)
        elif global_cfg['loss']['adv_loss'] == 'hinge':
            d_loss_real = torch.nn.ReLU()(1.0 - d_out_real).mean()

        z = tensor2var(torch.randn(real_data.size(0), G.z_dim))
        fake_images, gf1, gf2 = G(z, real_features)
        d_out_fake, df1, df2 = D(fake_images, real_features)

        if global_cfg['loss']['adv_loss'] == 'wgan-gp':
            d_loss_fake = d_out_fake.mean()
        elif global_cfg['loss']['adv_loss'] == 'hinge':
            d_loss_fake = torch.nn.ReLU()(1.0 + d_out_fake).mean()

        # Backward + Optimize
        d_loss = d_loss_real + d_loss_fake

        if global_cfg['loss']['adv_loss'] == 'wgan-gp':
            d_loss += op_cfg['lambda_gp'] * compute_gradient_penalty(
                feature_extractor, D, real_data.data, fake_images.data)

        D_optimizer.zero_grad()
        G_optimizer.zero_grad()
        d_loss.backward()
        D_optimizer.step()

        # ================== Train G and gumbel ================== #
        # Create random noise
        z = tensor2var(torch.randn(real_data.size(0), G.z_dim))
        _, real_features = feature_extractor(real_data, -1)
        fake_images, _, _ = G(z, real_features)

        # Compute loss with fake images
        g_out_fake, _, _ = D(fake_images, real_features)  # batch x n
        _, fake_features = feature_extractor(fake_images, -1)

        if global_cfg['loss']['adv_loss'] == 'wgan-gp':
            g_loss_fake = -g_out_fake.mean()
        elif global_cfg['loss']['adv_loss'] == 'hinge':
            g_loss_fake = -g_out_fake.mean()

        g_loss_feature = F.mse_loss(fake_features, real_features)

        g_loss = g_loss_fake + g_loss_feature

        D_optimizer.zero_grad()
        G_optimizer.zero_grad()
        g_loss.backward()
        G_optimizer.step()
        ###

        # Add additional metrics!!!
        avg_loss += (d_loss + g_loss)

    ## Epoch
    # Print out log info

    summary = {
        'avg_loss': avg_loss / in_data_size,
        'lr': optim.get_lr_at_epoch(op_cfg, cur_epoch),
        'epoch': cur_epoch,
        'real_feature': real_feature,
        'real_target': real_target,
    }

    return summary
Пример #6
0
def main(cfg):
    # basic settings
    loss_F = torch.nn.CrossEntropyLoss()
    gpu_nums = int(cfg['NUM_GPUS'])
    if gpu_nums == 0:
        use_cuda = False
    else:
        use_cuda = True

    # load model
    model = AnyNet(cfg)
    if use_cuda:
        model = torch.nn.DataParallel(model, device_ids=[0])
        model = model.cuda()

    # load_dataset
    Trainpath   = cfg['TRAIN']['PATH']
    RESIZE_SIZE = cfg['TRAIN']['IM_SIZE']
    train_data  = SingleDataset(Trainpath, split='train', resize_size=RESIZE_SIZE)
    train_loader= DataLoader(dataset=train_data, batch_size=cfg['TRAIN']['BATCH_SIZE'],
                             shuffle=True, num_workers=cfg['DATA_LOADER']['NUM_WORKERS'], pin_memory=True)

    Testpath    = cfg['TEST']['PATH']
    RESIZE_SIZE_val = cfg['TEST']['IM_SIZE']
    test_data   = SingleDataset(Testpath, split='val', resize_size=RESIZE_SIZE_val)
    test_loader = DataLoader(dataset=test_data, batch_size=cfg['TEST']['BATCH_SIZE'],
                             shuffle=False, num_workers=cfg['DATA_LOADER']['NUM_WORKERS'], pin_memory=True)

    # optimizer and loss function and evaluator
    if cfg['OPTIM']['OPTIMIZER'] == 'Adam':
        optimizer = torch.optim.Adam(model.parameters(), lr=cfg['OPTIM']['BASE_LR'], weight_decay=1e-4)
    else:
        optimizer = torch.optim.SGD(model.parameters(), lr=cfg['OPTIM']['BASE_LR'], momentum=0.9, weight_decay=5e-4)

    # load checkpoint or initial weights
    start_epoch = 0
    if cfg['TRAIN']['RESUME'] is not None:
        resume = cfg['TRAIN']['RESUME']
        if not os.path.isfile(resume):
            raise RuntimeError("=> no checkpoint found at '{}'".format(resume))
        checkpoint_epoch = cp.load_checkpoint(resume, gpu_num=gpu_nums, model=model, optimizer=optimizer)
        start_epoch = checkpoint_epoch + 1
    elif cfg['TRAIN']['WEIGHTS']:
        cp.load_checkpoint(cfg['TRAIN']['WEIGHTS'], gpu_nums, model)
    else:
        init_weights(model, zero_init_gamma=cfg['BN']['ZERO_INIT_FINAL_GAMMA'])

    # save training process
    log_file = log_g.get_log_filename(os.path.join(cfg['OUT_DIR'], 'log/'))
    log = open(log_file, 'w+')

    # start training
    max_epoch   = cfg['OPTIM']['MAX_EPOCH']
    batch_size  = cfg['TRAIN']['BATCH_SIZE']
    eval_period = cfg['TRAIN']['EVAL_PERIOD']
    batch_count = 0
    total_step  = len(train_loader)
    num_class   = cfg['MODEL']['NUM_CLASSES']
    # correct_all = list(0. for i in range(cfg['MODEL']['NUM_CLASSES']))
    # total_all   = list(0. for i in range(cfg['MODEL']['NUM_CLASSES']))
    for epoch in range(start_epoch, max_epoch):
        print('**************train --%d-- **************' % (epoch))
        log.write('**************train --%d-- **************\n' % (epoch))

        # update learning rate
        lr = optim.get_epoch_lr(epoch_i=epoch, cfg=cfg)
        optim.set_lr(optimizer, lr)

        #############################################################################
        # start training an epoch
        #############################################################################
        model.train()
        c_train = 0
        t_train = 0
        for i, (img, lbl) in enumerate(train_loader):
            batch_count += 1

            # use cuda
            if use_cuda:
                img, lbl = img.cuda(), lbl.cuda()

            # forward
            preds = model(img)
            loss = loss_F(preds, lbl)

            # backward
            # optimizer.zero_grad()
            loss.backward()
            # optimizer.step()
            torch.nn.utils.clip_grad_norm_(model.parameters(), 5.0)
            if (batch_count % batch_size) == 0:
                optimizer.step()
                optimizer.zero_grad()
                batch_count = 0

            _, predicted = preds.max(1)
            c_train += predicted.eq(lbl).sum().item()
            t_train += lbl.size(0)

            # print epoch, step, loss, lr
            print('[%s]--train: %d/%d\tstep:%d/%d----lr:%.5f---loss:%.4f---Acc:%.3f' % (
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                (epoch + 1), max_epoch, (i + 1), total_step, lr, loss.item(), 100*(c_train/t_train)))
            log.write('[%s]--train: [%d/%d]\tstep: [%d/%d]\t----lr:%.5f---loss:%.4f---Acc:%.3f\n' %(
                      datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                      (epoch + 1), max_epoch, (i + 1), total_step, lr, loss.item(), 100*(c_train/t_train)))


        #############################################################################
        # start validation
        #############################################################################
        if ((epoch+1) % eval_period == 0):
            print('**************validation --%d-- **************' % ((epoch + 1) // eval_period))
            model.eval()
            mean_loss_val = 0
            correct = np.zeros((num_class))
            total = np.zeros((num_class))
            top1_acc_sum = []
            with torch.no_grad():
                for val_epoch, (img_val, lbl_val) in enumerate(test_loader):
                    if use_cuda:
                        img_val, lbl_val = img_val.cuda(), lbl_val.cuda()

                    # predict
                    preds_val = model(img_val)

                    # calculate loss
                    loss_val  = loss_F(preds_val, lbl_val)
                    mean_loss_val += loss_val.item()

                    # evaluation
                    top1_acc, top2_acc = Evaluator.accuracy(preds_val, lbl_val, [1,2])
                    correct_i, total_i = Evaluator.accuracy_perclass(preds_val, lbl_val, num_class)
                    correct += correct_i
                    total   += total_i
                    top1_acc_sum.append(top1_acc)

                    print('[%s]--valid: [%d/%d]\tloss: %.4f---top1_acc: %.3f' % (
                        datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                        val_epoch, len(test_loader), loss_val.item(), top1_acc.item()))
                print('[{}]--valid: [{}]\tmean_loss: {}\ttop1_acc: {}\tper_class_acc: {}'.format(
                    datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                    (epoch + 1), (mean_loss_val / len(test_loader)), np.mean(top1_acc_sum), 100*(correct/total)))
                # save log
                log.write('[{}]--valid: [{}]\tmean_loss: {}\ttop1_acc: {}\tper_class_acc: {}\n'.format(
                    datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                    (epoch + 1), (mean_loss_val / val_epoch), np.mean(top1_acc_sum), 100*(correct/total)))


        #############################################################################
        # save model
        #############################################################################
        if ((epoch+1)%5==0):
            checkpoint_file = os.path.join(cfg['OUT_DIR'], 'checkpoint/')
            checkpoint_filename = cp.save_checkpoint(model, optimizer, epoch, gpu_nums, checkpoint_file)
            log.write('[{}]--save checkpoint: {}\n'.format(
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                checkpoint_filename
            ))

    log.close()