Настройка рекомендуемых агрегатов для обучения

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

tff.learning модуль содержит ряд способов агрегатных модели udpates с рекомендованной конфигурацией по умолчанию:

В этом руководстве мы объясняем лежащую в основе мотивацию, то, как они реализованы, и даем предложения по настройке их конфигурации.


!pip install --quiet --upgrade tensorflow-federated-nightly
!pip install --quiet --upgrade nest-asyncio

import nest_asyncio
nest_asyncio.apply()
import math
import tensorflow_federated as tff
tff.federated_computation(lambda: 'Hello, World!')()
b'Hello, World!'

Методы агрегирования представлены объекты , которые могут быть переданы tff.learning.build_federated_averaging_process в качестве model_update_aggregation_factory аргумента ключевого слова. Таким образом , агрегаторы , обсуждаемые здесь могут быть непосредственно использованы для изменения предыдущего учебника по федеративному обучению.

Базовый взвешенный средний из FedAvg алгоритма может быть выражена с помощью tff.aggregators.MeanFactory следующим образом :

mean = tff.aggregators.MeanFactory()
iterative_process = tff.learning.build_federated_averaging_process(
    ...,
    model_update_aggregation_factory=mean)

Методы, которые можно использовать для расширения средневзвешенного значения, описанные в этом руководстве:

  • Обнуление
  • Вырезка
  • Дифференциальная конфиденциальность
  • Сжатие
  • Безопасное агрегирование

Расширение осуществляется с помощью композиции, в которой MeanFactory обертывает внутренний завод , к которому он делегируют некоторую часть агрегации, или сами по себе , обернутой другой агрегации фабрики. Более подробную информацию о конструкции, см Реализация пользовательских агрегаторов учебник.

Сначала мы объясним, как включить и настроить эти методы по отдельности, а затем покажем, как их можно комбинировать.

Методы

Прежде чем углубляться в отдельные методы, мы сначала представим алгоритм квантильного сопоставления, который будет полезен для настройки методов ниже.

Квантильное соответствие

Некоторые из приведенных ниже методов агрегации должны использовать границу нормы, которая контролирует некоторые аспекты агрегации. Такие границы могут быть заданы как константа, но обычно лучше адаптировать границу в процессе обучения. Рекомендуемый способ заключается в использовании алгоритма сопоставления квантиля Эндрю и др. (2019) , первоначально предложенные для его совместимости с дифференциальной личной жизнью , но полезна в более широком смысле. Чтобы оценить значение в данных квантилях, вы можете использовать tff.aggregators.PrivateQuantileEstimationProcess . Например, чтобы адаптироваться к медиане распределения, вы можете использовать:

median_estimate = tff.aggregators.PrivateQuantileEstimationProcess.no_noise(
    initial_estimate=1.0, target_quantile=0.5, learning_rate=0.2)

Как мы увидим, для разных технологий, использующих алгоритм квантильной оценки, потребуются разные значения параметров алгоритма. В целом, увеличение learning_rate означает более быструю адаптацию параметра к правильному квантилю, но с более высокой дисперсией. no_noise classmethod конструкция квантиль процесс согласования , который не добавляет шума для дифференциальной уединенности.

Обнуление

Обнуление означает замену нулями необычно больших значений. Здесь «необычно большой» может означать больше, чем заранее заданный порог, или большой по сравнению со значениями из предыдущих раундов вычислений. Обнуление может повысить устойчивость системы к повреждению данных на неисправных клиентах.

Для того, чтобы вычислить среднее значений с L-инфинити нормы больше , чем ZEROING_CONSTANT обнуленных, мы завернуть tff.aggregators.MeanFactory с tff.aggregators.zeroing_factory , который выполняет обнуление:

zeroing_mean = tff.aggregators.zeroing_factory(
    zeroing_norm=MY_ZEROING_CONSTANT,
    inner_agg_factory=tff.aggregators.MeanFactory())

Здесь мы обернуть MeanFactory с zeroing_factory , потому что мы хотим (предварительное агрегирование) эффекты zeroing_factory применить к значениям у клиентов , прежде чем они будут переданы внутренней MeanFactory для агрегации с помощью усреднения.

Однако для большинства приложений мы рекомендуем адаптивное обнуление с помощью квантильной оценки. Для этого мы используем алгоритм квантильного сопоставления следующим образом:

zeroing_norm = tff.aggregators.PrivateQuantileEstimationProcess.no_noise(
    initial_estimate=10.0,
    target_quantile=0.98,
    learning_rate=math.log(10),
    multiplier=2.0,
    increment=1.0)
zeroing_mean = tff.aggregators.zeroing_factory(
    zeroing_norm=zeroing_norm,
    inner_agg_factory=tff.aggregators.MeanFactory())

# Equivalent to:
# zeroing_mean = tff.learning.robust_aggregator(clipping=False)

Параметры были выбраны таким образом , что процесс адаптируется очень быстро (относительно большой learning_rate ) до величины , несколько больше , чем наибольшие значения видели до сих пор. Для оценки квантиля Q , порог , используемый для обнуления будет Q * multiplier + increment .

Отсечение до границы L2 нормы

Отсечение обновлений клиента (проецирование на шар L2) может повысить устойчивость к выбросам. tff.aggregators.clipping_factory структурирован так же , как tff.aggregators.zeroing_factory обсуждалось выше, и может принимать либо константу или tff.templates.EstimationProcess в качестве своего clipping_norm аргумента. Рекомендуемая передовая практика - использовать отсечение, которое умеренно быстро адаптируется к умеренно высокой норме, а именно:

clipping_norm = tff.aggregators.PrivateQuantileEstimationProcess.no_noise(
    initial_estimate=1.0,
    target_quantile=0.8,
    learning_rate=0.2)
clipping_mean = tff.aggregators.clipping_factory(
    clipping_norm=clipping_norm,
    inner_agg_factory=tff.aggregators.MeanFactory())

# Equivalent to:
# clipping_mean = tff.learning.robust_aggregator(zeroing=False)

По нашему опыту по многим проблемам, точное значение target_quantile , кажется, не имеет значения слишком много , так долго , как учебные курсы настроены соответствующим образом . Однако установка очень низкого значения может потребовать увеличения скорости обучения сервера для лучшей производительности по сравнению с отказом от использования отсечения, поэтому мы рекомендуем 0,8 по умолчанию.

Дифференциальная конфиденциальность

TFF также поддерживает дифференциальную частную агрегацию с использованием адаптивного ограничения и гауссовского шума. Агрегатор, выполняющий дифференциально частное усреднение, может быть построен следующим образом:

dp_mean = tff.aggregators.DifferentiallyPrivateFactory.gaussian_adaptive(
    noise_multiplier=0.1, clients_per_round=100)

# Equivalent to:
# dp_mean = tff.learning.dp_aggregator(
#   noise_multiplier=0.1, clients_per_round=100, zeroing=False)

Руководство о том , как установить noise_multiplier аргумент можно найти в руководстве ПТФ DP .

Сжатие с потерями

По сравнению со сжатием без потерь, таким как gzip, сжатие с потерями обычно приводит к гораздо более высокой степени сжатия, и впоследствии его можно комбинировать со сжатием без потерь. Поскольку на обмен данными между клиентом и сервером нужно тратить меньше времени, раунды обучения завершаются быстрее. Из-за изначально рандомизированной природы алгоритмов обучения до некоторого порога неточность сжатия с потерями не оказывает отрицательного влияния на общую производительность.

Рекомендация по умолчанию заключается в использовании простого равномерного квантования (см Суреш и threshold quantization_bits др. , К примеру), параметризовано два значений: сжатия размера тензора threshold и числа quantization_bits . Для каждого тензора t , если число элементов t меньше или равно threshold , он не сжимается. Если он больше, элементы t квантуются с использованием вероятностного округления до quantizaton_bits битов. То есть применяем операцию

t = round((t - min(t)) / (max(t) - min(t)) * (2**quantizaton_bits - 1)),

в результате чего целые значения в диапазоне [0, 2**quantizaton_bits-1] . Квантованные значения непосредственно упаковываются в целочисленный тип для передачи, а затем применяется обратное преобразование.

Мы рекомендуем устанавливать quantizaton_bits равным 8 и threshold равен 20000:

compressed_mean = tff.aggregators.MeanFactory(
    tff.aggregators.EncodedSumFactory.quantize_above_threshold(
        quantization_bits=8, threshold=20000))

# Equivalent to:
# compressed_mean = tff.learning.compression_aggregator(zeroing=False, clipping=False)

Предложения по настройке

Оба параметра, quantization_bits и threshold можно регулировать, а количество клиентов , участвующих в каждом раунде обучения также может повлиять на эффективность сжатия.

Порог. Значение по умолчанию 20000 выбрано, потому что мы заметили, что переменные с небольшим количеством элементов, такие как смещения в общих типах слоев, намного более чувствительны к вносимому шуму. Более того, на практике мало что можно получить от сжатия переменных с небольшим количеством элементов, поскольку их размер без сжатия изначально относительно мал.

В некоторых приложениях может иметь смысл изменить выбор порога. Например, смещения выходного слоя модели классификации могут быть более чувствительными к шуму. Если вы тренируетесь языковая модель с словарем 20004, вы можете установить threshold , чтобы быть 20004.

Биты квантования. Значение по умолчанию 8 для quantization_bits должно быть достаточно для большинства пользователей. Если 8 работает хорошо, и вы хотите немного увеличить производительность, вы можете попробовать снизить ее до 7 или 6. Если ресурсы позволяют выполнить небольшой поиск по сетке, мы рекомендуем вам определить значение, при котором обучение становится нестабильным или качество окончательной модели начинает ухудшаться, а затем увеличьте это значение на два. Например, если установка quantization_bits 5 работ, но установка до 4 -х деградирует модель, мы рекомендуем по умолчанию будет 6 , чтобы быть «на безопасной стороне».

Клиентов за раунд. Следует отметить , что значительное увеличение числа клиентов за раунд может дать меньшее значение quantization_bits хорошо работать, поскольку рандомизированная неточность введены квантованием может быть выравнивает путем усреднения по более обновлениям клиентов.

Безопасное агрегирование

Под безопасным агрегированием (SecAgg) мы понимаем криптографический протокол, в котором обновления клиента зашифрованы таким образом, что сервер может расшифровать только их сумму. Если количество клиентов, которые отчитываются, недостаточно, сервер вообще ничего не узнает - и ни в коем случае сервер не сможет проверить отдельные обновления. Это осуществляется с помощью tff.federated_secure_sum_bitwidth оператора.

Обновления модели представляют собой значения с плавающей запятой, но SecAgg работает с целыми числами. Поэтому нам нужно обрезать любые большие значения до некоторой границы перед дискретизацией до целочисленного типа. Граница отсечения может быть постоянной или определяться адаптивно (рекомендуемое значение по умолчанию). Затем целые числа надежно суммируются, и сумма снова отображается в домен с плавающей запятой.

Для того, чтобы вычислить среднее со взвешенными значениями , суммированных с использованием SecAgg с MY_SECAGG_BOUND как отсечение связанного, проходят SecureSumFactory к MeanFactory как:

secure_mean = tff.aggregators.MeanFactory(
    tff.aggregators.SecureSumFactory(MY_SECAGG_BOUND))

Чтобы сделать то же самое при адаптивном определении границ:

secagg_bound = tff.aggregators.PrivateQuantileEstimationProcess.no_noise(
    initial_estimate=50.0,
    target_quantile=0.95,
    learning_rate=1.0,
    multiplier=2.0)
secure_mean = tff.aggregators.MeanFactory(
    tff.aggregators.SecureSumFactory(secagg_bound))

# Equivalent to:
# secure_mean = tff.learning.secure_aggregator(zeroing=Fasle, clipping=False)

Предложения по настройке

Адаптивные параметры были выбраны так, чтобы границы были жесткими (мы не потеряем большой точности при дискретизации), но отсечение случается редко.

При настройке параметров имейте в виду, что протокол SecAgg суммирует взвешенные обновления модели после взвешивания в среднем. Веса обычно представляют собой количество точек данных, обрабатываемых локально, поэтому для разных задач правильная граница может зависеть от этого количества.

Мы не рекомендуем использовать increment аргумента ключевого слова при создании адаптивного secagg_bound , так как это может привести к большой относительной потере точности, в случае фактических концов оценочных до того мало.

Приведенный выше фрагмент кода будет использовать SecAgg только взвешенные значения. Если SecAgg также должен использоваться для суммы весов, мы рекомендуем установить границы как константы, так как в обычной тренировочной установке максимально возможный вес будет известен заранее:

secure_mean = tff.aggregators.MeanFactory(
    value_sum_factory=tff.aggregators.SecureSumFactory(secagg_bound),
    weight_sum_factory=tff.aggregators.SecureSumFactory(
        upper_bound_threshold=MAX_WEIGHT, lower_bound_threshold=0.0))

Композиционные техники

Отдельные методы увеличения среднего, представленные выше, можно комбинировать вместе.

Мы рекомендуем порядок, в котором эти методы применяются у клиентов.

  1. Обнуление
  2. Вырезка
  3. Другие техники

Агрегаторы в tff.aggregators модулы состоит из оберточных «внутренних» (агрегаторов которых предварительно агрегации эффекты случаются последняя и после агрегации эффекты произойдет первой) внутри «внешние агрегаторы». Например, чтобы выполнить обнуление, отсечение и сжатие (в указанном порядке), можно написать:

# Compression is innermost because its pre-aggregation effects are last.
compressed_mean = tff.aggregators.MeanFactory(
    tff.aggregators.EncodedSumFactory.quantize_above_threshold(
        quantization_bits=8, threshold=20000))
# Compressed mean is inner aggregator to clipping...
clipped_compressed_mean = tff.aggregators.clipping_factory(
    clipping_norm=MY_CLIPPING_CONSTANT,
    inner_agg_factory=compressed_mean)
# ...which is inner aggregator to zeroing, since zeroing happens first.
final_aggregator = tff.aggregators.zeroing_factory(
    zeroing_norm=MY_ZEROING_CONSTANT,
    inner_agg_factory=clipped_compressed_mean)

Обратите внимание , что эта структура соответствует агрегаторов по умолчанию для алгоритмов обучения.

Возможны и другие композиции. Мы расширяем этот документ, когда уверены, что можем предоставить конфигурацию по умолчанию, которая работает в нескольких различных приложениях. Для реализации новых идей см Реализация пользовательских агрегаторов учебник.