Path: blob/master/site/ko/federated/openmined2020/openmined_conference_2020.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
Before we start
To edit the colab notebook, please go to "File" -> "Save a copy in Drive" and make any edits on your copy.
Before we start, please run the following to make sure that your environment is correctly setup. If you don't see a greeting, please refer to the Installation guide for instructions.
이미지 분류를 위한 TensorFlow Federated
시뮬레이션에서 페더레이션 학습을 실험해 봅시다. 이 튜토리얼에서는 TFF의 Federated Learning(FL) API 레이어를 소개하는 고전적인 MNIST 훈련 예제를 사용합니다. tff.learning
은 TensorFlow에서 구현된 사용자 제공 모델에 반하여, 페더레이션 학습과 같은 일반적인 유형의 페더레이션 학습 작업을 수행하는 데 사용할 수 있는 상위 수준의 인터페이스 세트입니다.
튜토리얼 개요
이미지에서 숫자를 분류하는 신경망 학습으로 고전적인 MNIST 데이터세트를 사용하여 이미지 분류를 수행하는 모델을 훈련할 것입니다. 이 경우 훈련 데이터가 서로 다른 기기에 배포되어 있는 페더레이션 학습을 시뮬레이션할 것입니다.
섹션
TFF 라이브러리를 로드합니다.
페더레이션 EMNIST 데이터세트를 탐색/사전 처리합니다.
모델을 만듭니다.
훈련을 위한 페더레이션 평균화 프로세스를 설정합니다.
훈련 메트릭을 분석합니다.
페더레이션 평가 계산을 설정합니다.
평가 메트릭을 분석합니다.
입력 데이터 준비하기
데이터부터 시작하겠습니다. 페더레이션 학습에는 페더레이션 데이터세트, 즉 여러 사용자의 데이터 모음이 필요합니다. 페더레이션 데이터는 일반적으로 i.i.d.가 아니므로 고유한 문제가 있습니다. 사용자의 데이터 분포는 일반적으로 사용 패턴에 따라 서로 다릅니다.
실험을 용이하게 하기 위해 몇 가지 데이터세트로 TFF 리포지토리를 시드했습니다.
샘플 데이터세트를 로드하는 방법은 다음과 같습니다.
load_data()
가 반환하는 데이터세트는 사용자 세트를 열거하고 특정 사용자의 데이터를 나타내는 tf.data.Dataset
를 구성하고 개별 요소의 구조를 쿼리할 수 있는 인터페이스인 tff.simulation.datasets.ClientData
의 인스턴스입니다.
데이터세트를 살펴보겠습니다.
비 iid 데이터 탐색하기
데이터 전처리하기
데이터가 이미 tf.data.Dataset
이므로 Dataset 변환을 사용하여 전처리를 수행할 수 있습니다. 이들 변환에 대한 자세한 내용은 여기를 참조하세요.
이것이 작동하는지 확인해 보겠습니다.
다음은 훈련 또는 평가 라운드에 대한 입력으로 주어진 사용자 세트에서 데이터세트 목록을 구성하는 간단한 도우미 함수입니다.
이제 클라이언트를 어떻게 선택할까요?
Keras로 모델 만들기
Keras를 사용하는 경우, Keras 모델을 구성하는 코드가 이미 있을 수 있습니다. 다음은 요구 사항에 맞는 간단한 모델의 예제입니다.
Keras를 사용한 중앙 집중식 훈련
Keras 모델을 사용한 페더레이션 훈련
TFF가 있는 모델을 사용하려면, tff.learning.Model
인터페이스의 인스턴스에 래핑되어야 합니다.
추가할 수 있는 더 많은 Keras 메트릭은 여기에서 찾을 수 있습니다.
페더레이션 데이터로 모델 훈련하기
TFF와 함께 사용하기 위해 tff.learning.Model
로 래핑된 모델이 있으므로 다음과 같이 도우미 함수 tff.learning.build_federated_averaging_process
를 호출하여 TFF에서 Federated Averaging 알고리즘을 구성하도록 할 수 있습니다.
방금 무슨 일이 있었나요? TFF는 한 쌍의 페더레이션 계산을 구성하고 tff.templates.IterativeProcess
로 패키징하여 이들 계산을 한 쌍의 속성 initialize
및 next
로 사용할 수 있습니다.
반복 프로세스는 일반적으로 다음과 같은 제어 루프에 의해 구동됩니다.
initialize
계산을 호출하여 서버 상태를 구성해 보겠습니다.
두 번째 페더레이션 계산 쌍인 next
는 서버 상태(모델 매개변수 포함)를 클라이언트에 푸시, 로컬 데이터에 대한 기기 내 훈련, 모델 업데이트 수집 및 평균화로 구성된 단일 라운드의 페더레이션 평균화를 나타내며, 서버에서 업데이트된 새 모델을 생성합니다.
훈련을 한 라운드 실행하고 결과를 시각화해 보겠습니다. 사용자의 샘플을 위해 위에서 이미 생성한 페더레이션 데이터를 사용할 수 있습니다.
몇 라운드 더 실행해 봅시다. 앞서 언급했듯이, 일반적으로 이 시점에서는 사용자가 지속적으로 오고가는 현실적인 배포를 시뮬레이션하기 위해 각 라운드에서 무작위로 선택한 새로운 사용자 샘플에서 시뮬레이션 데이터의 하위 세트를 선택합니다. 그러나 이 대화형 노트북에서는 데모를 위해 같은 사용자만 재사용하여 시스템이 빠르게 수렴되도록 합니다.
페더레이션 훈련의 각 라운드 후에 훈련 손실이 감소하여 모델이 수렴되고 있음을 나타냅니다. 이러한 훈련 메트릭에는 몇 가지 중요한 주의 사항이 있지만, 이 튜토리얼 뒷부분의 평가 섹션을 참조하세요.
TensorBoard Next에 모델 메트릭을 표시하고, Tensorboard를 사용하여 이들 페더레이션 계산의 메트릭을 시각화해 보겠습니다.
메트릭을 기록할 디렉터리와 해당 요약 작성기를 만드는 것으로 시작하겠습니다.
같은 요약 작성기를 사용하여 관련 스칼라 메트릭을 플롯합니다.
위에서 지정한 루트 로그 디렉터리로 TensorBoard를 시작합니다. 데이터를 로드하는 데 몇 초 정도 걸릴 수 있습니다.
같은 방식으로 평가 메트릭을 보려면 "logs/scalars/eval"과 같은 별도의 eval 폴더를 만들어 TensorBoard에 쓸 수 있습니다.
평가
페더레이션 데이터에 대한 평가를 수행하려면, tff.learning.build_federated_evaluation
함수를 사용하고 모델 생성자를 인수로 전달하는, 바로 이 목적을 위해 설계된 또 다른 페더레이션 계산을 구성할 수 있습니다.
이제 페더레이션 데이터의 테스트 샘플을 컴파일하고 테스트 데이터에 대한 평가를 다시 실행해 보겠습니다. 데이터는 다른 사용자 샘플에서 가져오지만, 별개의 보류된 데이터세트에서 가져옵니다.
이것으로 튜토리얼을 마칩니다. 매개변수(예: 배치 크기, 사용자 수, epoch, 학습률 등)를 사용하여 위의 코드를 수정하여 각 라운드에서 무작위 사용자 샘플에서 훈련을 시뮬레이션하고 기타 튜토리얼을 탐색해 보는 것이 좋습니다.
나만의 FL 알고리즘 빌드하기
이전 튜토리얼에서는 모델 및 데이터 파이프라인을 설정하고 이를 사용하여 tff.learning
API를 사용하는 페더레이션 훈련을 수행하는 방법을 배웠습니다.
물론 이것은 FL 연구와 관련하여 빙산의 일각에 불과합니다. 이 튜토리얼에서는 tff.learning
API를 따르지 않고 페더레이션 학습 알고리즘을 구현하는 방법에 대해 설명합니다. 다음을 달성하는 것을 목표로 합니다.
목표:
페더레이션 학습 알고리즘의 일반적인 구조를 이해합니다.
TFF의 페더레이션 코어를 탐색합니다.
Federated Core를 사용하여 Federated Averaging을 직접 구현합니다.
입력 데이터 준비하기
먼저 TFF에 포함된 EMNIST 데이터세트를 로드하고 전처리합니다. 기본적으로 첫 번째 튜토리얼에서와 같은 코드를 사용합니다.
모델 준비하기
숨겨진 단일 레이어와 소프트맥스 레이어가 있는 첫 번째 튜토리얼과 같은 모델을 사용합니다.
이 Keras 모델을 tff.learning.Model
로 래핑합니다.
FL 알고리즘 맞춤 설정하기
tff.learning
API는 Federated Averaging의 많은 변형을 포함하지만, 이 프레임워크에 깔끔하게 맞지 않는 다른 많은 알고리즘이 있습니다. 예를 들어, 정규화, 클리핑 또는 페더레이션 GAN 훈련과 같은 더 복잡한 알고리즘을 추가할 수 있습니다. 대신 페더레이션 분석에 관심이 있을 수도 있습니다.
이러한 고급 알고리즘의 경우 사용자 정의 FL 알고리즘을 작성해야합니다.
일반적으로 FL 알고리즘에는 4 가지 주요 구성 요소가 있습니다.
서버-클라이언트 브로드 캐스트 단계.
로컬 클라이언트 업데이트 단계.
클라이언트-서버 업로드 단계.
서버 업데이트 단계.
TFF에서 우리는 일반적으로 연합 알고리즘을 IterativeProcess
로 표현합니다. 이것은 initialize_fn
및 next_fn
을 포함하는 단순한 클래스입니다. initialize_fn
서버 초기화하는 데 사용되며, 상기 next_fn
연합 평균화 한 라운드 통신을 수행한다. FedAvg에 대한 우리의 반복 프로세스가 어떻게 생겼는지에 대한 골격을 작성해 보겠습니다.
먼저 tff.learning.Model
생성하고 훈련 가능한 가중치를 반환하는 초기화 함수가 있습니다.
이 함수는 괜찮아 보이지만 나중에 살펴 보 겠지만 TFF 계산을 위해 약간의 수정이 필요합니다.
또한, 우리는 next_fn
를 스케치하려고 합니다.
이 네 가지 구성 요소를 개별적으로 구현하는 데 중점을 둘 것입니다. 먼저 순수 TensorFlow에서 구현할 수있는 부분, 즉 클라이언트 및 서버 업데이트 단계에 초점을 맞출 것입니다.
TensorFlow 블록
클라이언트 업데이트
tff.learning.Model
을 사용하여 기본적으로 TF 모델을 학습하는 것과 동일한 방식으로 클라이언트 학습을 수행합니다. 특히 tf.GradientTape
를 사용하여 데이터 배치에 대한 그라디언트를 계산 한 다음 client_optimizer
사용하여 이러한 그라디언트를 적용합니다.
각 tff.learning.Model
인스턴스에는 두 개의 하위 속성이있는 weights
속성이 있습니다.
trainable
: 훈련 가능한 레이어에 해당하는 텐서 목록입니다.non_trainable
: 훈련 불가능한 레이어에 해당하는 텐서 목록입니다.
우리의 목적을 위해 우리는 훈련 가능한 가중치만을 사용할 것입니다 (우리 모델에는 그것들 만 있습니다!).
서버 업데이트
서버 업데이트에는 더 적은 노력이 필요합니다. 우리는 단순히 서버 모델 가중치를 클라이언트 모델 가중치의 평균으로 대체하는 바닐라 연합 평균을 구현할 것입니다. 다시 말하지만, 훈련 가능한 가중치에만 초점을 맞출 것입니다.
위의 코드 스 니펫은 단순히 mean_client_weights
를 반환 할 수 있으므로 분명히 과잉입니다. 그러나 Federated Averaging의 고급 구현에서는 모멘텀 또는 적응성과 같은보다 정교한 기술과 함께 mean_client_weights
를 사용할 수 있습니다.
지금까지 순수한 TensorFlow 코드 만 작성했습니다. TFF를 사용하면 이미 익숙한 TensorFlow 코드를 많이 사용할 수 있으므로 이는 의도적으로 설계된 것입니다. 그러나 이제 오케스트레이션 로직 , 즉 서버가 클라이언트에 브로드 캐스트하는 내용과 클라이언트가 서버에 업로드하는 내용을 지정하는 로직을 지정해야합니다.
이를 위해서는 TFF의 "Federated Core"가 필요합니다.
페더레이션 코어 소개
페더레이션 코어(FC)는 tff.learning
API의 기반 역할을 하는 하위 수준 인터페이스 집합입니다. 그러나 이러한 인터페이스는 학습에만 국한되지 않습니다. 실제로 분산 데이터에 대한 분석 및 기타 많은 계산에 사용할 수 있습니다.
상위 수준에서 페더레이션 코어는 간결하게 표현된 프로그램 로직을 사용하여 TensorFlow 코드를 분산 통신 연산자(예: 분산 합계 및 브로드캐스트)와 결합할 수 있는 개발 환경입니다. 목표는 시스템 구현 세부 사항(예: 지점 간 네트워크 메시지 교환 지정)을 요구하지 않고 연구자와 실무자에게 시스템의 분산 통신을 신속하게 제어할 수 있도록 하는 것입니다.
한 가지 요점은 TFF가 개인 정보 보호를 위해 설계되었다는 것입니다. 따라서 중앙 집중식 서버 위치에서 원치 않는 데이터 축적을 방지하기 위해 데이터가 있는 위치를 명시적으로 제어할 수 있습니다.
페더레이션 데이터
기본 개념 중 하나 인 TensorFlow의 "Tensor"개념과 유사하게 TFF의 핵심 개념은 분산 시스템의 장치 그룹 (예 : 클라이언트 데이터 세트 또는 서버 모델 가중치). 우리는 모든 장치에 걸친 전체 데이터 항목 컬렉션을 하나의 연합 값 으로 모델링합니다.
예를 들어, 센서의 온도를 나타내는 부동 소수점이있는 클라이언트 장치가 있다고 가정합니다. 우리는 그것을 연합 된 float 로 표현할 수 있습니다.
Federated types are specified by a type T
of its member constituents (eg. tf.float32
) and a group G
of devices. We will focus on the cases where G
is either tff.CLIENTS
or tff.SERVER
. Such a federated type is represented as {T}@G
, as shown below.
게재 위치에 관심이 많은 이유는 무엇입니까? TFF의 핵심 목표는 실제 분산 시스템에 배포 할 수있는 코드를 작성할 수 있도록하는 것입니다. 즉, 장치의 하위 집합이 어떤 코드를 실행하고 다른 데이터 조각이 어디에 있는지 추론하는 것이 중요합니다.
TFF는 데이터, 데이터가 배치되는 위치 및 데이터가 변환되는 방법의 세 가지에 중점을 둡니다. 처음 두 개는 페더레이션 유형으로 캡슐화되고 마지막 두 개는 페더레이션 계산에 캡슐화됩니다.
페더레이션 계산
TFF는 기본 단위가 페더레이션 계산인 강력한 형식의 함수형 프로그래밍 환경입니다. 이들은 페더레이션 값을 입력으로 받아들이고 페더레이션 값을 출력으로 반환하는 논리 조각입니다.
예를 들어 클라이언트 센서의 온도를 평균화하고 싶다고 가정합니다. 다음을 정의 할 수 있습니다 (페더레이션 된 float 사용).
TensorFlow의 tf.function
데코레이터와 어떻게 다른지 물어볼 수 있습니다. 핵심적인 대답은 tff.federated_computation
에 의해 생성된 코드가 TensorFlow도 아니고 Python 코드도 아니라는 것입니다. 내부 플랫폼 독립적인 글루 언어로 된 분산 시스템의 사양입니다.
복잡하게 들릴 수 있지만 TFF 계산은 잘 정의된 형식 서명이 있는 함수로 생각할 수 있습니다. 이러한 유형 서명은 직접 쿼리할 수 있습니다.
이 tff.federated_computation
은 페더레이션 유형 <float>@CLIENTS
의 인수를 받아들이고 페더레이션 유형 <float>@SERVER
의 값을 반환합니다. 페더레이션 계산은 서버에서 클라이언트로, 클라이언트에서 클라이언트로 또는 서버에서 서버로 이동할 수도 있습니다. 페더레이션 계산은 유형 서명이 일치하는 한 일반 함수처럼 구성할 수도 있습니다.
개발을 지원하기 위해 TFF를 사용하면 tff.federated_computation
을 Python 함수로 호출 할 수 있습니다. 예를 들어
비 즉시 실행 계산 및 TensorFlow
주의해야 할 두 가지 주요 제한 사항이 있습니다. 첫째, 파이썬 인터프리터가 tff.federated_computation
데코레이터를 만나면 함수가 한 번 추적되고 나중에 사용하기 위해 직렬화됩니다. 따라서 TFF 계산은 근본적으로 비열 심적 입니다. 이 동작은 TensorFlow의 tf.function
데코레이터와 다소 유사합니다.
둘째, 연합 계산은 연합 연산자 (예 : tff.federated_mean
)로만 구성 될 수 있으며 TensorFlow 작업을 포함 할 수 없습니다. TensorFlow 코드는 tff.tf_computation
장식 된 블록으로 제한되어야합니다. 숫자를 취하고 여기에 0.5
를 더하는 다음 함수와 같이 대부분의 일반적인 TensorFlow 코드는 직접 decotrated 할 수 있습니다.
또한 유형 서명이 있지만 배치는 없습니다 . 예를 들어
여기에서 tff.federated_computation
과 tff.tf_computation
의 중요한 차이점을 볼 수 있습니다. 전자는 명시 적 배치가있는 반면 후자는 그렇지 않습니다.
게재 위치를 지정하여 연합 계산에서 tff.tf_computation
블록을 사용할 수 있습니다. 절반을 추가하지만 클라이언트에서 연합 부동 수에만 추가하는 함수를 만들어 보겠습니다. 게제 위치를 유지하면서 지정된 tff.tf_computation
을 적용하는 tff.federated_map
을 사용하여 이를 수행할 수 있습니다.
이 기능은 거의 동일 add_half
, 그것은 단지에서 위치와 값을 받아들이는 것을 제외하고 tff.CLIENTS
같은 배치로, 반환 값을 설정합니다. 유형 서명에서 이것을 볼 수 있습니다.
요약하자면:
TFF는 페더레이션 값에서 작동합니다.
각 페더레이션 값에는 유형(예:
tf.float32
)과 배치(예:tff.CLIENTS
)가 있는 페더레이션 유형{/em}이 있습니다.페더레이션 값은 페더레이션 계산을 사용하여 변환될 수 있으며,
tff.federated_computation
및 연합 유형 서명으로 데코레이션되어야 합니다.TensorFlow 코드는
tff.tf_computation
데코레이터가 있는 블록에 포함되어야 합니다.그런 다음 이러한 블록을 페더레이션 계산에 통합할 수 있습니다.
나만의 FL 알고리즘 구축 (2 부)
이제 연합 코어를 살펴 보았으므로 자체 연합 학습 알고리즘을 구축 할 수 있습니다. 위에서 알고리즘에 initialize_fn
및 next_fn
을 정의했습니다. next_fn
은 순수한 TensorFlow 코드를 사용하여 정의한 client_update
및 server_update
를 사용합니다.
그러나 알고리즘을 연합 계산으로 만들기 위해서는 next_fn
과 initialize_fn
이 모두 tff.federated_computations
합니다.
TensorFlow 페더레이션 블록
초기화 계산 만들기
initialize 함수는 매우 간단합니다. model_fn
사용하여 모델을 생성합니다. 그러나 tff.tf_computation
사용하여 TensorFlow 코드를 분리해야합니다.
그런 다음 tff.federated_value
를 사용하여 이를 페더레이션 계산에 직접 전달할 수 있습니다.
next_fn
만들기
이제 클라이언트 및 서버 업데이트 코드를 사용하여 실제 알고리즘을 작성합니다. 우리는 먼저 우리의 켜집니다 client_update
에 tff.tf_computation
클라이언트 데이터 셋 및 서버 가중치를 받아들이고, 업데이트 된 클라이언트 무게 텐서를 출력합니다.
함수를 적절하게 꾸미려면 해당 유형이 필요합니다. 다행히도 서버 가중치 유형은 모델에서 직접 추출 할 수 있습니다.
데이터 세트 유형 서명을 살펴 보겠습니다. 28 x 28 이미지 (정수 레이블 포함)를 가져와 병합했다는 것을 기억하십시오.
위의 server_init
함수를 사용하여 모델 가중치 유형을 추출 할 수도 있습니다.
형식 서명을 살펴보면 모델의 아키텍처를 볼 수 있습니다!
이제 클라이언트 업데이트를위한 tff.tf_computation
을 생성 할 수 있습니다.
서버 업데이트의 tff.tf_computation
버전은 이미 추출한 유형을 사용하여 유사한 방식으로 정의 할 수 있습니다.
마지막으로 이 모든 것을 통합하는 tff.federated_computation
을 만들어야 합니다. 이 함수는 두 개의 페더레이션 값을 받아 들입니다. 하나는 서버 가중치(게재 위치 tff.SERVER
)에 해당하고 다른 하나는 클라이언트 데이터세트(게재 위치 tff.CLIENTS
)에 해당합니다.
이들 두 가지 유형 모두는 위에 정의되어 있습니다! `tff.type_at_{server/clients}``를 사용하여 적절한 게재 위치를 제공하기만 하면 됩니다.
FL 알고리즘의 4가지 요소를 기억하십니까?
서버-클라이언트 브로드 캐스트 단계.
로컬 클라이언트 업데이트 단계.
클라이언트-서버 업로드 단계.
서버 업데이트 단계.
이제 위의 내용을 작성 했으므로 각 부분을 한 줄의 TFF 코드로 간결하게 표현할 수 있습니다. 이 단순함 때문에 연합 유형과 같은 것을 지정하기 위해 특별히주의해야했습니다!
이제 알고리즘 초기화와 알고리즘의 한 단계를 실행하기 위한 tff.federated_computation
이 있습니다. 알고리즘을 완료하기 위해 이를 tff.templates.IterativeProcess
에 전달합니다.
반복 프로세스의 initialize
및 next
함수의 유형 서명을 살펴보겠습니다.
이는 federated_algorithm.initialize
가 단일 레이어 모델(784x10 가중치 행렬 및 10개의 바이어스 단위 포함)을 반환하는 인수가 없는 함수라는 사실을 반영합니다.
여기에서 federated_algorithm.next
는 서버 모델과 클라이언트 데이터를 받아들이고 업데이트 된 서버 모델을 반환합니다.
알고리즘 평가
몇 라운드를 실행하고 손실이 어떻게 변하는 지 살펴 보겠습니다. 먼저 두 번째 튜토리얼에서 논의한 중앙 집중식 접근 방식을 사용하여 평가 기능을 정의합니다.
먼저 중앙 집중식 평가 데이터 세트를 만든 다음 훈련 데이터에 사용한 것과 동일한 전처리를 적용합니다.
주 우리는 것을 take
계산 효율성을 이유로 처음 1000 개 요소가 있지만, 일반적으로 우리는 전체 테스트 데이터 세트를 사용하십시오.
다음으로 서버 상태를 받아들이고 Keras를 사용하여 테스트 데이터 세트를 평가하는 함수를 작성합니다. 당신이 익숙하다면 tf.Keras
,이 모든 모습을 잘 알고, 참고하지만 사용 set_weights
!
이제 알고리즘을 초기화하고 테스트세트에서 평가해 보겠습니다.
몇 라운드 동안 훈련하고 변경 사항이 있는지 살펴보겠습니다.
손실 함수가 약간 감소합니다. 점프는 작지만, 우리는 10 번의 훈련 라운드와 소수의 클라이언트에 대해서만 수행했습니다. 더 나은 결과를 보려면 수천 번은 아니더라도 수백 번을해야 할 수도 있습니다.
알고리즘 수정
이 시점에서 멈추고 우리가 성취 한 것에 대해 생각해 봅시다. 순수 TensorFlow 코드 (클라이언트 및 서버 업데이트 용)를 TFF의 Federated Core의 연합 계산과 결합하여 Federated Averaging을 직접 구현했습니다.
보다 정교한 학습을 수행하려면 위에있는 내용을 간단히 변경할 수 있습니다. 특히 위의 순수 TF 코드를 편집하여 클라이언트가 학습을 수행하는 방법 또는 서버가 모델을 업데이트하는 방법을 변경할 수 있습니다.
도전 과제: client_update
함수에 그레디언트 클리핑을 추가합니다.