ホーム » TensorFlow Federated

TensorFlow Federated」カテゴリーアーカイブ

TensorFlow Federated: Tutorials : 画像分類のための Federated ラーニング

TensorFlow Federated : Tutorials : 画像分類のための Federated ラーニング (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/06/2019

* 本ページは、TensorFlow の本家サイトの TensorFlow Federated のチュートリアル – Federated Learning for Image Classification を翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

Tutorials : 画像分類のための Federated ラーニング

このチュートリアルでは、TFF の Federated ラーニング (FL) API コンポーネント – tff.learning を紹介するために古典的な MNIST 訓練サンプルを使用します。tff.learning は高位レベル・インターフェイスのセットで、TensorFlow で実装されたユーザ供給モデルに対する federated 訓練のような federated ラーニング・タスクの一般的なタイプを遂行するために使用されます。

このチュートリアル、そして Federated ラーニング API は、TFF を殆どブラックボックスとして扱いながら、彼ら自身の TensorFlow モデルを TFF に接続する (= plug) ことを望むユーザのために意図されています。TFF のより深い理解そして貴方自身の federated ラーニング・アルゴリズムをどのように実装するかのために、フォローアップとして低位インターフェイスのチュートリアルをレビューすることも考えてください – Custom Federated Algorithms Part 1Part 2

tff.learning のより多くについては、テキスト生成のための Federated ラーニング で続けてください、このチュートリアルはリカレント・モデルをカバーすることに加えてまた、Keras を使用する評価と結合された federated ラーニングで洗練するために事前訓練されたシリアライズ化された Keras モデルをロードすることを示します。

 

Before we start

始める前に、貴方の環境が正しくセットアップされていることを確かなものにするために次のコマンドを実行してください。

# NOTE: If you are running a Jupyter notebook, and installing a locally built
# pip package, you may need to edit the following to point to the '.whl' file
# on your local filesystem.

!pip install -q tensorflow_federated
from __future__ import absolute_import, division, print_function


import collections
from six.moves import range
import numpy as np
import tensorflow as tf
from tensorflow.python.keras.optimizer_v2 import gradient_descent
from tensorflow_federated import python as tff

nest = tf.contrib.framework.nest

np.random.seed(0)

tf.enable_eager_execution()
tf.enable_resource_variables()
tf.compat.v1.enable_v2_behavior()

tff.federated_computation(lambda: 'Hello, World!')()
WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.
For more information, please see:
  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md
  * https://github.com/tensorflow/addons
If you depend on functionality not listed there, please file an issue.


'Hello, World!'

 

入力データを準備する

データから始めましょう。Federated ラーニングは federated データセットを必要とします、i.e. 複数のユーザからのデータのコレクションです。federated データは典型的には非 i.i.d. です、これは特有の挑戦を課します。

実験を容易にするために、TFF レポジトリに幾つかのデータセットの種をまいています、これは Leaf を使用して再処理された 元の NIST データセット のバージョンを含む MNIST の federated バージョンを含みます。それはデータが Leaf を使用して再処理されています。その結果、データは数字の元の書き手によりキー付けされています。各書き手はユニークなスタイルを持ちますので、データセットは federated データセットに期待されるある種の非 i.i.d. 挙動を示します。

ここにそれをどのようにロードできるかがあります。

#@test {"output": "ignore"}
emnist_train, emnist_test = tff.simulation.datasets.emnist.load_data()
Downloading data from https://storage.googleapis.com/tff-datasets-public/fed_emnist_digitsonly.tar.bz2
97402880/97398400 [==============================] - 2s 0us/step

load_data() で返されるデータセット群は、特定のユーザのデータを表わす tf.data.Dataset を構築して個々の要素の構造を問い合わせる tff.simulation.ClientData のインスタンス群で、インターフェイスはユーザのセットを列挙することを可能にします。ここにデータセットの内容を調査するためにこのインターフェイスをどのように使用できるかがあります。このインターフェイスがクライアント id に渡り列挙することを貴方に可能にする一方で、それはシミュレーション・データの特徴に過ぎないことに留意してください。すぐに見るように、クライアント識別子は federated ラーニング・フレームワークでは使用されません – それらの唯一の目的はシミュレーションのためにデータのサブセットを選択することを可能にすることです。

len(emnist_train.client_ids)
3383
emnist_train.output_types, emnist_train.output_shapes
(OrderedDict([('label', tf.int32), ('pixels', tf.float32)]),
 OrderedDict([('label', TensorShape([])), ('pixels', TensorShape([28, 28]))]))
example_dataset = emnist_train.create_tf_dataset_for_client(
    emnist_train.client_ids[0])

example_element = iter(example_dataset).next()

example_element['label'].numpy()
WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/python/data/ops/iterator_ops.py:532: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.

5
#@test {"output": "ignore"}
from matplotlib import pyplot as plt
plt.imshow(example_element['pixels'].numpy(), cmap='gray', aspect='equal')
plt.grid('off')
_ = plt.show()
/usr/local/lib/python3.5/dist-packages/matplotlib/cbook/__init__.py:424: MatplotlibDeprecationWarning: 
Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead.
  warn_deprecated("2.2", "Passing one of 'on', 'true', 'off', 'false' as a "

<Figure size 640x480 with 1 Axes>

データは既に tf.data.Dataset ですから、前処理は Dataset 変換を使用して成されます。ここでは、28×28 画像を 784-要素配列に平坦化し、個々のサンプルをシャッフルし、それらをバッチに体系化し、そして Keras での使用のためにピクセルからの特徴とラベルを x と y に名前変更します。幾つかのエポックを実行するためにデータセットに渡り repeat もはさみます。

NUM_EPOCHS = 10
BATCH_SIZE = 20
SHUFFLE_BUFFER = 500

def preprocess(dataset):
  def element_fn(element):
    return collections.OrderedDict([
      ('x', tf.reshape(element['pixels'], [-1])), ('y', element['label'])])
  return dataset.repeat(NUM_EPOCHS).map(element_fn).shuffle(SHUFFLE_BUFFER).batch(BATCH_SIZE)

これが動作するか検証しましょう。

#@test {"output": "ignore"}
preprocessed_example_dataset = preprocess(example_dataset)

sample_batch = nest.map_structure(
    lambda x: x.numpy(), iter(preprocessed_example_dataset).next())

sample_batch
OrderedDict([('x', array([[1., 1., 1., ..., 1., 1., 1.],
                     [1., 1., 1., ..., 1., 1., 1.],
                     [1., 1., 1., ..., 1., 1., 1.],
                     ...,
                     [1., 1., 1., ..., 1., 1., 1.],
                     [1., 1., 1., ..., 1., 1., 1.],
                     [1., 1., 1., ..., 1., 1., 1.]], dtype=float32)),
             ('y',
              array([5, 3, 2, 4, 7, 3, 6, 1, 5, 9, 0, 9, 1, 8, 8, 9, 0, 1, 3, 7],
                    dtype=int32))])

federated データセットを構築するための殆ど総てのビルディング・ブロックを適所に持ちます。

シミュレーションで federated データを TFF に供給する方法の一つは、リストの各要素が個々のユーザのデータを保持するような単純に Python リストとしてです、リストとしてあるいは tf.data.Dataset として。既に後者を提供するインターフェイスを持ちますので、それを使用しましょう。

ここに単純なヘルパー関数があります、これはユーザの与えられたセットから一巡の訓練や評価への入力としてデータセットのリストを構築します。

def make_federated_data(client_data, client_ids):
  return [preprocess(client_data.create_tf_dataset_for_client(x))
          for x in client_ids]

さて、どのようにクライアントを選びましょうか?

典型的な federated 訓練シナリオでは、潜在的にユーザデバイスの非常に巨大な集団を扱っており、時間で与えられたポイントで訓練のためにそれらの断片だけが利用可能かもしれません。例えばこれは、クライアントデバイスが電源に接続され、計測ネットワークから離れて (= off a metered network) いるときに限り (さもなければアイドルしています) 訓練に参加しているモバイルフォンであるときに当てはまります。

もちろん、私達はシミュレーション環境にあり、総てのデータはローカルで利用可能です。それで典型的には、シミュレーションを実行するとき、訓練の各ラウンドで関係するクライアントの (一般には各ラウンドで異なる) ランダムなサブセットから単純にサンプリングするでしょう。

とは言え、Federated Averaging アルゴリズムのペーパーを研究することにより見い出せるように、各ラウンドでクライアントのランダムにサンプリングされたサブセットを持つシステムで収束を獲得することは時間がかかる可能性があり、そしてこの対話的なチュートリアルで数百のラウンドを実行しなければならないことは実践的ではありません。

従って、代わりに私達が行なうことはクライアントのセットから一度サンプリングして、収束をスピードアップするためにラウンド群に渡り同じセットを再利用することです (これらの少ないユーザのデータに意図的に over-fitting させます)。ランダムサンプリングをシミュレートするためにこのチュートリアルを変更することは読者のための課題として残します – 行なうことは非常に容易です (ひとたびそれを行えば、モデルを収束させることは時間がかかるかもしれないことに留意してください)。

#@test {"output": "ignore"}
NUM_CLIENTS = 3

sample_clients = emnist_train.client_ids[0:NUM_CLIENTS]

federated_train_data = make_federated_data(emnist_train, sample_clients)

len(federated_train_data), federated_train_data[0]
(3,
 <DatasetV1Adapter shapes: OrderedDict([(x, (None, 784)), (y, (None,))]), types: OrderedDict([(x, tf.float32), (y, tf.int32)])>)

 

Keras でモデルを作成する

Keras を使用しているのであれば、既に Keras モデルを構築するコードを持っていることでしょう。ここの私達のニーズを満たす単純なモデルの例があります。

def create_compiled_keras_model():
  model = tf.keras.models.Sequential([
      tf.keras.layers.Dense(
          10, activation=tf.nn.softmax, kernel_initializer='zeros', input_shape=(784,))])
  
  def loss_fn(y_true, y_pred):
    return tf.reduce_mean(tf.keras.metrics.sparse_categorical_crossentropy(
        y_true, y_pred))
 
  model.compile(
      loss=loss_fn,
      optimizer=gradient_descent.SGD(learning_rate=0.02),
      metrics=[])
  return model

compile についての一つの重要なノートです。下のように、Federated Averaging アルゴリズムで使用されるとき、optimizer はトータルな最適化アルゴリズムの半分に過ぎません、何故ならばそれは各クライアント上のローカル・モデル更新を計算するために使用されるだけだからです。アルゴリズムの残りはこれらの更新がクライアントに渡りどのように平均され、そしてそれらがサーバのグローバル・モデルにどのように適用されるかを伴います。特に、これはここで使用される optimizer と学習率の選択は標準的な i.i.d. データセット上のモデルを訓練するために使用したものとは違う必要があるかもしれないことを意味します。標準的な SGD で、おそらくは通常よりも小さい学習率で開始することを推奨します。ここで使用する学習率は注意深く調整されていません、自由に実験してください。

TFF で任意のモデルを使用するために、それは tff.learning.Model インターフェイスのインスタンスでラップされる必要があります、そのインターフェイスは Keras と同様に、モデルの forward パス、メタデータ・プロパティ, etc., をマークするためにメソッドを公開しますが、federated メトリクスを計算するプロセスを制御する方法のような、追加の要素も導入します。これについては今のところ心配しないでください ; 上で定義したようなコンパイルされた Keras モデルを持つ場合、下で示されるように、tff.learning.from_compiled_keras_model を起動して、引数としてモデルとサンプルデータ・バッチを渡すことにより、貴方のために TFF にそれをラップさせることができます。

def model_fn():
  keras_model = create_compiled_keras_model()
  return tff.learning.from_compiled_keras_model(keras_model, sample_batch)

 

federated データ上でモデルを訓練する

TFF での使用のために tff.learning.Model としてラップされたモデルを持つ今、ヘルパー関数 tff.learning.build_federated_averaging_process を次のように起動することにより TFF に Federated Averaging アルゴリズムを構築させることができます。

引数は既にコンストラクトされたインスタンスではなく (上の model_fn のような) コンストラクタである必要があることに留意してください、その結果モデルのコンストラクションは TFF で制御されるコンテキストで発生します (この理由について好奇心があれば、カスタム・アルゴリズム の follow-up チュートリアルを読むことを勧めます)。

iterative_process = tff.learning.build_federated_averaging_process(model_fn)

何が起きたのでしょう?TFF は一対の federated 計算を構築してそれらを tff.utils.IterativeProcess にパッケージしています、そこではこれらの計算が一対のプロパティ initialize と next として利用可能です。

簡単に言えば、federated 計算は様々な federated アルゴリズムを表現できる TFF の内部言語のプログラムです (これについて カスタム・アルゴリズム でより多くを見つけることができます)。このケースでは、生成されて iterative_process にパックされた 2 つの計算は Federated Averaging を実装しています。

現実の federated ラーニング設定で実行されるような方法で計算を定義することは TFF のゴールですが、現在はローカル実行シミュレーション・ランタイムだけが実装されています。計算をシミュレータで実行するために、単純にそれを Python 関数のように起動します。このデフォルトのインタープリットされた環境は高いパフォーマンスのために設計されていませんが、このチュートリアルのためには十分です ; 将来的なリリースでより大きなスケールの研究を手助けするためにより高いパフォーマンスのシミュレーション・ランタイムを提供することを期待します。

initialize 計算から始めましょう。総ての federated 計算の場合のように、それを関数として考えることができます。計算は引数を取らず、一つの結果を返します – サーバ上の Federated Averaging プロセスの状態の表現です。TFF の詳細に潜ることを望まない一方で、この状態がどのように見えるかを見ることはためになるかもしれません。次のようにそれを可視化できます。

#@test {"output": "ignore"}
str(iterative_process.initialize.type_signature)
'( -> <model=<trainable=<dense/kernel=float32[784,10],dense/bias=float32[10]>,non_trainable=<>>,optimizer_state=<int64>>@SERVER)'

上の型シグネチャは最初は少し暗号のように見えるかもしれない一方で、サーバ状態がモデル (総てのデバイスに分散される MNIST のための初期モデル・パラメータ) と optimizer_state (ハイパーパラメータ・スケジュール, etc. のために使用するラウンド数のような、サーバにより維持される追加情報) から成ることを認識できるでしょう。

サーバ状態を構築するために initialize 計算を呼び出しましょう。

state = iterative_process.initialize()

federated 計算のペアの 2 番目, next は Federated Averaging の単一のラウンドを表します、これは (モデルパラメータを含む) サーバ状態をプッシュし、ローカルデータ上でオンデバイス訓練をし、収集し、そしてモデル更新を平均し、そしてサーバで新しい更新されたモデルを生成します。

概念的には、next を次のように見える関数型シグネチャを持つものとして考えることができます。

SERVER_STATE, FEDERATED_DATA -> SERVER_STATE, TRAINING_METRICS

特に、next() をサーバ上で動作する関数として考えるべきではありません、寧ろ全体的な分散された計算の宣言的な関数型表現です – 入力の一部はサーバ (SERVER_STATE) により提供されますが、各参加しているデバイスはそれ自身のローカルデータセットを与えます。

訓練の単一ラウンドを実行して結果を可視化しましょう。ユーザのサンプルのために上で既に生成した federated データを使用できます。

#@test {"timeout": 600, "output": "ignore"}
state, loss = iterative_process.next(state, federated_train_data)
print('round  1, loss={:.4f}'.format(loss))
round  1, loss=2.9608

更に 2, 3 ラウンドを実行しましょう。前にノートしたように、ユーザが連続的に出入りするような現実的な配備をシミュレートするために、典型的にはこの時点で各ラウンドのためにユーザの新しくランダムに選択されたサンプルからシミュレーション・データのサブセットを選択するでしょう、しかしこの対話的ノートブックでは、デモのために単に同じユーザを再利用します、その結果システムは迅速に収束します。

#@test {"skip": true}
for round_num in range(2, 11):
  state, loss = iterative_process.next(state, federated_train_data)
  print('round {:2d}, loss={:.4f}'.format(round_num, loss))
round  2, loss=2.9340
round  3, loss=2.7860
round  4, loss=2.4084
round  5, loss=2.0972
round  6, loss=2.0610
round  7, loss=1.8308
round  8, loss=1.6044
round  9, loss=1.4647
round 10, loss=1.3858

 

モデル実装をカスタマイズする

Keras は TensorFlow のための推奨される高位モデル API で、可能なときはいつでも TFF で (tff.learning.from_keras_model または tff.learning.from_compiled_keras_model 経由で) Keras モデルの使用を勧めます。

けれども、tff.learning は低位モデル・インターフェイス, tff.learning.Model を提供します、これは federated ラーニングのためのモデルを使用するために必要な最小機能を公開します。このインターフェイス (多分依然として tf.keras.layers のようなビルディング・ブロックを使用します) を直接的に実装することは federated ラーニング・アルゴリズムの内部を変更することなく最大限のカスタマイゼーションを可能にします。

そこでスクラッチからもう一度それを行ないましょう。

 

モデル変数、forward パス、そしてメトリクスを定義する

最初のステップはそれで作業していく TensorFlow 変数を識別することです。次のコードをより読みやすくするために、セット全体を表わすデータ構造を定義しましょう。これは訓練する重みとバイアスのような変数と、loss_sum, accuracy_sum, と num_examples のような訓練の間に更新する様々な累積する統計値とカウンターを保持する変数を含みます。

MnistVariables = collections.namedtuple(
    'MnistVariables', 'weights bias num_examples loss_sum accuracy_sum')

ここに変数を作成するメソッドがあります。単純化のために、総ての統計を tf.float32 として表します、それは後のステージで型変換の必要性を除去するからです。変数 initializer を lambda としてラップするのは resource 変数 により課せられた要件です。

def create_mnist_variables():
  return MnistVariables(
      weights = tf.Variable(
          lambda: tf.zeros(dtype=tf.float32, shape=(784, 10)),
          name='weights',
          trainable=True),
      bias = tf.Variable(
          lambda: tf.zeros(dtype=tf.float32, shape=(10)),
          name='bias',
          trainable=True),
      num_examples = tf.Variable(0.0, name='num_examples', trainable=False),
      loss_sum = tf.Variable(0.0, name='loss_sum', trainable=False),
      accuracy_sum = tf.Variable(0.0, name='accuracy_sum', trainable=False))

モデル・パラメータと適所の累積する統計のための変数により、今では入力データの単一のバッチのために損失を計算し、予測を出し、そして累積する統計を更新する forward パスメソッドを、次のように定義できます。

def mnist_forward_pass(variables, batch):
  y = tf.nn.softmax(tf.matmul(batch['x'], variables.weights) + variables.bias)
  predictions = tf.cast(tf.argmax(y, 1), tf.int32)

  loss = -tf.reduce_mean(tf.reduce_sum(
      tf.one_hot(batch['y'], 10) * tf.log(y), reduction_indices=[1]))
  accuracy = tf.reduce_mean(
      tf.cast(tf.equal(predictions, batch['y']), tf.float32))

  num_examples = tf.to_float(tf.size(batch['y']))

  tf.assign_add(variables.num_examples, num_examples)
  tf.assign_add(variables.loss_sum, loss * num_examples)
  tf.assign_add(variables.accuracy_sum, accuracy * num_examples)

  return loss, predictions

次に、再度 TensorFlow を使用してローカル・メトリクスを返す関数を定義します。これらは (自動的に処理されるモデル更新に加えて、) federated ラーニングや評価プロセスでサーバに集められるに適格な変数です。

ここで、平均損失と精度そして num_examples を単純に返します、federated 集合を計算するときそれらは異なるユーザからの貢献を正しく重み付ける必要があります。

def get_local_mnist_metrics(variables):
  return collections.OrderedDict([
      ('num_examples', variables.num_examples),
      ('loss', variables.loss_sum / variables.num_examples),
      ('accuracy', variables.accuracy_sum / variables.num_examples)
    ])

最後に、各デバイスにより出力されたローカルメトリクスを get_local_mnist_metrics 経由でどのように集めるかを決める必要があります。これはコードの TensorFlow で書かれない唯一のパートです – それは TFF で表わされる federated 計算です。より深く探索しないのであれば、カスタム・アルゴリズム チュートリアルを一読してください、しかし多くのアプリケーションでは、実際には必要ありません ; 下で示されるパターンの変種で十分であるはずです。ここにそれがどのように見えるかがあります :

@tff.federated_computation
def aggregate_mnist_metrics_across_clients(metrics):
  return {
      'num_examples': tff.federated_sum(metrics.num_examples),
      'loss': tff.federated_average(metrics.loss, metrics.num_examples),
      'accuracy': tff.federated_average(metrics.accuracy, metrics.num_examples)
  }

入力メトリクス引数は上の get_local_mnist_metrics で返される OrderedDict に対応しますが、決定的に値はもはや tf.Tensors ではありません – それらは tff.Values として “boxed (箱詰め)” されています、それを明らかにするとそれらを TensorFlow を使用してもはや操作できませんが、tff.federated_average and tff.federated_sum のような TFF の federated 演算子だけが使用できます。グローバルな集合の返された辞書はメトリクスのセットを定義します、これはサーバで利用可能です。

 

tff.learning.Model のインスタンスを構築する

適所の上の総てにより、TFF に Keras モデルを摂取させたときに貴方のために生成されたものに類似した、 TFF で使用するためのモデル表現を構築する準備ができました。

class MnistModel(tff.learning.Model):

  def __init__(self):
    self._variables = create_mnist_variables()

  @property
  def trainable_variables(self):
    return [self._variables.weights, self._variables.bias]

  @property
  def non_trainable_variables(self):
    return []

  @property
  def local_variables(self):
    return [
        self._variables.num_examples, self._variables.loss_sum,
        self._variables.accuracy_sum
    ]

  @property
  def input_spec(self):
    return collections.OrderedDict([('x', tf.TensorSpec([None, 784],
                                                        tf.float32)),
                                    ('y', tf.TensorSpec([None], tf.int32))])

  @tf.contrib.eager.function(autograph=False)
  def forward_pass(self, batch, training=True):
    del training
    loss, predictions = mnist_forward_pass(self._variables, batch)
    return tff.learning.BatchOutput(loss=loss, predictions=predictions)

  @tf.contrib.eager.function(autograph=False)
  def report_local_outputs(self):
    return get_local_mnist_metrics(self._variables)

  @property
  def federated_output_computation(self):
    return aggregate_mnist_metrics_across_clients

見て取れるように、tff.learning.Model により定義される抽象メソッドとプロパティは変数を導入するコードスニペットに密接に対応し、前のセクションで導入した損失と統計を定義します。

ここにハイライトに値する幾つかのポイントがあります :

  • 貴方のモデルが使用する総ての状態は TensorFlow 変数として捕捉されなければなりません、何故ならば TFF は実行時に Python を使用しないからです (貴方のコードはそれがモバイルデバイスに配備できるように書かれるべきであることを忘れないでください ; 理由のより深い注釈のためには カスタム・アルゴリズム チュートリアルを見てください)。
  • 貴方のモデルはそれがどのようなデータ形式を受け取るか (input_spec) 記述すべきです、何故ならば一般に、TFF は強く型付けられた環境で総てのコンポーネントに対して型シグネチャを決定することを望むからです。貴方のモデルの入力の形式の宣言はそれの本質的なパートです。
  • 技術的には必要とされませんが、総ての TensorFlow ロジック (forward パス、メトリック計算) を tf.contrib.eager.functions としてラップすることを推奨します、何故ならばこれは TensorFlow がシリアライズ化できることを確実にすることを助け、そして明示的な制御依存性の必要性を除去できるからです。

上は評価と Federated SGD のようなアルゴリズムのためには十分です。けれども、Federated Averaging のためには、モデルを各バッチ上でどのようにローカルで訓練するかを指定する必要があります。

class MnistTrainableModel(MnistModel, tff.learning.TrainableModel):

  @tf.contrib.eager.defun(autograph=False)
  def train_on_batch(self, batch):
    output = self.forward_pass(batch)
    optimizer = tf.train.GradientDescentOptimizer(0.02)
    optimizer.minimize(output.loss, var_list=self.trainable_variables)
    return output

 

新しいモデルで federated 訓練をシミュレートする

適所の上の総てにより、プロセスの残りは既に見たもののように見えます – 単にモデル・コンストラクタを新しいモデル・クラスのコンストラクタで置き換え、訓練ラウンドを通して繰り返すための作成した iterative プロセスで 2 つの federated 計算を使用します。

iterative_process = tff.learning.build_federated_averaging_process(
    MnistTrainableModel)
WARNING:tensorflow:From :10: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
state = iterative_process.initialize()
#@test {"timeout": 600, "output": "ignore"}
state, metrics = iterative_process.next(state, federated_train_data)
print('round  1, metrics={}'.format(metrics))
round  1, metrics=
#@test {"skip": true}
for round_num in range(2, 11):
  state, metrics = iterative_process.next(state, federated_train_data)
  print('round {:2d}, metrics={}'.format(round_num, metrics))
round  2, metrics=<accuracy=0.15927273,loss=2.8832564,num_examples=2750.0>
round  3, metrics=<accuracy=0.18399999,loss=2.6661496,num_examples=2750.0>
round  4, metrics=<accuracy=0.25781816,loss=2.2566185,num_examples=2750.0>
round  5, metrics=<accuracy=0.29309088,loss=2.1758642,num_examples=2750.0>
round  6, metrics=<accuracy=0.356,loss=1.9697735,num_examples=2750.0>
round  7, metrics=<accuracy=0.37854546,loss=1.837882,num_examples=2750.0>
round  8, metrics=<accuracy=0.4341818,loss=1.726984,num_examples=2750.0>
round  9, metrics=<accuracy=0.4698182,loss=1.5935063,num_examples=2750.0>
round 10, metrics=<accuracy=0.5087273,loss=1.4720244,num_examples=2750.0>

 

評価

ここまでの実験の総ては federated 訓練メトリクス – ラウンドの総てのクライアントに渡り訓練されたデータの総てのバッチに渡る平均メトリクスのみを提示しています。これは overfitting に関する通常の関心を引き起こします、特に単純化のために各ラウンドでクライアントの同じセットを使用しましたので、しかし Federated Averaging アルゴリズムに特有の訓練プロセスにおける overfitting の追加的注意もあります。これを見るには、各クライアントがデータの単一のバッチを持つことを想像して、そしてそのバッチ上で多くの反復 (epochs) を訓練することを考えれば容易です。この場合、ローカルモデルは迅速に正確にその一つのバッチに fit するでしょう、そして平均したローカル精度メトリックは 1.0 に近づきます。このように、これらの訓練メトリクスは訓練が進捗している兆候として取ることができますが、それ以上のものではありません。

federated データ上で評価を遂行するために、ちょうどこの目的のために設計されたもう一つの federated 計算を構築できます、tff.learning.build_federated_evaluation 関数を使用して、モデル・コンストラクタを引数として渡します。Federated Averaging とは違い、そこでは MnistTrainableModel を使用しました、それは MnistModel を渡せば十分です。評価は勾配降下を遂行しません、そして optimizer を構築する必要はありません。

実験と研究のために、中央集中したテスト・データセットが利用可能なとき、テキスト生成のための Federated ラーニング はもう一つの評価オプションを示します : federated ラーニングから訓練された重みを取り、それらを標準的な Keras モデルに適用し、そしてそれから単純に中央集中されたデータセットに tf.keras.models.Model.evaluate() を呼び出します。

evaluation = tff.learning.build_federated_evaluation(MnistModel)

evaluation 関数の抽象型シグネチャを次のように調査できます。

str(evaluation.type_signature)
'(<<trainable=<weights=float32[784,10],bias=float32[10]>,non_trainable=<>>@SERVER,{<x=float32[?,784],y=int32[?]>*}@CLIENTS> -> <accuracy=float32@SERVER,loss=float32@SERVER,num_examples=float32@SERVER>)'

この時点で詳細を気にする必要はありませんが、それは次の一般的な形式を取ることだけは認識してください、tff.utils.IterativeProcess.next に類似していますが 2 つの重要な違いを伴います。一つ目は、サーバ状態を返していません、何故ならば評価はモデルあるいは状態の任意の他の様相を変更しないからです – それをステートレスと考えることができます。2 番目に、評価はモデルを必要とするだけです、そして optimizer 変数のような訓練に関連するかもしれないサーバー状態の任意の他のパートを必要としません。

SERVER_MODEL, FEDERATED_DATA -> TRAINING_METRICS

訓練の間に到達した最新の状態で evaluation を起動しましょう。サーバー状態から最新の訓練モデルを抽出するためには次のように、.model メンバーに単にアクセスします。

#@test {"output": "ignore"}
train_metrics = evaluation(state.model, federated_train_data)

ここに私達が得たものがあります。数字は上の訓練の最後のラウンドから報告されたものよりも僅かばかり良いようであることに注意してください。慣習により、反復訓練プロセスにより報告された訓練メトリクスは訓練ラウンドの最初にモデルの性能を一般に反映しますので、評価メトリクスは常にワンステップ進んでいます。

#@test {"output": "ignore"}
str(train_metrics)
'<accuracy=0.6545454,loss=1.1885377,num_examples=2750.0>'

さて、federated データのテスト・サンプルをコンパイルしてテストデータ上の評価を再実行しましょう。データは実際のユーザの同じサンプルに由来しますが、異なる取り置いたデータセットからです。

federated_test_data = make_federated_data(emnist_test, sample_clients)

len(federated_test_data), federated_test_data[0]
(3,
 <DatasetV1Adapter shapes: OrderedDict([(x, (None, 784)), (y, (None,))]), types: OrderedDict([(x, tf.float32), (y, tf.int32)])>)
#@test {"output": "ignore"}
test_metrics = evaluation(state.model, federated_test_data)
#@test {"output": "ignore"}
str(test_metrics)
'<accuracy=0.6666667,loss=1.3322104,num_examples=330.0>'

チュートリアルは以上です。上で注意したように、パラメータ (e.g., バッチサイズ、ユーザ数、エポック、学習率, etc.) で遊び、各ラウンドでユーザのランダムサンプル上の訓練をシミュレートするために上のコードを変更し、そして私達が開発した他のチュートリアルを探究することを勧めます。

 

以上






TensorFlow Federated: 概要

TensorFlow Federated : 概要 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/01/2019

* 本ページは、TensorFlow の本家サイトの TensorFlow Federated – Overview と Get Started を翻訳した上で
適宜、補足説明したものです:


* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow Federated 概要

TensorFlow Federated (TFF) は分散された (= decentralized) データ上の機械学習と他の計算のためのオープンソース・フレームワークです。TFF は、共有されたグローバルモデルが多くの参加するクライアント (それらの訓練データはローカルに保持します) に渡り訓練されるアプローチである、Federated ラーニング (FL) によるオープンな研究と実験を促進するために開発されました。例えば、FL は機密なタイピング・データをサーバにアップロードすることなしに モバイル・キーボードのための予測モデル を訓練するために使用されてきています。

TFF は開発者に彼らのモデルとデータ上で含まれる federated ラーニング・アルゴリズムをシミュレートし、そして新しいアルゴリズムによる実験を可能にします。TFF により提供されるビルディングブロックはまた分散されたデータに渡る集約分析 (= aggregated analytics) のような非ラーニング計算を実装するためにも使用できます。

TFF のインターフェイスは 2 つの層に体系化されます :

  • Federated ラーニング (FL) API
    この層は既存の TensorFlow モデルへの federated 訓練と評価の含まれる実装を適用することを可能にする高位インターフェイスのセットを提供します。

  • Federated コア (FC) API
    システムのコアでは強く型付けられた関数型プログラミング環境内で TensorFlow と分散通信演算子を結合することにより新しい federated アルゴリズムを簡潔に表現するための低位インターフェイスのセットがあります。この層はまた私達がその上で構築した Federated ラーニングの基礎としてもサーブします。

TFF は federated 計算を宣言的に表現することを開発者に可能にしますので、それらは様々なランタイム環境に配備可能です。実験のためのシングルマシン・シミュレーション・ランタイムが TFF に含まれています。チュートリアル を訪ねて貴方自身で試してください!

 
主要な TFF 概念と実践的なサンプルを使用する API を貴方にウォークスルーさせる次のチュートリアルを読むことから開始します。

  • 画像分類のための federated ラーニング (Federated Learning for image classification) は Federated ラーニング (FL) API の主要パートを紹介して federated MNIST-ライクなデータ上で federated ラーニングをシミュレートするためにどのように TFF を使用するかを示します。
  • テキスト生成のための federated ラーニング (Federated Learning for text generation) は更に言語モデリング・タスクのためのシリアライズ化された事前訓練されたモデルを洗練するためにどのように TFF の FL API を使用するかを示します。
  • Custom Federated Algorithms, Part 1: Introduction to the Federated CorePart 2: Implementing Federated Averaging は主要な概念と Federated Core API (FC API) により提供されるインターフェイスを紹介し、そして単純な federated averaging 訓練アルゴリズムをどのように実装して federated 評価をどのように遂行するかを示します。

 

from six.moves import range
import tensorflow as tf
import tensorflow_federated as tff
from tensorflow_federated.python.examples import mnist
tf.compat.v1.enable_v2_behavior()

# Load simulation data.
source, _ = tff.simulation.datasets.emnist.load_data()
def client_data(n):
  dataset = source.create_tf_dataset_for_client(source.client_ids[n])
  return mnist.keras_dataset_from_emnist(dataset).repeat(10).batch(20)

# Pick a subset of client devices to participate in training.
train_data = [client_data(n) for n in range(3)]

# Grab a single batch of data so that TFF knows what data looks like.
sample_batch = tf.contrib.framework.nest.map_structure(
    lambda x: x.numpy(), iter(train_data[0]).next())

# Wrap a Keras model for use with TFF.
def model_fn():
  return tff.learning.from_compiled_keras_model(
      mnist.create_simple_keras_model(), sample_batch)

# Simulate a few rounds of training with the selected client devices.
trainer = tff.learning.build_federated_averaging_process(model_fn)
state = trainer.initialize()
for _ in range(5):
  state, metrics = trainer.next(state, train_data)
  print (metrics.loss)
 

以上






AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com