日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

联邦学习:按Dirichlet分布划分Non-IID样本

發(fā)布時(shí)間:2023/12/3 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 联邦学习:按Dirichlet分布划分Non-IID样本 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Python微信訂餐小程序課程視頻

https://edu.csdn.net/course/detail/36074

Python實(shí)戰(zhàn)量化交易理財(cái)系統(tǒng)

https://edu.csdn.net/course/detail/35475
我們?cè)凇禤ython中的隨機(jī)采樣和概率分布(二)》介紹了如何用Python現(xiàn)有的庫(kù)對(duì)一個(gè)概率分布進(jìn)行采樣,其中的Dirichlet分布大家一定不會(huì)感到陌生。該分布的概率密度函數(shù)為

P(x;α)∝k∏i=1xαi?1ix=(x1,x2,…,xk),xi>0,k∑i=1xi=1α=(α1,α2,…,αk).αi>0P(\bm{x}; \bm{\alpha}) \propto \prod_{i=1}^{k} x_{i}^{\alpha_{i}-1} \
\bm{x}=(x_1,x_2,…,x_k),\quad x_i > 0 , \quad \sum_{i=1}^k x_i = 1\
\bm{\alpha} = (\alpha_1,\alpha_2,…, \alpha_k). \quad \alpha_i > 0
其中α\bm{\alpha}為參數(shù)。

我們?cè)诼?lián)邦學(xué)習(xí)中,經(jīng)常會(huì)假設(shè)不同client間的數(shù)據(jù)集不滿足獨(dú)立同分布(Non-IID)。那么我們?nèi)绾螌⒁粋€(gè)現(xiàn)有的數(shù)據(jù)集按照Non-IID劃分呢?我們知道帶標(biāo)簽樣本的生成分布看可以表示為p(x,y)p(\bm{x}, y),我們進(jìn)一步將其寫(xiě)作p(x,y)=p(x|y)p(y)p(\bm{x}, y)=p(\bm{x}|y)p(y)。其中如果要估計(jì)p(x|y)p(\bm{x}|y)的計(jì)算開(kāi)銷非常大,但估計(jì)p(y)p(y)的計(jì)算開(kāi)銷就很小。所有我們按照樣本的標(biāo)簽分布來(lái)對(duì)樣本進(jìn)行Non-IID劃分是一個(gè)非常高效、簡(jiǎn)便的做法。

總而言之,我們采取的算法思路是盡量讓每個(gè)client上的樣本標(biāo)簽分布不同。我們?cè)O(shè)有KK個(gè)類別標(biāo)簽,NN個(gè)client,每個(gè)類別標(biāo)簽的樣本需要按照不同的比例劃分在不同的client上。我們?cè)O(shè)矩陣X∈RK?N\bm{X}\in \mathbb{R}^{K*N}為類別標(biāo)簽分布矩陣,其行向量xk∈RN\bm{x}_k\in \mathbb{R}^N表示類別kk在不同client上的概率分布向量(每一維表示kk類別的樣本劃分到不同client上的比例),該隨機(jī)向量就采樣自Dirichlet分布。

據(jù)此,我們可以寫(xiě)出以下的劃分算法:

import numpy as np
np.random.seed(42)
def split\_noniid(train\_labels, alpha, n\_clients):'''參數(shù)為alpha的Dirichlet分布將數(shù)據(jù)索引劃分為n\_clients個(gè)子集'''n_classes = train_labels.max()+1label_distribution = np.random.dirichlet([alpha]*n_clients, n_classes)# (K, N)的類別標(biāo)簽分布矩陣X,記錄每個(gè)client占有每個(gè)類別的多少class_idcs = [np.argwhere(train_labels==y).flatten() for y in range(n_classes)]# 記錄每個(gè)K個(gè)類別對(duì)應(yīng)的樣本下標(biāo)client_idcs = [[] for _ in range(n_clients)]# 記錄N個(gè)client分別對(duì)應(yīng)樣本集合的索引for c, fracs in zip(class_idcs, label_distribution):# np.split按照比例將類別為k的樣本劃分為了N個(gè)子集# for i, idcs 為遍歷第i個(gè)client對(duì)應(yīng)樣本集合的索引for i, idcs in enumerate(np.split(c, (np.cumsum(fracs)[:-1]*len(c)).astype(int))):client_idcs[i] += [idcs]client_idcs = [np.concatenate(idcs) for idcs in client_idcs]return client_idcs

加下來(lái)我們?cè)贓MNIST數(shù)據(jù)集上調(diào)用該函數(shù)進(jìn)行測(cè)試,并進(jìn)行可視化呈現(xiàn)。我們?cè)O(shè)client數(shù)量N=10N=10,Dirichlet概率分布的參數(shù)向量α\bm{\alpha}滿足αi=1.0,?i=1,2,…N\alpha_i=1.0,\space i=1,2,…N:

import torch
from torchvision import datasets
import numpy as np
import matplotlib.pyplot as plttorch.manual_seed(42)if __name__ == "\_\_main\_\_":N_CLIENTS = 10 DIRICHLET_ALPHA = 1.0train_data = datasets.EMNIST(root=".", split="byclass", download=True, train=True)test_data = datasets.EMNIST(root=".", split="byclass", download=True, train=False)n_channels = 1input_sz, num_cls = train_data.data[0].shape[0],  len(train_data.classes)train_labels = np.array(train_data.targets)# 我們讓每個(gè)client不同label的樣本數(shù)量不同,以此做到Non-IID劃分client_idcs = split_noniid(train_labels, alpha=DIRICHLET_ALPHA, n_clients=N_CLIENTS)# 展示不同client的不同label的數(shù)據(jù)分布plt.figure(figsize=(20,3))plt.hist([train_labels[idc]for idc in client_idcs], stacked=True, bins=np.arange(min(train_labels)-0.5, max(train_labels) + 1.5, 1),label=["Client {}".format(i) for i in range(N_CLIENTS)], rwidth=0.5)plt.xticks(np.arange(num_cls), train_data.classes)plt.legend()plt.show()

最終的可視化結(jié)果如下:

可以看到,62個(gè)類別標(biāo)簽在不同client上的分布確實(shí)不同,證明我們的樣本劃分算法是有效的。

總結(jié)

以上是生活随笔為你收集整理的联邦学习:按Dirichlet分布划分Non-IID样本的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。