def cotrain(configs, data, iter_step=1, train_ratio=0.2): """ cotrain model: params: model_names: model configs data: dataset include train and untrain data save_paths: paths for storing models iter_step: maximum iteration steps train_ratio: labeled data ratio """ assert iter_step >= 1 train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio, args.seed) data_dir = data.images_dir new_train_data = train_data for step in range(iter_step): pred_probs = [] add_ids = [] for view in range(2): configs[view].set_training(True) model = mu.train(new_train_data, data_dir, configs[view]) save_checkpoint( { 'state_dict': model.state_dict(), 'epoch': step + 1, 'train_data': new_train_data }, False, fpath=os.path.join(configs[view].logs_dir, configs[view].model_name, 'cotrain.epoch%d' % step)) if len(untrain_data) == 0: continue pred_probs.append( mu.predict_prob(model, untrain_data, data_dir, configs[view])) add_ids.append(dp.sel_idx(pred_probs[view], train_data)) # calculate predict probility on all data p_b = mu.predict_prob(model, data.trainval, data_dir, configs[view]) p_y = np.argmax(p_b, axis=1) t_y = [c for (_, c, _, _) in data.trainval] print(np.mean(t_y == p_y)) if len(untrain_data) == 0: break # update training data pred_y = np.argmax(sum(pred_probs), axis=1) add_id = sum(add_ids) new_train_data, untrain_data = dp.update_train_untrain( add_id, new_train_data, untrain_data, pred_y)
def cotrain(model_names, data, save_paths, iter_step=1, train_ratio=0.2): """ cotrain model: params: model_names: model names such as ['resnet50','densenet121'] data: dataset include train and untrain data save_paths: paths for storing models iter_step: maximum iteration steps train_ratio: labeled data ratio """ assert iter_step >= 1 assert len(model_names) == 2 and len(save_paths) == 2 train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio) data_dir = data.images_dir for step in range(iter_step): pred_probs = [] add_ids = [] for view in range(2): model = mu.train(model_names[view], train_data, data_dir, data.num_trainval_ids, epochs=50) data_params = mu.get_params_by_name(model_names[view]) pred_probs.append( mu.predict_prob(model, untrain_data, data_dir, data_params)) add_ids.append(dp.sel_idx(pred_probs[view], data.train)) torch.save(model.state_dict(), save_paths[view] + '.cotrain.epoch%d' % (step + 1)) mu.evaluate(model, data, params=data_params) pred_y = np.argmax(sum(pred_probs), axis=1) add_id = sum(add_ids) train_data, untrain_data = dp.update_train_untrain( add_id, train_data, untrain_data, pred_y)
def spaco(configs, data, iter_step=1, gamma=0.3, train_ratio=0.2): """ self-paced co-training model implementation based on Pytroch params: model_names: model names for spaco, such as ['resnet50','densenet121'] data: dataset for spaco model save_pathts: save paths for two models iter_step: iteration round for spaco gamma: spaco hyperparameter train_ratio: initiate training dataset ratio """ num_view = len(configs) train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio, args.seed) data_dir = data.images_dir ########### # initiate classifier to get preidctions ########### add_ratio = 0.5 pred_probs = [] add_ids = [] start_step = 0 for view in range(num_view): if configs[view].checkpoint is None: model = mu.train(train_data, data_dir, configs[view]) save_checkpoint( { 'state_dict': model.state_dict(), 'epoch': 0, 'train_data': train_data }, False, fpath=os.path.join(configs[view].logs_dir, configs[view].model_name, 'spaco.epoch0')) else: model = models.create(configs[view].model_name, num_features=configs[view].num_features, dropout=configs[view].dropout, num_classes=configs[view].num_classes) model = torch.nn.DataParallel(model).cuda() checkpoint = load_checkpoint(configs[view].checkpoint) model.load_state_dict(checkpoint['state_dict']) start_step = checkpoint['epoch'] configs[view].set_training(False) add_ratio += start_step * 0.5 # mu.evaluate(model, data, configs[view]) pred_probs.append( mu.predict_prob(model, untrain_data, data_dir, configs[view])) add_ids.append(dp.sel_idx(pred_probs[view], train_data, add_ratio)) pred_y = np.argmax(sum(pred_probs), axis=1) for step in range(start_step, iter_step): for view in range(num_view): # update v_view ov = add_ids[1 - view] pred_probs[view][ov, pred_y[ov]] += gamma add_id = dp.sel_idx(pred_probs[view], train_data, add_ratio) # update w_view new_train_data, _ = dp.update_train_untrain( add_id, train_data, untrain_data, pred_y) configs[view].set_training(True) model = mu.train(new_train_data, data_dir, configs[view]) # update y pred_probs[view] = mu.predict_prob(model, untrain_data, data_dir, configs[view]) pred_y = np.argmax(sum(pred_probs), axis=1) # udpate v_view for next view add_ratio += 0.5 pred_probs[view][ov, pred_y[ov]] += gamma add_ids[view] = dp.sel_idx(pred_probs[view], train_data, add_ratio) # calculate predict probility on all data p_b = mu.predict_prob(model, data.trainval, data_dir, configs[view]) p_y = np.argmax(p_b, axis=1) t_y = [c for (_, c, _, _) in data.trainval] print(np.mean(t_y == p_y)) # evaluation current model and save it # mu.evaluate(model,data,configs[view]) save_checkpoint( { 'state_dict': model.state_dict(), 'epoch': step + 1, 'train_data': new_train_data }, False, fpath=os.path.join(configs[view].logs_dir, configs[view].model_name, 'spaco.epoch%d' % (step + 1)))
def spaco(model_names, data, save_paths, iter_step=1, gamma=0.3, train_ratio=0.2): """ self-paced balance learning model implementation based on Pytroch """ assert iter_step >= 1 assert len(model_names) == 1 and len(save_paths) == 1 num_view = len(model_names) printflag = True add_ratios = config.add_ratios train_data, untrain_data = dp.split_dataset( data.train, train_ratio) #(data.trainval, train_ratio) data_dir = data.images_dir num_classes = data.num_trainval_ids res_model = mu.get_model_by_name(model_names[0], num_classes) res_model = nn.DataParallel(res_model).cuda() data_params = mu.get_params_by_name(model_names[0]) res_model = mu.train_wxp(res_model, data.val, model_names[0], train_data, data_dir, num_classes, config.epochs, weight=None) #weight)# - 5 * step) # modi clf = SVC(probability=False, decision_function_shape='ovr') # extract features torch.save(res_model, 'res50_198_temp.pkl') res_model.module.classifier = nn.LeakyReLU(0.1) features_train, labels_train = mu.extract_model_feature_ww( res_model, train_data, data_dir, data_params) if (printflag is True): features_test, labels_test = mu.extract_model_feature_ww( res_model, data.val, data_dir, data_params) features_untrain, _ = mu.extract_model_feature_ww(res_model, untrain_data, data_dir, data_params) features_paced = features_train.copy() labels_paced = labels_train.copy() sample_weights_paced = np.ones((len(labels_train), )) clf.fit(features_paced, labels_paced, sample_weights_paced) sample_weights_paced = sample_weights_paced * 0.2 if (printflag is True): pred_svm = clf.predict(features_test) pred_prob_svm = clf.decision_function(features_test) print('\n...svm...') print( classification_report_imbalanced_light(labels_test, pred_svm, pred_prob_svm, num_classes)) pred_prob = clf.decision_function(features_untrain) pred_prob = pred_prob - np.max(pred_prob, axis=1).reshape((-1, 1)) # new pred_prob = np.exp(pred_prob) pred_prob = pred_prob / np.sum(pred_prob, axis=1).reshape((-1, 1)) res_model = torch.load('res50_198_temp.pkl').module res_model = nn.DataParallel(res_model).cuda() weight = None weights = None weights_save = np.zeros((len(add_ratios), num_classes)) weight_save = np.zeros((len(add_ratios), num_classes)) subCurriculums = np.zeros((len(add_ratios), num_classes)) for step in range(len(add_ratios)): # update v add_ratio = add_ratios[step] add_id, weights, subCurriculum = dp.sel_idx_wspl( pred_prob, untrain_data, add_ratio) #weights = weights / min(weights) # ensure min(weights) == 1.0 ''' if(weight is None): weight = weights.copy() else: weight = weight * 0.8 + weights * 0.2 weight = weight / min(weight)''' weight = weights.copy() weight_save[step] = weight weights_save[step] = weights subCurriculums[step] = subCurriculum # update w new_train_data, _ = dp.update_train_untrain(add_id, train_data, untrain_data) # modi res_model = mu.train_wxp(res_model, data.val, model_names[0], new_train_data, data_dir, num_classes, config.epochs, weight=None) #weight)# - 5 * step) # modi #extract features torch.save(res_model, 'res50_198_temp.pkl') res_model.module.classifier = nn.LeakyReLU(0.1) features_new_train, labels_new_train = mu.extract_model_feature_ww( res_model, new_train_data, data_dir, data_params) # curriculum reconstructing### #subCurriculum needsampled_indices = np.array([]).astype( int) #range(features_new_train.shape[0]) sample_indices = np.array([]).astype( int) #range(features_new_train.shape[0]) target_stats = Counter(labels_new_train) subCurriculum = subCurriculum.astype(int) for i in range(num_classes): target_class_indices = np.where(labels_new_train == i)[0] assert target_stats[i] == len(target_class_indices) if (subCurriculum[i] > 0): indices = range(target_stats[i]) #target_class_indices.copy() indices = np.append( indices, np.random.randint(low=0, high=target_stats[i], size=subCurriculum[i])) elif (subCurriculum[i] == 0): indices = range(target_stats[i]) #target_class_indices.copy() elif (subCurriculum[i] < 0): indices = np.array([]).astype(int) indices = np.append( indices, np.random.randint(low=0, high=target_stats[i], size=target_stats[i] + subCurriculum[i])) needsampled_indices = np.append(needsampled_indices, subCurriculum[i] + target_stats[i]) sample_indices = np.append(sample_indices, target_class_indices[indices]) features_new_train = features_new_train[sample_indices] labels_new_train = labels_new_train[sample_indices] ''' RND_SEED = 42 kind = 'regular' ratio = dict(zip(range(num_classes), needsampled_indices)) smote = SMOTE(ratio=ratio,random_state=RND_SEED, k_neighbors=2, kind=kind) new_fe, new_la = smote.fit_sample(features_new_train, labels_new_train) features_new_train = new_fe.copy()# np.append(features_new_train, new_fe) labels_new_train = new_la.copy()#np.append(labels_new_train, new_la) ''' #weight = weight[sample_indices] ############################## if (printflag is True or add_ratio > 0.9): features_test, labels_test = mu.extract_model_feature_ww( res_model, data.val, data_dir, data_params) features_untrain, _ = mu.extract_model_feature_ww( res_model, untrain_data, data_dir, data_params) sample_weights_paced_temp = np.zeros((len(labels_new_train), )) for i, x in enumerate(labels_new_train): sample_weights_paced_temp[i] = weight[x] sample_weights_paced_temp_temp = np.concatenate( (sample_weights_paced, sample_weights_paced_temp)) features_paced = np.concatenate((features_paced, features_new_train)) labels_paced = np.concatenate((labels_paced, labels_new_train)) clf.fit(features_paced, labels_paced, sample_weights_paced_temp_temp) sample_weights_paced_temp = sample_weights_paced_temp * ( add_ratio * (1 - train_ratio) + train_ratio) sample_weights_paced = np.concatenate( (sample_weights_paced, sample_weights_paced_temp)) if (printflag is True or add_ratio > 0.9): pred_svm = clf.predict(features_test) pred_prob_svm = clf.decision_function(features_test) print('\n...svm...') if add_ratio > 0.9: print( classification_report_imbalanced(labels_test, pred_svm, pred_prob_svm, num_classes)) else: print( classification_report_imbalanced_light( labels_test, pred_svm, pred_prob_svm, num_classes)) res_model = torch.load('res50_198_temp.pkl').module res_model = nn.DataParallel(res_model).cuda() # update proba pred_prob = clf.decision_function(features_untrain) pred_prob = pred_prob - np.max(pred_prob, axis=1).reshape( (-1, 1)) # new pred_prob = np.exp(pred_prob) pred_prob = pred_prob / np.sum(pred_prob, axis=1).reshape((-1, 1)) if (printflag is True or add_ratio > 0.9): pred_sm, lab_sm, score_sm = mu.pre_from_feature_ww( res_model, data.val, data_dir, data_params) print('\n...softmax...') if (add_ratio > 0.9): print( classification_report_imbalanced_light( lab_sm, pred_sm, score_sm, len(np.unique(lab_sm)))) else: print( classification_report_imbalanced_light( lab_sm, pred_sm, score_sm, len(np.unique(lab_sm))))
def spaco(configs, data, iter_steps=1, gamma=0, train_ratio=0.2, regularizer='hard', device='cuda:0'): """ self-paced co-training model implementation based on Pytroch params: model_names: model names for spaco, such as ['resnet50','densenet121'] data: dataset for spaco model save_pathts: save paths for two models iter_step: iteration round for spaco gamma: spaco hyperparameter train_ratio: initiate training dataset ratio """ num_view = len(configs) train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio, args.seed) data_dir = data.images_dir query_gallery = list(set(data.query) | set(data.gallery)) save_dir = os.path.join('logs', 'parallel_spaco', regularizer, 'seed_%d' % args.seed) ########### # initiate classifier to get preidctions ########### add_ratio = 0.5 pred_probs = [] sel_ids = [] weights = [] features = [] start_step = 0 for view in range(num_view): net = models.create(configs[view].model_name, num_features=configs[view].num_features, dropout=configs[view].dropout, num_classes=configs[view].num_classes).to(device) mu.train(net, train_data, data_dir, configs[view], device) pred_probs.append(mu.predict_prob(net, untrain_data, data_dir, configs[view], device)) predictions = mu.predict_prob(net, data.trainval, data_dir, configs[view], device) mAP = mu.evaluate(net, data, configs[view], device) save_checkpoint( { 'state_dict': net.state_dict(), 'epoch': 0, 'train_data': train_data, 'trainval': data.trainval, 'predictions': predictions, 'performance': mAP }, False, fpath=os.path.join(save_dir, '%s.epoch0' % (configs[view].model_name))) pred_y = np.argmax(sum(pred_probs), axis=1) # initiate weights for unlabled examples for view in range(num_view): sel_id, weight = dp.get_ids_weights(pred_probs[view], pred_y, train_data, add_ratio, gamma, regularizer, num_view) sel_ids.append(sel_id) weights.append(weight) # start iterative training for step in range(start_step, iter_steps): for view in range(num_view): # update v_view sel_ids[view], weights[view] = update_ids_weights(view, pred_probs, sel_ids, weights, pred_y, train_data, add_ratio, gamma, regularizer) # update w_view new_train_data, _ = dp.update_train_untrain(sel_ids[view], train_data, untrain_data, pred_y, weights[view]) configs[view].set_training(True) net = models.create(configs[view].model_name, num_features=configs[view].num_features, dropout=configs[view].dropout, num_classes=configs[view].num_classes).to(device) mu.train(net, new_train_data, data_dir, configs[view], device) # update y pred_probs[view] = mu.predict_prob(net, untrain_data, data_dir, configs[view], device) # calculate predict probility on all data test_acc(net, data.trainval, data_dir, configs[view], device) # evaluation current model and save it mAP = mu.evaluate(net, data, configs[view], device) predictions = mu.predict_prob(net, data.trainval, data_dir, configs[view], device) save_checkpoint( { 'state_dict': net.state_dict(), 'epoch': step + 1, 'train_data': new_train_data, 'trainval': data.trainval, 'predictions': predictions, 'performance': mAP }, False, fpath=os.path.join( save_dir, '%s.epoch%d' % (configs[view].model_name, step + 1))) if step + 1 == iter_steps: features += [ mu.get_feature(net, query_gallery, data.images_dir, configs[view], device) ] add_ratio += 1.2 # pred_y = np.argmax(sum(pred_probs), axis=1) acc = mu.combine_evaluate(features, data) print(acc)
def spaco(model_names, data, save_paths, iter_step=1, gamma=0.3, train_ratio=0.2): """ self-paced co-training model implementation based on Pytroch params: model_names: model names for spaco, such as ['resnet50','densenet121'] data: dataset for spaco model save_pathts: save paths for two models iter_step: iteration round for spaco gamma: spaco hyperparameter train_ratio: initiate training dataset ratio """ assert iter_step >= 1 assert len(model_names) == 2 and len(save_paths) == 2 num_view = len(model_names) train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio) data_dir = data.images_dir num_classes = data.num_trainval_ids ########### # initiate classifier to get preidctions ########### add_ratio = 0.5 pred_probs = [] add_ids = [] for view in range(num_view): pred_probs.append( mu.train_predict(model_names[view], train_data, untrain_data, num_classes, data_dir)) add_ids.append(dp.sel_idx(pred_probs[view], train_data, add_ratio)) pred_y = np.argmax(sum(pred_probs), axis=1) for step in range(iter_step): for view in range(num_view): # update v_view ov = add_ids[1 - view] pred_probs[view][ov, pred_y[ov]] += gamma add_id = dp.sel_idx(pred_probs[view], train_data, add_ratio) # update w_view new_train_data, _ = dp.update_train_untrain( add_id, train_data, untrain_data, pred_y) model = mu.train(model_names[view], new_train_data, data_dir, num_classes) # update y data_params = mu.get_params_by_name(model_names[view]) pred_probs[view] = mu.predict_prob(model, untrain_data, data_dir, data_params) pred_y = np.argmax(sum(pred_probs), axis=1) # udpate v_view for next view add_ratio += 0.5 add_ids[view] = dp.sel_idx(pred_probs[view], train_data, add_ratio) # evaluation current model and save it mu.evaluate(model, data, data_params) torch.save(model.state_dict(), save_paths[view] + '.spaco.epoch%d' % (step + 1))
def cotrain(configs, data, iter_steps=1, train_ratio=0.2, device='cuda:0'): """ cotrain model: params: model_names: model configs data: dataset include train and untrain data save_paths: paths for storing models iter_steps: maximum iteration steps train_ratio: labeled data ratio """ add_ratio = 0.5 assert iter_steps >= 1 train_data, untrain_data = dp.split_dataset(data.trainval, train_ratio, args.seed) query_gallery = list(set(data.query) | set(data.gallery)) data_dir = data.images_dir new_train_data = deepcopy(train_data) features = [] for step in range(iter_steps): pred_probs = [] add_ids = [] for view in range(2): config = configs[view] config.set_training(True) net = models.create(config.model_name, num_features=config.num_features, dropout=config.dropout, num_classes=config.num_classes).to(device) mu.train(net, new_train_data, data_dir, configs[view], device) save_checkpoint( { 'state_dict': net.state_dict(), 'epoch': step + 1, 'train_data': new_train_data }, False, fpath=os.path.join('logs/cotrain/seed_%d/%s.epoch%d' % (args.seed, config.model_name, step))) if len(untrain_data) == 0: continue pred_probs.append( mu.predict_prob(net, untrain_data, data_dir, configs[view], device)) add_ids.append(dp.sel_idx(pred_probs[view], train_data, add_ratio)) # calculate predict probility on all data p_b = mu.predict_prob(net, data.trainval, data_dir, configs[view], device) p_y = np.argmax(p_b, axis=1) t_y = [c for (_, c, _, _) in data.trainval] print(np.mean(t_y == p_y)) ### final evaluation if step + 1 == iter_steps: features += [ mu.get_feature(net, query_gallery, data.images_dir, configs[view], device) ] # update training data pred_y = np.argmax(sum(pred_probs), axis=1) add_id = sum(add_ids) if args.tricks: add_ratio += 1.2 new_train_data, _ = dp.update_train_untrain( add_id, train_data, untrain_data, pred_y) else: if len(untrain_data) == 0: break new_train_data, untrain_data = dp.update_train_untrain( add_id, new_train_data, untrain_data, pred_y) acc = mu.combine_evaluate(features, data) print(acc)