Exemplo n.º 1
0
def predict(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    if prep_config["test_10crop"]:
        prep_dict["database"] = prep.image_test_10crop( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
        prep_dict["test"] = prep.image_test_10crop( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
    else:
        prep_dict["database"] = prep.image_test( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
        prep_dict["test"] = prep.image_test( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
               
    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["database"+str(i)] = ImageList(open(data_config["database"]["list_path"]).readlines(), \
                                transform=prep_dict["database"]["val"+str(i)])
            dset_loaders["database"+str(i)] = util_data.DataLoader(dsets["database"+str(i)], \
                                batch_size=data_config["database"]["batch_size"], \
                                shuffle=False, num_workers=4)
            dsets["test"+str(i)] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"]["val"+str(i)])
            dset_loaders["test"+str(i)] = util_data.DataLoader(dsets["test"+str(i)], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)

    else:
        dsets["database"] = ImageList(open(data_config["database"]["list_path"]).readlines(), \
                                transform=prep_dict["database"])
        dset_loaders["database"] = util_data.DataLoader(dsets["database"], \
                                batch_size=data_config["database"]["batch_size"], \
                                shuffle=False, num_workers=4)
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"])
        dset_loaders["test"] = util_data.DataLoader(dsets["test"], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)
    ## set base network
    base_network = torch.load(config["snapshot_path"])

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        base_network = base_network.cuda()

    database_codes, database_labels = code_predict(dset_loaders, base_network, "database", test_10crop=prep_config["test_10crop"], gpu=use_gpu)
    test_codes, test_labels = code_predict(dset_loaders, base_network, "test", test_10crop=prep_config["test_10crop"], gpu=use_gpu)

    return {"database_code":database_codes.numpy(), "database_labels":database_labels.numpy(), \
            "test_code":test_codes.numpy(), "test_labels":test_labels.numpy()}
Exemplo n.º 2
0
def run(config,path):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop(**config["prep"]['params'])
    else:
        prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    train_bs = 34
    test_bs = 34
    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
                                        shuffle=True, num_workers=0, drop_last=True)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
                                        shuffle=True, num_workers=0, drop_last=True)
    dset_loaders["test1"] = DataLoader(dsets["target"], batch_size=train_bs, \
                                        shuffle=False, num_workers=1, drop_last=False)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test"] = [ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                       transform=prep_dict["test"][i]) for i in range(10)]
            dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \
                                               shuffle=False, num_workers=0) for dset in dsets['test']]
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                  transform=prep_dict["test"])
        dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                          shuffle=False, num_workers=0)

    n_class = config["network"]["params"]["class_num"]
    # for p in [499,999,1499,1999,2499,2999]:
    #     PATH = path + '/'+ str(p) + '_model.pth.tar'
    #
    #     model = load_model(PATH)
    #     base_network = model.cuda()
    #     fun1(dset_loaders, base_network, n_class)

    PATH = path+'/2999_model.pth.tar'

    model = load_model(PATH)
    base_network = model.cuda()
    # homo_cl = train_homo_cl(dset_loaders, base_network)

    fun1(dset_loaders, base_network, n_class, dsets)
Exemplo n.º 3
0
def perform_operation(file_path):
    torch.no_grad()
    e_net.eval()
    a_net.eval()
    s_net.eval()
    fusion.eval()

    imDataset = ImageList(crop_size=args.IM_SIZE, path=file_path, img_path=args.img_path, NUM_CLASS=args.NUM_CLASS,
              phase='test', transform=prep.image_test(crop_size=args.IM_SIZE),
              target_transform=prep.land_transform(img_size=args.IM_SIZE))
    imDataLoader = torch.utils.data.DataLoader(imDataset, batch_size=args.Test_BATCH, num_workers=0)

    pbar = tqdm(total=len(imDataLoader))
    for batch_Idx, data in enumerate(imDataLoader):

        datablob, datalb, pos_para = data
        datablob = torch.autograd.Variable(datablob).cuda()
        y_lb = torch.autograd.Variable(datalb).view(datalb.size(0), -1).cuda()
        pos_para = torch.autograd.Variable(pos_para).cuda()

        pred_global = e_net(datablob)
        feat_data = e_net.predict_BN(datablob)
        pred_att_map, pred_conf = a_net(feat_data)
        slice_feat_data = prep_model_input(pred_att_map, pos_para)
        pred_local = s_net(slice_feat_data)
        cls_pred = fusion(pred_global + pred_local)

        cls_pred = cls_pred.data.cpu().float()
        y_lb = y_lb.data.cpu().float()

        if batch_Idx == 0:
            all_output = cls_pred
            all_label = y_lb
        else:
            all_output = torch.cat((all_output, cls_pred), 0)
            all_label = torch.cat((all_label, y_lb), 0)
        pbar.update()

    pbar.close()
    all_acc_scr = get_acc(all_output, all_label)
    all_f1_score = get_f1(all_output, all_label)

    print('f1 score: ', str(all_f1_score.numpy().tolist()))
    print('average f1 score: ', str(all_f1_score.mean().numpy().tolist()))
    print('acc score: ', str(all_acc_scr.numpy().tolist()))
    print('average acc score: ', str(all_acc_scr.mean().numpy().tolist()))
Exemplo n.º 4
0
def train(config):
    # set pre-process
    prep_dict = {'source': prep.image_train(**config['prep']['params']),
                 'target': prep.image_train(**config['prep']['params'])}
    if config['prep']['test_10crop']:
        prep_dict['test'] = prep.image_test_10crop(**config['prep']['params'])
    else:
        prep_dict['test'] = prep.image_test(**config['prep']['params'])

    # prepare data
    data_set = {}
    data_set_loader = {}
    data_config = config['data']
    data_set['source'] = ImageList(open(data_config['source']['list_path']).readlines(),
                                   transform=prep_dict['source'])
    data_set_loader['source'] = torch.utils.data.DataLoader(data_set['source'],
                                                            batch_size=data_config['source']['batch_size'],
                                                            shuffle=True, num_workers=4, drop_last=True)
    data_set['target'] = ImageList(open(data_config['target']['list_path']).readlines(),
                                   transform=prep_dict['target'])
    data_set_loader['target'] = torch.utils.data.DataLoader(data_set['target'],
                                                            batch_size=data_config['target']['batch_size'],
                                                            shuffle=True, num_workers=4, drop_last=True)
    if config['prep']['test_10crop']:
        data_set['test'] = [ImageList(open(data_config['test']['list_path']).readlines(),
                                      transform=prep_dict['test'][i])
                            for i in range(10)]
        data_set_loader['test'] = [torch.utils.data.DataLoader(dset, batch_size=data_config['test']['batch_size'],
                                                               shuffle=False, num_workers=4)
                                   for dset in data_set['test']]
    else:
        data_set['test'] = ImageList(open(data_config['test']['list_path']).readlines(),
                                     transform=prep_dict['test'])
        data_set_loader['test'] = torch.utils.data.DataLoader(data_set['test'],
                                                              batch_size=data_config['test']['batch_size'],
                                                              shuffle=False, num_workers=4)

    # set base network
    net_config = config['network']
    base_net = net_config['name']()  # res50
    base_net = base_net.cuda()
    # add domain, classifier network
    class_num = config['network']['params']['class_num']
    ad_net = network.Domain(in_features=base_net.output_num(), hidden_size=1024)
    f1_net = network.Classifier(in_features=base_net.output_num(), hidden_size=128, class_num=class_num)
    f2_net = network.Classifier(in_features=base_net.output_num(), hidden_size=128, class_num=class_num)
    ad_net = ad_net.cuda()
    f1_net = f1_net.cuda()
    f2_net = f2_net.cuda()
    parameter_list = base_net.get_parameters() + ad_net.get_parameters() \
                     + f1_net.get_parameters() + f2_net.get_parameters()

    # multi gpus
    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        base_net = nn.DataParallel(base_net, device_ids=[int(i) for i in gpus])
        f1_net = nn.DataParallel(f1_net, device_ids=[int(i) for i in gpus])
        f2_net = nn.DataParallel(f2_net, device_ids=[int(i) for i in gpus])
        ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus])

    # set optimizer
    optimizer_config = config['optimizer']
    optimizer = optimizer_config['type'](parameter_list, **(optimizer_config['optim_params']))
    schedule_param = optimizer_config['lr_param']
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config['lr_type']]

    # set loss
    class_criterion = nn.CrossEntropyLoss()
    transfer_criterion = nn.BCELoss()
    loss_params = config['loss']

    # train
    len_train_source = len(data_set_loader['source'])
    len_train_taget = len(data_set_loader['target'])
    best_acc = 0.0
    since = time.time()
    for num_iter in tqdm(range(config['max_iter'])):
        if num_iter % config['val_iter'] == 0:
            base_net.train(False)
            f1_net.train(False)
            f2_net.train(False)
            temp_acc = val(data_set_loader, base_net, f1_net, f2_net,
                           test_10crop=config['prep']['test_10crop'],
                           config=config, num_iter=num_iter)
            if temp_acc > best_acc:
                best_acc = temp_acc
            log_str = 'iter: {:d}, accu: {:.4f}\ntime: {:.4f}'.format(num_iter, temp_acc, time.time() - since)
            config['logger'].logger.debug(log_str)
            config['results'][num_iter].append(temp_acc)
        if num_iter % config['snapshot_iter'] == 0:
            # TODO
            pass

        base_net.train(True)
        f1_net.train(True)
        f2_net.train(True)
        ad_net.train(True)

        optimizer = lr_scheduler(optimizer, num_iter, **schedule_param)
        optimizer.zero_grad()

        if num_iter % len_train_source == 0:
            iter_source = iter(data_set_loader['source'])
        if num_iter % len_train_taget == 0:
            iter_target = iter(data_set_loader['target'])
        input_source, label_source = iter_source.next()
        input_target, _ = iter_target.next()
        input_source, label_source, input_target = input_source.cuda(), label_source.cuda(), input_target.cuda()
        inputs = torch.cat((input_source, input_target), 0)
        batch_size = len(label_source)

        # class-wise adaptation
        features = base_net(inputs)
        alpha = 2. / (1. + np.exp(-10 * float(num_iter / config['max_iter']))) - 1
        output1 = f1_net(features, alpha)
        output2 = f2_net(features, alpha)
        output_s1 = output1[:batch_size, :]
        output_s2 = output2[:batch_size, :]
        output_t1 = output1[batch_size:, :]
        output_t2 = output2[batch_size:, :]
        output_t1 = F.softmax(output_t1)
        output_t2 = F.softmax(output_t2)

        inconsistency_loss = torch.mean(torch.abs(output_t1 - output_t2))
        classifier_loss1 = class_criterion(output_s1, label_source)
        classifier_loss2 = class_criterion(output_s2, label_source)
        classifier_loss = classifier_loss1 + classifier_loss2

        # domain-wise adaptation
        domain_labels = torch.from_numpy(np.array([[1]] * batch_size + [[0]] * batch_size)).float().cuda()
        domain_output = ad_net(features, alpha)
        transfer_loss = transfer_criterion(domain_output, domain_labels)

        total_loss = classifier_loss + loss_params['domain_off'] * transfer_loss \
                     - loss_params['dis_off'] * inconsistency_loss
        total_loss.backward()
        optimizer.step()

        if num_iter % config['val_iter'] == 0:
            print('class:', classifier_loss.item(),
                  'domain:', transfer_loss.item() * loss_params['domain_off'],
                  'inconsistency:', inconsistency_loss.item() * loss_params['dis_off'],
                  'total:', total_loss.item())
            if config['is_writer']:
                config['writer'].add_scalars('train', {'total': total_loss.item(), 'class': classifier_loss.item(),
                                                       'domain': transfer_loss.item() * loss_params['domain_off'],
                                                       'inconsistency': inconsistency_loss.item() * loss_params[
                                                           'dis_off']},
                                             num_iter)
    if config['is_writer']:
        config['writer'].close()

    return best_acc
Exemplo n.º 5
0
def train(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop(**config["prep"]['params'])
    else:
        prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    train_bs = data_config["source"]["batch_size"]
    test_bs = data_config["test"]["batch_size"]
    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
                                        shuffle=True, num_workers=4, drop_last=True)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
                                        shuffle=True, num_workers=4, drop_last=True)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test"] = [ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"][i]) for i in range(10)]
            dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \
                                shuffle=False, num_workers=4) for dset in dsets['test']]
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"])
        dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                shuffle=False, num_workers=4)

    class_num = config["network"]["params"]["class_num"]

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])
    base_network = base_network.cuda()  #加载基础网络结构
    parameter_list = base_network.get_parameters()
    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                                         **(optimizer_config["optim_params"]))

    crit = LabelSmoothingLoss(smoothing=0.1, classes=31)  #标签平滑操作

    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        base_network = nn.DataParallel(base_network,
                                       device_ids=[int(i) for i in gpus])

    ## train
    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])
    best_acc = 0.0
    start_time = time.time()
    for i in range(config["num_iterations"]):
        if i % config["test_interval"] == config["test_interval"] - 1:
            # 在这里进行测试的工作
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders,
                                                 base_network,
                                                 test_10crop=False)
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            print(log_str)
            end_time = time.time()
            print('iter {} cost time {:.4f} sec.'.format(
                i, end_time - start_time))  # 打印时间间隔
            start_time = time.time()

        if i % config["snapshot_interval"] == 0:
            torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \
                                                             "iter_{:05d}_model.pth.tar".format(i)))
        ## train one iter
        base_network.train(True)  # 训练模式
        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()

        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])

        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        inputs_source, inputs_target, labels_source = inputs_source.cuda(
        ), inputs_target.cuda(), labels_source.cuda()
        features_source, outputs_source = base_network(inputs_source)
        features_target, outputs_target = base_network(inputs_target)
        #目标域的熵正则化操作
        t_logit = outputs_target
        t_prob = F.softmax(t_logit)
        t_entropy_loss = get_entropy_loss(t_prob)  # 计算目标域的熵的损失
        entropy_loss = config['ENT_w'] * (t_entropy_loss)

        # classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)  # 源域的分类损失
        classifier_loss = crit(outputs_source, labels_source)

        total_loss = classifier_loss + entropy_loss
        if i % config["test_interval"] == config["test_interval"] - 1:
            print('total loss: {:.4f}, classifier loss: {:.4f}'.format(
                total_loss.item(), classifier_loss.item()))

        total_loss.backward()
        optimizer.step()
        if (i + 1) % 1000 == 0:
            model_path = os.path.join(
                os.path.dirname(config['save_model_name']), 'temp_model.pth')
            save_model(base_network, model_path)

    model_path = config['save_model_name']
    best_model_path = os.path.join(os.path.dirname(model_path),
                                   'best_model.pth')
    save_model(base_network, model_path)
    save_model(best_model, best_model_path)

    torch.save(best_model, osp.join(config["output_path"],
                                    "best_model.pth.tar"))
    return best_acc
Exemplo n.º 6
0
np.random.seed(args.seed)
torch.manual_seed(args.seed)
# torch.backends.cudnn.deterministic = True
# torch.backends.cudnn.benchmark = False
os.system("clear")

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

dataset = flickr.Flickr()
# loop_train = dataset.loop_set("labeled", shuffle=True)
C = dataset.load_centre().cuda()  # [c, #bit]
C_random = torch.randint_like(C[0], 2) * 2 - 1  # {-1, 1}
N_TRAIN = dataset.count("labeled")

train_transform = prep.image_train(resize_size=255, crop_size=224)
test_transform = prep.image_test(resize_size=255, crop_size=224)

if args.model_type == 'resnet50' or args.model_type == 'resnet152':
    model = Model().cuda()
elif args.model_type == 'alexnet':
    model = AlexNetFc().cuda()
# model = model.to(device)
# model = torch.nn.DataParallel(model).cuda()

bce_loss = nn.BCELoss().cuda()
#criterion = nn.MSELoss().cuda()
params_list = [
    {
        'params': model.feature_layers.parameters(),
        'lr': args.lrp * args.lr
    },  # 0.05*(args.lr)
Exemplo n.º 7
0
def transfer_classification(config):
    # ---set log writer ---
    writer = SummaryWriter(log_dir=config["log_dir"])
    # set pre-process
    prep_dict = {}
    for prep_config in config["prep"]:
        name = prep_config["name"]
        prep_dict[name] = {}
        if prep_config["type"] == "image":
            prep_dict[name]["test_10crop"] = prep_config["test_10crop"]
            prep_dict[name]["train"] = prep.image_train(resize_size=prep_config["resize_size"], crop_size=prep_config["crop_size"])
            if prep_config["test_10crop"]:
                prep_dict[name]["test"] = prep.image_test_10crop(resize_size=prep_config["resize_size"], crop_size=prep_config["crop_size"])
            else:
                prep_dict[name]["test"] = prep.image_test(resize_size=prep_config["resize_size"], crop_size=prep_config["crop_size"])
    # print(prep_dict)

    ## set loss
    class_criterion = nn.CrossEntropyLoss()
    loss_config = config["loss"]
    # transfer_criterion = loss.loss_dict[loss_config["name"]]
    if "params" not in loss_config:
        loss_config["params"] = {}
    # print(transfer_criterion)
    transfer_criterion = DANLoss(**loss_config["params"])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    for data_config in config["data"]:
        name = data_config['name']
        dsets[name] = {}
        dset_loaders[name] = {}
        ## image data
        if data_config["type"] == "image":
            dsets[name]["train"] = ImageList(open(data_config["list_path"]["train"]).readlines(), 
                                                            transform=prep_dict[name]["train"])
            dset_loaders[name]["train"] = util_data.DataLoader(dsets[name]["train"], 
                                                                batch_size=data_config["batch_size"]["train"], 
                                                                shuffle=True, num_workers=4)
            if "test" in data_config["list_path"]:
                if prep_dict[name]["test_10crop"]:
                    for i in range(10):
                        dsets[name]["test" + str(i)] = ImageList(
                            open(data_config["list_path"]["test"]).readlines(),
                            transform=prep_dict[name]["test"]["val" + str(i)])
                        dset_loaders[name]["test" + str(i)] = util_data.DataLoader(
                            dsets[name]["test" + str(i)], batch_size=data_config["batch_size"]["test"],
                            shuffle=False, num_workers=4)
                else:
                    dsets[name]["test"] = ImageList(
                        open(data_config["list_path"]["test"]).readlines(),
                        transform=prep_dict[name]["test"])
                    dset_loaders[name]["test"] = util_data.DataLoader(
                        dsets[name]["test"], batch_size = data_config["batch_size"]["test"],
                        shuffle=False, num_workers=4)
            else:
                if prep_dict[name]["test_10crop"]:
                    for i in range(10):
                        dsets[name]["test" + str(i)] = ImageList(
                            open(data_config["list_path"]["train"]).readlines(),
                            transform=prep_dict[name]["test"]["val" + str(i)])
                        dset_loaders[name]["test" + str(i)] = util_data.DataLoader(
                            dsets[name]["test" + str(i)], batch_size=data_config["batch_size"]["test"],
                            shuffle=False, num_workers=4)
                else:
                    dsets[name]["test"] = ImageList(open(data_config["list_path"]["train"]).readlines(),
                                                                   transform=prep_dict[name]["test"])
                    dset_loaders[data_config["name"]]["test"] = util_data.DataLoader(
                        dsets[data_config["name"]]["test"], batch_size=data_config["batch_size"]["test"],
                        shuffle=False, num_workers=4)

    class_num = 31

    ## set base network
    net_config = config["network"]
    base_network = network.network_dict[net_config["name"]]()
    if net_config["use_bottleneck"]:
        bottleneck_layer = nn.Linear(base_network.output_num(), net_config["bottleneck_dim"])
        classifier_layer = nn.Linear(bottleneck_layer.out_features, class_num)
    else:
        classifier_layer = nn.Linear(base_network.output_num(), class_num)

    ## initialization
    if net_config["use_bottleneck"]:
        bottleneck_layer.weight.data.normal_(0, 0.005)
        bottleneck_layer.bias.data.fill_(0.1)
        bottleneck_layer = nn.Sequential(bottleneck_layer, nn.ReLU(), nn.Dropout(0.5))
    classifier_layer.weight.data.normal_(0, 0.01)
    classifier_layer.bias.data.fill_(0.0)

    # print(base_network.state_dict())
    # print(classifier_layer.state_dict())

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        if net_config["use_bottleneck"]:
            bottleneck_layer = bottleneck_layer.to(device)
        classifier_layer = classifier_layer.to(device)
        base_network = base_network.to(device)


    ## collect parameters
    if net_config["use_bottleneck"]:
        parameter_list = [{"params":base_network.parameters(), "lr":1}, 
                          {"params":bottleneck_layer.parameters(), "lr":10}, 
                          {"params":classifier_layer.parameters(), "lr":10}]
       
    else:
        parameter_list = [{"params":base_network.parameters(), "lr":1}, 
                          {"params":classifier_layer.parameters(), "lr":10}]

    ## add additional network for some methods
    if loss_config["name"] == "JAN":
        softmax_layer = nn.Softmax()
        if use_gpu:
            softmax_layer = softmax_layer.to(device)
           
 
    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](parameter_list, **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]


    ## train
    len_train_source = len(dset_loaders["source"]["train"]) - 1
    len_train_target = len(dset_loaders["target"]["train"]) - 1
    # transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    for i in range(config["num_iterations"]):
        # test in the train
        if i % config["test_interval"] == 0:
            base_network.train(False)
            classifier_layer.train(False)
            if net_config["use_bottleneck"]:
                bottleneck_layer.train(False)
                test_model = nn.Sequential(base_network, bottleneck_layer, classifier_layer)
                test_acc = image_classification_test(dset_loaders["target"],
                    test_model,
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)
                print("iteration: %d, test accuracy: %f" % (i, test_acc))

            else:
                test_model = nn.Sequential(base_network, classifier_layer)
                test_acc = image_classification_test(dset_loaders["target"],
                    test_model,
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)
                print("iteration: %d, test accuracy: %f" % (i, test_acc))
            # save model parameters
            if i % config["checkpoint_iterval"] == 0:
                torch.save(test_model.state_dict(), config["checkpoint_dir"]+"checkpoint_"+str(i).zfill(5)+".pth")

        # loss_test = nn.BCELoss()
        # train one iter
        base_network.train(True)
        if net_config["use_bottleneck"]:
            bottleneck_layer.train(True)
        classifier_layer.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"]["train"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"]["train"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        
        inputs_source = inputs_source.to(device)
        inputs_target = inputs_target.to(device)
        labels_source = labels_source.to(device)
          
        inputs = torch.cat((inputs_source, inputs_target), dim=0) ### cat the source and target 
        features = base_network(inputs)
        if net_config["use_bottleneck"]:
            features = bottleneck_layer(features)

        outputs = classifier_layer(features)

        # split the output for different loss
        num = inputs.size(0)//2
        # the premise is the batch size of source and target is the same
        classifier_loss = class_criterion(outputs.narrow(0, 0, num), labels_source)
        ## switch between different transfer loss
        if loss_config["name"] == "DAN":
            # transfer_loss = transfer_criterion(features.narrow(0, 0, num),
            #                                    features.narrow(0, num, num),
            #                                    **loss_config["params"])

            transfer_loss = transfer_criterion(features.narrow(0, 0, num),
                                               features.narrow(0, num, num))
        elif loss_config["name"] == "RTN":
            ## RTN is still under developing
            transfer_loss = 0
        elif loss_config["name"] == "JAN":
            softmax_out = softmax_layer(outputs)
            transfer_loss = transfer_criterion([features.narrow(0, 0, num), softmax_out.narrow(0, 0, num)],
                                               [features.narrow(0, num, num), softmax_out.narrow(0, num, num)],
                                               **loss_config["params"])

        total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss
        if i % 100 == 0:
            print("iteration: ", str(i), "\t transfer loss: ", str(transfer_loss.item()),
                  "\t classification loss: ", str(classifier_loss.item()),
                  "\t total loss: ", str(total_loss.item()))
            for param_group in optimizer.param_groups:
                print("lr: ", param_group["lr"])
            # log for losses
            writer.add_scalar('Train/loss_classification', classifier_loss.item(), i//100)
            writer.add_scalar('Train/loss_transfer', transfer_loss.item(), i//100)
            writer.add_scalar('Train/loss_total', total_loss.item(), i//100)
        total_loss.backward()
        optimizer.step()
Exemplo n.º 8
0
def train(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop(**config["prep"]['params'])
    else:
        prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    tensor_writer = SummaryWriter(config["tensorboard_path"])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    train_bs = data_config["source"]["batch_size"]
    test_bs = data_config["test"]["batch_size"]

    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
            shuffle=True, num_workers=4, drop_last=True)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
            shuffle=True, num_workers=4, drop_last=True)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test"] = [ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"][i]) for i in range(10)]
            dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \
                                shuffle=False, num_workers=4) for dset in dsets['test']]
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"])
        dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                shuffle=False, num_workers=4)

    class_num = config["network"]["params"]["class_num"]

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])
    base_network = base_network.cuda()
    parameter_list = base_network.get_parameters()
 
    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                    **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus])

    ## train   
    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])
    best_acc = 0.0
    for i in range(config["num_iterations"]):
        if i % config["test_interval"] == config["test_interval"] - 1 or i==0:
            base_network.train(False)
            temp_acc, output, prediction, label, feature = image_classification_test(dset_loaders, \
                base_network, test_10crop=prep_config["test_10crop"])
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str+"\n")
            config["out_file"].flush()
            print(log_str)
        if i % config["snapshot_interval"] == 0:
            torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \
                "iter_{:05d}_model.pth.tar".format(i)))

        loss_params = config["loss"]                  
        ## train one iter
        base_network.train(True)
        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        inputs_source, inputs_target, labels_source = inputs_source.cuda(), inputs_target.cuda(), labels_source.cuda()
        features_source, outputs_source = base_network(inputs_source)
        features_target, outputs_target = base_network(inputs_target)

        outputs_target_temp = outputs_target / config['temperature']
        target_softmax_out_temp = nn.Softmax(dim=1)(outputs_target_temp)
        target_entropy_weight = loss.Entropy(target_softmax_out_temp).detach()
        target_entropy_weight = 1 + torch.exp(-target_entropy_weight)
        target_entropy_weight = train_bs * target_entropy_weight / torch.sum(target_entropy_weight)
        cov_matrix_t = target_softmax_out_temp.mul(target_entropy_weight.view(-1,1)).transpose(1,0).mm(target_softmax_out_temp)
        cov_matrix_t = cov_matrix_t / torch.sum(cov_matrix_t, dim=1)
        mcc_loss = (torch.sum(cov_matrix_t) - torch.trace(cov_matrix_t)) / class_num

        classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)
        total_loss = classifier_loss + mcc_loss
        total_loss.backward()
        optimizer.step()

        tensor_writer.add_scalar('total_loss', total_loss, i)
        tensor_writer.add_scalar('classifier_loss', classifier_loss, i)
        tensor_writer.add_scalar('cov_matrix_penalty', mcc_loss, i)

    torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar"))
    return best_acc
Exemplo n.º 9
0
def train(config):
    # pre-process training and test data
    prep_dict = {
        'source': prep.image_train(**config['prep']['params']),
        'target': prep.image_train(**config['prep']['params'])
    }
    if config['prep']['test_10crop']:
        prep_dict['test'] = prep.image_test_10crop(**config['prep']['params'])
    else:
        prep_dict['test'] = prep.image_test(**config['prep']['params'])

    data_set = {}
    dset_loaders = {}
    data_config = config['data']
    data_set['source'] = ImageList(open(
        data_config['source']['list_path']).readlines(),
                                   transform=prep_dict['source'])
    dset_loaders['source'] = torch.utils.data.DataLoader(
        data_set['source'],
        batch_size=data_config['source']['batch_size'],
        shuffle=True,
        num_workers=4,
        drop_last=True)
    data_set['target'] = ImageList(open(
        data_config['target']['list_path']).readlines(),
                                   transform=prep_dict['target'])
    dset_loaders['target'] = torch.utils.data.DataLoader(
        data_set['target'],
        batch_size=data_config['target']['batch_size'],
        shuffle=True,
        num_workers=4,
        drop_last=True)
    if config['prep']['test_10crop']:
        data_set['test'] = [
            ImageList(open(data_config['test']['list_path']).readlines(),
                      transform=prep_dict['test'][i]) for i in range(10)
        ]
        dset_loaders['test'] = [
            torch.utils.data.DataLoader(
                dset,
                batch_size=data_config['test']['batch_size'],
                shuffle=False,
                num_workers=4) for dset in data_set['test']
        ]
    else:
        data_set['test'] = ImageList(open(
            data_config['test']['list_path']).readlines(),
                                     transform=prep_dict['test'])
        dset_loaders['test'] = torch.utils.data.DataLoader(
            data_set['test'],
            batch_size=data_config['test']['batch_size'],
            shuffle=False,
            num_workers=4)

    # set base network, classifier network, residual net
    class_num = config['network']['params']['class_num']
    net_config = config['network']
    if net_config['name'] == '50':
        base_network = dcca_resnet50()
    elif net_config['name'] == '101':
        base_network = dcca_resnet101()
    else:
        raise ValueError('base network %s not found!' % (net_config['name']))

    classifier_layer = nn.Linear(2048, class_num)
    # feature residual layer: two fully connected layers
    residual_fc1 = nn.Linear(2048, 2048)
    residual_bn1 = nn.BatchNorm1d(2048)
    residual_fc2 = nn.Linear(2048, 128)
    residual_bn2 = nn.BatchNorm1d(128)
    residual_fc3 = nn.Linear(128, 2048)
    classifier_layer.weight.data.normal_(0, 0.01)
    classifier_layer.bias.data.fill_(0.0)
    residual_fc1.weight.data.normal_(0, 0.005)
    residual_fc1.bias.data.fill_(0.1)
    residual_fc2.weight.data.normal_(0, 0.005)
    residual_fc2.bias.data.fill_(0.1)
    residual_fc3.weight.data.normal_(0, 0.005)
    residual_fc3.bias.data.fill_(0.1)
    feature_residual_layer = nn.Sequential(residual_fc2, nn.ReLU(),
                                           residual_fc3)

    # class residual layer: two fully connected layers
    residual_fc22 = nn.Linear(classifier_layer.out_features,
                              classifier_layer.out_features)
    residual_bn22 = nn.BatchNorm1d(classifier_layer.out_features)
    residual_fc23 = nn.Linear(classifier_layer.out_features,
                              classifier_layer.out_features)
    residual_fc22.weight.data.normal_(0, 0.005)
    residual_fc22.bias.data.fill_(0.1)
    residual_fc23.weight.data.normal_(0, 0.005)
    residual_fc23.bias.data.fill_(0.1)
    class_residual_layer = nn.Sequential(residual_fc22, nn.ReLU(),
                                         residual_fc23)

    base_network = base_network.cuda()
    feature_residual_layer = feature_residual_layer.cuda()
    classifier_layer = classifier_layer.cuda()
    class_residual_layer = class_residual_layer.cuda()
    softmax_layer = nn.Softmax().cuda()

    # set optimizer
    parameter_list = [{
        'params': base_network.parameters(),
        'lr_mult': 1,
        'decay_mult': 2
    }, {
        'params': classifier_layer.parameters(),
        'lr_mult': 10,
        'decay_mult': 2
    }, {
        'params': feature_residual_layer.parameters(),
        'lr_mult': 0.01,
        'decay_mult': 2
    }, {
        'params': class_residual_layer.parameters(),
        'lr_mult': 0.01,
        'decay_mult': 2
    }]
    optimizer_config = config['optimizer']
    optimizer = optimizer_config['type'](parameter_list,
                                         **(optimizer_config['optim_params']))
    schedule_param = optimizer_config['lr_param']
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config['lr_type']]

    # set loss
    class_criterion = nn.CrossEntropyLoss().cuda()
    loss_config = config['loss']
    if 'params' not in loss_config:
        loss_config['params'] = {}

    # train
    len_train_source = len(dset_loaders['source'])
    len_train_target = len(dset_loaders['target'])
    best_acc = 0.0
    since = time.time()
    for num_iter in tqdm(range(config['max_iter'])):
        if num_iter % config['val_iter'] == 0 and num_iter != 0:
            base_network.train(False)
            classifier_layer.train(False)
            feature_residual_layer.train(False)
            class_residual_layer.train(False)
            base_network = nn.Sequential(base_network)
            classifier_layer = nn.Sequential(classifier_layer)
            feature_residual_layer = nn.Sequential(feature_residual_layer)
            class_residual_layer = nn.Sequential(class_residual_layer)
            temp_acc = image_classification_test(
                loader=dset_loaders,
                base_net=base_network,
                classifier_layer=classifier_layer,
                residual_layer1=feature_residual_layer,
                residual_layer2=class_residual_layer,
                test_10crop=config['prep']['test_10crop'],
                config=config,
                num_iter=num_iter)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = {
                    'base': base_network.state_dict(),
                    'classifier': classifier_layer.state_dict(),
                    'feature_residual': feature_residual_layer.state_dict(),
                    'class_residual': class_residual_layer.state_dict()
                }

            log_str = 'iter: {:d}, all_accu: {:.4f},\ttime: {:.4f}'.format(
                num_iter, temp_acc,
                time.time() - since)
            config['logger'].logger.debug(log_str)
            config['results'][num_iter].append(temp_acc)

        # This has any effect only on modules such as Dropout or BatchNorm.
        base_network.train(True)
        classifier_layer.train(True)
        feature_residual_layer.train(True)
        class_residual_layer.train(True)

        # freeze BN layers
        for m in base_network.modules():
            if isinstance(m, nn.BatchNorm2d):
                m.training = False
                m.weight.requires_grad = False
                m.bias.requires_grad = False

        # load data
        if num_iter % len_train_source == 0:
            iter_source = iter(dset_loaders['source'])
        if num_iter % len_train_target == 0:
            iter_target = iter(dset_loaders['target'])
        inputs_source, labels_source = iter_source.next()
        inputs_target, _ = iter_target.next()
        batch_size = len(labels_source)
        inputs_source, inputs_target, labels_source = inputs_source.cuda(
        ), inputs_target.cuda(), labels_source.cuda()

        optimizer = lr_scheduler(optimizer, num_iter / config['max_iter'],
                                 **schedule_param)
        optimizer.zero_grad()

        inputs = torch.cat((inputs_source, inputs_target), dim=0)
        features_base = base_network(inputs)
        features_residual = feature_residual_layer(features_base)
        total_feature_residual = features_base + features_residual

        # source classification loss with original features
        output_base = classifier_layer(features_base)
        classifier_loss = class_criterion(output_base[:batch_size, :],
                                          labels_source)

        # target residual feature entropy loss
        residual_output_base = classifier_layer(total_feature_residual)
        output_residual = class_residual_layer(residual_output_base)
        total_output_residual = residual_output_base + output_residual
        softmax_output_base = softmax_layer(output_base)
        total_softmax_residual = softmax_layer(total_output_residual)
        entropy_loss = EntropyLoss(total_softmax_residual[batch_size:, :])

        # alignment of L task-specific feature layers (Here, we have one layer)
        transfer_loss = MMD(features_base[:batch_size, :],
                            total_feature_residual[batch_size:, :])
        # alignment of softmax layer
        transfer_loss += MMD(softmax_output_base[:batch_size, :],
                             total_softmax_residual[batch_size:, :],
                             kernel_num=1,
                             fix_sigma=1.68)

        source_labels_data = labels_source.data.float()
        sum_reg_loss = 0
        for k in range(class_num):
            source_k_index = []
            for index, source_k in enumerate(source_labels_data):
                # find all indexes of k-th class source samples
                if source_k == k:
                    source_k_index.append(index)
            fea_reg_loss = 0
            out_reg_loss = 0
            if len(source_k_index) > 0:
                # random subset indexes of source samples
                source_rand_index = []
                index = 0
                for z in range(batch_size):
                    prob = random.random()
                    if prob < config['random_prob'] / class_num:
                        source_rand_index.append(index)
                        index += 1

                if len(source_rand_index) > 0:
                    # source feature of k-th class
                    source_k_fea = features_base.index_select(
                        0,
                        torch.tensor(source_k_index, dtype=torch.long).cuda())
                    source_k_out = output_base.index_select(
                        0,
                        torch.tensor(source_k_index, dtype=torch.long).cuda())

                    # random selected source feature
                    source_rand_fea = total_feature_residual.index_select(
                        0,
                        torch.tensor(source_rand_index,
                                     dtype=torch.long).cuda())
                    source_rand_out = total_output_residual.index_select(
                        0,
                        torch.tensor(source_rand_index,
                                     dtype=torch.long).cuda())

                    fea_reg_loss = MMD_reg(source_k_fea, source_rand_fea)
                    out_reg_loss = MMD_reg(source_k_out,
                                           source_rand_out,
                                           kernel_num=1,
                                           fix_sigma=1.68)

            sum_reg_loss += (fea_reg_loss + out_reg_loss)

        total_loss = classifier_loss + \
                     config['loss']['alpha_off'] * (transfer_loss +
                                                    config['loss']['constant_off'] * sum_reg_loss) + \
                     config['loss']['beta_off'] * entropy_loss
        total_loss.backward()
        optimizer.step()

        if num_iter % config['val_iter'] == 0:
            config['logger'].logger.debug(
                'class: {:.4f}\tmmd: {:.4f}\tmmd_seg: {:.4f}\tentropy: {:.4f}'.
                format(classifier_loss.item(), transfer_loss.item(),
                       config['loss']['constant_off'] * sum_reg_loss,
                       entropy_loss.item() * config['loss']['beta_off']))
            if config['is_writer']:
                config['writer'].add_scalars(
                    'train', {
                        'class':
                        classifier_loss.item(),
                        'mmd':
                        transfer_loss.item(),
                        'mmd_seg':
                        config['loss']['constant_off'] * sum_reg_loss.item(),
                        'entropy':
                        config['loss']['beta_off'] * entropy_loss.item()
                    }, num_iter)

    if config['is_writer']:
        config['writer'].close()

    torch.save(
        best_model,
        osp.join(config['path']['model'], config['task'] + '_best_model.pth'))
    return best_acc
Exemplo n.º 10
0
def transfer_classification(config):
    ## set pre-process
    prep_dict = {}
    for prep_config in config["prep"]:
        prep_dict[prep_config["name"]] = {}
        if prep_config["type"] == "image":
            prep_dict[prep_config["name"]]["test_10crop"] = prep_config[
                "test_10crop"]
            prep_dict[prep_config["name"]]["train"] = prep.image_train(
                resize_size=prep_config["resize_size"],
                crop_size=prep_config["crop_size"])
            if prep_config["test_10crop"]:
                prep_dict[
                    prep_config["name"]]["test"] = prep.image_test_10crop(
                        resize_size=prep_config["resize_size"],
                        crop_size=prep_config["crop_size"])
            else:
                prep_dict[prep_config["name"]]["test"] = prep.image_test(
                    resize_size=prep_config["resize_size"],
                    crop_size=prep_config["crop_size"])

    ## set loss
    class_criterion = nn.CrossEntropyLoss()
    loss_config = config["loss"]
    transfer_criterion = loss.loss_dict[loss_config["name"]]
    if "params" not in loss_config:
        loss_config["params"] = {}

    ## prepare data
    dsets = {}
    dset_loaders = {}
    for data_config in config["data"]:
        dsets[data_config["name"]] = {}
        dset_loaders[data_config["name"]] = {}
        ## image data
        if data_config["type"] == "image":
            dsets[data_config["name"]]["train"] = ImageList(
                open(data_config["list_path"]["train"]).readlines(),
                transform=prep_dict[data_config["name"]]["train"])
            dset_loaders[data_config["name"]]["train"] = util_data.DataLoader(
                dsets[data_config["name"]]["train"],
                batch_size=data_config["batch_size"]["train"],
                shuffle=True,
                num_workers=4)
            if "test" in data_config["list_path"]:
                if prep_dict[data_config["name"]]["test_10crop"]:
                    for i in range(10):
                        dsets[data_config["name"]][
                            "test" + str(i)] = ImageList(
                                open(data_config["list_path"]
                                     ["test"]).readlines(),
                                transform=prep_dict[data_config["name"]]
                                ["test"]["val" + str(i)])
                        dset_loaders[data_config["name"]][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[data_config["name"]]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[data_config["name"]]["test"] = ImageList(
                        open(data_config["list_path"]["test"]).readlines(),
                        transform=prep_dict[data_config["name"]]["test"])
                    dset_loaders[
                        data_config["name"]]["test"] = util_data.DataLoader(
                            dsets[data_config["name"]]["test"],
                            batch_size=data_config["batch_size"]["test"],
                            shuffle=False,
                            num_workers=4)
            else:
                if prep_dict[data_config["name"]]["test_10crop"]:
                    for i in range(10):
                        dsets[data_config["name"]][
                            "test" + str(i)] = ImageList(
                                open(data_config["list_path"]
                                     ["train"]).readlines(),
                                transform=prep_dict[data_config["name"]]
                                ["test"]["val" + str(i)])
                        dset_loaders[data_config["name"]][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[data_config["name"]]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[data_config["name"]]["test"] = ImageList(
                        open(data_config["list_path"]["train"]).readlines(),
                        transform=prep_dict[data_config["name"]]["test"])
                    dset_loaders[
                        data_config["name"]]["test"] = util_data.DataLoader(
                            dsets[data_config["name"]]["test"],
                            batch_size=data_config["batch_size"]["test"],
                            shuffle=False,
                            num_workers=4)

    class_num = config["classnum"]

    ## set base network
    net_config = config["network"]
    base_network = network.network_dict[net_config["name"]]()
    if net_config["DAN2"]:
        fc7 = nn.Sequential(nn.ReLU(True), nn.Dropout(), nn.Linear(4096, 4096))
        fc7_relu = nn.Sequential(nn.ReLU(True), nn.Dropout())
    if net_config["use_bottleneck"]:
        bottleneck_layer = nn.Linear(base_network.output_num(),
                                     net_config["bottleneck_dim"])
        classifier_layer = nn.Linear(bottleneck_layer.out_features, class_num)
    else:
        classifier_layer = nn.Linear(base_network.output_num(), class_num)
    for param in base_network.parameters():
        param.requires_grad = False

    ## initialization
    if net_config["use_bottleneck"]:
        bottleneck_layer.weight.data.normal_(0, 0.005)
        bottleneck_layer.bias.data.fill_(0.1)
        bottleneck_layer = nn.Sequential(bottleneck_layer, nn.ReLU(),
                                         nn.Dropout(0.5))

    classifier_layer.weight.data.normal_(0, 0.01)
    classifier_layer.bias.data.fill_(0.0)

    use_gpu = config["use_gpu"]

    if use_gpu:
        if net_config["use_bottleneck"]:
            bottleneck_layer = bottleneck_layer.cuda()

        if net_config["DAN2"]:
            fc7 = fc7.cuda()
            fc7_relu = fc7_relu.cuda()

        classifier_layer = classifier_layer.cuda()
        base_network = base_network.cuda()

    ## collect parameters
    if net_config["use_bottleneck"]:
        parameter_list = [{
            "params": bottleneck_layer.parameters(),
            "lr": 10
        }, {
            "params": classifier_layer.parameters(),
            "lr": 10
        }]

    else:
        parameter_list = [{"params": classifier_layer.parameters(), "lr": 10}]

    ## add additional network for some methods
    if loss_config["name"] == "JAN":
        softmax_layer = nn.Softmax()
        if use_gpu:
            softmax_layer = softmax_layer.cuda()

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](
        parameter_list, **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    ## train
    len_train_source = len(dset_loaders["source"]["train"]) - 1
    len_train_target = len(dset_loaders["target"]["train"]) - 1
    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0

    ## Quyan::HERE needs to add mini-batch------------------------------------------------------------------------------------------------------------------------
    for i in range(config["num_iterations"]):
        ## train one iter
        if net_config["use_bottleneck"]:
            bottleneck_layer.train(True)
        classifier_layer.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"]["train"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"]["train"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        if use_gpu:
            inputs_source, inputs_target, labels_source = Variable(
                inputs_source).cuda(), Variable(
                    inputs_target).cuda(), Variable(labels_source).cuda()
        else:
            inputs_source, inputs_target, labels_source = Variable(
                inputs_source), Variable(inputs_target), Variable(
                    labels_source)

        inputs = torch.cat((inputs_source, inputs_target), dim=0)
        features = base_network(inputs)
        if net_config["use_bottleneck"]:
            features = bottleneck_layer(features)

        if net_config["DAN2"]:
            features2 = fc7(features)
            outputs = classifier_layer(fc7_relu(features2))
        else:
            outputs = classifier_layer(features)

        classifier_loss = class_criterion(
            outputs.narrow(0, 0, int((inputs.size(0) / 2))), labels_source)

        ## switch between different transfer loss
        if loss_config["name"] == "DAN":
            transfer_loss = transfer_criterion(
                features.narrow(0, 0, int(features.size(0) / 2)),
                features.narrow(0, int(features.size(0) / 2),
                                int(features.size(0) / 2)),
                **loss_config["params"])
        elif loss_config["name"] == "RTN":
            ## RTN is still under developing
            transfer_loss = 0
        elif loss_config["name"] == "JAN":
            softmax_out = softmax_layer(outputs)
            transfer_loss = transfer_criterion([
                features.narrow(0, 0, int(features.size(0) / 2)),
                softmax_out.narrow(0, 0, int(softmax_out.size(0) / 2))
            ], [
                features.narrow(0, int(features.size(0) / 2),
                                int(features.size(0) / 2)),
                softmax_out.narrow(0, int(softmax_out.size(0) / 2),
                                   int(softmax_out.size(0) / 2))
            ], **loss_config["params"])

        if net_config["DAN2"]:
            transfer_loss2 = transfer_criterion(
                features2.narrow(0, 0, int(features2.size(0) / 2)),
                features2.narrow(0, int(features2.size(0) / 2),
                                 int(features2.size(0) / 2)),
                **loss_config["params"])

        total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss
        if net_config["DAN2"]:
            total_loss = total_loss + loss_config["trade_off"] * transfer_loss2
        total_loss.backward()
        optimizer.step()

        ## show loss every show_interval

        if (i + 1) % config["show_interval"] == 0 and not (
                i + 1) % config["test_interval"] == 0:
            print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                  "----------------------------------iter=", i + 1,
                  "\nclassifier_loss=", round(float(classifier_loss),
                                              3), " | transfer_loss=",
                  round(float(transfer_loss), 3))

        ## test in the train
        if (i + 1) % config["test_interval"] == 0:
            print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                  "----------------------------------iter=", i + 1,
                  "\nclassifier_loss=", round(float(classifier_loss),
                                              3), " | transfer_loss=",
                  round(float(transfer_loss), 3))
            print("optimizer_param=", optimizer.param_groups)
            base_network.train(False)
            classifier_layer.train(False)
            if net_config["use_bottleneck"]:
                bottleneck_layer.train(False)
                print(
                    "accuracy=",
                    round(
                        image_classification_test(
                            dset_loaders["target"],
                            nn.Sequential(base_network, bottleneck_layer,
                                          classifier_layer),
                            test_10crop=prep_dict["target"]["test_10crop"],
                            gpu=use_gpu), 3))

            else:
                if net_config["DAN2"]:
                    print(
                        "Domain S[" + args.source + "] accuracy=",
                        round(
                            image_classification_test(
                                dset_loaders["source"],
                                nn.Sequential(base_network, fc7, fc7_relu,
                                              classifier_layer),
                                test_10crop=prep_dict["source"]["test_10crop"],
                                gpu=use_gpu), 3))
                    print(
                        "Domain T[" + args.target + "] accuracy=",
                        round(
                            image_classification_test(
                                dset_loaders["target"],
                                nn.Sequential(base_network, fc7, fc7_relu,
                                              classifier_layer),
                                test_10crop=prep_dict["target"]["test_10crop"],
                                gpu=use_gpu), 3))
                else:
                    print(
                        "accuracy=",
                        round(
                            image_classification_test(
                                dset_loaders["target"],
                                nn.Sequential(base_network, classifier_layer),
                                test_10crop=prep_dict["target"]["test_10crop"],
                                gpu=use_gpu), 3))

        loss_test = nn.BCELoss()

        ## Quyan::snap-------------------------------------------------------------------------------------------------------------------------------------------
        if config["snap"]["snap"] and (i + 1) % config["snap"]["step"] == 0:
            # save model
            torch.save(
                base_network, "../model/office/" + config["loss"]["name"] +
                "_" + config["network"]["name"] + "_iter" +
                str(config["num_iterations"]) + ".pkl")
            # torch.save(bottleneck_layer, "../model/office/" + config["loss"]["name"] + "_" + config["network"]["name"] + "_bottleneck_iter" + str(config["num_iterations"]) + ".pkl")
            torch.save(
                classifier_layer, "../model/office/" + config["loss"]["name"] +
                "_" + config["network"]["name"] + "_classifier_iter" +
                str(config["num_iterations"]) + ".pkl")
Exemplo n.º 11
0
def transfer_classification(config):
    ## set pre-process
    prep_dict = {}
    for prep_config in config["prep"]:
        prep_dict[prep_config["name"]] = {}
        if prep_config["type"] == "image":
            prep_dict[prep_config["name"]]["test_10crop"] = prep_config[
                "test_10crop"]
            prep_dict[prep_config["name"]]["train"] = prep.image_train(
                resize_size=prep_config["resize_size"],
                crop_size=prep_config["crop_size"])
            if prep_config["test_10crop"]:
                prep_dict[
                    prep_config["name"]]["test"] = prep.image_test_10crop(
                        resize_size=prep_config["resize_size"],
                        crop_size=prep_config["crop_size"])
            else:
                prep_dict[prep_config["name"]]["test"] = prep.image_test(
                    resize_size=prep_config["resize_size"],
                    crop_size=prep_config["crop_size"])

    ## set loss
    class_criterion = nn.CrossEntropyLoss()

    loss_config = config["loss"]
    transfer_criterion = loss.loss_dict[loss_config["name"]]
    if "params" not in loss_config:
        loss_config["params"] = {}

    ## prepare data
    dsets = {}
    dset_loaders = {}
    for data_config in config["data"]:
        dsets[data_config["name"]] = {}
        dset_loaders[data_config["name"]] = {}
        ## image data
        if data_config["type"] == "image":
            dsets[data_config["name"]]["train"] = ImageList(
                open(data_config["list_path"]["train"]).readlines(),
                transform=prep_dict[data_config["name"]]["train"])
            dset_loaders[data_config["name"]]["train"] = util_data.DataLoader(
                dsets[data_config["name"]]["train"],
                batch_size=data_config["batch_size"]["train"],
                shuffle=True,
                num_workers=4)

            if "test" in data_config["list_path"]:
                if prep_dict[data_config["name"]]["test_10crop"]:
                    for i in range(10):
                        dsets[data_config["name"]][
                            "test" + str(i)] = ImageList(
                                open(data_config["list_path"]
                                     ["test"]).readlines(),
                                transform=prep_dict[data_config["name"]]
                                ["test"]["val" + str(i)])
                        dset_loaders[data_config["name"]][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[data_config["name"]]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[data_config["name"]]["test"] = ImageList(
                        open(data_config["list_path"]["test"]).readlines(),
                        transform=prep_dict[data_config["name"]]["test"])
                    dset_loaders[
                        data_config["name"]]["test"] = util_data.DataLoader(
                            dsets[data_config["name"]]["test"],
                            batch_size=data_config["batch_size"]["test"],
                            shuffle=False,
                            num_workers=4)
            else:
                if prep_dict[data_config["name"]]["test_10crop"]:
                    for i in range(10):
                        dsets[data_config["name"]][
                            "test" + str(i)] = ImageList(
                                open(data_config["list_path"]
                                     ["train"]).readlines(),
                                transform=prep_dict[data_config["name"]]
                                ["test"]["val" + str(i)])
                        dset_loaders[data_config["name"]][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[data_config["name"]]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[data_config["name"]]["test"] = ImageList(
                        open(data_config["list_path"]["train"]).readlines(),
                        transform=prep_dict[data_config["name"]]["test"])
                    dset_loaders[
                        data_config["name"]]["test"] = util_data.DataLoader(
                            dsets[data_config["name"]]["test"],
                            batch_size=data_config["batch_size"]["test"],
                            shuffle=False,
                            num_workers=4)

    class_num = 2

    ## set base network
    net_config = config["network"]
    base_network = network.network_dict[net_config["name"]]()
    if net_config["use_bottleneck"]:
        bottleneck_layer = nn.Linear(base_network.output_num(),
                                     net_config["bottleneck_dim"])
        classifier_layer = nn.Linear(bottleneck_layer.out_features, class_num)
    else:
        classifier_layer = nn.Linear(base_network.output_num(), class_num)
    for param in base_network.parameters():
        param.requires_grad = True

    ## initialization
    if net_config["use_bottleneck"]:
        bottleneck_layer.weight.data.normal_(0, 0.005)
        bottleneck_layer.bias.data.fill_(0.1)
        bottleneck_layer = nn.Sequential(bottleneck_layer, nn.ReLU(),
                                         nn.Dropout(0.5))
    classifier_layer.weight.data.normal_(0, 0.01)
    classifier_layer.bias.data.fill_(0.0)

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        if net_config["use_bottleneck"]:
            bottleneck_layer = bottleneck_layer.cuda()
        classifier_layer = classifier_layer.cuda()
        base_network = base_network.cuda()

    ## collect parameters
    if net_config["use_bottleneck"]:
        parameter_list = [{
            "params": base_network.parameters(),
            "lr": 10
        }, {
            "params": bottleneck_layer.parameters(),
            "lr": 10
        }, {
            "params": classifier_layer.parameters(),
            "lr": 10
        }]

    else:
        parameter_list = [{
            "params": base_network.parameters(),
            "lr": 10
        }, {
            "params": classifier_layer.parameters(),
            "lr": 10
        }]

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](
        parameter_list, **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    ## train
    len_train_source = len(dset_loaders["source"]["train"]) - 1
    len_train_target = len(dset_loaders["target"]["train"]) - 1
    F_best = 0
    mmd_meter = AverageMeter()
    for i in range(config["num_iterations"]):
        ## test in the train
        if i % config["test_interval"] == 0:
            base_network.train(False)
            classifier_layer.train(False)
            if net_config["use_bottleneck"]:
                bottleneck_layer.train(False)
                test_acc, F = image_classification_test(
                    dset_loaders["target"],
                    nn.Sequential(base_network, bottleneck_layer,
                                  classifier_layer),
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)

            else:
                test_acc, F = image_classification_test(
                    dset_loaders["target"],
                    nn.Sequential(base_network, classifier_layer),
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)

            print(args.source + '->' + args.target)
            print('Iter: %d, mmd = %.4f, test_acc = %.3f, f1 score = %.4f' %
                  (i, mmd_meter.avg, test_acc, F))
            mmd_meter.reset()

            if F_best < F:
                F_best = F

        ## train one iter
        if net_config["use_bottleneck"]:
            bottleneck_layer.train(True)
        classifier_layer.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        # optimzer4center = optim.SGD(lmcl_loss.parameters(), lr=0.05)
        # sheduler_4center = lr_scheduler_torch.StepLR(optimizer, 20, gamma=0.5)

        # optimizer.zero_grad()
        # optimzer4center.zero_grad()

        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"]["train"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"]["train"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()

        if use_gpu:
            inputs_source, inputs_target, labels_source = Variable(
                inputs_source).cuda(), Variable(
                    inputs_target).cuda(), Variable(labels_source).cuda()
        else:
            inputs_source, inputs_target, labels_source = Variable(
                inputs_source), Variable(inputs_target), Variable(
                    labels_source)

        inputs = torch.cat((inputs_source, inputs_target), dim=0)
        features = base_network(inputs)
        if net_config["use_bottleneck"]:
            features = bottleneck_layer(features)

        outputs = classifier_layer(features)

        #
        # logits, mlogits = lmcl_loss(outputs.narrow(0, 0, int(inputs.size(0)/2)), labels_source)
        # classifier_loss = class_criterion(mlogits, labels_source)

        classifier_loss = class_criterion(
            outputs.narrow(0, 0, int(inputs.size(0) / 2)), labels_source)

        ## switch between different transfer loss
        if loss_config["name"] == "DAN" or loss_config["name"] == "DAN_Linear":
            transfer_loss = transfer_criterion(
                features.narrow(0, 0, int(features.size(0) / 2)),
                features.narrow(0, int(features.size(0) / 2),
                                int(features.size(0) / 2)),
                **loss_config["params"])

        mmd_meter.update(transfer_loss.item(), inputs_source.size(0))
        # mmd_meter.update(transfer_loss.data[0], inputs_source.size(0))
        total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss
        # total_loss = classifier_loss
        total_loss.backward()
        optimizer.step()

        # optimzer4center.step()
        # sheduler_4center.step()

    print(args.source + '->' + args.target)
    print(F_best)
Exemplo n.º 12
0
def train(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop(**config["prep"]['params'])
    else:
        prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    train_bs = data_config["source"]["batch_size"]
    test_bs = data_config["test"]["batch_size"]
    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
                                        shuffle=True, num_workers=4, drop_last=True)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
                                        shuffle=True, num_workers=4, drop_last=True)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test"] = [ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                       transform=prep_dict["test"][i]) for i in range(10)]
            dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \
                                               shuffle=False, num_workers=4) for dset in dsets['test']]
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                  transform=prep_dict["test"])
        dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                          shuffle=False, num_workers=4)

    class_num = config["network"]["params"]["class_num"]
    crit = LabelSmoothingLoss(smoothing=0.05, classes=class_num)#标签平滑操作

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])
    base_network = base_network.cuda()  # 加载基础网络结构

    ## add additional network for some methods
    if config["loss"]["random"]:
        random_layer = network.RandomLayer([base_network.output_num(), class_num], config["loss"]["random_dim"])
        ad_net = network.AdversarialNetwork(config["loss"]["random_dim"], 1024)
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(base_network.output_num() * class_num, 1024)  # 对抗网络结构
    if config["loss"]["random"]:
        random_layer.cuda()
    ad_net = ad_net.cuda()
    parameter_list = base_network.get_parameters() + ad_net.get_parameters()

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                                         **(optimizer_config["optim_params"]))

    #中心损失函数
    criterion_centor=CenterLoss(num_classes=class_num,feat_dim=256,use_gpu=True)
    optimizer_centerloss=torch.optim.SGD(criterion_centor.parameters(),lr=config['lr'])

    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus])
        base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus])

    ## train
    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])
    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    best_acc = 0.0
    start_time = time.time()
    for i in range(config["num_iterations"]):

        if i % config["test_interval"] == config["test_interval"] - 1:
            # 在这里进行测试的工作
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders, \
                                                 base_network, test_10crop=prep_config["test_10crop"])
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            print(log_str)
            end_time = time.time()
            print('iter {} cost time {:.4f} sec.'.format(i, end_time - start_time))  # 打印时间间隔
            start_time = time.time()

        if i % config["snapshot_interval"] == 0:
            torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \
                                                             "iter_{:05d}_model.pth.tar".format(i)))

        loss_params = config["loss"]

        ## train one iter
        base_network.train(True)  # 训练模式
        ad_net.train(True)

        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        # optimizer_centerloss=lr_scheduler(optimizer_centerloss, i, **schedule_param)

        optimizer.zero_grad()
        optimizer_centerloss.zero_grad()

        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        inputs_source, inputs_target, labels_source = inputs_source.cuda(), inputs_target.cuda(), labels_source.cuda()
        features_source, outputs_source = base_network(inputs_source)
        features_target, outputs_target = base_network(inputs_target)
        features = torch.cat((features_source, features_target), dim=0)
        outputs = torch.cat((outputs_source, outputs_target), dim=0)
        softmax_out = nn.Softmax(dim=1)(outputs)
        if config['method'] == 'CDAN+E':
            entropy = loss.Entropy(softmax_out)
            transfer_loss = loss.CDAN([features, softmax_out], ad_net, entropy, network.calc_coeff(i), random_layer)
        elif config['method'] == 'CDAN':
            transfer_loss = loss.CDAN([features, softmax_out], ad_net, None, None, random_layer)
        elif config['method'] == 'DANN':
            transfer_loss = loss.DANN(features, ad_net)
        else:
            raise ValueError('Method cannot be recognized.')
        # classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)  # 源域的分类损失
        classifier_loss = crit(outputs_source, labels_source)  # 源域的分类损失,标签平滑操作

        # 目标域的熵正则化操作
        outputs_target=outputs[len(inputs_source):,:]
        t_logit = outputs_target
        t_prob = torch.softmax(t_logit,dim=1)
        t_entropy_loss = get_entropy_loss(t_prob)  # 计算目标域的熵的损失
        entropy_loss = 0.05 * (t_entropy_loss)

        # 计算中心损失函数
        loss_centor = criterion_centor(features_source, labels_source)  # 中心损失计算

        total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss + config['centor_w']*loss_centor
        if i % config["test_interval"] == config["test_interval"] - 1:
            print('total loss: {:.4f}, transfer loss: {:.4f}, classifier loss: {:.4f}, centor loss: {:.4f}'.format(
                total_loss.item(),transfer_loss.item(),classifier_loss.item(),config['centor_w']*loss_centor.item()
            ))
        total_loss.backward()
        optimizer.step()
        # by doing so, weight_cent would not impact on the learning of centers
        for param in criterion_centor.parameters():
            param.grad.data *= (1. / config['centor_w'])
        optimizer_centerloss.step()

    torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar"))
    return best_acc
Exemplo n.º 13
0
def train(config):
    ## set pre-process
    prep_dict = {}
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    prep_config = config["prep"]
    if "webcam" in data_config["source"]["list_path"] or "dslr" in data_config[
            "source"]["list_path"]:
        prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    else:
        prep_dict["source"] = prep.image_target(**config["prep"]
                                                ['params'])  #TODO

    if "webcam" in data_config["target"]["list_path"] or "dslr" in data_config[
            "target"]["list_path"]:
        prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    else:
        prep_dict["target"] = prep.image_target(**config["prep"]
                                                ['params'])  #TODO

    prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ### set pre-process
    #prep_dict = {}
    #dsets = {}
    #dset_loaders = {}
    #data_config = config["data"]
    #prep_config = config["prep"]
    #prep_dict["source"] = prep.image_target(**config["prep"]['params'])
    #prep_dict["target"] = prep.image_target(**config["prep"]['params'])
    #prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ## prepare data
    train_bs = data_config["source"]["batch_size"]
    test_bs = data_config["test"]["batch_size"]
    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
            shuffle=True, num_workers=4, drop_last=True)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
            shuffle=True, num_workers=4, drop_last=True)

    dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                            transform=prep_dict["test"])
    dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                shuffle=False, num_workers=4)

    ## set base network
    class_num = config["network"]["params"]["class_num"]
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])
    base_network = base_network.cuda()

    ## set optimizer
    parameter_list = base_network.get_parameters()
    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                    **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    #multi gpu
    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        base_network = nn.DataParallel(
            base_network, device_ids=[int(i) for i, k in enumerate(gpus)])

    ## train
    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])
    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    best_acc = 0.0
    for i in range(config["num_iterations"]):
        #test
        if i % config["test_interval"] == config["test_interval"] - 1:
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders, base_network)
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            print(log_str)
        #save model
        if i % config["snapshot_interval"] == 0 and i:
            torch.save(base_network.state_dict(), osp.join(config["output_path"], \
                "iter_{:05d}_model.pth.tar".format(i)))

        ## train one iter
        base_network.train(True)
        loss_params = config["loss"]
        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()

        #dataloader
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])

        #network
        inputs_source, labels_source = iter_source.next()
        inputs_target, _ = iter_target.next()
        inputs_source, inputs_target, labels_source = inputs_source.cuda(
        ), inputs_target.cuda(), labels_source.cuda()
        features_source, outputs_source = base_network(inputs_source)
        features_target, outputs_target = base_network(inputs_target)
        features = torch.cat((features_source, features_target), dim=0)
        outputs = torch.cat((outputs_source, outputs_target), dim=0)
        softmax_src = nn.Softmax(dim=1)(outputs_source)
        softmax_tgt = nn.Softmax(dim=1)(outputs_target)
        softmax_out = torch.cat((softmax_src, softmax_tgt), dim=0)

        #loss calculation
        classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)
        _, s_tgt, _ = torch.svd(softmax_tgt)
        if config["method"] == "BNM":
            transfer_loss = -torch.mean(s_tgt)
        elif config["method"] == "BFM":
            transfer_loss = -torch.sqrt(
                torch.sum(s_tgt * s_tgt) / s_tgt.shape[0])
        elif config["method"] == "ENT":
            transfer_loss = -torch.mean(
                torch.sum(softmax_tgt * torch.log(softmax_tgt + 1e-8),
                          dim=1)) / torch.log(softmax_tgt.shape[1])
        total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss

        if i % config["print_num"] == 0:
            log_str = "iter: {:05d}, transferloss: {:.5f}, classifier_loss: {:.5f}".format(
                i, transfer_loss, classifier_loss)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            #print(log_str)

        total_loss.backward()
        optimizer.step()
    torch.save(best_model, osp.join(config["output_path"],
                                    "best_model.pth.tar"))
    return best_acc
Exemplo n.º 14
0
def transfer_classification(config):
    # ---set log writer ---
    writer = SummaryWriter(log_dir=config["log_dir"])
    # set pre-process
    prep_dict = {}
    for prep_config in config["prep"]:
        name = prep_config["name"]
        prep_dict[name] = {}
        if prep_config["type"] == "image":
            prep_dict[name]["test_10crop"] = prep_config["test_10crop"]
            prep_dict[name]["train"] = prep.image_train(
                resize_size=prep_config["resize_size"],
                crop_size=prep_config["crop_size"])
            if prep_config["test_10crop"]:
                prep_dict[name]["test"] = prep.image_test_10crop(
                    resize_size=prep_config["resize_size"],
                    crop_size=prep_config["crop_size"])
            else:
                prep_dict[name]["test"] = prep.image_test(
                    resize_size=prep_config["resize_size"],
                    crop_size=prep_config["crop_size"])
    # print(prep_dict)

    ## set loss
    class_criterion = nn.CrossEntropyLoss()
    loss_config = config["loss"]
    # transfer_criterion = loss.loss_dict[loss_config["name"]]
    if "params" not in loss_config:
        loss_config["params"] = {}
    # print(transfer_criterion)
    transfer_criterion = DANLoss(**loss_config["params"])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    for data_config in config["data"]:
        name = data_config['name']
        dsets[name] = {}
        dset_loaders[name] = {}
        ## image data
        if data_config["type"] == "image":
            dsets[name]["train"] = ImageList(
                open(data_config["list_path"]["train"]).readlines(),
                transform=prep_dict[name]["train"])
            dset_loaders[name]["train"] = util_data.DataLoader(
                dsets[name]["train"],
                batch_size=data_config["batch_size"]["train"],
                shuffle=True,
                num_workers=4)
            if "test" in data_config["list_path"]:
                if prep_dict[name]["test_10crop"]:
                    for i in range(10):
                        dsets[name]["test" + str(i)] = ImageList(
                            open(data_config["list_path"]["test"]).readlines(),
                            transform=prep_dict[name]["test"]["val" + str(i)])
                        dset_loaders[name][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[name]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[name]["test"] = ImageList(
                        open(data_config["list_path"]["test"]).readlines(),
                        transform=prep_dict[name]["test"])
                    dset_loaders[name]["test"] = util_data.DataLoader(
                        dsets[name]["test"],
                        batch_size=data_config["batch_size"]["test"],
                        shuffle=False,
                        num_workers=4)
            else:
                if prep_dict[name]["test_10crop"]:
                    for i in range(10):
                        dsets[name]["test" + str(i)] = ImageList(
                            open(
                                data_config["list_path"]["train"]).readlines(),
                            transform=prep_dict[name]["test"]["val" + str(i)])
                        dset_loaders[name][
                            "test" + str(i)] = util_data.DataLoader(
                                dsets[name]["test" + str(i)],
                                batch_size=data_config["batch_size"]["test"],
                                shuffle=False,
                                num_workers=4)
                else:
                    dsets[name]["test"] = ImageList(
                        open(data_config["list_path"]["train"]).readlines(),
                        transform=prep_dict[name]["test"])
                    dset_loaders[
                        data_config["name"]]["test"] = util_data.DataLoader(
                            dsets[data_config["name"]]["test"],
                            batch_size=data_config["batch_size"]["test"],
                            shuffle=False,
                            num_workers=4)

    class_num = 31

    ## set base network
    net_config = config["network"]
    base_network = network.network_dict[net_config["name"]]()
    if net_config["use_bottleneck"]:
        bottleneck_layer = nn.Linear(base_network.output_num(),
                                     net_config["bottleneck_dim"])
        classifier_layer = nn.Linear(bottleneck_layer.out_features, class_num)
    else:
        classifier_layer = nn.Linear(base_network.output_num(), class_num)

    ## initialization
    if net_config["use_bottleneck"]:
        bottleneck_layer.weight.data.normal_(0, 0.005)
        bottleneck_layer.bias.data.fill_(0.1)
        bottleneck_layer = nn.Sequential(bottleneck_layer, nn.ReLU(),
                                         nn.Dropout(0.5))
    classifier_layer.weight.data.normal_(0, 0.01)
    classifier_layer.bias.data.fill_(0.0)

    # print(base_network.state_dict())
    # print(classifier_layer.state_dict())

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        if net_config["use_bottleneck"]:
            bottleneck_layer = bottleneck_layer.to(device)
        classifier_layer = classifier_layer.to(device)
        base_network = base_network.to(device)

    ## collect parameters
    if net_config["use_bottleneck"]:
        parameter_list = [{
            "params": base_network.parameters(),
            "lr": 1
        }, {
            "params": bottleneck_layer.parameters(),
            "lr": 10
        }, {
            "params": classifier_layer.parameters(),
            "lr": 10
        }]

    else:
        parameter_list = [{
            "params": base_network.parameters(),
            "lr": 1
        }, {
            "params": classifier_layer.parameters(),
            "lr": 10
        }]

    ## add additional network for some methods
    if loss_config["name"] == "JAN":
        softmax_layer = nn.Softmax()
        if use_gpu:
            softmax_layer = softmax_layer.to(device)

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](
        parameter_list, **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    ## train
    len_train_source = len(dset_loaders["source"]["train"]) - 1
    len_train_target = len(dset_loaders["target"]["train"]) - 1
    # transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    for i in range(config["num_iterations"]):
        # test in the train
        if i % config["test_interval"] == 0:
            base_network.train(False)
            classifier_layer.train(False)
            if net_config["use_bottleneck"]:
                bottleneck_layer.train(False)
                test_model = nn.Sequential(base_network, bottleneck_layer,
                                           classifier_layer)
                test_acc = image_classification_test(
                    dset_loaders["target"],
                    test_model,
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)
                print("iteration: %d, test accuracy: %f" % (i, test_acc))

            else:
                test_model = nn.Sequential(base_network, classifier_layer)
                test_acc = image_classification_test(
                    dset_loaders["target"],
                    test_model,
                    test_10crop=prep_dict["target"]["test_10crop"],
                    gpu=use_gpu)
                print("iteration: %d, test accuracy: %f" % (i, test_acc))
            # save model parameters
            if i % config["checkpoint_iterval"] == 0:
                torch.save(
                    test_model.state_dict(), config["checkpoint_dir"] +
                    "checkpoint_" + str(i).zfill(5) + ".pth")

        # loss_test = nn.BCELoss()
        # train one iter
        base_network.train(True)
        if net_config["use_bottleneck"]:
            bottleneck_layer.train(True)
        classifier_layer.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"]["train"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"]["train"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()

        inputs_source = inputs_source.to(device)
        inputs_target = inputs_target.to(device)
        labels_source = labels_source.to(device)

        inputs = torch.cat((inputs_source, inputs_target),
                           dim=0)  ### cat the source and target
        features = base_network(inputs)
        if net_config["use_bottleneck"]:
            features = bottleneck_layer(features)

        outputs = classifier_layer(features)

        # split the output for different loss
        num = inputs.size(0) // 2
        # the premise is the batch size of source and target is the same
        classifier_loss = class_criterion(outputs.narrow(0, 0, num),
                                          labels_source)
        ## switch between different transfer loss
        if loss_config["name"] == "DAN":
            # transfer_loss = transfer_criterion(features.narrow(0, 0, num),
            #                                    features.narrow(0, num, num),
            #                                    **loss_config["params"])

            transfer_loss = transfer_criterion(features.narrow(0, 0, num),
                                               features.narrow(0, num, num))
        elif loss_config["name"] == "RTN":
            ## RTN is still under developing
            transfer_loss = 0
        elif loss_config["name"] == "JAN":
            softmax_out = softmax_layer(outputs)
            transfer_loss = transfer_criterion([
                features.narrow(0, 0, num),
                softmax_out.narrow(0, 0, num)
            ], [features.narrow(0, num, num),
                softmax_out.narrow(0, num, num)], **loss_config["params"])

        total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss
        if i % 100 == 0:
            print("iteration: ", str(i), "\t transfer loss: ",
                  str(transfer_loss.item()), "\t classification loss: ",
                  str(classifier_loss.item()), "\t total loss: ",
                  str(total_loss.item()))
            for param_group in optimizer.param_groups:
                print("lr: ", param_group["lr"])
            # log for losses
            writer.add_scalar('Train/loss_classification',
                              classifier_loss.item(), i // 100)
            writer.add_scalar('Train/loss_transfer', transfer_loss.item(),
                              i // 100)
            writer.add_scalar('Train/loss_total', total_loss.item(), i // 100)
        total_loss.backward()
        optimizer.step()
Exemplo n.º 15
0
def train(config):
    base_network = network.ResNetFc('ResNet50', use_bottleneck=True, bottleneck_dim=config["bottleneck_dim"], new_cls=True, class_num=config["class_num"])
    ad_net = network.AdversarialNetwork(config["bottleneck_dim"], config["hidden_dim"])

    base_network = base_network.cuda()
    ad_net = ad_net.cuda()

    parameter_list = base_network.get_parameters() + ad_net.get_parameters()

    source_path = ImageList(open(config["s_path"]).readlines(), transform=preprocess.image_train(resize_size=256, crop_size=224))
    target_path = ImageList(open(config["t_path"]).readlines(), transform=preprocess.image_train(resize_size=256, crop_size=224))
    test_path   = ImageList(open(config["t_path"]).readlines(), transform=preprocess.image_test(resize_size=256, crop_size=224))

    source_loader = DataLoader(source_path, batch_size=config["train_bs"], shuffle=True, num_workers=0, drop_last=True)
    target_loader = DataLoader(target_path, batch_size=config["train_bs"], shuffle=True, num_workers=0, drop_last=True)
    test_loader   = DataLoader(test_path, batch_size=config["test_bs"], shuffle=True, num_workers=0, drop_last=True)

    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                    **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    gpus = config["gpus"].split(',')
    if len(gpus) > 1:
        ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus])
        base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus])


    len_train_source = len(source_loader)
    len_train_target = len(target_loader)

    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    best_acc = 0.0
    best_model_path = None

    for i in trange(config["iterations"], leave=False):
        if i % config["test_interval"] == config["test_interval"] - 1:
            base_network.train(False)
            temp_acc = image_classification_test(test_loader, base_network)
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = copy.deepcopy(temp_model)
                best_iter = i
                if best_model_path and osp.exists(best_model_path):
                    try:
                        os.remove(best_model_path)
                    except:
                        pass
                best_model_path = osp.join(config["output_path"], "iter_{:05d}.pth.tar".format(best_iter))
                torch.save(best_model, best_model_path)
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str+"\n")
            config["out_file"].flush()
            # print("cut_loss: ", cut_loss.item())
            print("mix_loss: ", mix_loss.item())
            print(log_str)

        base_network.train(True)
        ad_net.train(True)
        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(source_loader)
        if i % len_train_target == 0:
            iter_target = iter(target_loader)

        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        inputs_source, inputs_target, labels_source = inputs_source.cuda(), inputs_target.cuda(), labels_source.cuda()
        labels_src_one_hot = torch.nn.functional.one_hot(labels_source, config["class_num"]).float()

        # inputs_cut, labels_cut = cutmix(base_network, inputs_source, labels_src_one_hot, inputs_target, config["alpha"], config["class_num"])
        inputs_mix, labels_mix = mixup(base_network, inputs_source, labels_src_one_hot, inputs_target, config["alpha"], config["class_num"], config["temperature"])

        features_source, outputs_source = base_network(inputs_source)
        features_target, outputs_target = base_network(inputs_target)
        # features_cut,    outputs_cut    = base_network(inputs_cut)
        features_mix,    outputs_mix    = base_network(inputs_mix)

        features = torch.cat((features_source, features_target), dim=0)
        outputs = torch.cat((outputs_source, outputs_target), dim=0)
        softmax_out = nn.Softmax(dim=1)(outputs)

        if config["method"] == 'DANN':
            transfer_loss = loss.DANN(features, ad_net)
            # cut_loss = utils.kl_loss(outputs_cut, labels_cut.detach())
            mix_loss = utils.kl_loss(outputs_mix, labels_mix.detach())
        else:
            raise ValueError('Method cannot be recognized.')

        classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)
        total_loss = transfer_loss + classifier_loss + (5*mix_loss)
        total_loss.backward()
        optimizer.step()
    torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar"))
    print("Training Finished! Best Accuracy: ", best_acc)
    return best_acc
Exemplo n.º 16
0
def train(config):
    ####################################################
    # Tensorboard setting
    ####################################################
    #tensor_writer = SummaryWriter(config["tensorboard_path"])

    ####################################################
    # Data setting
    ####################################################

    prep_dict = {}  # 데이터 전처리 transforms 부분
    prep_dict["source"] = prep.image_train(**config['prep']['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    prep_dict["test"] = prep.image_test(**config['prep']['params'])

    dsets = {}
    dsets["source"] = datasets.ImageFolder(config['s_dset_path'],
                                           transform=prep_dict["source"])
    dsets["target"] = datasets.ImageFolder(config['t_dset_path'],
                                           transform=prep_dict['target'])
    dsets['test'] = datasets.ImageFolder(config['t_dset_path'],
                                         transform=prep_dict['test'])

    data_config = config["data"]
    train_source_bs = data_config["source"][
        "batch_size"]  #원본은 source와 target 모두 source train bs로 설정되었는데 이를 수정함
    train_target_bs = data_config['target']['batch_size']
    test_bs = data_config["test"]["batch_size"]

    dset_loaders = {}
    dset_loaders["source"] = DataLoader(
        dsets["source"],
        batch_size=train_source_bs,
        shuffle=True,
        num_workers=4,
        drop_last=True
    )  # 원본은 drop_last=True, 이렇게 해야 마지막까지 source, target에서 동일한 수로 배치 생성가능
    dset_loaders["target"] = DataLoader(dsets["target"],
                                        batch_size=train_target_bs,
                                        shuffle=True,
                                        num_workers=4,
                                        drop_last=True)
    dset_loaders['test'] = DataLoader(dsets['test'],
                                      batch_size=test_bs,
                                      shuffle=False,
                                      num_workers=4,
                                      drop_last=False)

    ####################################################
    # Network Setting
    ####################################################

    class_num = config["network"]['params']['class_num']

    net_config = config["network"]
    """
        config['network'] = {'name': network.ResNetFc,
                         'params': {'resnet_name': args.net,
                                    'use_bottleneck': True,
                                    'bottleneck_dim': 256,
                                    'new_cls': True,
                                    'class_num': args.class_num,
                                    'type' : args.type}
                         }
    """

    base_network = net_config["name"](**net_config["params"])
    #network.py에 정의된 ResNetFc() 클래스 호출
    base_network = base_network.cuda()  # ResNetFc(Resnet, True, 256, True, 12)

    if config["loss"]["random"]:
        random_layer = network.RandomLayer(
            [base_network.output_num(), class_num],
            config["loss"]["random_dim"])
        random_layer.cuda()
        ad_net = network.AdversarialNetwork(config["loss"]["random_dim"], 1024)
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(
            base_network.output_num() * class_num, 1024)  # 왜 class 수 만큼 곱하지?

    ad_net = ad_net.cuda()

    parameter_list = base_network.get_parameters() + ad_net.get_parameters()

    ####################################################
    # Env Setting
    ####################################################

    #gpus = config['gpu'].split(',')
    #if len(gpus) > 1 :
    #ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus])
    #base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus])

    ####################################################
    # Optimizer Setting
    ####################################################

    optimizer_config = config['optimizer']
    optimizer = optimizer_config["type"](parameter_list,
                                         **(optimizer_config["optim_params"]))
    # optim.SGD

    #config['optimizer'] = {'type': optim.SGD,
    #'optim_params': {'lr': args.lr,
    #'momentum': 0.9,
    #'weight_decay': 0.0005,
    #'nestrov': True},
    #'lr_type': "inv",
    #'lr_param': {"lr": args.lr,
    #'gamma': 0.001, # 이거 0.01이여야 하지 않나?
    #'power': 0.75
    #}

    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group['lr'])

    schedule_param = optimizer_config['lr_param']

    lr_scheduler = lr_schedule.schedule_dict[
        optimizer_config["lr_type"]]  # return optimizer

    ####################################################
    # Train
    ####################################################

    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])

    transfer_loss_value = 0.0
    classifier_loss_value = 0.0
    total_loss_value = 0.0

    best_acc = 0.0

    batch_size = config["data"]["source"]["batch_size"]

    for i in range(
            config["num_iterations"]):  # num_iterations수의 batch가 학습에 사용됨
        sys.stdout.write("Iteration : {} \r".format(i))
        sys.stdout.flush()

        loss_params = config["loss"]

        base_network.train(True)
        ad_net.train(True)

        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()

        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])

        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()

        inputs_source, labels_source = inputs_source.cuda(
        ), labels_source.cuda()
        inputs_target = inputs_target.cuda()

        inputs = torch.cat((inputs_source, inputs_target), dim=0)

        features, outputs, tau, cur_mean_source, cur_mean_target, output_mean_source, output_mean_target = base_network(
            inputs)

        softmax_out = nn.Softmax(dim=1)(outputs)

        outputs_source = outputs[:batch_size]
        outputs_target = outputs[batch_size:]

        if config['method'] == 'CDAN+E' or config['method'] == 'CDAN_TransNorm':
            entropy = loss.Entropy(softmax_out)
            transfer_loss = loss.CDAN([features, softmax_out], ad_net, entropy,
                                      network.calc_coeff(i), random_layer)
        elif config['method'] == 'CDAN':
            transfer_loss = loss.CDAN([features, softmax_out], ad_net, None,
                                      None, random_layer)
        elif config['method'] == 'DANN':
            pass  # 나중에 정리하기
        else:
            raise ValueError('Method cannot be recognized')

        classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)
        total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss

        total_loss.backward()
        optimizer.step()

        #tensor_writer.add_scalar('total_loss', total_loss.i )
        #tensor_writer.add_scalar('classifier_loss', classifier_loss, i)
        #tensor_writer.add_scalar('transfer_loss', transfer_loss, i)

        ####################################################
        # Test
        ####################################################
        if i % config["test_interval"] == config["test_interval"] - 1:
            # test interval 마다
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders, base_network)
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
                ACC = round(best_acc, 2) * 100
                torch.save(
                    best_model,
                    os.path.join(config["output_path"],
                                 "iter_{}_model.pth.tar".format(ACC)))
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            print(log_str)
Exemplo n.º 17
0
def train(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
    prep_dict["target"] = prep.image_train( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])
    else:
        prep_dict["test"] = prep.image_test( \
                            resize_size=prep_config["resize_size"], \
                            crop_size=prep_config["crop_size"])

    ## set loss
    class_criterion = nn.CrossEntropyLoss()
    transfer_criterion = loss.PADA
    loss_params = config["loss"]

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]

    # seperate the source and validation set
    cls_source_list, cls_validation_list = sep.split_set(
        data_config["source"]["list_path"],
        config["network"]["params"]["class_num"])
    source_list = sep.dimension_rd(cls_source_list)

    dsets["source"] = ImageList(source_list, \
                                transform=prep_dict["source"])
    dset_loaders["source"] = util_data.DataLoader(dsets["source"], \
            batch_size=data_config["source"]["batch_size"], \
            shuffle=True, num_workers=4)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = util_data.DataLoader(dsets["target"], \
            batch_size=data_config["target"]["batch_size"], \
            shuffle=True, num_workers=4)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test"+str(i)] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"]["val"+str(i)])
            dset_loaders["test"+str(i)] = util_data.DataLoader(dsets["test"+str(i)], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)

            dsets["target"+str(i)] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["test"]["val"+str(i)])
            dset_loaders["target"+str(i)] = util_data.DataLoader(dsets["target"+str(i)], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                transform=prep_dict["test"])
        dset_loaders["test"] = util_data.DataLoader(dsets["test"], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)

        dsets["target_test"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["test"])
        dset_loaders["target_test"] = MyDataLoader(dsets["target_test"], \
                                batch_size=data_config["test"]["batch_size"], \
                                shuffle=False, num_workers=4)

    class_num = config["network"]["params"]["class_num"]

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        base_network = base_network.cuda()

    ## collect parameters
    if net_config["params"]["new_cls"]:
        if net_config["params"]["use_bottleneck"]:
            parameter_list = [{"params":base_network.feature_layers.parameters(), "lr":1}, \
                            {"params":base_network.bottleneck.parameters(), "lr":10}, \
                            {"params":base_network.fc.parameters(), "lr":10}]
        else:
            parameter_list = [{"params":base_network.feature_layers.parameters(), "lr":1}, \
                            {"params":base_network.fc.parameters(), "lr":10}]
    else:
        parameter_list = [{"params": base_network.parameters(), "lr": 1}]

    ## add additional network for some methods
    class_weight = torch.from_numpy(np.array([1.0] * class_num))
    if use_gpu:
        class_weight = class_weight.cuda()
    ad_net = network.AdversarialNetwork(base_network.output_num())
    gradient_reverse_layer = network.AdversarialLayer(
        high_value=config["high"])
    if use_gpu:
        ad_net = ad_net.cuda()
    parameter_list.append({"params": ad_net.parameters(), "lr": 10})

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](parameter_list, \
                    **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    ## train
    len_train_source = len(dset_loaders["source"]) - 1
    len_train_target = len(dset_loaders["target"]) - 1
    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    best_acc = 0.0
    best_model = 0
    for i in range(config["num_iterations"]):
        if (i + 1) % config["test_interval"] == 0:
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders, \
                base_network, test_10crop=prep_config["test_10crop"], \
                gpu=use_gpu)
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str)
            config["out_file"].flush()
            print(log_str)
        if (i + 1) % config["snapshot_interval"] == 0:
            torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \
                "iter_{:05d}_model.pth.tar".format(i)))

        # if i % loss_params["update_iter"] == loss_params["update_iter"] - 1:
        #     base_network.train(False)
        #     target_fc8_out = image_classification_predict(dset_loaders, base_network, softmax_param=config["softmax_param"])
        #     class_weight = torch.mean(target_fc8_out, 0)
        #     class_weight = (class_weight / torch.mean(class_weight)).cuda().view(-1)
        #     class_criterion = nn.CrossEntropyLoss(weight = class_weight)

        ## train one iter
        base_network.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        if use_gpu:
            inputs_source, inputs_target, labels_source = \
                Variable(inputs_source).cuda(), Variable(inputs_target).cuda(), \
                Variable(labels_source).cuda()
        else:
            inputs_source, inputs_target, labels_source = Variable(inputs_source), \
                Variable(inputs_target), Variable(labels_source)

        inputs = torch.cat((inputs_source, inputs_target), dim=0)
        features, outputs = base_network(inputs)

        # #
        # if i % 100 == 0:
        #     check = dev.get_label_list(open(data_config["source"]["list_path"]).readlines(),
        #                                base_network,
        #                                prep_config["resize_size"],
        #                                prep_config["crop_size"],
        #                                data_config["target"]["batch_size"],
        #                                use_gpu)
        #     f = open("Class_result.txt", "a+")
        #     f.close()
        #     for cls in range(class_num):
        #         count = 0
        #         for j in check:
        #             if int(j.split(" ")[1].replace("\n", "")) == cls:
        #                 count = count + 1
        #         f = open("Source_result.txt", "a+")
        #         f.write("Source_Class: " + str(cls) + "\n" + "Number of images: " + str(count) + "\n")
        #         f.close()
        #
        #     check = dev.get_label_list(open(data_config["target"]["list_path"]).readlines(),
        #                                base_network,
        #                                prep_config["resize_size"],
        #                                prep_config["crop_size"],
        #                                data_config["target"]["batch_size"],
        #                                use_gpu)
        #     f = open("Class_result.txt", "a+")
        #     f.write("Iteration: " + str(i) + "\n")
        #     f.close()
        #     for cls in range(class_num):
        #         count = 0
        #         for j in check:
        #             if int(j.split(" ")[1].replace("\n", "")) == cls:
        #                 count = count + 1
        #         f = open("Class_result.txt", "a+")
        #         f.write("Target_Class: " + str(cls) + "\n" + "Number of images: " + str(count) + "\n")
        #         f.close()

        #
        # #
        # print("Training test:")
        # print(features)
        # print(features.shape)
        # print(outputs)
        # print(outputs.shape)

        softmax_out = nn.Softmax(dim=1)(outputs).detach()
        ad_net.train(True)
        weight_ad = torch.ones(inputs.size(0))
        # label_numpy = labels_source.data.cpu().numpy()
        # for j in range(int(inputs.size(0) / 2)):
        #     weight_ad[j] = class_weight[int(label_numpy[j])]
        # weight_ad = weight_ad / torch.max(weight_ad[0:int(inputs.size(0)/2)])
        # for j in range(int(inputs.size(0) / 2), inputs.size(0)):
        #     weight_ad[j] = 1.0
        transfer_loss = transfer_criterion(features, ad_net, gradient_reverse_layer, \
                                           weight_ad, use_gpu)

        classifier_loss = class_criterion(
            outputs.narrow(0, 0, int(inputs.size(0) / 2)), labels_source)

        total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss
        total_loss.backward()
        optimizer.step()
    cv_loss = dev.cross_validation_loss(
        base_network, base_network, cls_source_list,
        data_config["target"]["list_path"], cls_validation_list, class_num,
        prep_config["resize_size"], prep_config["crop_size"],
        data_config["target"]["batch_size"], use_gpu)
    print(cv_loss)
Exemplo n.º 18
0
def train(config):
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train(**config["prep"]['params'])
    prep_dict["target"] = prep.image_train(**config["prep"]['params'])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop(**config["prep"]['params'])
    else:
        prep_dict["test"] = prep.image_test(**config["prep"]['params'])

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    train_bs = data_config["source"]["batch_size"]
    test_bs = data_config["test"]["batch_size"]

    source_list = [
        '.' + i for i in open(data_config["source"]["list_path"]).readlines()
    ]
    target_list = [
        '.' + i for i in open(data_config["target"]["list_path"]).readlines()
    ]

    dsets["source"] = ImageList(source_list, \
                                transform=prep_dict["source"])
    dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \
            shuffle=True, num_workers=config['args'].num_worker, drop_last=True)
    dsets["target"] = ImageList(target_list, \
                                transform=prep_dict["target"])
    dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
            shuffle=True, num_workers=config['args'].num_worker, drop_last=True)
    print("source dataset len:", len(dsets["source"]))
    print("target dataset len:", len(dsets["target"]))

    if prep_config["test_10crop"]:
        for i in range(10):
            test_list = [
                '.' + i
                for i in open(data_config["test"]["list_path"]).readlines()
            ]
            dsets["test"] = [ImageList(test_list, \
                                transform=prep_dict["test"][i]) for i in range(10)]
            dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \
                                shuffle=False, num_workers=config['args'].num_worker) for dset in dsets['test']]
    else:
        test_list = [
            '.' + i
            for i in open(data_config["test"]["list_path"]).readlines()
        ]
        dsets["test"] = ImageList(test_list, \
                                transform=prep_dict["test"])
        dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \
                                shuffle=False, num_workers=config['args'].num_worker)

    dsets["target_label"] = ImageList_label(target_list, \
                            transform=prep_dict["target"])
    dset_loaders["target_label"] = DataLoader(dsets["target_label"], batch_size=test_bs, \
            shuffle=False, num_workers=config['args'].num_worker, drop_last=False)

    class_num = config["network"]["params"]["class_num"]

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])
    base_network = base_network.to(network.dev)
    if config["restore_path"]:
        checkpoint = torch.load(
            osp.join(config["restore_path"], "best_model.pth"))["base_network"]
        ckp = {}
        for k, v in checkpoint.items():
            if "module" in k:
                ckp[k.split("module.")[-1]] = v
            else:
                ckp[k] = v
        base_network.load_state_dict(ckp)
        log_str = "successfully restore from {}".format(
            osp.join(config["restore_path"], "best_model.pth"))
        config["out_file"].write(log_str + "\n")
        config["out_file"].flush()
        print(log_str)

    ## add additional network for some methods
    if "ALDA" in args.method:
        ad_net = network.Multi_AdversarialNetwork(base_network.output_num(),
                                                  1024, class_num)
    else:
        ad_net = network.AdversarialNetwork(base_network.output_num(), 1024)
    ad_net = ad_net.to(network.dev)
    parameter_list = base_network.get_parameters() + ad_net.get_parameters()

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optimizer_config["type"](parameter_list, \
                    **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    gpus = config['gpu'].split(',')
    if len(gpus) > 1:
        ad_net = nn.DataParallel(ad_net,
                                 device_ids=[int(i) for i in range(len(gpus))])
        base_network = nn.DataParallel(
            base_network, device_ids=[int(i) for i in range(len(gpus))])

    loss_params = config["loss"]
    high = loss_params["trade_off"]
    begin_label = False
    writer = SummaryWriter(config["output_path"])

    ## train
    len_train_source = len(dset_loaders["source"])
    len_train_target = len(dset_loaders["target"])
    transfer_loss_value = classifier_loss_value = total_loss_value = 0.0
    best_acc = 0.0
    loss_value = 0
    loss_adv_value = 0
    loss_correct_value = 0
    for i in tqdm(range(config["num_iterations"]),
                  total=config["num_iterations"]):
        if i % config["test_interval"] == config["test_interval"] - 1:
            base_network.train(False)
            temp_acc = image_classification_test(dset_loaders, \
                base_network, test_10crop=prep_config["test_10crop"])
            temp_model = base_network  #nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_step = i
                best_acc = temp_acc
                best_model = temp_model
                checkpoint = {
                    "base_network": best_model.state_dict(),
                    "ad_net": ad_net.state_dict()
                }
                torch.save(checkpoint,
                           osp.join(config["output_path"], "best_model.pth"))
                print(
                    "\n##########     save the best model.    #############\n")
            log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc)
            config["out_file"].write(log_str + "\n")
            config["out_file"].flush()
            writer.add_scalar('precision', temp_acc, i)
            print(log_str)

            print("adv_loss: {:.3f} correct_loss: {:.3f} class_loss: {:.3f}".
                  format(loss_adv_value, loss_correct_value, loss_value))
            loss_value = 0
            loss_adv_value = 0
            loss_correct_value = 0

            #show val result on tensorboard
            images_inv = prep.inv_preprocess(inputs_source.clone().cpu(), 3)
            for index, img in enumerate(images_inv):
                writer.add_image(str(index) + '/Images', img, i)

        # save the pseudo_label
        if 'PseudoLabel' in config['method'] and (
                i % config["label_interval"] == config["label_interval"] - 1):
            base_network.train(False)
            pseudo_label_list = image_label(dset_loaders, base_network, threshold=config['threshold'], \
                                out_dir=config["output_path"])
            dsets["target"] = ImageList(open(pseudo_label_list).readlines(), \
                                transform=prep_dict["target"])
            dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \
                    shuffle=True, num_workers=config['args'].num_worker, drop_last=True)
            iter_target = iter(
                dset_loaders["target"]
            )  # replace the target dataloader with Pseudo_Label dataloader
            begin_label = True

        if i > config["stop_step"]:
            log_str = "method {}, iter: {:05d}, precision: {:.5f}".format(
                config["output_path"], best_step, best_acc)
            config["final_log"].write(log_str + "\n")
            config["final_log"].flush()
            break

        ## train one iter
        base_network.train(True)
        ad_net.train(True)
        optimizer = lr_scheduler(optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        inputs_source, inputs_target, labels_source = Variable(
            inputs_source).to(network.dev), Variable(inputs_target).to(
                network.dev), Variable(labels_source).to(network.dev)
        features_source, outputs_source = base_network(inputs_source)
        if args.source_detach:
            features_source = features_source.detach()
        features_target, outputs_target = base_network(inputs_target)
        features = torch.cat((features_source, features_target), dim=0)
        outputs = torch.cat((outputs_source, outputs_target), dim=0)
        softmax_out = nn.Softmax(dim=1)(outputs)
        loss_params["trade_off"] = network.calc_coeff(
            i, high=high)  #if i > 500 else 0.0
        transfer_loss = 0.0
        if 'DANN' in config['method']:
            transfer_loss = loss.DANN(features, ad_net)
        elif "ALDA" in config['method']:
            ad_out = ad_net(features)
            adv_loss, reg_loss, correct_loss = loss.ALDA_loss(
                ad_out,
                labels_source,
                softmax_out,
                weight_type=config['args'].weight_type,
                threshold=config['threshold'])
            # whether add the corrected self-training loss
            if "nocorrect" in config['args'].loss_type:
                transfer_loss = adv_loss
            else:
                transfer_loss = config['args'].adv_weight * adv_loss + config[
                    'args'].adv_weight * loss_params["trade_off"] * correct_loss
            # reg_loss is only backward to the discriminator
            if "noreg" not in config['args'].loss_type:
                for param in base_network.parameters():
                    param.requires_grad = False
                reg_loss.backward(retain_graph=True)
                for param in base_network.parameters():
                    param.requires_grad = True
        # on-line self-training
        elif 'SelfTraining' in config['method']:
            transfer_loss += loss_params["trade_off"] * loss.SelfTraining_loss(
                outputs, softmax_out, config['threshold'])
        # off-line self-training
        elif 'PseudoLabel' in config['method']:
            labels_target = labels_target.to(network.dev)
            if begin_label:
                transfer_loss += loss_params["trade_off"] * nn.CrossEntropyLoss(
                    ignore_index=-1)(outputs_target, labels_target)
            else:
                transfer_loss += 0.0 * nn.CrossEntropyLoss(ignore_index=-1)(
                    outputs_target, labels_target)

        classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source)
        loss_value += classifier_loss.item() / config["test_interval"]
        loss_adv_value += adv_loss.item() / config["test_interval"]
        loss_correct_value += correct_loss.item() / config["test_interval"]
        total_loss = classifier_loss + transfer_loss
        total_loss.backward()
        optimizer.step()
    checkpoint = {
        "base_network": temp_model.state_dict(),
        "ad_net": ad_net.state_dict()
    }
    torch.save(checkpoint, osp.join(config["output_path"], "final_model.pth"))
    return best_acc
def train(config):
    tie = 1.0
    ## set pre-process
    prep_dict = {}
    prep_config = config["prep"]
    prep_dict["source"] = prep.image_train( \
        resize_size=prep_config["resize_size"], \
        crop_size=prep_config["crop_size"])
    prep_dict["target"] = prep.image_train( \
        resize_size=prep_config["resize_size"], \
        crop_size=prep_config["crop_size"])
    if prep_config["test_10crop"]:
        prep_dict["test"] = prep.image_test_10crop( \
            resize_size=prep_config["resize_size"], \
            crop_size=prep_config["crop_size"])
    else:
        prep_dict["test"] = prep.image_test( \
            resize_size=prep_config["resize_size"], \
            crop_size=prep_config["crop_size"])

    ## set loss
    class_criterion = nn.CrossEntropyLoss()  # 分类损失
    transfer_criterion1 = loss.PADA  # 迁移学习损失(带权重),BCEloss
    balance_criterion = loss.balance_loss()
    loss_params = config["loss"]

    ## prepare data
    dsets = {}
    dset_loaders = {}
    data_config = config["data"]
    dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \
                                transform=prep_dict["source"])
    dset_loaders["source"] = util_data.DataLoader(dsets["source"], \
                                                  batch_size=data_config["source"]["batch_size"], \
                                                  shuffle=True, num_workers=4)
    dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                transform=prep_dict["target"])
    dset_loaders["target"] = util_data.DataLoader(dsets["target"], \
                                                  batch_size=data_config["target"]["batch_size"], \
                                                  shuffle=True, num_workers=4)

    if prep_config["test_10crop"]:
        for i in range(10):
            dsets["test" + str(i)] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                               transform=prep_dict["test"]["val" + str(i)])
            dset_loaders["test" + str(i)] = util_data.DataLoader(dsets["test" + str(i)], \
                                                                 batch_size=data_config["test"]["batch_size"], \
                                                                 shuffle=False, num_workers=4)

            dsets["target" + str(i)] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                                 transform=prep_dict["test"]["val" + str(i)])
            dset_loaders["target" + str(i)] = util_data.DataLoader(dsets["target" + str(i)], \
                                                                   batch_size=data_config["test"]["batch_size"], \
                                                                   shuffle=False, num_workers=4)
    else:
        dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \
                                  transform=prep_dict["test"])
        dset_loaders["test"] = util_data.DataLoader(dsets["test"], \
                                                    batch_size=data_config["test"]["batch_size"], \
                                                    shuffle=False, num_workers=4)

        dsets["target_test"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \
                                         transform=prep_dict["test"])
        dset_loaders["target_test"] = MyDataLoader(dsets["target_test"], \
                                                   batch_size=data_config["test"]["batch_size"], \
                                                   shuffle=False, num_workers=4)

    class_num = config["network"]["params"]["class_num"]

    ## set base network
    net_config = config["network"]
    base_network = net_config["name"](**net_config["params"])

    use_gpu = torch.cuda.is_available()
    if use_gpu:
        base_network = base_network.cuda()

    ## collect parameters
    if net_config["params"]["new_cls"]:
        if net_config["params"]["use_bottleneck"]:
            parameter_list = [{"params": base_network.feature_layers.parameters(), "lr": 1}, \
                              {"params": base_network.bottleneck.parameters(), "lr": 10}, \
                              {"params": base_network.fc.parameters(), "lr": 10}]
        else:
            parameter_list = [{"params": base_network.feature_layers.parameters(), "lr": 1}, \
                              {"params": base_network.fc.parameters(), "lr": 10}]
    else:
        parameter_list = [{"params": base_network.parameters(), "lr": 1}]

    ## add additional network for some methods
    class_weight = torch.from_numpy(np.array(
        [1.0] * class_num))  # 权重初始化为class_num维向量,初始值为1
    if use_gpu:
        class_weight = class_weight.cuda()
    ad_net = network.AdversarialNetwork(
        base_network.output_num())  # 鉴别器设置,输入为特征提取器的维数,输出为属于共域的可能性
    nad_net = network.NAdversarialNetwork(base_network.output_num())
    gradient_reverse_layer = network.AdversarialLayer(
        high_value=config["high"])
    if use_gpu:
        ad_net = ad_net.cuda()
        nad_net = nad_net.cuda()
    parameter_list.append({"params": ad_net.parameters(), "lr": 10})

    ## set optimizer
    optimizer_config = config["optimizer"]
    optimizer = optim_dict[optimizer_config["type"]](parameter_list, \
                                                     **(optimizer_config["optim_params"]))
    param_lr = []
    for param_group in optimizer.param_groups:
        param_lr.append(param_group["lr"])
    schedule_param = optimizer_config["lr_param"]
    lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]]

    ## train
    len_train_source = len(dset_loaders["source"]) - 1
    len_train_target = len(dset_loaders["target"]) - 1
    transfer_loss_value = classifier_loss_value = total_loss_value = attention_loss_value = 0.0
    best_acc = 0.0
    for i in range(config["num_iterations"]):
        if i % config["test_interval"] == 0:  # 测试
            base_network.train(False)  # 先对特征提取器进行训练
            temp_acc = image_classification_test(dset_loaders, \
                                                 base_network, test_10crop=prep_config["test_10crop"], \
                                                 gpu=use_gpu)  # 对第一个有监督训练器进行分类训练,提取特征
            temp_model = nn.Sequential(base_network)
            if temp_acc > best_acc:
                best_acc = temp_acc
                best_model = temp_model
            log_str = "iter: {:05d}, alpha: {:03f}, tradeoff: {:03f} ,precision: {:.5f}".format(
                i, loss_params["para_alpha"], loss_params["trade_off"],
                temp_acc)
            config["out_file"].write(log_str + '\n')
            config["out_file"].flush()
            print(log_str)
        if i % config["snapshot_interval"] == 0:  # 输出
            torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \
                                                             "iter_{:05d}_model.pth.tar".format(i)))

        if i % loss_params["update_iter"] == loss_params["update_iter"] - 1:
            base_network.train(False)
            target_fc8_out = image_classification_predict(
                dset_loaders,
                base_network,
                softmax_param=config["softmax_param"]
            )  # 在对有监督学习进行了训练后,喂进去目标域数据,判断权重
            class_weight = torch.mean(
                target_fc8_out, 0)  # predict模型输出的预测向量取均值,为每一个体权重,将个体权重转化为类别权重
            class_weight = (class_weight /
                            torch.mean(class_weight)).cuda().view(-1)  # 归一化
            class_criterion = nn.CrossEntropyLoss(
                weight=class_weight)  # 这里的交叉熵损失函数就是带权重的

        ## train one iter
        base_network.train(True)
        optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param)
        optimizer.zero_grad()
        if i % len_train_source == 0:
            iter_source = iter(dset_loaders["source"])
        if i % len_train_target == 0:
            iter_target = iter(dset_loaders["target"])
        inputs_source, labels_source = iter_source.next()
        inputs_target, labels_target = iter_target.next()
        if use_gpu:
            inputs_source, inputs_target, labels_source = \
                Variable(inputs_source).cuda(), Variable(inputs_target).cuda(), \
                Variable(labels_source).cuda()
        else:
            inputs_source, inputs_target, labels_source = Variable(inputs_source), \
                                                          Variable(inputs_target), Variable(labels_source)

        inputs = torch.cat((inputs_source, inputs_target),
                           dim=0)  # 这里输入后一半目标域,前一半源域
        features, outputs = base_network(inputs)  # 从有分类网络获得特征与输出,到这里是特征提取器
        softmax_out = nn.Softmax(dim=1)(outputs).detach()
        ad_net.train(True)
        nad_net.train(True)
        weight_ad = torch.zeros(inputs.size(0))
        label_numpy = labels_source.data.cpu().numpy()
        for j in range(inputs.size(0) / 2):
            weight_ad[j] = class_weight[int(label_numpy[j])]  # 计算实际样例权重
        # print(label_numpy)
        weight_ad = weight_ad / torch.max(
            weight_ad[0:inputs.size(0) / 2])  # 权重归一化
        for j in range(inputs.size(0) / 2,
                       inputs.size(0)):  # 前一半源域,所以权重是计算的,后一半目标域,权重全为1
            weight_ad[j] = 1.0
        classifier_loss = class_criterion(
            outputs.narrow(0, 0,
                           inputs.size(0) / 2), labels_source)  # 分类损失
        total_loss = classifier_loss
        total_loss.backward()
        optimizer.step()

    torch.save(best_model, osp.join(config["output_path"],
                                    "best_model.pth.tar"))
    return best_acc