Tutorial: Tool-urile de bază pentru Private Deep Learning

Bine ați venit la tutorialul introductiv în PySyft, un tool pentru deep learning descentralizat, pentru păstrarea anonimității datelor. Acestă serie de notebook-uri este un ghid pas-cu-pas care își propune să vă familiarizeze cu noile tool-uri și tehnici necesare pentru a face deep learning pe date/modele secrete/private făra ca acestea să fie deținute de o autoritate.

Notă: Nu vom vorbi doar despre descentralizarea / criptarea datelor, dar vom vedea și cum PySyft poate fi folosit pentru a ajuta la descentralizara întregului ecosistem din jurul datelor, incluzând chiar și bazele de date (unde datele sunt stocate și interogate), rețelele neuronale care sunt folosite să extragem informații din date. Pe măsura ce noi extensii vor fi create pentru PySyft, aceste notebook-uri vor fi extinse cu noi tutoriale pentru a explica noua funcționalitate.

Autor:

Traducător:

Outline:

  • Partea 1: Tool-uri de bază pentru Private Deep Learning

De ce să faci acest tutorial?

1) Un avantaj în carieră - În ultimi 20 de ani, evoluția digitală a făcut ca datele sa fie din ce în ce mai accesibile, Cu toate acestea, cu reglementări precum GDPR, corporațiile se află sub presiune să nu mai puțină libertate cu modul în care folosesc - și mai important despre cum analizează - datele personale. Concluzie: Persoanele care lucrează în domeniul Data Science nu vor putea avea acces la fel de multe date cu tool-uri "de modă veche", însă învățând tool-urile de Private Deep Learning, TU poți avea un avantajat competitiv în carieră. 2) Oportunități antreprenoriale - Există o serie întreagă de probleme în societate pe care Deep Learnig-ul le poate soluționa, dar multe dintre acestea nu au fost explorate deoarece ar necesita accesul la informații foarte sensibile despre oameni (consideră că ai folosi Deep Learning pentru a ajuta persoane cu probleme mentale sau probleme în relație!). Având în vedere aceste lucruri, învățând despre Private Deep Learning scoate la lumină o noua mulțime de oportunități de startup care nu erau valabile înainte fără aceste tool-uri. 3) Binele social - Deep Learning poate fi folosit pentru rezolvarea unei game variate de probleme în viața reală, însă aplicarea metodelor Deep Learning pe informații personale este Deep Learning despre oameni, pentru oameni. Învățând cum să aplici Deep Learning pe date nedeținute

Cum primesc extra credit?

... ok ... hai să trecem la treaba!

Partea -1: Cerințe preliminare

  • Cunosți PyTorch - dacă nu, poți lua cursul http://fast.ai, iar după te poți întoarce la acest notebook
  • Citește paper-ul despre Framework-ul de PySyft https://arxiv.org/pdf/1811.04017.pdf! Acest lucru iți va oferi un background despre cum este construit PySyft și va face ca lucrurile să aibă mai mult sens.

Part 0: Setup

Pentru a începe, trebuie să te asiguri că ai instalate pachetele necesare. Pentru a face acest lucru, mergi la README-ul PySyft și urmărește instrucțiunile de setup. TLDR pentru majoritatea. To begin, you'll need to make sure you have the right things installed. To do so, head on over to PySyft's readme and follow the setup instructions. TLDR for most folks is.

  • Install Python 3.6 or higher
  • Install PyTorch 1.4
  • pip install syft[udacity]

Dacă nu merge o anumită parte din tutorial (sau pica vreun test) - prima dată verifică README-ul pentru ajutor, iar după deschide un Issue pe GitHub sau dă un ping pe canalul de #beginner de pe Slack! slack.openmined.org


In [1]:
# Run this cell to see if things work
import sys

import torch
from torch.nn import Parameter
import torch.nn as nn
import torch.nn.functional as F

import syft as sy
hook = sy.TorchHook(torch)

torch.tensor([1,2,3,4,5])


Falling back to insecure randomness since the required custom op could not be found for the installed version of TensorFlow. Fix this by compiling custom ops. Missing file was '/home/george/.conda/envs/pysyft-contrib/lib/python3.7/site-packages/tf_encrypted/operations/secure_random/secure_random_module_tf_1.15.0.so'
WARNING:tensorflow:From /home/george/.conda/envs/pysyft-contrib/lib/python3.7/site-packages/tf_encrypted/session.py:24: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.

---------------------------------------------------------------------------
UndefinedProtocolTypeError                Traceback (most recent call last)
<ipython-input-1-c5d7ccb73f59> in <module>
      7 import torch.nn.functional as F
      8 
----> 9 import syft as sy
     10 hook = sy.TorchHook(torch)
     11 

~/contrib/PySyft/syft/__init__.py in <module>
     77 
     78 # Import serialization tools
---> 79 from syft import serde
     80 
     81 # import functions

~/contrib/PySyft/syft/serde/__init__.py in <module>
----> 1 from syft.serde.serde import *
      2 from syft.serde.torch_serde import *
      3 from syft.serde.serde import _simplify
      4 from syft.serde.serde import _detail
      5 from syft.serde.serde import _compress

~/contrib/PySyft/syft/serde/serde.py in <module>
    250 
    251 
--> 252 simplifiers, forced_full_simplifiers, detailers = _generate_simplifiers_and_detailers()
    253 # Store types that are not simplifiable (int, float, None) so we
    254 # can ignore them during serialization.

~/contrib/PySyft/syft/serde/serde.py in _generate_simplifiers_and_detailers()
    240     for syft_type in OBJ_SIMPLIFIER_AND_DETAILERS + EXCEPTION_SIMPLIFIER_AND_DETAILERS:
    241         simplifier, detailer = syft_type.simplify, syft_type.detail
--> 242         _add_simplifier_and_detailer(syft_type, simplifier, detailer)
    243 
    244     # Register syft objects with custom force_simplify and force_detail methods

~/contrib/PySyft/syft/serde/serde.py in _add_simplifier_and_detailer(curr_type, simplifier, detailer, forced)
    224 
    225     def _add_simplifier_and_detailer(curr_type, simplifier, detailer, forced=False):
--> 226         type_info = proto_type_info(curr_type)
    227         if forced:
    228             forced_full_simplifiers[curr_type] = (type_info.forced_code, simplifier)

~/contrib/PySyft/syft/serde/proto.py in proto_type_info(cls)
     68         return TypeInfo(name=type_name, obj=proto_info["TYPES"][type_name])
     69     else:
---> 70         raise UndefinedProtocolTypeError("%s is not defined in the protocol file" % type_name)

UndefinedProtocolTypeError: syft.frameworks.torch.tensors.interpreters.private.PrivateTensor is not defined in the protocol file

Dacă celula precedentă s-a executat, atunci totul este în regulă! Putem sa continuăm tutorialul.

Partea 1: Tool-urile de baza pentru Data Science Privat, Descentralizat

Prima întrebare care poate să apară - Cum putem să antrenăm un model pe date la care nu avem accces? Răspunsul este surprinzător de simplu. Dacă ești obișnuit să lucrezi în PyTorch, atunci vei fi obișnuit să lucrezi cu obiecte de tipul torch.Tensor în modul în care vom vedea în acest tutorial.


In [2]:
x = torch.tensor([1,2,3,4,5])
y = x + x
print(y)


tensor([ 2,  4,  6,  8, 10])

Evident, folosirea acestor tensori extravaganți (și puternici!) este important, dar trebuie să ai datele și pe mașina locală. Aici începe călătoria noastră.

Secțiunea 1.1 - Trimiterea de Tensori spre mașina lui Bob

În mod normal am efectua tehnici de data science / deep learning pe mașina care deține datele, acum dorim să efectuăm acest tip de calcul pe altă mașină. Mai specific, nu mai putem face presupunerea că datele sunt pe mașina noastră locală.

Prin urmare, în loc să folosim tensorii din Torch, vom folosi pointeri spre tensori. Lasă-mă să îți arăt ce vreau să spun. Prima data, hai să creăm o "presupusă" mașină deținută de o "presupusă" persoană - se va numi Bob.


In [3]:
bob = sy.VirtualWorker(hook, id="bob")


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-3-b9e1037deafb> in <module>
----> 1 bob = sy.VirtualWorker(hook, id="bob")

NameError: name 'sy' is not defined

Hai să zicem că mașina lui Bob este pe o altă planetă - poate pe Marte! Dar, în acest moment, mașina nu conține informații. Vom crea niște date astfel încât le vom trimite lui Bob și vom învăța despre pointeri!


In [4]:
x = torch.tensor([1,2,3,4,5])
y = torch.tensor([1,1,1,1,1])

Și acum - să trimitem tensorii lui Bob!!


In [ ]:
x_ptr = x.send(bob)
y_ptr = y.send(bob)

In [ ]:
x_ptr

BOOM! Acum Bob are doi tensori! Nu mă crezi? Aruncă o privire!


In [ ]:
bob._objects

In [ ]:
z = x_ptr + x_ptr

In [ ]:
z

In [ ]:
bob._objects

Acum observă. Când am apelat x.send(bob) a întors un nou obiect pe care l-am numit x_ptr. Acesta este primul nostru pointer la un tensor. Pointerii la tensori NU conțin date efective. În loc, ei conțin doar metadate despre un tensor (cu anumite date) stocat pe o altă mașină. Scopul acestor tensori este de a ne oferi un API intuitiv

Now notice something. When we called x.send(bob) it returned a new object that we called x_ptr. This is our first pointer to a tensor. Pointers to tensors do NOT actually hold data themselves. Instead, they simply contain metadata about a tensor (with data) stored on another machine. The purpose of these tensors is to give us an intuitive API to tell the other machine to compute functions using this tensor. Let's take a look at the metadata that pointers contain.


In [ ]:
x_ptr

Check out that metadata!

Sunt două atribute principale specifice pointerilor:

  • x_ptr.location : bob, locația, o referință the location, a reference to the location that the pointer is pointing to
  • x_ptr.id_at_location : <random integer>, id-ul where the tensor is stored at location

Sunt afișați în următorul format <id_at_location>@<location>

Există și alte atribute mai generice:

  • x_ptr.id : <random integer>, id-ul pointer-ului la tensor, a fost alocat random
  • x_ptr.owner : "me", worker-ul (vom folosi cuvântul worker pentru astfel de termeni) care deține pointer-ul la tensor, aici este worker-ul local, numit "me"

In [ ]:
x_ptr.location

In [ ]:
bob

In [ ]:
bob == x_ptr.location

In [ ]:
x_ptr.id_at_location

In [ ]:
x_ptr.owner

Poate te întrebi de ce worker-ul local, care deține pointerul, este de asemenea un VirtualWorker, chiar daca nu l-am creat. Fun fact, la fel cum aveam un obiect de tipul VirtualWorker pentru Bob, mereu vom avea (în mod implicit) un VirtualWorker și pentru noi. Acest worker este creat automat când apelăm hook = sy.TorchHook() și astfel nu trebuie să îl creezi explciit.


In [ ]:
me = sy.local_worker
me

In [ ]:
me == x_ptr.owner

Și în final, la fel cum putem apela .send() pe un tensor, putem apela .get() pe un pointer la un tensor pentru a obține tensorul înapoi!!!


In [ ]:
x_ptr

In [ ]:
x_ptr.get()

In [ ]:
y_ptr

In [ ]:
y_ptr.get()

In [ ]:
z.get()

In [ ]:
bob._objects

Și după cum poți vedea... Bob nu mai deține tensorii!!! Au fost mutați înapoi pe mașina noastră!

Secțiunea 1.2 - Folosirea Pointerilor spre Tensori

Așadar, trimiterea și primirea tensorilor de la Bob este grozavă, dar acestui lucru i se poate spune cu greu Deep Learning! Dorim să putem face operații de tensori, pe tensori aflați la distanță (pe alte mașini). Din fericire, pointerii spre tensori fac acest lucru destul de ușor! Poți folosi pointerii excat ca și cum ai folosi tensori normali!


In [ ]:
x = torch.tensor([1,2,3,4,5]).send(bob)
y = torch.tensor([1,1,1,1,1]).send(bob)

In [ ]:
z = x + y

In [ ]:
z

Și voilà!

În spatele scenei, un lucru interesant s-a întâmplat. În loc ca x și y să , a fost serializată o comandă și a fost trimisă lui Bob, care a efectuat calculul, a creat un tensor z, și mai apoi a întors un pointer spre z!

Dacă apelăm .get() pe pointer, vom avea rezultatul operației pe mașina noastră!


In [ ]:
z.get()

Funcții Torch

API-ul a fost extins astfel încât să suporte toate operațiile din Torch!!!


In [ ]:
x

In [ ]:
y

In [ ]:
z = torch.add(x,y)
z

In [ ]:
z.get()

Variabile (inclusiv backpropagation!)


In [ ]:
x = torch.tensor([1,2,3,4,5.], requires_grad=True).send(bob)
y = torch.tensor([1,1,1,1,1.], requires_grad=True).send(bob)

In [ ]:
z = (x + y).sum()

In [ ]:
z.backward()

In [ ]:
x = x.get()

In [ ]:
x

In [ ]:
x.grad

După cum se poate vedea, API-ul este foarte flexibil și capabil să efectueze aproape toate operațiile pe care le-ai efectua în Torch pe date aflate la distanță. Acest lucru pune bazele pentru protocoalele noastre mai avansate de privacy preserving precum Federated Learning, Secure Multi-Party Computation și Differential Privacy!

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


In [ ]: