Î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:
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?
Să începem antrenând un simplu model folosind metoda centralizată. Inițial vom avea nevoie de:
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:
modificarea logicii de antrenare pentru federated learning
Noi pași de antrenare:
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()
Ș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!!!
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 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!
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.
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
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".
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!