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 perform_operation(file_path): torch.no_grad() e_net.eval() a_net.eval() s_net.eval() fusion.eval() imDataset = ImageList(crop_size=args.IM_SIZE, path=file_path, img_path=args.img_path, NUM_CLASS=args.NUM_CLASS, phase='test', transform=prep.image_test(crop_size=args.IM_SIZE), target_transform=prep.land_transform(img_size=args.IM_SIZE)) imDataLoader = torch.utils.data.DataLoader(imDataset, batch_size=args.Test_BATCH, num_workers=0) pbar = tqdm(total=len(imDataLoader)) for batch_Idx, data in enumerate(imDataLoader): datablob, datalb, pos_para = data datablob = torch.autograd.Variable(datablob).cuda() y_lb = torch.autograd.Variable(datalb).view(datalb.size(0), -1).cuda() pos_para = torch.autograd.Variable(pos_para).cuda() pred_global = e_net(datablob) feat_data = e_net.predict_BN(datablob) pred_att_map, pred_conf = a_net(feat_data) slice_feat_data = prep_model_input(pred_att_map, pos_para) pred_local = s_net(slice_feat_data) cls_pred = fusion(pred_global + pred_local) cls_pred = cls_pred.data.cpu().float() y_lb = y_lb.data.cpu().float() if batch_Idx == 0: all_output = cls_pred all_label = y_lb else: all_output = torch.cat((all_output, cls_pred), 0) all_label = torch.cat((all_label, y_lb), 0) pbar.update() pbar.close() all_acc_scr = get_acc(all_output, all_label) all_f1_score = get_f1(all_output, all_label) print('f1 score: ', str(all_f1_score.numpy().tolist())) print('average f1 score: ', str(all_f1_score.mean().numpy().tolist())) print('acc score: ', str(all_acc_scr.numpy().tolist())) print('average acc score: ', str(all_acc_scr.mean().numpy().tolist()))
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
np.random.seed(args.seed) torch.manual_seed(args.seed) # torch.backends.cudnn.deterministic = True # torch.backends.cudnn.benchmark = False os.system("clear") device = torch.device("cuda" if torch.cuda.is_available() else "cpu") dataset = flickr.Flickr() # loop_train = dataset.loop_set("labeled", shuffle=True) C = dataset.load_centre().cuda() # [c, #bit] C_random = torch.randint_like(C[0], 2) * 2 - 1 # {-1, 1} N_TRAIN = dataset.count("labeled") train_transform = prep.image_train(resize_size=255, crop_size=224) test_transform = prep.image_test(resize_size=255, crop_size=224) if args.model_type == 'resnet50' or args.model_type == 'resnet152': model = Model().cuda() elif args.model_type == 'alexnet': model = AlexNetFc().cuda() # model = model.to(device) # model = torch.nn.DataParallel(model).cuda() bce_loss = nn.BCELoss().cuda() #criterion = nn.MSELoss().cuda() params_list = [ { 'params': model.feature_layers.parameters(), 'lr': args.lrp * args.lr }, # 0.05*(args.lr)
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']) 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): # 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 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 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 train(config): ## set pre-process prep_dict = {} dsets = {} dset_loaders = {} data_config = config["data"] prep_config = config["prep"] if "webcam" in data_config["source"]["list_path"] or "dslr" in data_config[ "source"]["list_path"]: prep_dict["source"] = prep.image_train(**config["prep"]['params']) else: prep_dict["source"] = prep.image_target(**config["prep"] ['params']) #TODO if "webcam" in data_config["target"]["list_path"] or "dslr" in data_config[ "target"]["list_path"]: prep_dict["target"] = prep.image_train(**config["prep"]['params']) else: prep_dict["target"] = prep.image_target(**config["prep"] ['params']) #TODO prep_dict["test"] = prep.image_test(**config["prep"]['params']) ### set pre-process #prep_dict = {} #dsets = {} #dset_loaders = {} #data_config = config["data"] #prep_config = config["prep"] #prep_dict["source"] = prep.image_target(**config["prep"]['params']) #prep_dict["target"] = prep.image_target(**config["prep"]['params']) #prep_dict["test"] = prep.image_test(**config["prep"]['params']) ## prepare data train_bs = data_config["source"]["batch_size"] test_bs = data_config["test"]["batch_size"] dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \ transform=prep_dict["source"]) dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \ shuffle=True, num_workers=4, drop_last=True) dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \ transform=prep_dict["target"]) dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \ shuffle=True, num_workers=4, drop_last=True) dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \ transform=prep_dict["test"]) dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \ shuffle=False, num_workers=4) ## set base network class_num = config["network"]["params"]["class_num"] net_config = config["network"] base_network = net_config["name"](**net_config["params"]) base_network = base_network.cuda() ## set optimizer parameter_list = base_network.get_parameters() optimizer_config = config["optimizer"] optimizer = optimizer_config["type"](parameter_list, \ **(optimizer_config["optim_params"])) param_lr = [] for param_group in optimizer.param_groups: param_lr.append(param_group["lr"]) schedule_param = optimizer_config["lr_param"] lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]] #multi gpu gpus = config['gpu'].split(',') if len(gpus) > 1: base_network = nn.DataParallel( base_network, device_ids=[int(i) for i, k in enumerate(gpus)]) ## train len_train_source = len(dset_loaders["source"]) len_train_target = len(dset_loaders["target"]) transfer_loss_value = classifier_loss_value = total_loss_value = 0.0 best_acc = 0.0 for i in range(config["num_iterations"]): #test if i % config["test_interval"] == config["test_interval"] - 1: base_network.train(False) temp_acc = image_classification_test(dset_loaders, base_network) temp_model = nn.Sequential(base_network) if temp_acc > best_acc: best_acc = temp_acc best_model = temp_model log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc) config["out_file"].write(log_str + "\n") config["out_file"].flush() print(log_str) #save model if i % config["snapshot_interval"] == 0 and i: torch.save(base_network.state_dict(), osp.join(config["output_path"], \ "iter_{:05d}_model.pth.tar".format(i))) ## train one iter base_network.train(True) loss_params = config["loss"] optimizer = lr_scheduler(optimizer, i, **schedule_param) optimizer.zero_grad() #dataloader if i % len_train_source == 0: iter_source = iter(dset_loaders["source"]) if i % len_train_target == 0: iter_target = iter(dset_loaders["target"]) #network inputs_source, labels_source = iter_source.next() inputs_target, _ = iter_target.next() inputs_source, inputs_target, labels_source = inputs_source.cuda( ), inputs_target.cuda(), labels_source.cuda() features_source, outputs_source = base_network(inputs_source) features_target, outputs_target = base_network(inputs_target) features = torch.cat((features_source, features_target), dim=0) outputs = torch.cat((outputs_source, outputs_target), dim=0) softmax_src = nn.Softmax(dim=1)(outputs_source) softmax_tgt = nn.Softmax(dim=1)(outputs_target) softmax_out = torch.cat((softmax_src, softmax_tgt), dim=0) #loss calculation classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) _, s_tgt, _ = torch.svd(softmax_tgt) if config["method"] == "BNM": transfer_loss = -torch.mean(s_tgt) elif config["method"] == "BFM": transfer_loss = -torch.sqrt( torch.sum(s_tgt * s_tgt) / s_tgt.shape[0]) elif config["method"] == "ENT": transfer_loss = -torch.mean( torch.sum(softmax_tgt * torch.log(softmax_tgt + 1e-8), dim=1)) / torch.log(softmax_tgt.shape[1]) total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss if i % config["print_num"] == 0: log_str = "iter: {:05d}, transferloss: {:.5f}, classifier_loss: {:.5f}".format( i, transfer_loss, classifier_loss) config["out_file"].write(log_str + "\n") config["out_file"].flush() #print(log_str) total_loss.backward() optimizer.step() torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) return best_acc
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): base_network = network.ResNetFc('ResNet50', use_bottleneck=True, bottleneck_dim=config["bottleneck_dim"], new_cls=True, class_num=config["class_num"]) ad_net = network.AdversarialNetwork(config["bottleneck_dim"], config["hidden_dim"]) base_network = base_network.cuda() ad_net = ad_net.cuda() parameter_list = base_network.get_parameters() + ad_net.get_parameters() source_path = ImageList(open(config["s_path"]).readlines(), transform=preprocess.image_train(resize_size=256, crop_size=224)) target_path = ImageList(open(config["t_path"]).readlines(), transform=preprocess.image_train(resize_size=256, crop_size=224)) test_path = ImageList(open(config["t_path"]).readlines(), transform=preprocess.image_test(resize_size=256, crop_size=224)) source_loader = DataLoader(source_path, batch_size=config["train_bs"], shuffle=True, num_workers=0, drop_last=True) target_loader = DataLoader(target_path, batch_size=config["train_bs"], shuffle=True, num_workers=0, drop_last=True) test_loader = DataLoader(test_path, batch_size=config["test_bs"], shuffle=True, num_workers=0, drop_last=True) optimizer_config = config["optimizer"] optimizer = optimizer_config["type"](parameter_list, \ **(optimizer_config["optim_params"])) param_lr = [] for param_group in optimizer.param_groups: param_lr.append(param_group["lr"]) schedule_param = optimizer_config["lr_param"] lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]] gpus = config["gpus"].split(',') if len(gpus) > 1: ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus]) base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus]) len_train_source = len(source_loader) len_train_target = len(target_loader) transfer_loss_value = classifier_loss_value = total_loss_value = 0.0 best_acc = 0.0 best_model_path = None for i in trange(config["iterations"], leave=False): if i % config["test_interval"] == config["test_interval"] - 1: base_network.train(False) temp_acc = image_classification_test(test_loader, base_network) temp_model = nn.Sequential(base_network) if temp_acc > best_acc: best_acc = temp_acc best_model = copy.deepcopy(temp_model) best_iter = i if best_model_path and osp.exists(best_model_path): try: os.remove(best_model_path) except: pass best_model_path = osp.join(config["output_path"], "iter_{:05d}.pth.tar".format(best_iter)) torch.save(best_model, best_model_path) log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc) config["out_file"].write(log_str+"\n") config["out_file"].flush() # print("cut_loss: ", cut_loss.item()) print("mix_loss: ", mix_loss.item()) print(log_str) base_network.train(True) ad_net.train(True) optimizer = lr_scheduler(optimizer, i, **schedule_param) optimizer.zero_grad() if i % len_train_source == 0: iter_source = iter(source_loader) if i % len_train_target == 0: iter_target = iter(target_loader) inputs_source, labels_source = iter_source.next() inputs_target, labels_target = iter_target.next() inputs_source, inputs_target, labels_source = inputs_source.cuda(), inputs_target.cuda(), labels_source.cuda() labels_src_one_hot = torch.nn.functional.one_hot(labels_source, config["class_num"]).float() # inputs_cut, labels_cut = cutmix(base_network, inputs_source, labels_src_one_hot, inputs_target, config["alpha"], config["class_num"]) inputs_mix, labels_mix = mixup(base_network, inputs_source, labels_src_one_hot, inputs_target, config["alpha"], config["class_num"], config["temperature"]) features_source, outputs_source = base_network(inputs_source) features_target, outputs_target = base_network(inputs_target) # features_cut, outputs_cut = base_network(inputs_cut) features_mix, outputs_mix = base_network(inputs_mix) features = torch.cat((features_source, features_target), dim=0) outputs = torch.cat((outputs_source, outputs_target), dim=0) softmax_out = nn.Softmax(dim=1)(outputs) if config["method"] == 'DANN': transfer_loss = loss.DANN(features, ad_net) # cut_loss = utils.kl_loss(outputs_cut, labels_cut.detach()) mix_loss = utils.kl_loss(outputs_mix, labels_mix.detach()) else: raise ValueError('Method cannot be recognized.') classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = transfer_loss + classifier_loss + (5*mix_loss) total_loss.backward() optimizer.step() torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) print("Training Finished! Best Accuracy: ", best_acc) return best_acc
def train(config): #################################################### # Tensorboard setting #################################################### #tensor_writer = SummaryWriter(config["tensorboard_path"]) #################################################### # Data setting #################################################### prep_dict = {} # 데이터 전처리 transforms 부분 prep_dict["source"] = prep.image_train(**config['prep']['params']) prep_dict["target"] = prep.image_train(**config["prep"]['params']) prep_dict["test"] = prep.image_test(**config['prep']['params']) dsets = {} dsets["source"] = datasets.ImageFolder(config['s_dset_path'], transform=prep_dict["source"]) dsets["target"] = datasets.ImageFolder(config['t_dset_path'], transform=prep_dict['target']) dsets['test'] = datasets.ImageFolder(config['t_dset_path'], transform=prep_dict['test']) data_config = config["data"] train_source_bs = data_config["source"][ "batch_size"] #원본은 source와 target 모두 source train bs로 설정되었는데 이를 수정함 train_target_bs = data_config['target']['batch_size'] test_bs = data_config["test"]["batch_size"] dset_loaders = {} dset_loaders["source"] = DataLoader( dsets["source"], batch_size=train_source_bs, shuffle=True, num_workers=4, drop_last=True ) # 원본은 drop_last=True, 이렇게 해야 마지막까지 source, target에서 동일한 수로 배치 생성가능 dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_target_bs, shuffle=True, num_workers=4, drop_last=True) dset_loaders['test'] = DataLoader(dsets['test'], batch_size=test_bs, shuffle=False, num_workers=4, drop_last=False) #################################################### # Network Setting #################################################### class_num = config["network"]['params']['class_num'] net_config = config["network"] """ config['network'] = {'name': network.ResNetFc, 'params': {'resnet_name': args.net, 'use_bottleneck': True, 'bottleneck_dim': 256, 'new_cls': True, 'class_num': args.class_num, 'type' : args.type} } """ base_network = net_config["name"](**net_config["params"]) #network.py에 정의된 ResNetFc() 클래스 호출 base_network = base_network.cuda() # ResNetFc(Resnet, True, 256, True, 12) if config["loss"]["random"]: random_layer = network.RandomLayer( [base_network.output_num(), class_num], config["loss"]["random_dim"]) random_layer.cuda() ad_net = network.AdversarialNetwork(config["loss"]["random_dim"], 1024) else: random_layer = None ad_net = network.AdversarialNetwork( base_network.output_num() * class_num, 1024) # 왜 class 수 만큼 곱하지? ad_net = ad_net.cuda() parameter_list = base_network.get_parameters() + ad_net.get_parameters() #################################################### # Env Setting #################################################### #gpus = config['gpu'].split(',') #if len(gpus) > 1 : #ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in gpus]) #base_network = nn.DataParallel(base_network, device_ids=[int(i) for i in gpus]) #################################################### # Optimizer Setting #################################################### optimizer_config = config['optimizer'] optimizer = optimizer_config["type"](parameter_list, **(optimizer_config["optim_params"])) # optim.SGD #config['optimizer'] = {'type': optim.SGD, #'optim_params': {'lr': args.lr, #'momentum': 0.9, #'weight_decay': 0.0005, #'nestrov': True}, #'lr_type': "inv", #'lr_param': {"lr": args.lr, #'gamma': 0.001, # 이거 0.01이여야 하지 않나? #'power': 0.75 #} param_lr = [] for param_group in optimizer.param_groups: param_lr.append(param_group['lr']) schedule_param = optimizer_config['lr_param'] lr_scheduler = lr_schedule.schedule_dict[ optimizer_config["lr_type"]] # return optimizer #################################################### # Train #################################################### len_train_source = len(dset_loaders["source"]) len_train_target = len(dset_loaders["target"]) transfer_loss_value = 0.0 classifier_loss_value = 0.0 total_loss_value = 0.0 best_acc = 0.0 batch_size = config["data"]["source"]["batch_size"] for i in range( config["num_iterations"]): # num_iterations수의 batch가 학습에 사용됨 sys.stdout.write("Iteration : {} \r".format(i)) sys.stdout.flush() loss_params = config["loss"] base_network.train(True) ad_net.train(True) optimizer = lr_scheduler(optimizer, i, **schedule_param) optimizer.zero_grad() if i % len_train_source == 0: iter_source = iter(dset_loaders["source"]) if i % len_train_target == 0: iter_target = iter(dset_loaders["target"]) inputs_source, labels_source = iter_source.next() inputs_target, labels_target = iter_target.next() inputs_source, labels_source = inputs_source.cuda( ), labels_source.cuda() inputs_target = inputs_target.cuda() inputs = torch.cat((inputs_source, inputs_target), dim=0) features, outputs, tau, cur_mean_source, cur_mean_target, output_mean_source, output_mean_target = base_network( inputs) softmax_out = nn.Softmax(dim=1)(outputs) outputs_source = outputs[:batch_size] outputs_target = outputs[batch_size:] if config['method'] == 'CDAN+E' or config['method'] == 'CDAN_TransNorm': entropy = loss.Entropy(softmax_out) transfer_loss = loss.CDAN([features, softmax_out], ad_net, entropy, network.calc_coeff(i), random_layer) elif config['method'] == 'CDAN': transfer_loss = loss.CDAN([features, softmax_out], ad_net, None, None, random_layer) elif config['method'] == 'DANN': pass # 나중에 정리하기 else: raise ValueError('Method cannot be recognized') classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) total_loss = loss_params["trade_off"] * transfer_loss + classifier_loss total_loss.backward() optimizer.step() #tensor_writer.add_scalar('total_loss', total_loss.i ) #tensor_writer.add_scalar('classifier_loss', classifier_loss, i) #tensor_writer.add_scalar('transfer_loss', transfer_loss, i) #################################################### # Test #################################################### if i % config["test_interval"] == config["test_interval"] - 1: # test interval 마다 base_network.train(False) temp_acc = image_classification_test(dset_loaders, base_network) temp_model = nn.Sequential(base_network) if temp_acc > best_acc: best_acc = temp_acc best_model = temp_model ACC = round(best_acc, 2) * 100 torch.save( best_model, os.path.join(config["output_path"], "iter_{}_model.pth.tar".format(ACC))) log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc) config["out_file"].write(log_str + "\n") config["out_file"].flush() print(log_str)
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"] source_list = [ '.' + i for i in open(data_config["source"]["list_path"]).readlines() ] target_list = [ '.' + i for i in open(data_config["target"]["list_path"]).readlines() ] dsets["source"] = ImageList(source_list, \ transform=prep_dict["source"]) dset_loaders["source"] = DataLoader(dsets["source"], batch_size=train_bs, \ shuffle=True, num_workers=config['args'].num_worker, drop_last=True) dsets["target"] = ImageList(target_list, \ transform=prep_dict["target"]) dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \ shuffle=True, num_workers=config['args'].num_worker, drop_last=True) print("source dataset len:", len(dsets["source"])) print("target dataset len:", len(dsets["target"])) if prep_config["test_10crop"]: for i in range(10): test_list = [ '.' + i for i in open(data_config["test"]["list_path"]).readlines() ] dsets["test"] = [ImageList(test_list, \ transform=prep_dict["test"][i]) for i in range(10)] dset_loaders["test"] = [DataLoader(dset, batch_size=test_bs, \ shuffle=False, num_workers=config['args'].num_worker) for dset in dsets['test']] else: test_list = [ '.' + i for i in open(data_config["test"]["list_path"]).readlines() ] dsets["test"] = ImageList(test_list, \ transform=prep_dict["test"]) dset_loaders["test"] = DataLoader(dsets["test"], batch_size=test_bs, \ shuffle=False, num_workers=config['args'].num_worker) dsets["target_label"] = ImageList_label(target_list, \ transform=prep_dict["target"]) dset_loaders["target_label"] = DataLoader(dsets["target_label"], batch_size=test_bs, \ shuffle=False, num_workers=config['args'].num_worker, drop_last=False) class_num = config["network"]["params"]["class_num"] ## set base network net_config = config["network"] base_network = net_config["name"](**net_config["params"]) base_network = base_network.to(network.dev) if config["restore_path"]: checkpoint = torch.load( osp.join(config["restore_path"], "best_model.pth"))["base_network"] ckp = {} for k, v in checkpoint.items(): if "module" in k: ckp[k.split("module.")[-1]] = v else: ckp[k] = v base_network.load_state_dict(ckp) log_str = "successfully restore from {}".format( osp.join(config["restore_path"], "best_model.pth")) config["out_file"].write(log_str + "\n") config["out_file"].flush() print(log_str) ## add additional network for some methods if "ALDA" in args.method: ad_net = network.Multi_AdversarialNetwork(base_network.output_num(), 1024, class_num) else: ad_net = network.AdversarialNetwork(base_network.output_num(), 1024) ad_net = ad_net.to(network.dev) parameter_list = base_network.get_parameters() + ad_net.get_parameters() ## set optimizer optimizer_config = config["optimizer"] optimizer = optimizer_config["type"](parameter_list, \ **(optimizer_config["optim_params"])) param_lr = [] for param_group in optimizer.param_groups: param_lr.append(param_group["lr"]) schedule_param = optimizer_config["lr_param"] lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]] gpus = config['gpu'].split(',') if len(gpus) > 1: ad_net = nn.DataParallel(ad_net, device_ids=[int(i) for i in range(len(gpus))]) base_network = nn.DataParallel( base_network, device_ids=[int(i) for i in range(len(gpus))]) loss_params = config["loss"] high = loss_params["trade_off"] begin_label = False writer = SummaryWriter(config["output_path"]) ## train len_train_source = len(dset_loaders["source"]) len_train_target = len(dset_loaders["target"]) transfer_loss_value = classifier_loss_value = total_loss_value = 0.0 best_acc = 0.0 loss_value = 0 loss_adv_value = 0 loss_correct_value = 0 for i in tqdm(range(config["num_iterations"]), total=config["num_iterations"]): if i % config["test_interval"] == config["test_interval"] - 1: base_network.train(False) temp_acc = image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"]) temp_model = base_network #nn.Sequential(base_network) if temp_acc > best_acc: best_step = i best_acc = temp_acc best_model = temp_model checkpoint = { "base_network": best_model.state_dict(), "ad_net": ad_net.state_dict() } torch.save(checkpoint, osp.join(config["output_path"], "best_model.pth")) print( "\n########## save the best model. #############\n") log_str = "iter: {:05d}, precision: {:.5f}".format(i, temp_acc) config["out_file"].write(log_str + "\n") config["out_file"].flush() writer.add_scalar('precision', temp_acc, i) print(log_str) print("adv_loss: {:.3f} correct_loss: {:.3f} class_loss: {:.3f}". format(loss_adv_value, loss_correct_value, loss_value)) loss_value = 0 loss_adv_value = 0 loss_correct_value = 0 #show val result on tensorboard images_inv = prep.inv_preprocess(inputs_source.clone().cpu(), 3) for index, img in enumerate(images_inv): writer.add_image(str(index) + '/Images', img, i) # save the pseudo_label if 'PseudoLabel' in config['method'] and ( i % config["label_interval"] == config["label_interval"] - 1): base_network.train(False) pseudo_label_list = image_label(dset_loaders, base_network, threshold=config['threshold'], \ out_dir=config["output_path"]) dsets["target"] = ImageList(open(pseudo_label_list).readlines(), \ transform=prep_dict["target"]) dset_loaders["target"] = DataLoader(dsets["target"], batch_size=train_bs, \ shuffle=True, num_workers=config['args'].num_worker, drop_last=True) iter_target = iter( dset_loaders["target"] ) # replace the target dataloader with Pseudo_Label dataloader begin_label = True if i > config["stop_step"]: log_str = "method {}, iter: {:05d}, precision: {:.5f}".format( config["output_path"], best_step, best_acc) config["final_log"].write(log_str + "\n") config["final_log"].flush() break ## train one iter base_network.train(True) ad_net.train(True) optimizer = lr_scheduler(optimizer, i, **schedule_param) optimizer.zero_grad() if i % len_train_source == 0: iter_source = iter(dset_loaders["source"]) if i % len_train_target == 0: iter_target = iter(dset_loaders["target"]) inputs_source, labels_source = iter_source.next() inputs_target, labels_target = iter_target.next() inputs_source, inputs_target, labels_source = Variable( inputs_source).to(network.dev), Variable(inputs_target).to( network.dev), Variable(labels_source).to(network.dev) features_source, outputs_source = base_network(inputs_source) if args.source_detach: features_source = features_source.detach() features_target, outputs_target = base_network(inputs_target) features = torch.cat((features_source, features_target), dim=0) outputs = torch.cat((outputs_source, outputs_target), dim=0) softmax_out = nn.Softmax(dim=1)(outputs) loss_params["trade_off"] = network.calc_coeff( i, high=high) #if i > 500 else 0.0 transfer_loss = 0.0 if 'DANN' in config['method']: transfer_loss = loss.DANN(features, ad_net) elif "ALDA" in config['method']: ad_out = ad_net(features) adv_loss, reg_loss, correct_loss = loss.ALDA_loss( ad_out, labels_source, softmax_out, weight_type=config['args'].weight_type, threshold=config['threshold']) # whether add the corrected self-training loss if "nocorrect" in config['args'].loss_type: transfer_loss = adv_loss else: transfer_loss = config['args'].adv_weight * adv_loss + config[ 'args'].adv_weight * loss_params["trade_off"] * correct_loss # reg_loss is only backward to the discriminator if "noreg" not in config['args'].loss_type: for param in base_network.parameters(): param.requires_grad = False reg_loss.backward(retain_graph=True) for param in base_network.parameters(): param.requires_grad = True # on-line self-training elif 'SelfTraining' in config['method']: transfer_loss += loss_params["trade_off"] * loss.SelfTraining_loss( outputs, softmax_out, config['threshold']) # off-line self-training elif 'PseudoLabel' in config['method']: labels_target = labels_target.to(network.dev) if begin_label: transfer_loss += loss_params["trade_off"] * nn.CrossEntropyLoss( ignore_index=-1)(outputs_target, labels_target) else: transfer_loss += 0.0 * nn.CrossEntropyLoss(ignore_index=-1)( outputs_target, labels_target) classifier_loss = nn.CrossEntropyLoss()(outputs_source, labels_source) loss_value += classifier_loss.item() / config["test_interval"] loss_adv_value += adv_loss.item() / config["test_interval"] loss_correct_value += correct_loss.item() / config["test_interval"] total_loss = classifier_loss + transfer_loss total_loss.backward() optimizer.step() checkpoint = { "base_network": temp_model.state_dict(), "ad_net": ad_net.state_dict() } torch.save(checkpoint, osp.join(config["output_path"], "final_model.pth")) return best_acc
def train(config): tie = 1.0 ## set pre-process prep_dict = {} prep_config = config["prep"] prep_dict["source"] = prep.image_train( \ resize_size=prep_config["resize_size"], \ crop_size=prep_config["crop_size"]) prep_dict["target"] = prep.image_train( \ resize_size=prep_config["resize_size"], \ crop_size=prep_config["crop_size"]) if prep_config["test_10crop"]: prep_dict["test"] = prep.image_test_10crop( \ resize_size=prep_config["resize_size"], \ crop_size=prep_config["crop_size"]) else: prep_dict["test"] = prep.image_test( \ resize_size=prep_config["resize_size"], \ crop_size=prep_config["crop_size"]) ## set loss class_criterion = nn.CrossEntropyLoss() # 分类损失 transfer_criterion1 = loss.PADA # 迁移学习损失(带权重),BCEloss balance_criterion = loss.balance_loss() loss_params = config["loss"] ## prepare data dsets = {} dset_loaders = {} data_config = config["data"] dsets["source"] = ImageList(open(data_config["source"]["list_path"]).readlines(), \ transform=prep_dict["source"]) dset_loaders["source"] = util_data.DataLoader(dsets["source"], \ batch_size=data_config["source"]["batch_size"], \ shuffle=True, num_workers=4) dsets["target"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \ transform=prep_dict["target"]) dset_loaders["target"] = util_data.DataLoader(dsets["target"], \ batch_size=data_config["target"]["batch_size"], \ shuffle=True, num_workers=4) if prep_config["test_10crop"]: for i in range(10): dsets["test" + str(i)] = ImageList(open(data_config["test"]["list_path"]).readlines(), \ transform=prep_dict["test"]["val" + str(i)]) dset_loaders["test" + str(i)] = util_data.DataLoader(dsets["test" + str(i)], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=4) dsets["target" + str(i)] = ImageList(open(data_config["target"]["list_path"]).readlines(), \ transform=prep_dict["test"]["val" + str(i)]) dset_loaders["target" + str(i)] = util_data.DataLoader(dsets["target" + str(i)], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=4) else: dsets["test"] = ImageList(open(data_config["test"]["list_path"]).readlines(), \ transform=prep_dict["test"]) dset_loaders["test"] = util_data.DataLoader(dsets["test"], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=4) dsets["target_test"] = ImageList(open(data_config["target"]["list_path"]).readlines(), \ transform=prep_dict["test"]) dset_loaders["target_test"] = MyDataLoader(dsets["target_test"], \ batch_size=data_config["test"]["batch_size"], \ shuffle=False, num_workers=4) class_num = config["network"]["params"]["class_num"] ## set base network net_config = config["network"] base_network = net_config["name"](**net_config["params"]) use_gpu = torch.cuda.is_available() if use_gpu: base_network = base_network.cuda() ## collect parameters if net_config["params"]["new_cls"]: if net_config["params"]["use_bottleneck"]: parameter_list = [{"params": base_network.feature_layers.parameters(), "lr": 1}, \ {"params": base_network.bottleneck.parameters(), "lr": 10}, \ {"params": base_network.fc.parameters(), "lr": 10}] else: parameter_list = [{"params": base_network.feature_layers.parameters(), "lr": 1}, \ {"params": base_network.fc.parameters(), "lr": 10}] else: parameter_list = [{"params": base_network.parameters(), "lr": 1}] ## add additional network for some methods class_weight = torch.from_numpy(np.array( [1.0] * class_num)) # 权重初始化为class_num维向量,初始值为1 if use_gpu: class_weight = class_weight.cuda() ad_net = network.AdversarialNetwork( base_network.output_num()) # 鉴别器设置,输入为特征提取器的维数,输出为属于共域的可能性 nad_net = network.NAdversarialNetwork(base_network.output_num()) gradient_reverse_layer = network.AdversarialLayer( high_value=config["high"]) if use_gpu: ad_net = ad_net.cuda() nad_net = nad_net.cuda() parameter_list.append({"params": ad_net.parameters(), "lr": 10}) ## set optimizer optimizer_config = config["optimizer"] optimizer = optim_dict[optimizer_config["type"]](parameter_list, \ **(optimizer_config["optim_params"])) param_lr = [] for param_group in optimizer.param_groups: param_lr.append(param_group["lr"]) schedule_param = optimizer_config["lr_param"] lr_scheduler = lr_schedule.schedule_dict[optimizer_config["lr_type"]] ## train len_train_source = len(dset_loaders["source"]) - 1 len_train_target = len(dset_loaders["target"]) - 1 transfer_loss_value = classifier_loss_value = total_loss_value = attention_loss_value = 0.0 best_acc = 0.0 for i in range(config["num_iterations"]): if i % config["test_interval"] == 0: # 测试 base_network.train(False) # 先对特征提取器进行训练 temp_acc = image_classification_test(dset_loaders, \ base_network, test_10crop=prep_config["test_10crop"], \ gpu=use_gpu) # 对第一个有监督训练器进行分类训练,提取特征 temp_model = nn.Sequential(base_network) if temp_acc > best_acc: best_acc = temp_acc best_model = temp_model log_str = "iter: {:05d}, alpha: {:03f}, tradeoff: {:03f} ,precision: {:.5f}".format( i, loss_params["para_alpha"], loss_params["trade_off"], temp_acc) config["out_file"].write(log_str + '\n') config["out_file"].flush() print(log_str) if i % config["snapshot_interval"] == 0: # 输出 torch.save(nn.Sequential(base_network), osp.join(config["output_path"], \ "iter_{:05d}_model.pth.tar".format(i))) if i % loss_params["update_iter"] == loss_params["update_iter"] - 1: base_network.train(False) target_fc8_out = image_classification_predict( dset_loaders, base_network, softmax_param=config["softmax_param"] ) # 在对有监督学习进行了训练后,喂进去目标域数据,判断权重 class_weight = torch.mean( target_fc8_out, 0) # predict模型输出的预测向量取均值,为每一个体权重,将个体权重转化为类别权重 class_weight = (class_weight / torch.mean(class_weight)).cuda().view(-1) # 归一化 class_criterion = nn.CrossEntropyLoss( weight=class_weight) # 这里的交叉熵损失函数就是带权重的 ## train one iter base_network.train(True) optimizer = lr_scheduler(param_lr, optimizer, i, **schedule_param) optimizer.zero_grad() if i % len_train_source == 0: iter_source = iter(dset_loaders["source"]) if i % len_train_target == 0: iter_target = iter(dset_loaders["target"]) inputs_source, labels_source = iter_source.next() inputs_target, labels_target = iter_target.next() if use_gpu: inputs_source, inputs_target, labels_source = \ Variable(inputs_source).cuda(), Variable(inputs_target).cuda(), \ Variable(labels_source).cuda() else: inputs_source, inputs_target, labels_source = Variable(inputs_source), \ Variable(inputs_target), Variable(labels_source) inputs = torch.cat((inputs_source, inputs_target), dim=0) # 这里输入后一半目标域,前一半源域 features, outputs = base_network(inputs) # 从有分类网络获得特征与输出,到这里是特征提取器 softmax_out = nn.Softmax(dim=1)(outputs).detach() ad_net.train(True) nad_net.train(True) weight_ad = torch.zeros(inputs.size(0)) label_numpy = labels_source.data.cpu().numpy() for j in range(inputs.size(0) / 2): weight_ad[j] = class_weight[int(label_numpy[j])] # 计算实际样例权重 # print(label_numpy) weight_ad = weight_ad / torch.max( weight_ad[0:inputs.size(0) / 2]) # 权重归一化 for j in range(inputs.size(0) / 2, inputs.size(0)): # 前一半源域,所以权重是计算的,后一半目标域,权重全为1 weight_ad[j] = 1.0 classifier_loss = class_criterion( outputs.narrow(0, 0, inputs.size(0) / 2), labels_source) # 分类损失 total_loss = classifier_loss total_loss.backward() optimizer.step() torch.save(best_model, osp.join(config["output_path"], "best_model.pth.tar")) return best_acc