プライバシーに配慮したディープラーニングを実現するPySyftの入門チュートリアルへようこそ。
このJupyter notebooksのシリーズでは、機密や個人情報を含むデータやモデルを、一つの権限の元で一元管理するのではなく、権限的にも物理的にも分散した状態で実行するための、新しいツールやテクニックについて、一つ一つ順を追って説明していきます
適用範囲: 私たちはデータを分散化、暗号化する方法についてだけ扱うわけではありません。PySyftを使うことで、どうすれば各所に分散して配置されたデータを検索できるのか、一つのサーバーに集めずにデータを分散させたままにモデルの学習を行うにはどうすれば良いのか、モデル所有者とデータ所有者がそれぞれの知財を守りつつ連携した新しいサービスを生み出すにはそうすれば良いのか、といった新しいデータのエコシステム全体についての事柄を含みます。また、新しい拡張昨日がPySyftに追加された際には本Jupyter notebooksシリーズも同様に拡張されます。
著者:
1) キャリアアップ - この20年間、デジタル革命によってデータのデジタル化が進み、より多くのデータがアクセス可能になりました。しかし、GDPRに代表される新しい規制により、企業が自由に個人情報を分析、活用することは難しくなってきています。ボトムライン データサイエンティストも、昔ながらの手法では以前のようにはデータにアクセスできなくなります。しかし、個人情報に配慮したディープラーニングの手法を学ぶ事で、規制に従いつつデータにアクセスできるノウハウを身につけることができれば、このトレンドの先を行くことできます。あなたのキャリアにおいてもきっと強みとなるでしょう。
2) スタートアップのチャンス - ディープラーニングを解決できる社会の問題はまだまだ沢山あります。しかしながら、その多くは、特に最も重要な問題の多くは、デリケートな個人に関する情報へのアクセスを要するため、まだ十分に探究されていません。プライバシーに配慮したディープラーニングを学ぶ事で、従来の手法ではアクセス出来ないデータ、例えば心の問題や男女の問題に関するデータ、がアクセス可能になると想像してみてください。新たなビジネスチャンスが広がると思いませんか。
3) 社会的意義 - ディープラーニングは現実世界の様々な問題を解決しうる技術です。個人の情報を扱うディープラーニングは個人の問題を、そうです、個人の問題を解決します。自分が所有していないデータを使ってディープラーニングのモデルを学習できる手法を学ぶことには、個人のキャリアアップやスタートアップ企業操業のチャンス以上の可能性があります。人々の営みにおけるもっとも重要な問題を解決できる、それを大規模にできる、そんな可能性を秘めているんです。
等々... では、はじましょう!
まずは、正しいソフトウェアがインストールされていることを確認しましょう。PySyftのreadmeの指示にしたがってインストールを進めてください。
もし、どこかしらで、つまづいてしまった時は、まずはREADMEをチェックしてください。それでも解決策が見つからない場合は、GithubでIssueを挙げてみるか、slackの#beginner channel slack.openmined.org で質問をしてみてください。
In [ ]:
# 以下のコードを実行して、必要なソフトウェアが正しくインストールされているか確認します
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])
このセルが実行できていれば、準備はOKです。
In [ ]:
x = torch.tensor([1,2,3,4,5])
y = x + x
print(y)
Tensorオブジェクトとそのオペレーションはとても良くできていて、パワフルですが、データはあなたのマシンに存在している必要がありますよね。
さて、ここが出発点です。
データサイエンス/ディープラーニングは普通、データのあるマシンで行います。ところが今、私たちは行いたいのは、学習計算をどこか他のマシンで実行したいという事です。具体的にいうと、データがローカルマシンに無い場合もあるという事です。
そこで、Torchのtensorをかわりに、tensorへのポインタの使用を考えます。まずはコードを見てみましょう。最初に擬似的な外部マシンを所有する擬似的なユーザーを作成ます。ここではBobとします。
In [ ]:
bob = sy.VirtualWorker(hook, id="bob")
Bobのマシンはどこか別の惑星にでもあるものと仮定してください。 - 例えば火星とか!ですが、今のところマシンは空っぽです。 まずは何かしらデータを準備しましょう。そのデータをBobに送ったり、Bobに送ったデータのポインタを参照したりしてみたいと思います。
In [ ]:
x = torch.tensor([1,2,3,4,5])
y = torch.tensor([1,1,1,1,1])
では - Bobにtensor(データ)を送ってみましょう。
In [ ]:
x_ptr = x.send(bob)
y_ptr = y.send(bob)
In [ ]:
x_ptr
ジャジャーン! 今、Bobは2つのtensor(データ)を持っています!ご自身ても確認してみてください。
In [ ]:
bob._objects
In [ ]:
z = x_ptr + x_ptr
In [ ]:
z
In [ ]:
bob._objects
一つ気が付くことはありませんでしたか? x.send(bob)
が実行されると私たちがx_ptr
と名付けた新しいオブジェクトが帰ります。これは私たちの最初のtensorへのポインタです。ポインタは実際にはデータを持っていません。その代わりに別のマシンの実データであるTensorについてのメタデータを保持します。
tensorへのポインタのことを以後PointerTensorと記載します。
PointerTensorの目的は、リモートに存在するマシン上でTensorの計算処理を実行する際の、直感的なAPIを提供することです。では、ポインタが持っているメタデータを確認してみましょう。
In [ ]:
x_ptr
メタデータを確認しましょう。
ポインタ特有の属性が2つ存在します。
x_ptr.location : bob
, 場所, ポインタが参照している場所に関する情報ですx_ptr.id_at_location : <random integer>
, Tensorが存在するマシン上でのIDです。Tensorの場所は右記の形式で、表現できます <id_at_location>@<location>
もっと、一般的な属性もあります。
x_ptr.id : <random integer>
, 私たちマシン上でのIDです。IDはランダムに生成されます。x_ptr.owner : "me"
, PointerTensorを所有するユーザーです。PySyftではワーカーと呼ばれます。ローカルマシンのワーカーは"me"です。
In [ ]:
x_ptr.location
In [ ]:
bob
In [ ]:
bob == x_ptr.location
In [ ]:
x_ptr.id_at_location
In [ ]:
x_ptr.owner
ポインタの所有者もVirtual(擬似)ワーカーとなっていることが気になるかもしれません。そもそも私たちはローカルマシンのユーザーを作成してもいません。実を言うと、VirtualWorkerのBobと同様にデフォルトで私たち自身にもVirtualWorkerとしての割り当てがなされています。このワーカーはhook = sy.TorchHook()
が実行された時に自動的に作られます。そのため、私たちが明示的につくる必要はありません。
In [ ]:
me = sy.local_worker
me
In [ ]:
me == x_ptr.owner
最後になりますが、.send()
でtensorを送った時と同じように.get()
でtensorを自分たちのマシンに戻す事ができます。
In [ ]:
x_ptr
In [ ]:
x_ptr.get()
In [ ]:
y_ptr
In [ ]:
y_ptr.get()
In [ ]:
z.get()
In [ ]:
bob._objects
ご覧の通り、 Bobはもうtensorを持っていません。Bobが持っていたtensorは私たちのマシンに戻ってきています。
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
ジャジャーン!
この処理の裏では、実はとてもパワフルな事が行われています。xとyという2つのtensorをローカルマシンで加算するかわりに、加算コマンドがシリアライズされてBobに送られ、Bobのマシン上で演算を実行されることでzが作られ、zのポインタが私たちの元に戻ってきています。
.get()
を実行することで、演算結果を受け取ることもできるのです。
In [ ]:
z.get()
In [ ]:
x
In [ ]:
y
In [ ]:
z = torch.add(x,y)
z
In [ ]:
z.get()
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
上記の通り、このAPIはとても柔軟性があり、リモートデータに対して、ほぼ全てのTorchのオペレーションを実行可能です。 これによりFederated Learning, Secure Multi-Party Computation, DifferentialPrivacyのような、より高度なプライバシーに配慮したディープラーニングを実現するためのベースが提供されます!
In [ ]:
本チュートリアルを完了しました。おめでとうございます!もし、このチュートリアルを気に入って、プライバシーに配慮した非中央集権的なAI技術や付随する(データやモデルの)サプライチェーンにご興味があって、プロジェクトに参加したいと思われるなら、以下の方法で可能です。
一番簡単に貢献できる方法はこのGitHubのレポジトリにスターを付けていただくことです。スターが増えると露出が増え、より多くのデベロッパーにこのクールな技術の事を知って貰えます。
最新の開発状況のトラッキングする一番良い方法はSlackに入ることです。 下記フォームから入る事ができます。 http://slack.openmined.org
コミュニティに貢献する一番良い方法はソースコードのコントリビューターになることです。PySyftのGitHubへアクセスしてIssueのページを開き、"Projects"で検索してみてください。参加し得るプロジェクトの状況を把握することができます。また、"good first issue"とマークされているIssueを探す事でミニプロジェクトを探すこともできます。
もし、ソースコードで貢献できるほどの時間は取れないけど、是非何かサポートしたいという場合は、寄付をしていただくことも可能です。寄附金の全ては、ハッカソンやミートアップの開催といった、コミュニティ運営経費として利用されます。
In [ ]: