Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/federated/tutorials/federated_select.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

tff.federated_select를 사용하여 특정 클라이언트에 다른 데이터 보내기

이 튜토리얼에서는 TFF에서, 다른 클라이언트에 다른 데이터를 보내야 하는 사용자 지정 페더레이션 알고리즘을 구현하는 방법을 보여줍니다. 모든 클라이언트에 단일 서버 배치 값을 보내는 tff.federated_broadcast에 이미 익숙할 것입니다. 이 튜토리얼은 서버 기반 값의 서로 다른 부분이 다른 클라이언트로 전송되는 상황에 초점을 맞춥니다. 이것은 전체 모델을 단일 클라이언트에 보내는 것을 피하기 위해 여러 클라이언트에 걸쳐 모델을 여러 부분으로 나누는 데 유용할 수 있습니다.

tensorflowtensorflow_federated를 모두 가져와 시작하겠습니다.

#@test {"skip": true} !pip install --quiet --upgrade tensorflow-federated
import tensorflow as tf import tensorflow_federated as tff tff.backends.native.set_sync_local_cpp_execution_context()

클라이언트 데이터를 기반으로 다른 값 보내기

일부 클라이언트 배치 데이터를 기반으로 각 클라이언트에 몇 가지 요소를 보내려는 서버 배치 목록이 있는 경우를 고려하겠습니다. 예를 들어, 서버의 문자열 목록과 클라이언트의 다운로드할 인덱스 목록은 쉼표로 구분됩니다. 다음과 같이 이를 구현할 수 있습니다.

list_of_strings_type = tff.TensorType(tf.string, [None]) # We only ever send exactly two values to each client. The number of keys per # client must be a fixed number across all clients. number_of_keys_per_client = 2 keys_type = tff.TensorType(tf.int32, [number_of_keys_per_client]) get_size = tff.tf_computation(lambda x: tf.size(x)) select_fn = tff.tf_computation(lambda val, index: tf.gather(val, index)) client_data_type = tf.string # A function from our client data to the indices of the values we'd like to # select from the server. @tff.tf_computation(client_data_type) @tff.check_returns_type(keys_type) def keys_for_client(client_string): # We assume our client data is a single string consisting of exactly three # comma-separated integers indicating which values to grab from the server. split = tf.strings.split([client_string], sep=',')[0] return tf.strings.to_number([split[0], split[1]], tf.int32) @tff.tf_computation(tff.SequenceType(tf.string)) @tff.check_returns_type(tf.string) def concatenate(values): def reduce_fn(acc, item): return tf.cond(tf.math.equal(acc, ''), lambda: item, lambda: tf.strings.join([acc, item], ',')) return values.reduce('', reduce_fn) @tff.federated_computation(tff.type_at_server(list_of_strings_type), tff.type_at_clients(client_data_type)) def broadcast_based_on_client_data(list_of_strings_at_server, client_data): keys_at_clients = tff.federated_map(keys_for_client, client_data) max_key = tff.federated_map(get_size, list_of_strings_at_server) values_at_clients = tff.federated_select(keys_at_clients, max_key, list_of_strings_at_server, select_fn) value_at_clients = tff.federated_map(concatenate, values_at_clients) return value_at_clients

그런 다음 서버 배치 문자열 목록과 각 클라이언트에 대한 문자열 데이터를 제공하여 계산을 시뮬레이션할 수 있습니다.

client_data = ['0,1', '1,2', '2,0'] broadcast_based_on_client_data(['a', 'b', 'c'], client_data)
[<tf.Tensor: shape=(), dtype=string, numpy=b'a,b'>, <tf.Tensor: shape=(), dtype=string, numpy=b'b,c'>, <tf.Tensor: shape=(), dtype=string, numpy=b'c,a'>]

각 클라이언트에 무작위 요소 보내기

또는, 서버 데이터의 임의 부분을 각 클라이언트에 보내는 것이 유용할 수 있습니다. 먼저 각 클라이언트에서 임의의 키를 생성한 다음 위에서 사용한 것과 유사한 선택 프로세스를 수행하여 이를 구현할 수 있습니다.

@tff.tf_computation(tf.int32) @tff.check_returns_type(tff.TensorType(tf.int32, [1])) def get_random_key(max_key): return tf.random.uniform(shape=[1], minval=0, maxval=max_key, dtype=tf.int32) list_of_strings_type = tff.TensorType(tf.string, [None]) get_size = tff.tf_computation(lambda x: tf.size(x)) select_fn = tff.tf_computation(lambda val, index: tf.gather(val, index)) @tff.tf_computation(tff.SequenceType(tf.string)) @tff.check_returns_type(tf.string) def get_last_element(sequence): return sequence.reduce('', lambda _initial_state, val: val) @tff.federated_computation(tff.type_at_server(list_of_strings_type)) def broadcast_random_element(list_of_strings_at_server): max_key_at_server = tff.federated_map(get_size, list_of_strings_at_server) max_key_at_clients = tff.federated_broadcast(max_key_at_server) key_at_clients = tff.federated_map(get_random_key, max_key_at_clients) random_string_sequence_at_clients = tff.federated_select( key_at_clients, max_key_at_server, list_of_strings_at_server, select_fn) # Even though we only passed in a single key, `federated_select` returns a # sequence for each client. We only care about the last (and only) element. random_string_at_clients = tff.federated_map(get_last_element, random_string_sequence_at_clients) return random_string_at_clients

broadcast_random_element 함수는 어떤 클라이언트 배치 데이터도 사용하지 않으므로 사용할 기본 클라이언트 수로 TFF 시뮬레이션 런타임을 구성해야 합니다.

tff.backends.native.set_sync_local_cpp_execution_context(default_num_clients=3)

그런 다음 선택을 시뮬레이션할 수 있습니다. 위의 default_num_clients와 아래의 문자열 목록을 변경하여 다른 결과를 생성하거나 단순히 계산을 다시 실행하여 다른 무작위 출력을 생성할 수 있습니다.

broadcast_random_element(tf.convert_to_tensor(['foo', 'bar', 'baz']))