Exemplo n.º 1
0
def main(config_path):
    with open(config_path, 'r') as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
        print(config)

    device = torch.device(config['device'])
    """
    Setup models
    """
    global_model = MLP(dataset=config['dataset'], 
                       num_layers=config['num_layers'],
                       hidden_size=config['hidden_size'],
                       drop_rate=config['drop_rate']).to(device)
    print(global_model)

    local_model_list = []
    local_optim_list = []
    for local_id in range(config['num_devices']):
        local_model = MLP(dataset=config['dataset'], 
                       num_layers=config['num_layers'],
                       hidden_size=config['hidden_size'],
                       drop_rate=config['drop_rate']).to(device)
        local_optim = GD(local_model.parameters(), lr=config['lr'], weight_decay=1e-4)
        local_model_list.append(local_model)
        local_optim_list.append(local_optim)

    personal_model_list = []
    personal_optim_list = []
    for local_id in range(config['num_devices']):
        personal_model = MLP(dataset=config['dataset'], 
                            num_layers=config['num_layers'],
                            hidden_size=config['hidden_size'],
                            drop_rate=config['drop_rate']).to(device)
        personal_optim = GD(personal_model.parameters(), lr=config['lr'], weight_decay=1e-4)
        personal_model_list.append(personal_model)
        personal_optim_list.append(personal_optim)

    init_weight = copy.deepcopy(global_model.state_dict())

    criterion = nn.NLLLoss().to(device)

    """
    load data and user group
    """
    train_dataset, test_dataset, user_groups = get_dataset(config)
    weight_per_user = [len(user_groups[local_id]) for local_id in range(config['num_devices'])]
    weight_per_user = np.array(weight_per_user)/sum(weight_per_user)

    trainloader_list, validloader_list = [], []
    trainloader_iterator_list, validloader_iterator_list = [], []
    for local_id in range(config['num_devices']):
        trainloader, validloader = train_val_dataloader(train_dataset, user_groups[local_id], 
                                                        batch_size=config['local_batch_size'])
        trainloader_list.append(trainloader)
        validloader_list.append(validloader)

        trainloader_iterator_list.append(iter(trainloader_list[local_id]))
        validloader_iterator_list.append(iter(validloader_list[local_id]))

    """
    load initial value
    """
    global_model.load_state_dict(init_weight)
    for local_id in range(config['num_devices']):
        local_model_list[local_id].load_state_dict(init_weight)

    """
    start training
    """
    global_acc = []
    global_loss = []

    local_loss = []
    local_acc = []
    train_loss = []

    # test global model
    list_acc, list_loss = [], [] 
    for local_id in range(config['num_devices']):
        acc, loss = inference(global_model, validloader_list[local_id], criterion, device)
        list_acc.append(acc)
        list_loss.append(loss)
    global_acc +=  [sum(list_acc)/len(list_acc)]
    global_loss += [sum(list_loss)/len(list_loss)]
    print('global %d, acc %f, loss %f'%(len(global_acc), global_acc[-1], global_loss[-1]))

    for global_iter in range(config['global_iters']): # T
        activate_devices = np.random.permutation(config['num_devices'])[:config['num_active_devices']] # np.arange(config['num_devices'])
        # get the local grad for each device
        
        for local_iter in range(config['local_iters']): # E
            cur_local_loss = []
            cur_local_acc = []
            cur_train_loss = []
            for local_id in activate_devices: # K
                # load single mini-batch
                try:
                    inputs, labels = next(trainloader_iterator_list[local_id])
                except StopIteration:
                    trainloader_iterator_list[local_id] = iter(trainloader_list[local_id])
                    inputs, labels = next(trainloader_iterator_list[local_id])

                # train local model
                inputs, labels = inputs.to(device), labels.to(device)
                local_model_list[local_id].train()
                local_model_list[local_id].zero_grad()
                log_probs = local_model_list[local_id](inputs)
                loss = criterion(log_probs, labels)
                loss.backward()
                # cur_train_loss.append(loss.item())

                local_optim_list[local_id].step()
                
                # train personalize model
                personal_model_list[local_id].train()
                personal_model_list[local_id].zero_grad()
                log_probs_1 = local_model_list[local_id](inputs)
                log_probs_2 = personal_model_list[local_id](inputs)
                log_probs = (1-config['p_alpha']) * log_probs_1 + config['p_alpha'] * log_probs_2
                loss = criterion(log_probs, labels)
                loss.backward()
                cur_train_loss.append(loss.item())
                
                personal_optim_list[local_id].step()

                # test local model
                acc, loss = inference_personal(local_model_list[local_id], personal_model_list[local_id], 
                                               config['p_alpha'], validloader_list[local_id], criterion, device)
                cur_local_loss.append(loss)
                cur_local_acc.append(acc)

            cur_local_loss = sum(cur_local_loss)/len(cur_local_loss)
            cur_local_acc = sum(cur_local_acc)/len(cur_local_acc)
            cur_train_loss = sum(cur_train_loss)/len(cur_train_loss)
            local_loss.append(cur_local_loss)
            local_acc.append(cur_local_acc)
            train_loss.append(cur_train_loss)

        # update learning rate
        for local_id in activate_devices:
            local_optim_list[local_id].inverse_prop_decay_learning_rate(global_iter) 

        # average local models 
        local_weight_list = [local_model.state_dict() for local_model in local_model_list]
        avg_local_weight = average_state_dicts(local_weight_list, weight_per_user)
        global_model.load_state_dict(avg_local_weight)
        for local_id in range(config['num_devices']):
            local_model_list[local_id].load_state_dict(avg_local_weight)

        # test global model
        list_acc, list_loss = [], [] 
        for local_id in range(config['num_devices']):
            acc, loss = inference(global_model, validloader_list[local_id], criterion, device)
            list_acc.append(acc)
            list_loss.append(loss)
        global_acc +=  [sum(list_acc)/len(list_acc)]
        global_loss += [sum(list_loss)/len(list_loss)]
        print('global %d, acc %f, loss %f'%(len(global_acc), global_acc[-1], global_loss[-1]))
        
    """
    save results
    """
    with open('apfl_%s_noniid_%d.pkl'%(config['dataset'], config['noniid_level']), 'wb') as f:
        pickle.dump([global_acc, global_loss, local_acc, local_loss, train_loss], f)
Exemplo n.º 2
0
def main(config_path):
    with open(config_path, 'r') as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
        print(config)
        
    device = torch.device(config['device'])
    
    """
    Setup models
    """
    global_model = Perceptron(dim_in=config['dimension'], dim_out=config['num_classes']).to(device)
    
    local_model_list = []
    local_optim_list = []
    for local_id in range(config['num_devices']):
        local_model = Perceptron(dim_in=config['dimension'], dim_out=config['num_classes']).to(device)
        local_optim = GD(local_model.parameters(), lr=config['lr'], weight_decay=1e-4)
        local_model_list.append(local_model)
        local_optim_list.append(local_optim)

    init_weight = copy.deepcopy(global_model.state_dict())

    criterion = nn.NLLLoss().to(device)
    
    """
    generate training data
    """
    synthetic_dataset = SyntheticDataset(num_classes=config['num_classes'], 
                                     num_tasks=config['num_devices'], 
                                     num_dim=config['dimension'],
                                     alpha=config['alpha'], beta=config['beta'])
    data = synthetic_dataset.get_all_tasks()
    num_samples = synthetic_dataset.get_num_samples()
    weight_per_user = num_samples/sum(num_samples)

    trainloader_list, validloader_list = [], []
    trainloader_iterator_list, validloader_iterator_list = [], []
    for local_id in range(config['num_devices']):
        trainloader, validloader = train_val_dataloader(data[local_id]['x'], data[local_id]['y'], batch_size=config['local_batch_size'])
        trainloader_list.append(trainloader)
        validloader_list.append(validloader)

        trainloader_iterator_list.append(iter(trainloader_list[local_id]))
        validloader_iterator_list.append(iter(validloader_list[local_id]))
        
    """
    load initial value
    """
    global_model.load_state_dict(init_weight)
    for local_id in range(config['num_devices']):
        local_model_list[local_id].load_state_dict(init_weight)

    """
    start training
    """
    global_acc = []
    global_loss = []

    local_loss = []
    local_acc = []
    train_loss = []

    # test global model
    list_acc, list_loss = [], [] 
    for local_id in range(config['num_devices']):
        acc, loss = inference(global_model, validloader_list[local_id], criterion, device)
        list_acc.append(acc)
        list_loss.append(loss)
    global_acc +=  [sum(list_acc)/len(list_acc)]
    global_loss += [sum(list_loss)/len(list_loss)]
    print('global %d, acc %f, loss %f'%(len(global_acc), global_acc[-1], global_loss[-1]))

    for global_iter in range(config['global_iters']): # T
        activate_devices = np.random.permutation(config['num_devices'])[:config['num_active_devices']] # np.arange(config['num_devices'])
        # get the local grad for each device
        
        for local_iter in range(config['local_iters']): # E
            cur_local_loss = []
            cur_local_acc = []
            cur_train_loss = []
            for local_id in activate_devices: # K
                # load single mini-batch
                try:
                    inputs, labels = next(trainloader_iterator_list[local_id])
                except StopIteration:
                    trainloader_iterator_list[local_id] = iter(trainloader_list[local_id])
                    inputs, labels = next(trainloader_iterator_list[local_id])

                # train local model
                inputs, labels = inputs.to(device), labels.to(device)
                local_model_list[local_id].train()
                local_model_list[local_id].zero_grad()
                log_probs = local_model_list[local_id](inputs)
                loss = criterion(log_probs, labels)
                loss.backward()
                cur_train_loss.append(loss.item())

                local_optim_list[local_id].step() # lr=config['lr']/(1+global_iter)

                # test local model
                acc, loss = inference(local_model_list[local_id], validloader_list[local_id], criterion, device)
                cur_local_loss.append(loss)
                cur_local_acc.append(acc)

            cur_local_loss = sum(cur_local_loss)/len(cur_local_loss)
            cur_local_acc = sum(cur_local_acc)/len(cur_local_acc)
            cur_train_loss = sum(cur_train_loss)/len(cur_train_loss)
            local_loss.append(cur_local_loss)
            local_acc.append(cur_local_acc)
            train_loss.append(cur_train_loss)

        # update learning rate
        for local_id in activate_devices:
            local_optim_list[local_id].inverse_prop_decay_learning_rate(global_iter) 

        # average local models 
        local_weight_list = [local_model.state_dict() for local_model in local_model_list]
        avg_local_weight = average_state_dicts(local_weight_list, weight_per_user)
        global_model.load_state_dict(avg_local_weight)
        for local_id in range(config['num_devices']):
            local_model_list[local_id].load_state_dict(avg_local_weight)

        # test global model
        list_acc, list_loss = [], [] 
        for local_id in range(config['num_devices']):
            acc, loss = inference(global_model, validloader_list[local_id], criterion, device)
            list_acc.append(acc)
            list_loss.append(loss)
        global_acc +=  [sum(list_acc)/len(list_acc)]
        global_loss += [sum(list_loss)/len(list_loss)]
        print('global %d, acc %f, loss %f'%(len(global_acc), global_acc[-1], global_loss[-1]))
        
    """
    save results
    """
    with open('fedavg_%.2f.pkl'%config['beta'], 'wb') as f:
        pickle.dump([global_acc, global_loss, local_acc, local_loss, train_loss], f)
Exemplo n.º 3
0
 def startDescentGradient(self, idx_e1, idx_e2, r, er):
     x = self.makeX(idx_e1, idx_e2)
     y = self.makeY(idx_e1, idx_e2, r)
     gd = GD(er, x, y)
     result = gd.start()
     return result
Exemplo n.º 4
0
def main():
    global N, Y, X_mu, X_S, flat_global_statistics_bounds, fix_beta, global_statistics_names

    iterations = 100

    # Load data
    Y = numpy.concatenate((numpy.genfromtxt('./easydata/inputs/easy_1',
                                            delimiter=','),
                           numpy.genfromtxt('./easydata/inputs/easy_2',
                                            delimiter=','),
                           numpy.genfromtxt('./easydata/inputs/easy_3',
                                            delimiter=','),
                           numpy.genfromtxt('./easydata/inputs/easy_4',
                                            delimiter=',')))
    N = Y.shape[0]

    # We have several differet possible initialisations for the embeddings
    #X_mu = numpy.load(X_file)
    #X_mu = PCA(Y_file, Q)
    #X_mu = scipy.randn(N, Q)
    X_S = numpy.clip(
        numpy.ones((N, Q)) * 0.5 + 0.01 * scipy.randn(N, Q), 0.001, 1)
    #X_S = numpy.zeros((N, Q))

    X_mu = numpy.concatenate(
        (scipy.load('./easydata/embeddings/easy_1.embedding.npy'),
         scipy.load('./easydata/embeddings/easy_2.embedding.npy'),
         scipy.load('./easydata/embeddings/easy_3.embedding.npy'),
         scipy.load('./easydata/embeddings/easy_4.embedding.npy')))
    '''
    X_S = numpy.concatenate((
        scipy.load('./easydata/embeddings/easy_1.variance.npy'),
        scipy.load('./easydata/embeddings/easy_2.variance.npy'),
        scipy.load('./easydata/embeddings/easy_3.variance.npy'),
        scipy.load('./easydata/embeddings/easy_4.variance.npy')))
    '''
    # Initialise the inducing points
    Z = X_mu[numpy.random.permutation(N)[:M], :]
    #Z = X_mu[:M,:]
    Z += scipy.randn(M, Q) * 0.1

    global_statistics_names = {
        'Z': (M, Q),
        'sf2': (1, 1),
        'alpha': (1, Q),
        'beta': (1, 1),
        'X_mu': (N, Q),
        'X_S': (N, Q)
    }
    # Initialise the global statistics
    global_statistics = {
        'Z': Z,  # see GPy models/bayesian_gplvm.py
        'sf2': numpy.array([[1.0]]),  # see GPy kern/rbf.py
        'alpha': scipy.ones((1, Q)),  # see GPy kern/rbf.py
        'beta': numpy.array([[1.0]]),  # see GPy likelihood/gaussian.py
        'X_Zmu': X_mu,
        'X_S': X_S,
    }

    # Initialise bounds for optimisation
    global_statistics_bounds = {
        'Z': [(None, None) for i in range(M * Q)],
        'sf2': [(0, None)],
        'alpha': [(0, None) for i in range(Q)],
        'beta': [(0, None)],
        'X_mu': [(None, None) for i in range(N * Q)],
        'X_S': [(0, None) for i in range(N * Q)],
    }
    flat_global_statistics_bounds = []
    for key, statistic in global_statistics_bounds.items():
        flat_global_statistics_bounds = flat_global_statistics_bounds + statistic
    ''' 
    Run the optimiser 
    '''
    x0 = flatten_global_statistics(global_statistics)
    # Transform the positiv parameters to be in the range (-Inf, Inf)
    x0 = numpy.array([
        transform_back(b, x) for b, x in zip(flat_global_statistics_bounds, x0)
    ])
    ''' 
    SCG optimisation (adapted from GPy implementation to reduce function calls)
    The number of iterations might be greater than max_f_eval
    '''
    #fix_beta = True
    # We set the flag fixed_embeddings to true because we just need the globals (which now include the embeddings) optimised
    x = GD(likelihood_and_gradient,
           x0,
           './easydata/tmp/',
           fixed_embeddings=True,
           display=True,
           maxiters=iterations)
    #fix_beta = False
    #x = SC(likelihood_and_gradient, x[0], display=True, maxiters=iterations)
    flat_array = x[0]

    # Transform the parameters that have to be positive to be positive
    flat_array_transformed = numpy.array([
        transform(b, x)
        for b, x in zip(flat_global_statistics_bounds, flat_array)
    ])
    global_statistics = rebuild_global_statistics(global_statistics_names,
                                                  flat_array_transformed)
    print 'Final global_statistics'
    print global_statistics
Exemplo n.º 5
0
class draw():
    def __init__(self):
        self.obj = None
        self._range = 2 * math.pi

    def show(self):
        self.obj.fit()
        plt.plot(self.obj.dg.X, self.obj.dg.Y,"or")
        xs = np.linspace(0, self._range, 100)
        f = lambda x:self._f(x);
        plt.plot(xs, [math.sin(x) for x in xs])
        plt.plot(xs, [f(x) for x in xs])
        # plt.plot()
        plt.show()

    def _f(self,x):
        coes = self.obj.coes.T.tolist()[0]
        sum = 0
        xx = 1
        for coe in coes:
            sum += xx * coe
            xx *= x
        return sum

if __name__ == '__main__':
    draw = draw()
    draw.obj = GD()
    draw.show()