Exemple #1
0
def train_classifier(netG, args, device, testset=None):
    print('\nTraining a classifier')
    loader = data_utils.DataLoader(range(args.netC_per_epoch),
                                   batch_size=args.netC_batch_size,
                                   shuffle=True,
                                   num_workers=8)
    netC = network.LeNet(args.image_size, args.nc, args.ny).to(device)
    optimizerC = optim.Adam(netC.parameters(),
                            lr=args.netC_lr,
                            betas=(args.netC_beta1, args.netC_beta2))
    criterionCE = nn.CrossEntropyLoss().to(device)

    for epoch in range(1, args.netC_epochs + 1):
        adjust_learning_rate(optimizerC, epoch, args.netC_lr,
                             args.netC_lr_period)
        info = {'num': 0, 'loss_C': 0, 'acc': 0}

        # train network
        netC.train()
        for i, x in enumerate(loader):
            # forward
            fake_z = make_z(len(x), args.nz).to(device)  # B x nz
            fake_y = make_y(len(x), args.ny).to(device)  # B
            with torch.no_grad():
                fake_x = netG(fake_z, fake_y)  # B x nc x H x W
            out_fake = netC(fake_x)  # B x nc
            loss_C = criterionCE(out_fake, fake_y)
            acc = accuracy(out_fake, fake_y)

            # backward
            optimizerC.zero_grad()
            loss_C.backward()
            optimizerC.step()

            # update loss info
            info['num'] += 1
            info['loss_C'] += loss_C.item()
            info['acc'] += acc

        # evaluate performance
        info = normalize_info(info)
        message = "Epoch: {}  C: {:.4f}  acc (train): {:.4f}".format(
            epoch, info['loss_C'], info['acc'])

        if testset and epoch % args.netC_eval_period == 0:
            test_acc = eval_classifier(netC, args, device, testset)
            message += "  acc (test): {:.4f}".format(test_acc)

        print(message)
    print('')

    return netC
Exemple #2
0
def fitting_capacity(samples, testset, nc=1, ny=10, epochs=40, eval_period=10, verbose=False):
	netC = network.LeNet(32, nc, ny)
	netC = nn.DataParallel(netC, [0]).cuda()
	optimizerC = optim.Adam(netC.parameters(), lr=0.001, betas=(0.5, 0.999))
	criterionCE = nn.CrossEntropyLoss()

	loader = data_utils.DataLoader(samples, batch_size=128, shuffle=True, num_workers=8)
	test_acc = 0
	for epoch in range(1, epochs + 1):
		adjust_learning_rate(optimizerC, epoch, 0.001, epochs//2)
		info = {'num': 0, 'loss_C': 0, 'acc': 0}

		# train network
		netC.train()
		for i, (x, y) in enumerate(loader):
			# forward
			x = x.cuda()
			y = y.cuda()
			out = netC(x)  # B x nc
			loss_C = criterionCE(out, y)

			# backward
			optimizerC.zero_grad()
			loss_C.backward()
			optimizerC.step()

			# update loss info
			info['num'] += 1
			info['loss_C'] += loss_C.item()
			info['acc'] += accuracy(out, y)

		# evaluate performance
		info = normalize_info(info)
		message = "Epoch: {}  C: {:.4f}  acc (train): {:.4f}".format(epoch, info['loss_C'], info['acc'])
		if epoch % eval_period == 0:
			test_acc = eval_classifier(netC, testset)
			message += "  acc (test): {:.4f}".format(test_acc)

		if verbose:
			print(message)

	return test_acc
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('--method', type=str, default='CDAN-E', choices=['CDAN', 'CDAN-E', 'DANN'])
    parser.add_argument('--task', default='USPS2MNIST', help='task to perform')
    parser.add_argument('--batch_size', type=int, default=256, help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size', type=int, default=1000, help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=10, metavar='N', help='number of epochs to train (default: 10)')
    parser.add_argument('--lr', type=float, default=0.01, metavar='LR', help='learning rate (default: 0.01)')
    parser.add_argument('--momentum', type=float, default=0.5, metavar='M', help='SGD momentum (default: 0.5)')
    parser.add_argument('--gpu_id', type=str,default="0",  help='cuda device id')
    parser.add_argument('--seed', type=int, default=1, metavar='S',  help='random seed (default: 1)')
    parser.add_argument('--log_interval', type=int, default=10, help='how many batches to wait before logging training status')
    parser.add_argument('--random', type=bool, default=False, help='whether to use random')
    parser.add_argument('--output_dir',type=str,default="digits/u2m")
    parser.add_argument('--cla_plus_weight',type=float,default=0.3)
    parser.add_argument('--cyc_loss_weight',type=float,default=0.01)
    parser.add_argument('--weight_in_loss_g',type=str,default='1,0.01,0.1,0.1')
    args = parser.parse_args()

    torch.manual_seed(args.seed)
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id

    # train config
    import os.path as osp
    import datetime
    config = {}

    config['method'] = args.method
    config["gpu"] = args.gpu_id
    config['cyc_loss_weight'] = args.cyc_loss_weight
    config['cla_plus_weight'] = args.cla_plus_weight
    config['weight_in_loss_g'] = args.weight_in_loss_g
    config["epochs"] = args.epochs
    config["output_for_test"] = True
    config["output_path"] = "snapshot/" + args.output_dir
    if not osp.exists(config["output_path"]):
        os.system('mkdir -p ' + config["output_path"])
    config["out_file"] = open(osp.join(config["output_path"], "log_{}_{}.txt".
                                       format(args.task,str(datetime.datetime.utcnow()))),
                              "w")

    config["out_file"].write(str(config))
    config["out_file"].flush()


    source_list = '/data/usps/usps_train.txt'
    target_list = '/data/mnist/mnist_train.txt'
    test_list = '/data/mnist/mnist_test.txt'
    start_epoch = 1
    decay_epoch = 6


    train_loader = torch.utils.data.DataLoader(
        ImageList(open(source_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.batch_size, shuffle=True, num_workers=1, drop_last=True)
    train_loader1 = torch.utils.data.DataLoader(
        ImageList(open(target_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.batch_size, shuffle=True, num_workers=1, drop_last=True)
    test_loader = torch.utils.data.DataLoader(
        ImageList(open(test_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.test_batch_size, shuffle=True, num_workers=1)

    model = network.LeNet()
    # model = model.cuda()
    class_num = 10

    # 添加G,D,和额外的分类器
    import itertools
    from utils import ReplayBuffer
    import net
    z_dimension = 500
    D_s = network.models["Discriminator_um"]()
    # D_s = D_s.cuda()
    G_s2t = network.models["Generator_um"](z_dimension, 500)
    # G_s2t = G_s2t.cuda()

    D_t = network.models["Discriminator_um"]()
    # D_t = D_t.cuda()
    G_t2s = network.models["Generator_um"](z_dimension, 500)
    # G_t2s = G_t2s.cuda()

    criterion_GAN = torch.nn.MSELoss()
    criterion_cycle = torch.nn.L1Loss()
    criterion_identity = torch.nn.L1Loss()
    criterion_Sem = torch.nn.L1Loss()

    optimizer_G = torch.optim.Adam(itertools.chain(G_s2t.parameters(), G_t2s.parameters()), lr=0.0003)
    optimizer_D_s = torch.optim.Adam(D_s.parameters(), lr=0.0003)
    optimizer_D_t = torch.optim.Adam(D_t.parameters(), lr=0.0003)

    fake_S_buffer = ReplayBuffer()
    fake_T_buffer = ReplayBuffer()

    ## 添加分类器
    classifier1 = net.Net(500, class_num)
    # classifier1 = classifier1.cuda()
    classifier1_optim = optim.Adam(classifier1.parameters(), lr=0.0003)


    if args.random:
        random_layer = network.RandomLayer([model.output_num(), class_num], 500)
        ad_net = network.AdversarialNetwork(500, 500)
        # random_layer.cuda()
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num() * class_num, 500)
    # ad_net = ad_net.cuda()
    optimizer = optim.SGD(model.parameters(), lr=args.lr, weight_decay=0.0005, momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(), lr=args.lr, weight_decay=0.0005, momentum=0.9)

    for epoch in range(1, args.epochs + 1):
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * 0.5
        train(args, model, ad_net, random_layer, train_loader, train_loader1, optimizer, optimizer_ad, epoch, start_epoch, args.method,
              D_s, D_t, G_s2t, G_t2s, criterion_Sem, criterion_GAN, criterion_cycle, criterion_identity, optimizer_G,
              optimizer_D_t, optimizer_D_s,
              classifier1, classifier1_optim, fake_S_buffer, fake_T_buffer
              )
        test(args,epoch,config, model, test_loader)
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('--method', type=str, default='CDAN-E', choices=['CDAN', 'CDAN-E', 'DANN'])
    parser.add_argument('--task', default='MNIST2USPS', help='task to perform')
    parser.add_argument('--batch_size', type=int, default=64,
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size', type=int, default=1000,
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=10, metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--gpu_id', type=str, default='0',
                        help='cuda device id')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log_interval', type=int, default=10,
                        help='how many batches to wait before logging training status')
    parser.add_argument('--random', type=bool, default=False,
                        help='whether to use random')
    args = parser.parse_args()

    torch.manual_seed(args.seed)
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id


    source_list = '/data/mnist/mnist_train.txt'
    target_list = '/data/usps/usps_train.txt'
    test_list = '/data/usps/usps_test.txt'
    start_epoch = 1
    decay_epoch = 5


    train_loader = torch.utils.data.DataLoader(
        ImageList(open(source_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.batch_size, shuffle=True, num_workers=1, drop_last=True)
    train_loader1 = torch.utils.data.DataLoader(
        ImageList(open(target_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.batch_size, shuffle=True, num_workers=1, drop_last=True)
    test_loader = torch.utils.data.DataLoader(
        ImageList(open(test_list).readlines(), transform=transforms.Compose([
                           transforms.Resize((28,28)),
                           transforms.ToTensor(),
                           transforms.Normalize((0.5,), (0.5,))
                       ]), mode='L'),
        batch_size=args.test_batch_size, shuffle=True, num_workers=1)

    model = network.LeNet()
    # model = model.cuda()
    class_num = 10

    if args.random:
        random_layer = network.RandomLayer([model.output_num(), class_num], 500)
        ad_net = network.AdversarialNetwork(500, 500)
        # random_layer.cuda()
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num() * class_num, 500)
    # ad_net = ad_net.cuda()
    optimizer = optim.SGD(model.parameters(), lr=args.lr, weight_decay=0.0005, momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(), lr=args.lr, weight_decay=0.0005, momentum=0.9)

    for epoch in range(1, args.epochs + 1):
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * 0.5
        train(args, model, ad_net, random_layer, train_loader, train_loader1, optimizer, optimizer_ad, epoch, start_epoch, args.method)
        test(args, model, test_loader)
Exemple #5
0
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('--method',
                        type=str,
                        default='CDAN-E',
                        choices=['CDAN', 'CDAN-E', 'DANN'])
    parser.add_argument('--task', default='USPS2MNIST', help='task to perform')
    parser.add_argument('--batch_size',
                        type=int,
                        default=128,
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size',
                        type=int,
                        default=1000,
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs',
                        type=int,
                        default=550,
                        metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr',
                        type=float,
                        default=5e-5,
                        metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--lr2',
                        type=float,
                        default=0.005,
                        metavar='LR2',
                        help='learning rate2 (default: 0.01)')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.5,
                        metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--gpu_id',
                        type=str,
                        default='0',
                        help='cuda device id')
    parser.add_argument(
        '--log_interval',
        type=int,
        default=10,
        help='how many batches to wait before logging training status')
    parser.add_argument('--random',
                        type=bool,
                        default=False,
                        help='whether to use random')
    args = parser.parse_args()

    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id

    if args.task == 'USPS2MNIST':
        source_list, ordinary_train_dataset, target_list, test_list, ccp = data_loader(
            task='U2M')
        start_epoch = 50
        decay_epoch = 600
    elif args.task == 'MNIST2USPS':
        source_list, ordinary_train_dataset, target_list, test_list, ccp = data_loader(
            task='M2U')
        start_epoch = 50
        decay_epoch = 600
    else:
        raise Exception('task cannot be recognized!')

    train_loader = torch.utils.data.DataLoader(dataset=source_list,
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=8,
                                               drop_last=True)
    train_loader1 = torch.utils.data.DataLoader(dataset=target_list,
                                                batch_size=args.batch_size,
                                                shuffle=True,
                                                num_workers=8,
                                                drop_last=True)
    o_train_loader = torch.utils.data.DataLoader(
        dataset=ordinary_train_dataset,
        batch_size=args.test_batch_size,
        shuffle=True,
        num_workers=8)
    test_loader = torch.utils.data.DataLoader(dataset=test_list,
                                              batch_size=args.test_batch_size,
                                              shuffle=True,
                                              num_workers=8)

    model = network.LeNet()
    model = model.cuda()
    class_num = 10

    if args.random:
        random_layer = network.RandomLayer([model.output_num(), class_num],
                                           500)
        ad_net = network.AdversarialNetwork(500, 500)
        random_layer.cuda()
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num() * class_num,
                                            500)
    ad_net = ad_net.cuda()

    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          weight_decay=0.0005,
                          momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(),
                             lr=args.lr2,
                             weight_decay=0.0005,
                             momentum=0.9)

    save_table = np.zeros(shape=(args.epochs, 3))
    for epoch in range(1, args.epochs + 1):
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * 0.5
        train(args, model, ad_net, random_layer, train_loader, train_loader1,
              optimizer, optimizer_ad, epoch, start_epoch, args.method, ccp)
        acc1 = test(args, model, o_train_loader)
        acc2 = test(args, model, test_loader)
        save_table[epoch - 1, :] = epoch - 50, acc1, acc2
        np.savetxt(args.task + '_.txt', save_table, delimiter=',', fmt='%1.3f')
    np.savetxt(args.task + '_.txt', save_table, delimiter=',', fmt='%1.3f')
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('method',
                        type=str,
                        default='CDAN-E',
                        choices=[
                            'CDAN', 'CDAN-E', 'DANN', 'IWDAN', 'NANN',
                            'IWDANORACLE', 'IWCDAN', 'IWCDANORACLE',
                            'IWCDAN-E', 'IWCDAN-EORACLE'
                        ])
    parser.add_argument('--task',
                        default='mnist2usps',
                        help='task to perform',
                        choices=['usps2mnist', 'mnist2usps'])
    parser.add_argument('--batch_size',
                        type=int,
                        default=64,
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size',
                        type=int,
                        default=1000,
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs',
                        type=int,
                        default=70,
                        metavar='N',
                        help='number of epochs to train (default: 70)')
    parser.add_argument('--lr',
                        type=float,
                        default=0.0,
                        metavar='LR',
                        help='learning rate (default: 0.02)')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.5,
                        metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--seed',
                        type=int,
                        default=42,
                        metavar='S',
                        help='random seed (default: 42)')
    parser.add_argument(
        '--log_interval',
        type=int,
        default=50,
        help='how many batches to wait before logging training status')
    parser.add_argument(
        '--root_folder',
        type=str,
        default='data/usps2mnist/',
        help="The folder containing the datasets and the lists")
    parser.add_argument('--output_dir',
                        type=str,
                        default='results',
                        help="output directory")
    parser.add_argument(
        "-u",
        "--mu",
        help="Hyperparameter of the coefficient of the domain adversarial loss",
        type=float,
        default=1.0)
    parser.add_argument('--ratio', type=float, default=0, help='ratio option')
    parser.add_argument('--ma',
                        type=float,
                        default=0.5,
                        help='weight for the moving average of iw')
    args = parser.parse_args()
    args.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    # Running the JSD experiment on fewer epochs for efficiency
    if args.ratio >= 100:
        args.epochs = 25

    print('Running {} on {} for {} epochs on task {}'.format(
        args.method, args.device, args.epochs, args.task))

    # Set random number seed.
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    os.environ["CUDA_VISIBLE_DEVICES"] = '0'

    if args.task == 'usps2mnist':

        # CDAN parameters
        decay_epoch = 6
        decay_frac = 0.5
        lr = 0.02
        start_epoch = 1
        model = network.LeNet(args.ma)
        build_dataset = build_uspsmnist

        source_list = os.path.join(args.root_folder, 'usps_train.txt')
        source_path = os.path.join(args.root_folder, 'usps_train_dataset.pkl')
        target_list = os.path.join(args.root_folder, 'mnist_train.txt')
        target_path = os.path.join(args.root_folder, 'mnist_train_dataset.pkl')
        test_list = os.path.join(args.root_folder, 'mnist_test.txt')
        test_path = os.path.join(args.root_folder, 'mnist_test_dataset.pkl')

    elif args.task == 'mnist2usps':

        decay_epoch = 5
        decay_frac = 0.5
        lr = 0.02
        start_epoch = 1
        model = network.LeNet(args.ma)
        build_dataset = build_uspsmnist

        source_list = os.path.join(args.root_folder, 'mnist_train.txt')
        source_path = os.path.join(args.root_folder, 'mnist_train_dataset.pkl')
        target_list = os.path.join(args.root_folder, 'usps_train.txt')
        target_path = os.path.join(args.root_folder, 'usps_train_dataset.pkl')
        test_list = os.path.join(args.root_folder, 'usps_test.txt')
        test_path = os.path.join(args.root_folder, 'usps_test_dataset.pkl')

    else:
        raise Exception('Task cannot be recognized!')

    out_log_file = open(os.path.join(args.output_dir, "log.txt"), "w")
    out_log_file_train = open(os.path.join(args.output_dir, "log_train.txt"),
                              "w")
    if not os.path.exists(args.output_dir):
        os.mkdir(args.output_dir)

    model = model.to(args.device)
    class_num = 10

    if args.lr > 0:
        lr = args.lr

    print('Starting loading data')
    sys.stdout.flush()
    t_data = time.time()
    if os.path.exists(source_path):
        print('Found existing dataset for source')
        with open(source_path, 'rb') as f:
            [source_samples, source_labels] = pickle.load(f)
            source_samples, source_labels = torch.Tensor(source_samples).to(
                args.device), torch.LongTensor(source_labels).to(args.device)
    else:
        print('Building dataset for source and writing to {}'.format(
            source_path))
        source_samples, source_labels = build_dataset(source_list, source_path,
                                                      args.root_folder,
                                                      args.device)

    if os.path.exists(target_path):
        print('Found existing dataset for target')
        with open(target_path, 'rb') as f:
            [target_samples, target_labels] = pickle.load(f)
            target_samples, target_labels = torch.Tensor(target_samples).to(
                args.device), torch.LongTensor(target_labels).to(args.device)
    else:
        print('Building dataset for target and writing to {}'.format(
            target_path))
        target_samples, target_labels = build_dataset(target_list, target_path,
                                                      args.root_folder,
                                                      args.device)

    if os.path.exists(test_path):
        print('Found existing dataset for test')
        with open(test_path, 'rb') as f:
            [test_samples, test_labels] = pickle.load(f)
            test_samples, test_labels = torch.Tensor(test_samples).to(
                args.device), torch.LongTensor(test_labels).to(args.device)
    else:
        print('Building dataset for test and writing to {}'.format(test_path))
        test_samples, test_labels = build_dataset(test_list, test_path,
                                                  args.root_folder,
                                                  args.device)

    print('Data loaded in {}'.format(time.time() - t_data))

    if args.ratio == 1:
        # RATIO OPTION 1
        # 30% of the samples from the first 5 classes
        print('Using option 1, ie [0.3] * 5 + [1] * 5')
        ratios_source = [0.3] * 5 + [1] * 5
        ratios_target = [1] * 10
    elif args.ratio >= 200:
        s_ = subsampling[int(args.ratio) % 100]
        ratios_source = s_[0]
        ratios_target = [1] * 10
        print(
            'Using random subset ratio {} of the source, with theoretical jsd {}'
            .format(args.ratio, s_[1]))
    elif 200 > args.ratio >= 100:
        s_ = subsampling[int(args.ratio) % 100]
        ratios_source = [1] * 10
        ratios_target = s_[0]
        print(
            'Using random subset ratio {} of the target, with theoretical jsd {}'
            .format(args.ratio, s_[1]))
    else:
        # ORIGINAL DATASETS
        print('Using original datasets')
        ratios_source = [1] * 10
        ratios_target = [1] * 10
    ratios_test = ratios_target

    # Subsample dataset if need be
    source_samples, source_labels = sample_ratios(source_samples,
                                                  source_labels, ratios_source)
    target_samples, target_labels = sample_ratios(target_samples,
                                                  target_labels, ratios_target)
    test_samples, test_labels = sample_ratios(test_samples, test_labels,
                                              ratios_test)

    # compute labels distribution on the source and target domain
    source_label_distribution = np.zeros((class_num))
    for img in source_labels:
        source_label_distribution[int(img.item())] += 1
    print("Total source samples: {}".format(np.sum(source_label_distribution)),
          flush=True)
    print("Source samples per class: {}".format(source_label_distribution))
    source_label_distribution /= np.sum(source_label_distribution)
    write_list(out_log_file, source_label_distribution)
    print("Source label distribution: {}".format(source_label_distribution))
    target_label_distribution = np.zeros((class_num))
    for img in target_labels:
        target_label_distribution[int(img.item())] += 1
    print("Total target samples: {}".format(np.sum(target_label_distribution)),
          flush=True)
    print("Target samples per class: {}".format(target_label_distribution))
    target_label_distribution /= np.sum(target_label_distribution)
    write_list(out_log_file, target_label_distribution)
    print("Target label distribution: {}".format(target_label_distribution))
    test_label_distribution = np.zeros((class_num))
    for img in test_labels:
        test_label_distribution[int(img.item())] += 1
    print("Test samples per class: {}".format(test_label_distribution))
    test_label_distribution /= np.sum(test_label_distribution)
    write_list(out_log_file, test_label_distribution)
    print("Test label distribution: {}".format(test_label_distribution))
    mixture = (source_label_distribution + target_label_distribution) / 2
    jsd = (scipy.stats.entropy(source_label_distribution, qk=mixture) +
           scipy.stats.entropy(target_label_distribution, qk=mixture)) / 2
    print("JSD source to target : {}".format(jsd))
    mixture_2 = (test_label_distribution + target_label_distribution) / 2
    jsd_2 = (scipy.stats.entropy(test_label_distribution, qk=mixture_2) +
             scipy.stats.entropy(target_label_distribution, qk=mixture_2)) / 2
    print("JSD test to target : {}".format(jsd_2))
    out_wei_file = open(
        os.path.join(args.output_dir, "log_weights_{}.txt".format(jsd)), "w")
    write_list(out_wei_file, [round(x, 4) for x in source_label_distribution])
    write_list(out_wei_file, [round(x, 4) for x in target_label_distribution])
    out_wei_file.write(str(jsd) + "\n")
    true_weights = torch.tensor(target_label_distribution /
                                source_label_distribution,
                                dtype=torch.float,
                                requires_grad=False)[:, None].to(args.device)
    print("True weights : {}".format(true_weights[:, 0].cpu().numpy()))

    if 'CDAN' in args.method:
        ad_net = network.AdversarialNetwork(model.output_num() * class_num,
                                            500,
                                            sigmoid='WDANN' not in args.method)
    else:
        ad_net = network.AdversarialNetwork(model.output_num(),
                                            500,
                                            sigmoid='WDANN' not in args.method)

    ad_net = ad_net.to(args.device)

    optimizer = optim.SGD(model.parameters(),
                          lr=lr,
                          weight_decay=0.0005,
                          momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(),
                             lr=lr,
                             weight_decay=0.0005,
                             momentum=0.9)

    # Maintain two quantities for the QP.
    cov_mat = torch.tensor(np.zeros((class_num, class_num), dtype=np.float32),
                           requires_grad=False).to(args.device)
    pseudo_target_label = torch.tensor(np.zeros((class_num, 1),
                                                dtype=np.float32),
                                       requires_grad=False).to(args.device)
    # Maintain one weight vector for BER.
    class_weights = torch.tensor(1.0 / source_label_distribution,
                                 dtype=torch.float,
                                 requires_grad=False).to(args.device)

    for epoch in range(1, args.epochs + 1):
        start_time_test = time.time()
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * decay_frac
        test(args,
             epoch,
             model,
             test_samples,
             test_labels,
             start_time_test,
             out_log_file,
             name='Target test')
        train(args, model, ad_net, source_samples, source_labels,
              target_samples, target_labels, optimizer, optimizer_ad, epoch,
              start_epoch, args.method, source_label_distribution,
              out_wei_file, cov_mat, pseudo_target_label, class_weights,
              true_weights)
    test(args,
         epoch + 1,
         model,
         test_samples,
         test_labels,
         start_time_test,
         out_log_file,
         name='Target test')
    test(args,
         epoch + 1,
         model,
         source_samples,
         source_labels,
         start_time_test,
         out_log_file_train,
         name='Source train')
Exemple #7
0
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('--method',
                        type=str,
                        default='CDAN-E',
                        choices=['CDAN', 'CDAN-E', 'DANN'])
    parser.add_argument('--task',
                        default='MNIST2USPS',
                        help='MNIST2USPS or MNIST2USPS')
    parser.add_argument('--batch_size',
                        type=int,
                        default=64,
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size',
                        type=int,
                        default=1000,
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs',
                        type=int,
                        default=100,
                        metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr',
                        type=float,
                        default=0.01,
                        metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.5,
                        metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--gpu_id',
                        default='0',
                        type=str,
                        help='cuda device id')
    parser.add_argument('--seed',
                        type=int,
                        default=1,
                        metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument(
        '--log_interval',
        type=int,
        default=10,
        help='how many batches to wait before logging training status')
    parser.add_argument('--random',
                        type=bool,
                        default=False,
                        help='whether to use random')
    parser.add_argument('--mdd_weight', type=float, default=0.05)
    parser.add_argument('--entropic_weight', type=float, default=0)
    parser.add_argument("--use_seed", type=bool, default=True)
    args = parser.parse_args()
    import random
    if (args.use_seed):
        torch.manual_seed(args.seed)

        np.random.seed(args.seed)
        random.seed(args.seed)
        torch.backends.cudnn.deterministic = True
    import os.path as osp
    import datetime
    config = {}
    config["output_path"] = "snapshot/" + args.task
    config['seed'] = args.seed
    config["torch_seed"] = torch.initial_seed()
    config["torch_cuda_seed"] = torch.cuda.initial_seed()

    config["mdd_weight"] = args.mdd_weight
    config["entropic_weight"] = args.entropic_weight
    if not osp.exists(config["output_path"]):
        os.system('mkdir -p ' + config["output_path"])
    config["out_file"] = open(
        osp.join(
            config["output_path"],
            "log_{}_{}.txt".format(args.task,
                                   str(datetime.datetime.utcnow()))), "w")

    torch.manual_seed(args.seed)
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id

    if args.task == 'USPS2MNIST':
        source_list = 'data/usps2mnist/usps_train.txt'
        target_list = 'data/usps2mnist/mnist_train.txt'
        test_list = 'data/usps2mnist/mnist_test.txt'
        start_epoch = 1
        decay_epoch = 6
    elif args.task == 'MNIST2USPS':
        source_list = 'data/usps2mnist/mnist_train.txt'
        target_list = 'data/usps2mnist/usps_train.txt'
        test_list = 'data/usps2mnist/usps_test.txt'
        start_epoch = 1
        decay_epoch = 5
    else:
        raise Exception('task cannot be recognized!')

    train_loader = torch.utils.data.DataLoader(ImageList(
        open(source_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=1,
                                               drop_last=True)
    train_loader1 = torch.utils.data.DataLoader(ImageList(
        open(target_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                                batch_size=args.batch_size,
                                                shuffle=True,
                                                num_workers=1,
                                                drop_last=True)
    test_loader = torch.utils.data.DataLoader(ImageList(
        open(test_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                              batch_size=args.test_batch_size,
                                              shuffle=True,
                                              num_workers=1)

    model = network.LeNet()
    model = model.cuda()
    class_num = 10

    if args.random:
        random_layer = network.RandomLayer([model.output_num(), class_num],
                                           500)
        ad_net = network.AdversarialNetwork(500, 500)
        random_layer.cuda()
    else:
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num() * class_num,
                                            500)
    ad_net = ad_net.cuda()
    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          weight_decay=0.0005,
                          momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(),
                             lr=args.lr,
                             weight_decay=0.0005,
                             momentum=0.9)
    config["out_file"].write(str(config) + "\n")
    config["out_file"].flush()
    for epoch in range(1, args.epochs + 1):
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * 0.5
        train(args, model, ad_net, random_layer, train_loader, train_loader1,
              optimizer, optimizer_ad, epoch, start_epoch, args.method)
        test(args, epoch, config, model, test_loader)
def main():
    # Training settings
    parser = argparse.ArgumentParser(description='CDAN USPS MNIST')
    parser.add_argument('--method', type=str, default='DANN')
    parser.add_argument('--task', default='MNIST2USPS', help='task to perform')
    parser.add_argument('--batch_size',
                        type=int,
                        default=64,
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test_batch_size',
                        type=int,
                        default=1000,
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs',
                        type=int,
                        default=20,
                        metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr',
                        type=float,
                        default=0.01,
                        metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.5,
                        metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--gpu_id',
                        type=str,
                        default='0',
                        help='cuda device id')
    parser.add_argument('--seed',
                        type=int,
                        default=1,
                        metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument(
        '--log_interval',
        type=int,
        default=10,
        help='how many batches to wait before logging training status')
    parser.add_argument('--random',
                        type=bool,
                        default=False,
                        help='whether to use random')
    parser.add_argument('--weight',
                        type=int,
                        default=0,
                        help="whether use weights during transfer")
    parser.add_argument('--temp_max',
                        type=float,
                        default=5.,
                        help="weight relaxation parameter")
    parser.add_argument('--alpha',
                        type=float,
                        default=5.,
                        help="weight relaxation parameter")

    args = parser.parse_args()

    torch.manual_seed(args.seed)
    os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu_id

    if args.task == 'USPS2MNIST':
        source_list = '../data/usps2mnist/usps_train_shift_20.txt'
        target_list = '../data/usps2mnist/mnist_train.txt'
        test_list = '../data/usps2mnist/mnist_test.txt'
        start_epoch = 1
        decay_epoch = 6
    elif args.task == 'MNIST2USPS':
        source_list = '../data/usps2mnist/mnist_train_shift_20.txt'
        target_list = '../data/usps2mnist/usps_train.txt'
        test_list = '../data/usps2mnist/usps_test.txt'
        start_epoch = 1
        decay_epoch = 5
    else:
        raise Exception('task cannot be recognized!')

    train_loader = torch.utils.data.DataLoader(ImageList(
        open(source_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=1,
                                               drop_last=True)
    train_loader1 = torch.utils.data.DataLoader(ImageList(
        open(target_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                                batch_size=args.batch_size,
                                                shuffle=True,
                                                num_workers=1,
                                                drop_last=True)
    test_loader = torch.utils.data.DataLoader(ImageList(
        open(test_list).readlines(),
        transform=transforms.Compose([
            transforms.Resize((28, 28)),
            transforms.ToTensor(),
            transforms.Normalize((0.5, ), (0.5, ))
        ]),
        mode='L'),
                                              batch_size=args.test_batch_size,
                                              shuffle=True,
                                              num_workers=1)

    model = network.LeNet()
    model = model.cuda()
    class_num = 10

    if args.method is 'DANN':
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num(), 500)

    elif args.method is 'Y_DAN':
        random_layer = None
        ad_net = network.AdversarialNetwork(model.output_num(),
                                            500,
                                            output_dim=class_num)

    elif args.method is 'CDAN':
        if args.random:
            random_layer = network.RandomLayer([model.output_num(), class_num],
                                               500)
            random_layer.cuda()
        else:
            random_layer = None
        ad_net = network.AdversarialNetwork(500 * 10, 500)
    else:
        raise ValueError('Method cannot be recognized.')

    ad_w_net = network.AdversarialNetwork(model.output_num(),
                                          500,
                                          output_dim=1)

    ad_net = ad_net.cuda()
    ad_w_net = ad_w_net.cuda()

    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          weight_decay=0.0005,
                          momentum=0.9)
    optimizer_ad = optim.SGD(ad_net.parameters(),
                             lr=args.lr,
                             weight_decay=0.0005,
                             momentum=0.9)
    optimizer_ad_w = optim.SGD(ad_w_net.parameters(),
                               lr=args.lr,
                               weight_decay=0.0005,
                               momentum=0.9)

    for epoch in range(1, args.epochs + 1):
        print("epoch", epoch)
        if epoch % decay_epoch == 0:
            for param_group in optimizer.param_groups:
                param_group["lr"] = param_group["lr"] * 0.5
        train(args,
              epoch,
              model,
              ad_net,
              ad_w_net,
              train_loader,
              train_loader1,
              optimizer,
              optimizer_ad,
              optimizer_ad_w,
              epoch,
              start_epoch,
              args.method,
              random_layer=random_layer)
        test(args, model, test_loader)