跟我學ModelArts丨探索ModelArts平臺個性化聯邦學習API

摘要:ModelArts提供了一個實現個性化聯邦學習的API——pytorch_fedamp_emnist_classification,它主要是讓擁有相似數據分佈的客戶進行更多合作的一個橫向聯邦學習框架,讓我們來對它進行一些學習和探索。

本文分享自華爲雲社區《聯邦學習算法之一ModelArts “pytorch_fedamp_emnist_classification”學習(一)》,原文作者:darkpard。

隨着數字技術的發展,以及全社會對數字化的不斷重視,數據的資源屬性前所未有地突顯出來。相應地,數據隱私和數據安全也越來越受到人們的關注,聯邦學習應運而生,成爲當前比較熱門的一個AI算法發展方向。

什麼是聯邦學習:

聯邦學習(Federated Learning)是一種新興的人工智能基礎技術,在 2016 年由谷歌最先提出,原本用於解決安卓手機終端用戶在本地更新模型的問題,其設計目標是在保障大數據交換時的信息安全、保護終端數據和個人數據隱私、保證合法合規的前提下,在多參與方或多計算結點之間開展高效率的機器學習。

金融運用領域前景:

目前在金融領域,各個金融機構都會建設基於自己的業務場景風控模型,當運用了聯邦學習即可基於各自的風控模型建立聯合模型,就能更準確地識別信貸風險,金融欺詐。同時共同建立聯邦學習模型,還能解決原數據樣本少、數據質量低的問題。

如何實戰聯邦學習:

ModelArts提供了一個實現個性化聯邦學習的API——pytorch_fedamp_emnist_classification,它主要是讓擁有相似數據分佈的客戶進行更多合作的一個橫向聯邦學習框架,讓我們來對它進行一些學習和探索。

1. 環境準備¶

1.1. 導入文件操作模塊和輸出清理模塊¶

import os
import shutil
from IPython.display import clear_output

1.2. 下載聯邦學習包並清除輸出¶

!wget https://obsfs-notebook.obs.cn-north-4.myhuaweicloud.com/FedAMP.zip 
clear_output(wait=False)

1.3. 如果存在FedAMP文件夾,則把它完整地刪除,然後重新創建FedAMP文件夾¶

if os.path.exists('FedAMP'):
    shutil.rmtree('FedAMP')
!mkdir FedAMP

1.4. 把下載的聯邦學習包解壓到該文件夾,刪除壓縮包,並清理輸出¶

!unzip FedAMP.zip -d FedAMP
!rm FedAMP.zip
clear_output(wait=False)

1.5. 安裝基於Pytorch的圖像處理模塊torchvision,並清理輸出¶

!pip install torchvision==0.5.0
clear_output(wait=False)

1.6. 安裝torch框架並清理輸出¶

!pip install torch==1.4.0
clear_output(wait=False)

1.7. 安裝聯邦學習包,刪除原文件,並清理輸出¶

!pip install FedAMP/package/moxing_pytorch-1.17.3.fed-cp36-cp36m-linux_x86_64.whl
!rm -r FedAMP/package
clear_output(wait=False)

1.8. 導入torch框架、numpy、random、matplotlib.pyplot、華爲moxing¶

import torch, random
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import moxing as mox

1.9. 導入華爲moxing框架下的聯邦算法、支持和服務¶

from moxing.framework.federated import fed_algorithm
from moxing.framework.federated import fed_backend
from moxing.framework.federated import fed_server

1.10. 導入華爲moxing torch框架下聯邦學習的的載入、保存、hook和服務¶

from moxing.pytorch.executor.federated.util import torch_load
from moxing.pytorch.executor.federated.util import torch_save
from moxing.pytorch.executor.federated.util import TorchFedHook
from moxing.pytorch.executor.federated import client

1.11. 導入FedAMP和torch.nn下的函數包

from moxing.framework.federated.fed_algorithm import FedAMP
import torch.nn.functional as F

1.12. 準備好文件路徑¶

if mox.file.is_directory('/tmp/fed_workspace/'):
    mox.file.remove('/tmp/fed_workspace/', recursive=True)

2. 建立數據讀取類和數據結構類(具體內容將在下文用到時說明)¶

class DataFileLoaderHorizontal():
    def __init__(self, data=None, label=None):
        if data is None:
            self.data = data
        if label is None:
            self.label = label
    def getDataToTorch(self):
        return torch.FloatTensor(self.data), torch.FloatTensor(self.label)
    def load_file_binary(self, data_filename=None, label_filename=None):
        assert data_filename is not None
        assert label_filename is not None
        self.data = np.load(data_filename, allow_pickle=True)
        self.label = np.load(label_filename, allow_pickle=True)
        self.data, self.label = self.data.astype(float), self.label.astype(float)
class m_Data():
    def __init__(self):
        self.train_samples          = None
        self.train_labels           = None
        self.test_samples           = None
        self.train_samples          = None

3. 將數據讀入對應虛擬租戶¶

3.1. 設置虛擬租戶數量¶

num_clients = 62

3.2. 創建一個數據讀取類¶

df1 = DataFileLoaderHorizontal()

3.3. 初始化訓練集、測試集文件名和文件擴展名¶

rain_sample_filename = 'FedAMP/EMNIST/client_train_samples_'
train_label_filename = 'FedAMP/EMNIST/client_train_labels_'
val_sample_filename = 'FedAMP/EMNIST/client_test_samples_'
val_label_filename = 'FedAMP/EMNIST/client_test_labels_'
filename_sx = '.npy'

3.4. 讓我們來探索一下訓練數據集¶

3.4.1. 先導入一個樣本集¶

df1.load_file_binary(data_filename=train_sample_filename + str(1) + filename_sx,
                         label_filename=train_label_filename + str(1) + filename_sx)

這裏使用了“2.”中DataFileLoaderHorizontal類的load_file_binary方法,該方法首先確認傳入的文件名不爲空,然後numpy的load方法將.npy文件載入,最後用astype方法將其轉爲float類型

3.4.2. 先看一下自變量¶

df1.data

array([[[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

...,

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.]],

...,

[[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

...,

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.]],

[[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

...,

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.],

[0., 0., 0., ..., 0., 0., 0.]]])

df1.data[0]

array([[0. , 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. ],

[0. , 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. ],

………………

[0. , 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. ],

[0. , 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. , 0. , 0. ,

, 0. , 0. ]])

len(df1.data)

1000

可以看到,它是一個比較稀疏的三維數組,由1000個二維數組組成

3.4.3. 再看一下標籤集¶

df1.label

array([40., 7., 5., 4., 8., 8., 0., 9., 3., 34., 2., 2., 8.,

6., 5., 3., 9., 9., 6., 8., 5., 6., 6., 6., 6., 5.,

5., 8., 5., 6., 7., 5., 8., 59., 2., 9., 7., 6., 3.,

4., 57., 7., 9., 49., 52., 25., 4., 2., 43., 6., 9., 5.,

3., 5., 7., 7., 3., 0., 6., 7., 5., 27., 9., 24., 2.,

2., 7., 6., 1., 9., 45., 7., 0., 14., 9., 9., 0., 2.,

6., 5., 1., 4., 6., 36., 8., 0., 34., 0., 0., 53., 5.,

0., 2., 7., 52., 32., 2., 4., 35., 49., 15., 2., 60., 8.,

0., 7., 51., 19., 3., 1., 24., 9., 2., 2., 4., 8., 8.,

4., 3., 0., 9., 7., 6., 26., 7., 4., 7., 7., 2., 8.,

9., 4., 1., 4., 9., 8., 3., 16., 0., 5., 3., 16., 5.,

3., 1., 7., 19., 53., 4., 0., 2., 5., 23., 19., 46., 5.,

2., 7., 4., 51., 57., 7., 16., 2., 1., 0., 2., 4., 0.,

41., 21., 8., 1., 2., 39., 3., 1., 6., 58., 32., 3., 9.,

6., 4., 3., 54., 7., 3., 60., 7., 8., 3., 3., 2., 2.,

5., 60., 5., 5., 6., 7., 9., 9., 2., 8., 3., 43., 5.,

1., 9., 5., 9., 13., 6., 7., 6., 6., 59., 0., 8., 7.,

7., 2., 57., 4., 8., 3., 4., 6., 4., 3., 9., 8., 0.,

6., 48., 0., 4., 2., 3., 4., 8., 18., 2., 2., 4., 30.,

7., 2., 9., 7., 1., 1., 2., 20., 36., 9., 5., 32., 3.,

3., 3., 3., 3., 20., 37., 1., 25., 1., 0., 57., 2., 2.,

0., 3., 9., 2., 18., 2., 3., 40., 28., 1., 4., 2., 8.,

4., 8., 5., 0., 18., 0., 1., 2., 7., 8., 6., 0., 2.,

5., 35., 0., 1., 53., 2., 3., 3., 2., 8., 32., 3., 5.,

6., 8., 2., 7., 40., 8., 5., 6., 8., 4., 9., 1., 13.,

6., 3., 3., 5., 3., 51., 60., 2., 3., 40., 1., 0., 47.,

59., 9., 6., 1., 2., 1., 9., 8., 0., 3., 8., 53., 61.,

8., 5., 18., 7., 0., 4., 1., 1., 51., 0., 9., 43., 6.,

51., 5., 7., 22., 24., 42., 3., 47., 0., 59., 7., 42., 7.,

58., 7., 1., 0., 4., 8., 8., 8., 20., 1., 16., 9., 0.,

3., 23., 6., 4., 45., 5., 0., 1., 2., 9., 1., 27., 9.,

5., 4., 7., 7., 0., 15., 3., 9., 36., 9., 47., 3., 29.,

56., 42., 2., 7., 42., 4., 1., 9., 0., 34., 3., 5., 0.,

15., 0., 6., 4., 7., 4., 5., 0., 15., 9., 8., 43., 7.,

7., 6., 42., 6., 8., 7., 61., 2., 8., 1., 5., 7., 57.,

2., 23., 9., 4., 1., 59., 3., 1., 9., 9., 15., 5., 47.,

27., 6., 6., 0., 4., 2., 3., 2., 22., 3., 6., 2., 6.,

5., 8., 7., 9., 7., 3., 49., 5., 5., 1., 6., 8., 0.,

6., 7., 45., 4., 6., 3., 9., 5., 0., 12., 18., 8., 4.,

3., 4., 6., 6., 4., 5., 3., 29., 7., 7., 5., 9., 7.,

4., 0., 6., 8., 5., 2., 8., 1., 9., 8., 7., 25., 1.,

6., 8., 4., 9., 3., 1., 2., 9., 2., 5., 1., 9., 5.,

1., 2., 1., 5., 24., 45., 7., 0., 4., 8., 49., 9., 6.,

4., 2., 35., 4., 9., 8., 7., 8., 1., 6., 1., 7., 9.,

1., 8., 1., 1., 3., 0., 17., 47., 6., 0., 3., 2., 5.,

5., 55., 28., 9., 56., 7., 8., 2., 2., 50., 8., 4., 9.,

4., 3., 1., 1., 0., 5., 38., 8., 9., 0., 1., 5., 2.,

25., 5., 0., 4., 7., 9., 7., 61., 4., 4., 2., 2., 6.,

41., 45., 20., 5., 8., 5., 8., 7., 9., 4., 3., 1., 7.,

19., 3., 8., 1., 9., 7., 27., 3., 0., 4., 8., 8., 2.,

46., 6., 6., 5., 1., 8., 6., 8., 2., 4., 5., 33., 5.,

5., 5., 8., 0., 2., 31., 5., 1., 7., 1., 5., 48., 41.,

9., 4., 61., 9., 9., 34., 16., 7., 5., 0., 5., 32., 0.,

52., 3., 1., 4., 6., 29., 4., 2., 0., 4., 0., 1., 48.,

3., 9., 5., 1., 7., 6., 4., 4., 5., 8., 8., 9., 1.,

46., 0., 29., 0., 5., 4., 4., 48., 56., 9., 3., 1., 3.,

1., 5., 7., 9., 8., 8., 6., 6., 0., 8., 0., 53., 1.,

6., 1., 4., 4., 8., 11., 9., 8., 1., 44., 4., 2., 1.,

3., 7., 6., 2., 39., 8., 9., 4., 6., 4., 1., 2., 7.,

33., 4., 36., 3., 40., 1., 8., 5., 3., 3., 3., 28., 13.,

9., 1., 46., 1., 5., 22., 0., 9., 0., 0., 2., 1., 2.,

43., 7., 4., 0., 2., 28., 39., 48., 4., 0., 5., 3., 6.,

6., 7., 19., 6., 4., 0., 35., 13., 3., 28., 2., 6., 23.,

2., 5., 1., 0., 8., 8., 2., 10., 27., 0., 49., 58., 23.,

9., 2., 7., 7., 2., 9., 5., 4., 9., 22., 5., 8., 6.,

4., 58., 6., 5., 4., 9., 1., 7., 0., 3., 33., 3., 7.,

9., 6., 3., 1., 1., 6., 2., 1., 2., 7., 3., 7., 8.,

6., 0., 4., 34., 41., 8., 3., 6., 8., 6., 1., 6., 3.,

56., 24., 0., 0., 1., 58., 0., 1., 9., 29., 8., 9., 6.,

6., 8., 9., 1., 39., 3., 0., 4., 25., 8., 33., 0., 2.,

3., 7., 5., 0., 7., 7., 6., 46., 7., 8., 6., 2., 0.,

8., 7., 5., 20., 56., 9., 4., 41., 9., 8., 4., 13., 5.,

3., 61., 4., 5., 1., 33., 0., 1., 7., 1., 0., 6., 3.,

6., 2., 6., 4., 22., 5., 4., 36., 0., 9., 2., 9., 3.,

2., 0., 0., 7., 2., 35., 5., 9., 4., 4., 0., 6., 6.,

9., 5., 5., 39., 3., 1., 60., 4., 52., 6., 4., 0., 1.,

6., 9., 8., 52., 3., 1., 7., 3., 3., 9., 7., 8.])

可以推測,每一份訓練集由1000個樣本組成,自變量爲二維數組

3.4.4. 將樣本集和標籤集轉化爲torch.FloatTensor類型¶

samples, labels = df1.getDataToTorch()

3.5. 讓我們來創建一個“2.0”中m_Data的實例,並將訓練樣本集和標籤集導入m_Data¶

3.5.1. 先來創建一個m_Data¶

m_data = m_Data()

3.5.2. 初始化輸入格式¶

input_dim = (-1, 1, 28, 28)

3.5.3. 創建m_data的訓練集¶

m_data.train_samples = samples.reshape(input_dim)
m_data.train_labels = labels.squeeze()

3.5.4. 創建m_data的測試集¶

df1.load_file_binary(data_filename=val_sample_filename + str(1) + filename_sx,
                     label_filename=val_label_filename + str(1) + filename_sx)
samples, labels = df1.getDataToTorch()
m_data.val_samples = samples.reshape(input_dim)
m_data.val_labels = labels.squeeze()

在此,我們對比m_Data的數據結構,可以發現,m_Data的數據結構中似乎有個小bug,儘管它不影響使用 class m_Data(): def init(self): self.train_samples = None self.train_labels = None self.test_samples = None self.train_samples = None 這裏的test_samples應該是val_samples,最後一個train_samples應該是val_labels

pytorch_fedamp_emnist_classification的第一次學習讓我們先學到這裏。

我們已經在ModelAts上實現了pytorch_fedamp_emnist_classification的環境配置,對樣本數據結構以及pytorch_fedamp_emnist_classification需要的數據結構進行了簡單地探索。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章