美文网首页
(SOTA版本)基于pytorch实现Attack Federa

(SOTA版本)基于pytorch实现Attack Federa

作者: 小胖子善轩 | 来源:发表于2020-05-22 14:57 被阅读0次

    更新日期截止2020年5月22日,项目定期维护和更新,维护各种SOTA的Federated Learning的攻防模型。Github 地址https://github.com/shanxuanchen/attacking_federate_learning

    前言

    联邦学习通过只对梯度的传输,可以在互不公开数据集的前提下训练模型。然后,也正是这种隐匿性,让Federated Learning非常脆弱,天然不得不在non-iid的数据环境中进行训练(真实情况绝大部分是non-iid)。因此,黑客可以通过poison data,或者backdooor的方式攻击模型,从而使模型无法收敛或者留有后门。

    Krum

    Krum是2017年NIPS上具有拜占庭容错能力的SGD方法,Krum最核心的思想就是选择每次都会选择最靠近其余n-m-2个梯度的梯度。这个表达可能有点拗口,通俗易懂点理解就是,找出一个n-m-2个最集中的梯度集合,其中使用欧拉距离来进行度量。

    \operatorname{Krum}(\mathcal{P})=\left(p_{i} | \operatorname{argmin}_{i \in[n]} \sum_{i \rightarrow j}\left\|p_{i}-p_{j}\right\|^{2}\right)

    实现代码如下:

    def krum(users_grads, users_count, corrupted_count, distances=None,return_index=False, debug=False):
        if not return_index:
            assert users_count >= 2*corrupted_count + 1,('users_count>=2*corrupted_count + 3', users_count, corrupted_count)
        non_malicious_count = users_count - corrupted_count
        minimal_error = 1e20
        minimal_error_index = -1
    
        if distances is None:
            distances = _krum_create_distances(users_grads)
        for user in distances.keys():
            errors = sorted(distances[user].values())
            current_error = sum(errors[:non_malicious_count])
            if current_error < minimal_error:
                minimal_error = current_error
                minimal_error_index = user
    
        if return_index:
            return minimal_error_index
        else:
            return users_grads[minimal_error_index]
    
    

    Trimmed Mean

    基于均值的拜占庭容错SGD,核心思想很简单,就是找最接近均值的n-m个梯度。

    \text { TrimmedMean }(\mathcal{P})=\left\{v_{j}=\frac{1}{\left|U_{j}\right|} \sum_{i \in U_{j}}\left(p_{i}\right)_{j}: j \in[d]\right\}

    实现代码如下:

    
    def trimmed_mean(users_grads, users_count, corrupted_count):
        number_to_consider = int(users_grads.shape[0] - corrupted_count) - 1
        current_grads = np.empty((users_grads.shape[1],), users_grads.dtype)
    
        for i, param_across_users in enumerate(users_grads.T):
            med = np.median(param_across_users)
            good_vals = sorted(param_across_users - med, key=lambda x: abs(x))[:number_to_consider]
            current_grads[i] = np.mean(good_vals) + med
        return current_grads
    
    

    Bulyan

    Bulyan是目前SOTA的一个拜占庭容错算法,它十分巧妙,简单地来说,就是不断循环选择Selection Set,然后跑一次Trimmed Mean。而特别的是,该算法是使用Krum来选择Selection Set的。所以,目前SOTA的容错算法是Krum + Trimmed Mean的一个结合。

    算法如下:

    image.png

    代码如下:

    
    def bulyan(users_grads, users_count, corrupted_count):
        assert users_count >= 4*corrupted_count + 3
        set_size = users_count - 2*corrupted_count
        selection_set = []
    
        distances = _krum_create_distances(users_grads)
        while len(selection_set) < set_size:
            currently_selected = krum(users_grads, users_count - len(selection_set), corrupted_count, distances, True)
            selection_set.append(users_grads[currently_selected])
    
            # remove the selected from next iterations:
            distances.pop(currently_selected)
            for remaining_user in distances.keys():
                distances[remaining_user].pop(currently_selected)
    
        return trimmed_mean(np.array(selection_set), len(selection_set), 2*corrupted_count)
    
    

    总结

    代码里是实现了的,但是由于篇幅问题,最强的攻击模型《A Little Is Enough: Circumventing Defenses For Distributed Learning》留着下一篇。这篇论文攻击了上面三种SOTA的防御机制,值得深入研究与探讨。关于Byzantine SGD的攻防这个方向,其实代码量不大,需要有对SGD收敛性证明的能力,与SGD防御的证明能力。

    相关文章

      网友评论

          本文标题:(SOTA版本)基于pytorch实现Attack Federa

          本文链接:https://www.haomeiwen.com/subject/ktmfahtx.html