Partea 2: Introducere în Federated Learning

În partea trecută, am învățat despre PointerTensors, care crează infrastructura necesară pentru privacy preserving Deep Learning. În această parte, vom vedea cum să folosim aceste unelte de bază pentru a implementa primul nostru algoritm de privacy preserving deep learning , Federated Learning.

Autori:

Traducător:

Ce este Federated Learning?

Este o metodă simplă și puternică pentru a antrena modele pentru Deep Learning. Dacă te gândești la datele pentru antrenare, ele sunt rezultatul unui proces de colectare. Oamenii (prin device-uri) generează informații prin înregistrarea evenimentelor petrecute în lumea reală. Normal, aceaste date sunt agregate într-un singur loc, o locație centrală astfel încât să poți antrena un model de machine learning. Federated Learning face lucrurile exact invers!

În loc sa aduci datele pentru antrenare la un model (un server central), vei aduce modelul la date (oriunde se află acesta).

Acestă idea permite celui care crează datele să fie singurul care deține o copie permanenta a acestora, și prin aceasta să mențină controlul asupra accesului la date. Destul de mișto, nu?

The idea is that this allows whoever is creating the data to own the only permanent copy, and thus maintain control over who ever has access to it. Pretty cool, eh?

Secțiunea 2.1 - Un simple examplu de Federated Learning

Să începem antrenând un simplu model folosind metoda centralizată. Inițial vom avea nevoie de:

  • un dataset simplu
  • un model
  • logica de bază pentru antrenare astfel încât să învețe

Notă: Dacă acest API nu îți este familiar - mergi la fast.ai și fă cursul lor înainte de a continua cu acest tutorial.


In [ ]:
import torch
from torch import nn
from torch import optim

In [ ]:
# A Toy Dataset
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)

# A Toy Model
model = nn.Linear(2,1)

def train():
    # Logica de antrenare
    opt = optim.SGD(params=model.parameters(),lr=0.1)
    for iter in range(20):

        # 1) șterge gradienții din trecut (dacă aceștia există)
        opt.zero_grad()

        # 2) fă o predicție
        pred = model(data)

        # 3) calculează cât de mult ne-am înșelat
        loss = ((pred - target)**2).sum()

        # 4) verifică care ponderi ne fac să ne înșelăm
        loss.backward()

        # 5) modifică aceste ponderi
        opt.step()

        # 6) afișează progresul
        print(loss.data)

In [ ]:
train()

Și cam asta este! Am antrenat un model simplu în modul convențional. Toate datele sunt agregate pe mașina noastră locală și le putem folosi pentru a updata modelul. Federated Learning, totuși, nu funcționează așa. Așa că hai să modificăm acest exemplu pentru a folosi metoda de Federated Learning!

Așadar, de ce vom avea nevoie:

  • crearea câțiva workeri
  • pointeri pentru datele folosite la antrenare aflat la fiecare worker
  • modificarea logicii de antrenare pentru federated learning

    Noi pași de antrenare:

    • trimiterea modelului la worker
    • antrenarea pe datele aflate acolo
    • recuperează modelul și repetă pentru următorul worker

In [ ]:
import syft as sy
hook = sy.TorchHook(torch)

In [ ]:
# crează câțiva workeri

bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")

In [ ]:
# Un dataset simplu
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)

# obține pointeri la datele folosite pentru antrenare
# aflate la fiecare worker prin trimiterea datelor la
# bob și alice
data_bob = data[0:2]
target_bob = target[0:2]

data_alice = data[2:]
target_alice = target[2:]

# inițializează un model simplu
model = nn.Linear(2,1)

data_bob = data_bob.send(bob)
data_alice = data_alice.send(alice)
target_bob = target_bob.send(bob)
target_alice = target_alice.send(alice)

# organizează pointerii într-o listă
datasets = [(data_bob,target_bob),(data_alice,target_alice)]

opt = optim.SGD(params=model.parameters(),lr=0.1)

In [ ]:
def train():
    # Logica de antrenare
    opt = optim.SGD(params=model.parameters(),lr=0.1)
    for iter in range(10):
        
        # NOU) itereaza prin setul de date aflat la fiecare worker
        for data,target in datasets:
            
            # NOU) trimite modelul la worker-ul corect
            model.send(data.location)

            # 1) șterge gradieții din trecut (dacă aceștia există)
            opt.zero_grad()

            # 2) fă o predicție
            pred = model(data)

            # 3) calculează cât de mult ne-am înșelat
            loss = ((pred - target)**2).sum()

            # 4) verifică care ponderi ne fac să ne înșelăm
            loss.backward()

            # 5) modifică aceste ponderi
            opt.step()
            
            # NOU) recuperează modelul (cu noii gradienți)
            model.get()

            # 6) afișează progresul
            print(loss.get()) # NOU) ușoară modificare ... trebuie să apelăm .get() pe loss
    
# federated averaging

In [ ]:
train()

Bună treabă!

Și voilà! Acum antrenăm un model foarte simplu de Deep Learning folosind Federated Learning! Trimited modelul la fiecare worker, generăm un nou gradient, și apoi recuperăm gradientul unde ne updatăm modelul global. Niciodată în acest proces nu vedem sau cerem acces la datele folosite pentru antrenare! lui Bob Și Alice!!! Păstrăm confidențiale datele lui Bob și Alice!!!

Dezavantaje ale acestui Exemplu

Chiar dacă acest exemplu este drăguț pentru o introducere în Federated Learning, încă are câteva dezavantaje majore. Cel mai notabil, când apelăm model.get() și primim noul model de la Bob sau Alice, putem să despre datele folosite la antrenare ale lui Bob sau Alice prin simpla observare a gradientului. În anumite cazuri, putem să refacem datele de antrenare complet!

Așadar, ce se poate face? Ei bine, prima strategie folosită de oameni este să facă media aritmetică a gradientului înainte ca acesta să fie uploadat la serverul central. Cu toate astea, această strategie necesită folosirea mai sofisticată a obiectelor de tipul PointerTensor. Așadar, în următoarea secțiune, ne vom rezerva ceva timp pentru a învăța despre tehnici mai avansate și apoi vom updata acest exemplu de Federated Learning.

Felicitări!!! - Este timpul să te alături comunității!

Felicitări pentru completarea tutorialului! Daca ți-a făcut plăcere și ai dori să faci parte din Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the movement toward privacy preserving, decentralized ownership of AI and the AI supply chain (data), you can do so in the following ways!

Oferă o stea repo-ului PySyft pe GitHub

Cea mai ușoară metodă de a ajuta comunitatea este de a oferi o "steluță" repo-urilor de pe GitHub! Acest lucru ajută la acumularea de notorietate în ceea ce privesc tool-urile cool la care lucrăm.

Alaturăte comunității pe Slack!

Cea mai bună metodă de a fi la curent cu ultimele progrese este să te alături comunității noastre. Poți face acest lucru prin completarea formularului de la http://slack.openmined.org

Alătură-te unui proiect!

Cea mai bună metodă de a contribui este de a deveni un contributor activ (de a scrie cod și crea pull request-uri - PR-uri). În orice moment poți merge pe pagina GitHub, cu Issues, a proiectului, și să filtrezi după "Projects". Asta îți va arăta Ticketele "generale" și îți va oferi o privire de ansamblu despre proiectele la care poți participa. Dacă nu dorești să te alături unui proiect, dar dorești să scrii câteva linii de cod, poți să cauți "mini-proiecte" prin căutarea tagului de "good first issue".

Donează

Dacă nu ai timp să contribui la codebase, dar dorești să îți arăți suportul, se poate, de asemenea, să devii un Backer pentru Open Collective. Toate donațiile merg spre hosting-ului paginii web și alte cheltuieli ale comunității, cum ar fi hackathoane și întâlniri!

OpenMined's Open Collective Page