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)
save_pth = os.path.join(config.logs_dir, config.model_name, '%s' % (args.checkpoint)) if os.path.exists(save_pth) is not True: raise ValueError('wrong model pth') checkpoint = load_checkpoint(save_pth) state_dict = { k: v for k, v in checkpoint['state_dict'].items() if k in model.state_dict().keys() } model.load_state_dict(state_dict) else: model = mu.train(data.trainval, data.images_dir, config) save_checkpoint( { 'state_dict': model.state_dict(), 'epoch': 0, 'train_data': data.trainval }, False, fpath=os.path.join(config.logs_dir, config.model_name, 'full_supervised')) mu.evaluate(model, data, config) if args.evaluate is True: train_data = checkpoint['train_data'] weight = [w for (_, _, _, w) in train_data] print(np.median(weight)) print(np.mean(weight))
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 wrap_evaluate(net, data, config, view, mAPs): mAPs[view] = mu.evaluate(net, data, config, view)