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()}
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)
def run(config, model): ## 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=False) 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=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"] model.train(False) temp_acc = image_classification_test(dset_loaders, model, n_class=n_class) log_str = "precision: {:.5f}".format(temp_acc) print(log_str)
def save(config, model, save_name): ## 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=False) 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=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"] model.train(False) save_feature(dset_loaders, model, './snapshot/model/', save_name)
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
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
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()
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=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) 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) 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() ## 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"])) 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"]) best_acc = 0.0 best_model = nn.Sequential(base_network) each_log = "" 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}, transfer_loss:{:.4f}, classifier_loss:{:.4f}, total_loss:{:.4f}" \ .format(i, temp_acc, transfer_loss.item(), classifier_loss.item(), total_loss.item()) config["out_file"].write(log_str + "\n") config["out_file"].flush() print(log_str) config["out_file"].write(each_log) config["out_file"].flush() each_log = "" loss_params = config["loss"] ## 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 = 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) labels_target_fake = torch.max(nn.Softmax(dim=1)(outputs_target), 1)[1] labels = torch.cat((labels_source, labels_target_fake)) entropy = loss.Entropy(softmax_out) transfer_loss = loss.CDAN([features, softmax_out], ad_net, entropy, network.calc_coeff(i), random_layer) classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) mdd_loss = loss.mdd_loss(features=features, labels=labels, left_weight=args.left_weight, right_weight=args.right_weight) max_entropy_loss = loss.EntropicConfusion(features) total_loss = loss_params["trade_off"] * transfer_loss \ + args.cls_weight * classifier_loss \ + args.mdd_weight * mdd_loss \ + args.entropic_weight * max_entropy_loss total_loss.backward() optimizer.step() log_str = "iter: {:05d},transfer_loss:{:.4f}, classifier_loss:{:.4f}, mdd_loss:{:4f}," \ "max_entropy_loss:{:.4f},total_loss:{:.4f}" \ .format(i, transfer_loss.item(), classifier_loss.item(), mdd_loss.item(), max_entropy_loss.item(), total_loss.item()) each_log += log_str + "\n" torch.save( best_model, config['model_output_path'] + "{}_{}_p-{}_e-{}".format( config['log_name'], str(best_acc), str(config["mdd_weight"]), str(config["entropic_weight"]))) return best_acc
def train(config): ## set up summary writer writer = SummaryWriter(config['output_path']) # set up early stop early_stop_engine = EarlyStopping(config["early_stop_patience"]) ## 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_num = config["network"]["params"]["class_num"] loss_params = config["loss"] class_criterion = nn.CrossEntropyLoss() transfer_criterion = loss.PADA center_criterion = loss_params["loss_type"](num_classes=class_num, feat_dim=config["network"]["params"]["bottleneck_dim"]) ## prepare data dsets = {} dset_loaders = {} data_config = config["data"] dsets["source"] = ImageList(stratify_sampling(open(data_config["source"]["list_path"]).readlines(), prep_config["source_size"]), \ transform=prep_dict["source"]) dset_loaders["source"] = util_data.DataLoader(dsets["source"], \ batch_size=data_config["source"]["batch_size"], \ shuffle=True, num_workers=1) dsets["target"] = ImageList(stratify_sampling(open(data_config["target"]["list_path"]).readlines(), prep_config["target_size"]), \ transform=prep_dict["target"]) dset_loaders["target"] = util_data.DataLoader(dsets["target"], \ batch_size=data_config["target"]["batch_size"], \ shuffle=True, num_workers=1) if prep_config["test_10crop"]: for i in range(10): dsets["test"+str(i)] = ImageList(stratify_sampling(open(data_config["test"]["list_path"]).readlines(), ratio=prep_config['target_size']), \ 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=1) dsets["target"+str(i)] = ImageList(stratify_sampling(open(data_config["target"]["list_path"]).readlines(), ratio=prep_config['target_size']), \ 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=1) else: dsets["test"] = ImageList(stratify_sampling(open(data_config["test"]["list_path"]).readlines(), ratio=prep_config['target_size']), \ transform=prep_dict["test"]) dset_loaders["test"] = util_data.DataLoader(dsets["test"], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=1) dsets["target_test"] = ImageList(stratify_sampling(open(data_config["target"]["list_path"]).readlines(), ratio=prep_config['target_size']), \ transform=prep_dict["test"]) dset_loaders["target_test"] = MyDataLoader(dsets["target_test"], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=1) config['out_file'].write("dataset sizes: source={}, target={}\n".format( len(dsets["source"]), len(dsets["target"]))) ## 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_mult":1, 'decay_mult':2}, \ {"params":base_network.bottleneck.parameters(), "lr_mult":10, 'decay_mult':2}, \ {"params":base_network.fc.parameters(), "lr_mult":10, 'decay_mult':2}] else: parameter_list = [{"params":base_network.feature_layers.parameters(), "lr_mult":1, 'decay_mult':2}, \ {"params":base_network.fc.parameters(), "lr_mult":10, 'decay_mult':2}] else: parameter_list = [{"params":base_network.parameters(), "lr_mult":1, 'decay_mult':2}] ## add additional network for some methods ad_net = network.AdversarialNetwork(base_network.output_num()) gradient_reverse_layer = network.AdversarialLayer(high_value=config["high"]) #, #max_iter_value=config["num_iterations"]) if use_gpu: ad_net = ad_net.cuda() parameter_list.append({"params":ad_net.parameters(), "lr_mult":10, 'decay_mult':2}) parameter_list.append({"params":center_criterion.parameters(), "lr_mult": 10, 'decay_mult':1}) ## 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 for i in range(config["num_iterations"]): if i % config["test_interval"] == 0: base_network.train(False) if config['loss']['ly_type'] == "cosine": temp_acc = image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"], \ gpu=use_gpu) elif config['loss']['ly_type'] == "euclidean": temp_acc, _ = distance_classification_test(dset_loaders, \ base_network, center_criterion.centers.detach(), test_10crop=prep_config["test_10crop"], \ gpu=use_gpu) else: raise ValueError("no test method for cls loss: {}".format(config['loss']['ly_type'])) snapshot_obj = {'step': i, "base_network": base_network.state_dict(), 'precision': temp_acc, } if config["loss"]["loss_name"] != "laplacian" and config["loss"]["ly_type"] == "euclidean": snapshot_obj['center_criterion'] = center_criterion.state_dict() if temp_acc > best_acc: best_acc = temp_acc # save best model torch.save(snapshot_obj, osp.join(config["output_path"], "best_model.pth.tar")) log_str = "iter: {:05d}, {} precision: {:.5f}\n".format(i, config['loss']['ly_type'], temp_acc) config["out_file"].write(log_str) config["out_file"].flush() writer.add_scalar("precision", temp_acc, i) if early_stop_engine.is_stop_training(temp_acc): config["out_file"].write("no improvement after {}, stop training at step {}\n".format( config["early_stop_patience"], i)) # config["out_file"].write("finish training! \n") break if (i+1) % config["snapshot_interval"] == 0: torch.save(snapshot_obj, osp.join(config["output_path"], "iter_{:05d}_model.pth.tar".format(i))) ## 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) source_batch_size = inputs_source.size(0) if config['loss']['ly_type'] == 'cosine': features, logits = base_network(inputs) source_logits = logits.narrow(0, 0, source_batch_size) elif config['loss']['ly_type'] == 'euclidean': features, _ = base_network(inputs) logits = -1.0 * loss.distance_to_centroids(features, center_criterion.centers.detach()) source_logits = logits.narrow(0, 0, source_batch_size) ad_net.train(True) weight_ad = torch.ones(inputs.size(0)) transfer_loss = transfer_criterion(features, ad_net, gradient_reverse_layer, \ weight_ad, use_gpu) ad_out, _ = ad_net(features.detach()) ad_acc, source_acc_ad, target_acc_ad = domain_cls_accuracy(ad_out) # source domain classification task loss classifier_loss = class_criterion(source_logits, labels_source) # fisher loss on labeled source domain fisher_loss, fisher_intra_loss, fisher_inter_loss, center_grad = center_criterion(features.narrow(0, 0, int(inputs.size(0)/2)), labels_source, inter_class=config["loss"]["inter_type"], intra_loss_weight=loss_params["intra_loss_coef"], inter_loss_weight=loss_params["inter_loss_coef"]) # entropy minimization loss em_loss = loss.EntropyLoss(nn.Softmax(dim=1)(logits)) # final loss total_loss = loss_params["trade_off"] * transfer_loss \ + fisher_loss \ + loss_params["em_loss_coef"] * em_loss \ + classifier_loss total_loss.backward() if center_grad is not None: # clear mmc_loss center_criterion.centers.grad.zero_() # Manually assign centers gradients other than using autograd center_criterion.centers.backward(center_grad) optimizer.step() if i % config["log_iter"] == 0: config['out_file'].write('iter {}: total loss={:0.4f}, transfer loss={:0.4f}, cls loss={:0.4f}, ' 'em loss={:0.4f}, ' 'mmc loss={:0.4f}, intra loss={:0.4f}, inter loss={:0.4f}, ' 'ad acc={:0.4f}, source_acc={:0.4f}, target_acc={:0.4f}\n'.format( i, total_loss.data.cpu().float().item(), transfer_loss.data.cpu().float().item(), classifier_loss.data.cpu().float().item(), em_loss.data.cpu().float().item(), fisher_loss.cpu().float().item(), fisher_intra_loss.cpu().float().item(), fisher_inter_loss.cpu().float().item(), ad_acc, source_acc_ad, target_acc_ad, )) config['out_file'].flush() writer.add_scalar("total_loss", total_loss.data.cpu().float().item(), i) writer.add_scalar("cls_loss", classifier_loss.data.cpu().float().item(), i) writer.add_scalar("transfer_loss", transfer_loss.data.cpu().float().item(), i) writer.add_scalar("ad_acc", ad_acc, i) writer.add_scalar("d_loss/total", fisher_loss.data.cpu().float().item(), i) writer.add_scalar("d_loss/intra", fisher_intra_loss.data.cpu().float().item(), i) writer.add_scalar("d_loss/inter", fisher_inter_loss.data.cpu().float().item(), i) return best_acc
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=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) 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) # class_num = config["network"]["params"]["class_num"] n_class = config["network"]["params"]["class_num"] ## set base network net_config = config["network"] base_network_stu = net_config["name"](**net_config["params"]).cuda() base_network_tea = net_config["name"](**net_config["params"]).cuda() ## add additional network for some methods if config["loss"]["random"]: random_layer = network.RandomLayer([base_network_stu.output_num(), n_class], config["loss"]["random_dim"]) ad_net = network.AdversarialNetwork(config["loss"]["random_dim"], 1024) else: random_layer = None if config['method'] == 'DANN': ad_net = network.AdversarialNetwork(base_network_stu.output_num(), 1024)#DANN else: ad_net = network.AdversarialNetwork(base_network_stu.output_num() * n_class, 1024) if config["loss"]["random"]: random_layer.cuda() ad_net = ad_net.cuda() ad_net2 = network.AdversarialNetwork(n_class, n_class*4) ad_net2.cuda() parameter_list = base_network_stu.get_parameters() + ad_net.get_parameters() teacher_params = list(base_network_tea.parameters()) for param in teacher_params: param.requires_grad = False ## set optimizer optimizer_config = config["optimizer"] optimizer = optimizer_config["type"](parameter_list, \ **(optimizer_config["optim_params"])) teacher_optimizer = EMAWeightOptimizer(base_network_tea, base_network_stu, alpha=0.99) 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"]) len_train_target = len(dset_loaders["target"]) best_acc = 0.0 output1(log_name) loss1, loss2, loss3, loss4, loss5,loss6 = 0, 0, 0, 0, 0,0 output1(' ======= DA TRAINING ======= ') best1 = 0 f_t_result = [] max_iter = config["num_iterations"] for i in range(max_iter+1): if i % config["test_interval"] == config["test_interval"] - 1 and i > 1500: base_network_tea.train(False) base_network_stu.train(False) # print("test") if 'MT' in config['method']: temp_acc = image_classification_test(dset_loaders, base_network_tea, test_10crop=prep_config["test_10crop"]) if temp_acc > best_acc: best_acc = temp_acc log_str = "iter: {:05d}, tea_precision: {:.5f}".format(i, temp_acc) output1(log_str) # # if i > 20001 and best_acc < 0.69: # break # # if temp_acc < 0.67: # break # # if i > 30001 and best_acc < 0.71: # break # torch.save(base_network_tea, osp.join(path, "_model.pth.tar")) # temp_acc = image_classification_test(dset_loaders, # base_network_stu, test_10crop=prep_config["test_10crop"]) if temp_acc > best_acc: best_acc = temp_acc torch.save(base_network_stu, osp.join(path, "_model.pth.tar")) # log_str = "iter: {:05d}, stu_precision: {:.5f}".format(i, temp_acc) # output1(log_str) else: temp_acc = image_classification_test(dset_loaders, base_network_stu, test_10crop=prep_config["test_10crop"]) if temp_acc > best_acc: best_acc = temp_acc torch.save(base_network_stu, osp.join(path,"_model.pth.tar")) log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc) output1(log_str) loss_params = config["loss"] ## train one iter base_network_stu.train(True) base_network_tea.train(True) ad_net.train(True) optimizer = lr_scheduler(optimizer, i, **schedule_param) optimizer.zero_grad() if i % len_train_target == 0: iter_target = iter(dset_loaders["target"]) if i % len_train_source == 0: iter_source = iter(dset_loaders["source"]) 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_stu(inputs_source) features_target_stu, outputs_target_stu = base_network_stu(inputs_target) features_target_tea, outputs_target_tea = base_network_tea(inputs_target) softmax_out_source = nn.Softmax(dim=1)(outputs_source) softmax_out_target_stu = nn.Softmax(dim=1)(outputs_target_stu) softmax_out_target_tea = nn.Softmax(dim=1)(outputs_target_tea) features = torch.cat((features_source, features_target_stu), dim=0) if 'MT' in config['method']: softmax_out = torch.cat((softmax_out_source, softmax_out_target_tea), dim=0) else: softmax_out = torch.cat((softmax_out_source, softmax_out_target_stu), dim=0) vat_loss = VAT(base_network_stu).cuda() n, d = features_source.shape decay = cal_decay(start=1,end=0.6,i = i) # image number in each class s_labels = labels_source t_max, t_labels = torch.max(softmax_out_target_tea, 1) t_max, t_labels = t_max.cuda(), t_labels.cuda() if config['method'] == 'DANN+dis' or config['method'] == 'CDRL': pass elif config['method'] == 'RESNET': classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = classifier_loss elif config['method'] == 'CDAN+E': entropy = losssntg.Entropy(softmax_out) ad_loss = losssntg.CDANori([features, softmax_out], ad_net, entropy, network.calc_coeff(i), random_layer) transfer_loss = loss_params["trade_off"] * ad_loss classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN': ad_loss = losssntg.CDANori([features, softmax_out], ad_net, None, None, random_layer) transfer_loss = loss_params["trade_off"] * ad_loss classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'DANN': ad_loss = losssntg.DANN(features, ad_net) transfer_loss = loss_params["trade_off"] * ad_loss classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN+MT': th = config['th'] ad_loss = losssntg.CDANori([features, softmax_out], ad_net, None, None, random_layer) unsup_loss = compute_aug_loss(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) unsup_loss = compute_aug_loss2(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) transfer_loss = loss_params["trade_off"] * ad_loss \ + 0.01 * unsup_loss classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN+MT+VAT': cent = ConditionalEntropyLoss().cuda() ad_loss = losssntg.CDANori([features, softmax_out], ad_net, None, None, random_layer) unsup_loss = compute_aug_loss(softmax_out_target_stu, softmax_out_target_tea, n_class) loss_trg_cent = 1e-2 * cent(outputs_target_stu) loss_trg_vat = 1e-2 * vat_loss(inputs_target, outputs_target_stu) transfer_loss = loss_params["trade_off"] * ad_loss \ + 0.001*(unsup_loss + loss_trg_cent + loss_trg_vat) classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN+MT+cent+VAT+temp': th = 0.7 ad_loss = losssntg.CDANori([features, softmax_out], ad_net, None, None, random_layer) unsup_loss = compute_aug_loss(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) cent = ConditionalEntropyLoss().cuda() # loss_src_vat = vat_loss(inputs_source, outputs_source) loss_trg_cent = 1e-2 * cent(outputs_target_stu) loss_trg_vat = 1e-2 * vat_loss(inputs_target, outputs_target_stu) transfer_loss = loss_params["trade_off"] * ad_loss \ + unsup_loss + loss_trg_cent + loss_trg_vat # temperature classifier_loss = nn.NLLLoss()(nn.LogSoftmax(1)(outputs_source / 1.05), labels_source) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN+MT+cent+VAT+weightCross+T': if i % len_train_target == 0: if i != 0: # print(cnt) cnt = torch.tensor(cnt).float() weight = cnt.sum() - cnt weight = weight.cuda() else: weight = torch.ones(n_class).cuda() cnt = [0] * n_class for j in t_labels: cnt[j.item()] += 1 a = config['a'] b = config['b'] th = config['th'] temp = config['temp'] ad_loss = losssntg.CDANori([features, softmax_out], ad_net, None, None, random_layer) unsup_loss = compute_aug_loss2(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) # cbloss = compute_cbloss(softmax_out_target_stu, n_class, cls_balance=0.05) # unsup_loss = compute_aug_loss(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) cent = ConditionalEntropyLoss().cuda() # loss_src_vat = vat_loss(inputs_source, outputs_source) loss_trg_cent = 1e-2 * cent(outputs_target_stu) loss_trg_vat = 1e-2 * vat_loss(inputs_target, outputs_target_stu) classifier_loss = nn.CrossEntropyLoss(weight=weight)(outputs_source/temp, labels_source) # classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) transfer_loss = loss_params["trade_off"] * ad_loss \ + a*unsup_loss + b*(loss_trg_vat+loss_trg_cent) total_loss = transfer_loss + classifier_loss elif config['method'] == 'CDAN+MT+E+VAT+weightCross+T': entropy = losssntg.Entropy(softmax_out) if i % len_train_target == 0: if i != 0: # print(cnt) cnt = torch.tensor(cnt).float() weight = cnt.sum() - cnt weight = weight.cuda() else: weight = torch.ones(n_class).cuda() cnt = [0] * n_class for j in t_labels: cnt[j.item()] += 1 a = config['a'] b = config['b'] th = config['th'] temp = config['temp'] ad_loss = losssntg.CDANori([features, softmax_out], ad_net, entropy, network.calc_coeff(i), random_layer) # unsup_loss = compute_aug_loss2(softmax_out_target_stu, softmax_out_target_tea, n_class,confidence_thresh=th) # cbloss = compute_cbloss(softmax_out_target_stu, n_class, cls_balance=0.05) unsup_loss = compute_aug_loss(softmax_out_target_stu, softmax_out_target_tea, n_class, confidence_thresh=th) cent = ConditionalEntropyLoss().cuda() # loss_src_vat = vat_loss(inputs_source, outputs_source) loss_trg_cent = 1e-2 * cent(outputs_target_stu) loss_trg_vat = 1e-2 * vat_loss(inputs_target, outputs_target_stu) classifier_loss = nn.CrossEntropyLoss(weight=weight)(outputs_source / temp, labels_source) # classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) transfer_loss = loss_params["trade_off"] * ad_loss \ + a * unsup_loss + b * (loss_trg_vat + loss_trg_cent) total_loss = transfer_loss + classifier_loss # adout # ad_out1 = ad_net(features_source) # w = 1-ad_out1 # c = w * nn.CrossEntropyLoss(reduction='none')(outputs_source, labels_source) # classifier_loss = c.mean() # total_loss = transfer_loss + classifier_loss total_loss.backward() optimizer.step() teacher_optimizer.step() loss1 += ad_loss.item() loss2 += classifier_loss.item() # loss3 += unsup_loss.item() # loss4 += loss_trg_cent.item() # loss5 += loss_trg_vat.item() # loss6 += cbloss.item() # dis_sloss_l += sloss_l.item() if i % 50 == 0 and i != 0: output1('iter:{:d}, ad_loss_D:{:.2f}, closs:{:.2f}, unsup_loss:{:.2f}, loss_trg_cent:{:.2f}, loss_trg_vatcd:{:.2f}, cbloss:{:.2f}' .format(i, loss1, loss2, loss3, loss4, loss5,loss6)) loss1, loss2, loss3, loss4, loss5, loss6 = 0, 0, 0, 0, 0, 0 # torch.save(best_model, osp.join(path, "best_model.pth.tar")) return best_acc
dataset_loaders["val"] = torch.utils.data.DataLoader( dataset_list, batch_size=args.batch_size, shuffle=True, num_workers=args.num_workers) dataset_list = ImageList(open(dataset_test).readlines(), transform=prep.image_train(resize_size=256, crop_size=224)) dataset_loaders["test"] = torch.utils.data.DataLoader( dataset_list, batch_size=4, shuffle=False, num_workers=args.num_workers) prep_dict_test = prep.image_test_10crop(resize_size=256, crop_size=224) for i in range(10): dataset_list = ImageList(open(dataset_test).readlines(), transform=prep_dict_test["val" + str(i)]) dataset_loaders["val" + str(i)] = torch.utils.data.DataLoader( dataset_list, batch_size=4, shuffle=False, num_workers=6) # network construction feature_len = 2048 # fine-grained feature extractor + fine-grained label predictor devices = list(range(torch.cuda.device_count())) model_fc = model_no.Resnet50Fc() model_fc = model_fc.to(device) model_fc = nn.DataParallel(model_fc, device_ids=devices) my_fine_net = fine_net(feature_len) my_fine_net = my_fine_net.to(device)
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)
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
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()
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"] 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)) 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 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}, precision: {:.5f}".format(i, temp_acc) config["out_file"].write(log_str) 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))) ## 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) transfer_loss = transfer_criterion(features, ad_net, gradient_reverse_layer, use_gpu) classifier_loss = class_criterion( outputs.narrow(0, 0, inputs.size(0) / 2), labels_source) total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss total_loss.backward() optimizer.step() torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) return best_acc
def transfer_classification(config, name): ## 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类,其中含有source中数据及标签和预处理过程 dsets[data_config["name"]]["train"] = ImageList( open(data_config["list_path"]["train"]).readlines(), transform=prep_dict[data_config["name"]]["train"]) # dset_loaders含有数据batchsize信息等 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 = 12 ## 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: print 'outputnum:', base_network.output_num() classifier_layer = nn.Linear(base_network.output_num(), class_num) ## initialization if net_config["use_bottleneck"]: # 初始化bottlenect层weight bottleneck_layer.weight.data.normal_(0, 0.005) bottleneck_layer.bias.data.fill_(0.1) # nn.sequential按次序封装层 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": 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.cuda() ## set optimizer optimizer_config = config["optimizer"] # 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 max_accuracy = 0 for i in range(config["num_iterations"] + 1): ## test in the train if i % config["test_interval"] == 0 and i != 0: base_network.train(False) classifier_layer.train(False) if net_config["use_bottleneck"]: bottleneck_layer.train(False) accuracy = image_classification_test( dset_loaders["target"], nn.Sequential(base_network, bottleneck_layer, classifier_layer), test_10crop=prep_dict["target"]["test_10crop"], gpu=use_gpu) torch.save(base_network, '../save/nobottle_base_network_' + name + '.pkl') torch.save( classifier_layer, '../save/nobottle_classifier_layer_' + name + '.pkl') print 'save', i if (accuracy > max_accuracy): max_accuracy = accuracy print 'iter{0}accuracy:'.format( i), accuracy, 'max_accuracy:', max_accuracy else: torch.save(base_network, '../save/nobottle_base_network_' + name + '.pkl') torch.save( classifier_layer, '../save/nobottle_classifier_layer_' + name + '.pkl') print 'save', i accuracy = image_classification_test( dset_loaders["target"], nn.Sequential(base_network, classifier_layer), test_10crop=prep_dict["target"]["test_10crop"], gpu=use_gpu) if (accuracy > max_accuracy): max_accuracy = accuracy print 'iter{0}accuracy:'.format( i), accuracy, 'max_accuracy:', max_accuracy 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() 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) classifier_loss = class_criterion( outputs.narrow(0, 0, inputs.size(0) / 2), labels_source) total_loss = classifier_loss total_loss.backward() optimizer.step()
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 = 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) 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 = 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": 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 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) print 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: print image_classification_test( dset_loaders["target"], nn.Sequential(base_network, classifier_layer), test_10crop=prep_dict["target"]["test_10crop"], gpu=use_gpu) loss_test = nn.BCELoss() ## 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) outputs = classifier_layer(features) classifier_loss = class_criterion( outputs.narrow(0, 0, inputs.size(0) / 2), labels_source) ## switch between different transfer loss if loss_config["name"] == "DAN": transfer_loss = transfer_criterion( features.narrow(0, 0, features.size(0) / 2), features.narrow(0, features.size(0) / 2, 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, features.size(0) / 2), softmax_out.narrow(0, 0, softmax_out.size(0) / 2) ], [ features.narrow(0, features.size(0) / 2, features.size(0) / 2), softmax_out.narrow(0, softmax_out.size(0) / 2, softmax_out.size(0) / 2) ], **loss_config["params"]) total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss total_loss.backward() optimizer.step()
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"]]["validation"] = prep.image_test_10crop(resize_size=prep_config["resize_size"], crop_size=prep_config["crop_size"]) else: prep_dict[prep_config["name"]]["validation"] = prep.image_test(resize_size=prep_config["resize_size"], crop_size=prep_config["crop_size"]) print("Data preprocessing done..........::") ## 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("Setting loss done...............::") print("Data Preparation progressing................::") ## 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=2) if "validation" in data_config["list_path"]: if prep_dict[data_config["name"]]["test_10crop"]: for i in range(10): dsets[data_config["name"]]["validation"+str(i)] = ImageList(open(data_config["list_path"]["validation"]).readlines(), transform=prep_dict[data_config["name"]]["validation"]["val"+str(i)]) dset_loaders[data_config["name"]]["validation"+str(i)] = util_data.DataLoader(dsets[data_config["name"]]["validation"+str(i)], batch_size=data_config["batch_size"]["validation"], shuffle=False, num_workers=2) else: dsets[data_config["name"]]["validation"] = ImageList(open(data_config["list_path"]["validation"]).readlines(), transform=prep_dict[data_config["name"]]["validation"]) dset_loaders[data_config["name"]]["validation"] = util_data.DataLoader(dsets[data_config["name"]]["validation"], batch_size=data_config["batch_size"]["validation"], shuffle=False, num_workers=4) class_num = 2 print("Data prepration done.....::") print("Setting base network......::") ## 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(), 256) # bottleneck_layer_1 = nn.Linear(256, 64) classifier_layer = nn.Linear(256, class_num) else: classifier_layer = nn.Linear(base_network.output_num(), class_num) for param in base_network.parameters(): param.requires_grad = True print("Base network set......::") print("Intilializing bottleneck layer....::") ## initialization if net_config["use_bottleneck"]: bottleneck_layer.weight.data.normal_(0, 0.1) bottleneck_layer.bias.data.fill_(0.1) bottleneck_layer = nn.Sequential(bottleneck_layer, nn.ReLU(), nn.Dropout(0.2)) # bottleneck_layer_1.weight.data.normal_(0, 0.1) # bottleneck_layer_1.bias.data.fill_(0.1) # bottleneck_layer_1 = nn.Sequential(bottleneck_layer_1, nn.ReLU(), nn.Dropout(0.2)) classifier_layer.weight.data.normal_(0, 0.01) classifier_layer.bias.data.fill_(0.0) use_gpu = torch.cuda.is_available() # use_gpu = False if use_gpu: if net_config["use_bottleneck"]: bottleneck_layer = bottleneck_layer.cuda() # bottleneck_layer_1 = bottleneck_layer_1.cuda() classifier_layer = classifier_layer.cuda() base_network = base_network.cuda() print("Collect parameters.......") ## collect parameters if net_config["use_bottleneck"]: parameter_list = [{"params":bottleneck_layer.parameters(), "lr":0.1}, {"params":classifier_layer.parameters(), "lr":0.1}] else: parameter_list = [{"params":classifier_layer.parameters(), "lr":1.0}] ## add additional network for some methods if loss_config["name"] == "JAN": softmax_layer = nn.Softmax() if use_gpu: softmax_layer = softmax_layer.cuda() print("set optimizer.....::") ## 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"]] print("Training progress......::") ## 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 running_loss = 0.0 for i in range(config["num_iterations"]): ## test in the train # print("iteration::", i) if i % config["test_interval"] == 0 or i < 10: base_network.train(False) classifier_layer.train(False) if net_config["use_bottleneck"]: bottleneck_layer.train(False) # bottleneck_layer_1.train(False) print("Validation Accuracy:::", 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: print ("Validation Accuracy:::", image_classification_test(dset_loaders["target"], nn.Sequential(base_network, classifier_layer), test_10crop=prep_dict["target"]["test_10crop"], gpu=use_gpu)) loss_test = nn.BCELoss() ## train one iter # base_network.train(True) if net_config["use_bottleneck"]: bottleneck_layer.train(True) # bottleneck_layer_1.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) # print("source::",inputs_source) # print("target::", inputs_target) # print("label source::", labels_source) # print("labels target::", labels_target) inputs = torch.cat((inputs_source, inputs_target), dim=0) features_ = base_network(inputs) # print("********Base network features*******::", features_) # sys.exit(0) if net_config["use_bottleneck"]: features = bottleneck_layer(features_) # features = bottleneck_layer_1(features_1) # print("*****features from bottleneck layer*****", features) outputs = classifier_layer(features) # print("***output****", outputs) #print("Inputs size::",inputs.size(0)/2) 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"]) total_loss = loss_config["trade_off"] * transfer_loss + classifier_loss running_loss += total_loss.data.cpu().numpy() total_loss.backward() optimizer.step() if i % config["test_interval"] == 0 or i<10: if i == 0: print("Training loss at iteration {} is {}".format(i, (running_loss))) else: print("Training loss at iteration {} is {}".format(i, (running_loss/i))) if net_config["use_bottleneck"]: model = nn.Sequential(base_network, bottleneck_layer, classifier_layer) else: model = nn.Sequential(base_network, classifier_layer) torch.save(model.state_dict(), "./weights_sp/r18_epoch_{}.pt".format(i))
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
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 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")
def train(config): # set pre-process prep_config = config["prep"] prep_dict = {} 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"] = datasets.ImageFolder(data_config['source']['list_path'], transform=prep_dict["source"]) dset_loaders['source'] = getdataloader(dsets['source'], batchsize=train_bs, num_workers=4, drop_last=True, weightsampler=True) dsets["target"] = datasets.ImageFolder(data_config['target']['list_path'], 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"] = [datasets.ImageFolder(data_config['test']['list_path'], 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"] = datasets.ImageFolder(data_config['test']['list_path'], 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() # set test_ad_net test_ad_net = network.AdversarialNetwork(base_network.output_num(), 1024, test_ad_net=True) test_ad_net = test_ad_net.cuda() # add additional network for some methods if config['method'] == 'DANN': random_layer = None ad_net = network.AdversarialNetwork(base_network.output_num(), 1024) elif config['method'] == 'MADA': random_layer = None ad_net = network.AdversarialNetworkClassGroup(base_network.output_num(), 1024, class_num) elif config['method'] == 'proposed': 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) ad_net_group = network.AdversarialNetworkGroup(config['loss']['random_dim'], 256, class_num, config['center_threshold']) else: random_layer = None ad_net = network.AdversarialNetwork(base_network.output_num(), 1024) ad_net_group = network.AdversarialNetworkGroup(base_network.output_num(), 1024, class_num, config['center_threshold']) elif config['method'] == 'base': pass else: 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"] and config['method'] != 'base' and config['method'] != 'DANN' and config['method'] != 'MADA': random_layer.cuda() if config['method'] != 'base': ad_net = ad_net.cuda() if config['method'] == 'proposed': ad_net_group = ad_net_group.cuda() # set parameters if config['method'] == 'proposed': parameter_list = base_network.get_parameters() + test_ad_net.get_parameters() + ad_net.get_parameters() + ad_net_group.get_parameters() elif config['method'] == 'base': parameter_list = base_network.get_parameters() + test_ad_net.get_parameters() elif config['method'] == 'MADA': parameter_list = base_network.get_parameters() + test_ad_net.get_parameters() + ad_net.get_parameters() else: parameter_list = base_network.get_parameters() + test_ad_net.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"]] # parallel gpus = config['gpu'].split(',') if len(gpus) > 1: base_network = nn.DataParallel(base_network) test_ad_net = nn.DataParallel(test_ad_net) if config['method'] == 'DANN': ad_net = nn.DataParallel(ad_net) elif config['method'] == 'proposed': if config['loss']['random']: random_layer = nn.DataParallel(random_layer) ad_net = nn.DataParallel(ad_net) #将ad_net_group设置成并行将会引发error,原因可能是由于ad_net_group的输出不是tensor类型,parallel还不能支持。 #ad_net_group = nn.DataParallel(ad_net_group) else: ad_net = nn.DataParallel(ad_net) #ad_net_group = nn.DataParallel(ad_net_group) elif config['method'] == 'base': pass else: # CDAN+E if config["loss"]["random"]: random_layer = nn.DataParallel(random_layer) ad_net = nn.DataParallel(ad_net) # CDAN else: ad_net = nn.DataParallel(ad_net) ## 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"]): if i % config["test_interval"] == config["test_interval"] - 1: base_network.train(False) # eval() == train(False) is True 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) # 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) if config['method'] != 'base': ad_net.train(True) if config['method'] == 'proposed': ad_net_group.train(True) # lr_scheduler 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) if config['tsne']: # feature visualization by using T-SNE if i == int(0.98*config['num_iterations']): features_source_total = features_source.cpu().detach().numpy() features_target_total = features_target.cpu().detach().numpy() elif i > int(0.98*config['num_iterations']) and i < int(0.98*config['num_iterations'])+10: features_source_total = np.concatenate((features_source_total, features_source.cpu().detach().numpy())) features_target_total = np.concatenate((features_target_total, features_target.cpu().detach().numpy())) elif i == int(0.98*config['num_iterations'])+10: for index in range(config['tsne_num']): features_embeded = TSNE(perplexity=10,n_iter=5000).fit_transform(np.concatenate((features_source_total, features_target_total))) fig = plt.figure() plt.scatter(features_embeded[:len(features_embeded)//2, 0], features_embeded[:len(features_embeded)//2, 1], c='r', s=1) plt.scatter(features_embeded[len(features_embeded)//2:, 0], features_embeded[len(features_embeded)//2:, 1], c='b', s=1) plt.savefig(osp.join(config["output_path"], config['method']+'-'+str(index)+'.png')) plt.close() else: pass assert features_source.size(0) == features_target.size(0), 'The batchsize must be same' assert outputs_source.size(0) == outputs_target.size(0), 'The batchsize must be same' # source first, target second features = torch.cat((features_source, features_target), dim=0) outputs = torch.cat((outputs_source, outputs_target), dim=0) # output the A_distance if i % config["test_interval"] == config["test_interval"] - 1: A_distance = cal_A_distance(test_ad_net, features) config['A_distance_file'].write(str(A_distance)+'\n') config['A_distance_file'].flush() 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) elif config['method'] == 'MADA': transfer_loss = loss.MADA(features, softmax_out, ad_net) elif config['method'] == 'proposed': entropy = loss.Entropy(softmax_out) transfer_loss = loss.proposed([features, outputs], labels_source, ad_net, ad_net_group, entropy, network.calc_coeff(i), i, random_layer, config['loss']['trade_off23']) elif config['method'] == 'base': pass else: raise ValueError('Method cannot be recognized.') test_domain_loss = loss.DANN(features.clone().detach(), test_ad_net) classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) if config['method'] == 'base': total_loss = classifier_loss + test_domain_loss else: total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss + test_domain_loss total_loss.backward() optimizer.step() # torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) return best_acc
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"] print(config, data_config) # 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) print('load data finished') 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() #print(base_network) base_network = torch.load('snapshot/iter_90000_model.pth.tar') base_network = list(base_network.children())[0] base_network = base_network.module # for key, value in base_network.state_dict().items(): # print(key) base_network = list(base_network.children())[9].cuda() # base_network= torch.nn.Sequential(*list(base_network.children())[:-1]).cuda() base_network = nn.DataParallel(base_network) print(base_network) #base_network.load_state_dict(checkpoint, strict=False) # ## 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"])) # 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 base_network.train(False) image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"]) return
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=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) 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) 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() ## 添加判别器D_s,D_t,生成器G_s2t,G_t2s z_dimension = 256 D_s = network.models["Discriminator"]() # D_s = D_s.cuda() G_s2t = network.models["Generator"](z_dimension, 1024) # G_s2t = G_s2t.cuda() D_t = network.models["Discriminator"]() # D_t = D_t.cuda() G_t2s = network.models["Generator"](z_dimension, 1024) # 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() classifier_optimizer = torch.optim.Adam(base_network.parameters(), lr=0.0003) ## 添加分类器 classifier1 = net.Net(256,class_num) # classifier1 = classifier1.cuda() classifier1_optim = optim.Adam(classifier1.parameters(), lr=0.0003) ## 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"])) 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 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 now = datetime.datetime.now() d = str(now.month) + '-' + str(now.day) + ' ' + str(now.hour) + ':' + str(now.minute) + ":" + str( now.second) torch.save(best_model, osp.join(config["output_path"], "{}_to_{}_best_model_acc-{}_{}.pth.tar".format(args.source, args.target, best_acc, d))) 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"], \ "{}_to_{}_iter_{:05d}_model_{}.pth.tar".format(args.source, args.target, i, str( datetime.datetime.utcnow())))) print("it_train: {:05d} / {:05d} start".format(i, config["num_iterations"])) loss_params = config["loss"] ## train one iter classifier1.train(True) 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 = 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) outputs_source1 = classifier1(features_source.detach()) outputs_target1 = classifier1(features_target.detach()) outputs1 = torch.cat((outputs_source1,outputs_target1),dim=0) softmax_out1 = nn.Softmax(dim=1)(outputs1) softmax_out = (1-args.cla_plus_weight)*softmax_out + args.cla_plus_weight*softmax_out1 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) # Cycle num_feature = features_source.size(0) # =================train discriminator T real_label = Variable(torch.ones(num_feature)) # real_label = Variable(torch.ones(num_feature)).cuda() fake_label = Variable(torch.zeros(num_feature)) # fake_label = Variable(torch.zeros(num_feature)).cuda() # 训练生成器 optimizer_G.zero_grad() # Identity loss same_t = G_s2t(features_target.detach()) loss_identity_t = criterion_identity(same_t, features_target) same_s = G_t2s(features_source.detach()) loss_identity_s = criterion_identity(same_s, features_source) # Gan loss fake_t = G_s2t(features_source.detach()) pred_fake = D_t(fake_t) loss_G_s2t = criterion_GAN(pred_fake, labels_source.float()) fake_s = G_t2s(features_target.detach()) pred_fake = D_s(fake_s) loss_G_t2s = criterion_GAN(pred_fake, labels_source.float()) # cycle loss recovered_s = G_t2s(fake_t) loss_cycle_sts = criterion_cycle(recovered_s, features_source) recovered_t = G_s2t(fake_s) loss_cycle_tst = criterion_cycle(recovered_t, features_target) # sem loss pred_recovered_s = base_network.fc(recovered_s) pred_fake_t = base_network.fc(fake_t) loss_sem_t2s = criterion_Sem(pred_recovered_s, pred_fake_t) pred_recovered_t = base_network.fc(recovered_t) pred_fake_s = base_network.fc(fake_s) loss_sem_s2t = criterion_Sem(pred_recovered_t, pred_fake_s) loss_cycle = loss_cycle_tst + loss_cycle_sts weights = args.weight_in_lossG.split(',') loss_G = float(weights[0]) * (loss_identity_s + loss_identity_t) + \ float(weights[1]) * (loss_G_s2t + loss_G_t2s) + \ float(weights[2]) * loss_cycle + \ float(weights[3]) * (loss_sem_s2t + loss_sem_t2s) # 训练softmax分类器 outputs_fake = classifier1(fake_t.detach()) # 分类器优化 classifier_loss1 = nn.CrossEntropyLoss()(outputs_fake, labels_source) classifier1_optim.zero_grad() classifier_loss1.backward() classifier1_optim.step() total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss + args.cyc_loss_weight*loss_G total_loss.backward() optimizer.step() optimizer_G.step() ###### Discriminator S ###### optimizer_D_s.zero_grad() # Real loss pred_real = D_s(features_source.detach()) loss_D_real = criterion_GAN(pred_real, real_label) # Fake loss fake_s = fake_S_buffer.push_and_pop(fake_s) pred_fake = D_s(fake_s.detach()) loss_D_fake = criterion_GAN(pred_fake, fake_label) # Total loss loss_D_s = loss_D_real + loss_D_fake loss_D_s.backward() optimizer_D_s.step() ################################### ###### Discriminator t ###### optimizer_D_t.zero_grad() # Real loss pred_real = D_t(features_target.detach()) loss_D_real = criterion_GAN(pred_real, real_label) # Fake loss fake_t = fake_T_buffer.push_and_pop(fake_t) pred_fake = D_t(fake_t.detach()) loss_D_fake = criterion_GAN(pred_fake, fake_label) # Total loss loss_D_t = loss_D_real + loss_D_fake loss_D_t.backward() optimizer_D_t.step() print("it_train: {:05d} / {:05d} over".format(i, config["num_iterations"])) now = datetime.datetime.now() d = str(now.month)+'-'+str(now.day)+' '+str(now.hour)+':'+str(now.minute)+":"+str(now.second) torch.save(best_model, osp.join(config["output_path"], "{}_to_{}_best_model_acc-{}_{}.pth.tar".format(args.source, args.target, best_acc,d))) return best_acc
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["output_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) dsets["source"] = ImageFolder(root=data_config["source"]["list_path"], \ transform=prep_dict["source"]) dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \ shuffle=True, num_workers=4, drop_last=True) dsets["target"] = ImageFolder(root=data_config["target"]["list_path"], \ 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["val"] = [ImageFolder(root=data_config["source"]["list_path"], \ transform=prep_dict["test"][i]) for i in range(10)] dset_loaders["val"] = [DataLoader(dset, batch_size=test_bs, \ shuffle=False, num_workers=4) for dset in dsets['val']] dsets["test"] = [ImageFolder(root=data_config["target"]["list_path"], \ 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"] = ImageFolder(root=data_config["target"]["list_path"], \ 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 = torch.load( "./snapshot/finetune_pet/iter_01000_model.pth.tar")[0] base_network = base_network.cuda() classifier_network = network.Classifier( class_num=config["network"]["params"]["class_num"]) classifier_network = classifier_network.cuda() parameter_list = classifier_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"]) transfer_loss_value = classifier_loss_value = total_loss_value = 0.0 best_acc = 0.0 for i in range(config["num_iterations"]): print(i) if i % config["test_interval"] == config["test_interval"] - 1: base_network.train(False) temp_acc, output, label, feature, logit = image_classification_val(dset_loaders, \ base_network, classifier_network, test_10crop=prep_config["test_10crop"]) np.save( os.path.join(config["output_path"], str(i) + '_output_src.npy'), output) np.save( os.path.join(config["output_path"], str(i) + '_label_src.npy'), label) np.save( os.path.join(config["output_path"], str(i) + '_feature_src.npy'), feature) np.save( os.path.join(config["output_path"], str(i) + '_logit_src.npy'), logit) temp_acc, output, label, feature, logit = image_classification_test(dset_loaders, \ base_network, classifier_network, test_10crop=prep_config["test_10crop"]) np.save( os.path.join(config["output_path"], str(i) + '_output.npy'), output) np.save(os.path.join(config["output_path"], str(i) + '_label.npy'), label) np.save( os.path.join(config["output_path"], str(i) + '_feature.npy'), feature) np.save(os.path.join(config["output_path"], str(i) + '_logit.npy'), logit) 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(classifier_network), osp.join(config["output_path"], \ "iter_{:05d}_classifier.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, _ = base_network(inputs_source) embed_source, outputs_source = classifier_network(features_source) classifier_loss = nn.CrossEntropyLoss()(outputs_source, 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
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
def evaluate(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 = open(data_config["source"]["list_path"]).readlines() target_list = 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=4, 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=4, drop_last=True) 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=4) 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=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.to(network.dev) if config["restore_path"]: checkpoint = torch.load( osp.join(config["restore_path"], "best_model.pth")) base_network.load_state_dict(checkpoint) print("successfully restore from ", osp.join(config["restore_path"], "best_model.pth")) gpus = config['gpu'].split(',') if len(gpus) > 1: base_network = nn.DataParallel( base_network, device_ids=[int(i) for i in range(len(gpus))]) evaluater = Eval(class_num) base_network.train(False) temp_acc, predict, all_label = image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"]) print("arg acc:", temp_acc) evaluater.add_batch(predict, all_label) evaluater.Print_Every_class_Eval() evaluater.reset() return
def test(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"]) ## 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=2) 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=2) 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=2) 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=2) 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=2) dsets["target_test"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \ transform=prep_dict["test"]) dset_loaders["target_test"] = util_data.DataLoader(dsets["target_test"], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=2) class_num = config["network"]["params"]["class_num"] # load checkpoint print('load model from {}'.format(config['ckpt_path'])) # load in an old way # base_network = torch.load(config["ckpt_path"])[0] # recommended practice ckpt = torch.load(config['ckpt_path']) print('recorded best precision: {:0.4f} at step {}'.format( ckpt["precision"], ckpt["step"])) train_accuracy = ckpt["precision"] ## set base network net_config = config["network"] base_network = net_config["name"](**net_config["params"]) base_network.load_state_dict(ckpt['base_network']) centroids = None if 'center_criterion' in ckpt.keys(): centroids = ckpt['center_criterion']['centers'].cpu() target_centroids = None if 'target_center_criterion' in ckpt.keys(): target_centroids = ckpt['target_center_criterion']['centers'].cpu() use_gpu = torch.cuda.is_available() if use_gpu: base_network = base_network.cuda() ## test print("start test: ") base_network.train(False) if config["ly_type"] == 'cosine': test_acc, test_confusion_matrix = image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"], \ gpu=use_gpu) elif config["ly_type"] == "euclidean": eval_centroids = None if centroids is not None: eval_centroids = centroids if target_centroids is not None: eval_centroids = target_centroids test_acc, test_confusion_matrix = utils.distance_classification_test(dset_loaders, \ base_network, eval_centroids, test_10crop=prep_config["test_10crop"], \ gpu=use_gpu) # save train/test accuracy as pkl file with open(os.path.join(config["output_path"], 'accuracy.pkl'), 'wb') as pkl_file: pkl.dump({'train': train_accuracy, 'test': test_acc}, pkl_file) ## top k confusion classes for each class #base_data_path = os.path.split(data_config["target"]["list_path"])[0] #with open(os.path.join(base_data_path, 'label2class.json'), "r") as f: # obj = json.load(f)[0] # label_to_class = {int(k):v for k, v in obj.items()} #convert key to int np.set_printoptions(precision=2) log_str = "train precision: {:.5f}\ttest precision: {:.5f}\nconfusion matrix:\n{}\n".format( train_accuracy, test_acc, test_confusion_matrix) config["out_file"].write(log_str) config["out_file"].flush() print(log_str) return test_acc
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)
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() ## 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"])) 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 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) 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.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) if i % 10 == 0: print('iter: ', i, 'classifier_loss: ', classifier_loss.data, 'transfer_loss: ', transfer_loss.data) total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss total_loss.backward() optimizer.step() torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) 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