ปรับการรวมที่แนะนำสำหรับการเรียนรู้

ดูบน 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 โต้แย้งคำหลัก เช่นรวบรวมที่กล่าวถึงที่นี่สามารถใช้โดยตรงในการปรับเปลี่ยน ก่อนหน้านี้ การกวดวิชา ในการเรียนรู้แบบ federated

พื้นฐานถ่วงน้ำหนักเฉลี่ยจาก FedAvg อัลกอริทึมสามารถใช้แสดง tff.aggregators.MeanFactory ดังนี้

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

เทคนิคที่สามารถใช้เพื่อขยายค่าเฉลี่ยถ่วงน้ำหนักที่กล่าวถึงในบทช่วยสอนนี้คือ:

  • Zeroing
  • คลิปหนีบ
  • ความเป็นส่วนตัวที่แตกต่าง
  • การบีบอัด
  • การรวมที่ปลอดภัย

ส่วนขยายจะทำโดยใช้องค์ประกอบซึ่งใน MeanFactory wraps โรงงานภายในเพื่อที่จะได้รับมอบหมายเป็นส่วนหนึ่งของการรวมบางส่วนหรือเป็นตัวเองห่อโดยโรงงานรวมอีก สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการออกแบบให้ดูที่ รวบรวมข้อมูลที่กำหนดเองการดำเนินการ กวดวิชา

ขั้นแรก เราจะอธิบายวิธีเปิดใช้งานและกำหนดค่าเทคนิคเหล่านี้ทีละรายการ แล้วแสดงวิธีการรวมเข้าด้วยกัน

เทคนิค

ก่อนเจาะลึกเทคนิคแต่ละอย่าง ก่อนอื่นเราขอแนะนำอัลกอริธึมการจับคู่ควอนไทล์ ซึ่งจะเป็นประโยชน์สำหรับการกำหนดค่าเทคนิคด้านล่าง

การจับคู่ปริมาณ

เทคนิคการรวมหลายๆ แบบด้านล่างจำเป็นต้องใช้ขอบเขตปกติที่ควบคุมบางแง่มุมของการรวม ขอบเขตดังกล่าวสามารถกำหนดให้เป็นค่าคงที่ได้ แต่โดยปกติแล้วจะเป็นการดีกว่าที่จะปรับขอบเขตระหว่างการฝึก วิธีที่แนะนำคือการใช้อัลกอริทึม quantile การจับคู่ของ แอนดรู, et al (2019) เสนอครั้งแรกสำหรับการเข้ากันได้กับความเป็นส่วนตัวที่แตกต่างกัน แต่มีประโยชน์ในวงกว้างมากขึ้น ในการประมาณค่าที่ quantile ให้คุณสามารถใช้ tff.aggregators.PrivateQuantileEstimationProcess ตัวอย่างเช่น ในการปรับให้เข้ากับค่ามัธยฐานของการแจกแจง คุณสามารถใช้:

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

เทคนิคต่างๆ ที่ใช้อัลกอริธึมการประมาณค่าควอนไทล์จะต้องใช้ค่าพารามิเตอร์อัลกอริธึมที่แตกต่างกัน ตามที่เราจะเห็น โดยทั่วไปเพิ่ม learning_rate พารามิเตอร์หมายถึงการปรับตัวได้เร็วขึ้นไป quantile ที่ถูกต้อง แต่มีความแปรปรวนสูง no_noise classmethod โครงสร้าง quantile กระบวนการจับคู่ที่ไม่ได้เพิ่มเสียงเพื่อความเป็นส่วนตัวค่า

Zeroing

Zeroing หมายถึงการแทนที่ค่าที่มีขนาดใหญ่ผิดปกติด้วยศูนย์ ในที่นี้ "ขนาดใหญ่ผิดปกติ" อาจหมายถึงมากกว่าเกณฑ์ที่กำหนดไว้ล่วงหน้า หรือขนาดใหญ่เมื่อเทียบกับค่าจากการคำนวณรอบก่อนหน้า การกำหนดศูนย์สามารถเพิ่มความทนทานของระบบต่อความเสียหายของข้อมูลในไคลเอนต์ที่มีข้อผิดพลาด

การคำนวณค่าเฉลี่ยของค่ากับบรรทัดฐาน L-อินฟินิตี้ขนาดใหญ่กว่า ZEROING_CONSTANT zeroed ออกเราห่อ tff.aggregators.MeanFactory กับ tff.aggregators.zeroing_factory ที่ดำเนินการ zeroing:

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 ) เป็นค่าที่ค่อนข้างใหญ่กว่าค่าที่ใหญ่ที่สุดที่เห็นเพื่อให้ห่างไกล สำหรับการประมาณการ quantile Q เกณฑ์ที่ใช้สำหรับ zeroing จะ Q * multiplier + increment

การตัดขอบ L2 norm

การตัดการอัปเดตไคลเอ็นต์ (ฉายภาพไปยังลูกบอล 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 การบีบอัดแบบสูญเสียข้อมูลมักส่งผลให้มีอัตราส่วนการบีบอัดที่สูงกว่ามาก และยังสามารถใช้ร่วมกับการบีบอัดแบบไม่สูญเสียข้อมูลได้ในภายหลัง เนื่องจากต้องใช้เวลาน้อยลงในการสื่อสารระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ รอบการฝึกอบรมจึงเสร็จสิ้นเร็วขึ้น เนื่องจากลักษณะการสุ่มโดยธรรมชาติของอัลกอริธึมการเรียนรู้ จนถึงขีดจำกัดบางอย่าง ความไม่ถูกต้องจากการบีบอัดแบบสูญเสียข้อมูลจึงไม่ส่งผลกระทบด้านลบต่อประสิทธิภาพโดยรวม

คำแนะนำเริ่มต้นคือการใช้ควอนเครื่องแบบง่าย (ดู Suresh et al. เป็นต้น) แปรสองค่า: ขนาดเมตริกซ์อัด threshold และจำนวน quantization_bits ทุกเมตริกซ์ t ถ้าจำนวนขององค์ประกอบของ t เป็นน้อยกว่าหรือเท่ากับ threshold ก็จะไม่มีการบีบอัด ถ้ามันมีขนาดใหญ่องค์ประกอบของ t จะ quantized ใช้ปัดเศษแบบสุ่มเพื่อ 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 degrades รูปแบบที่เราจะแนะนำให้เริ่มต้นที่ 6 จะเป็น "ในด้านความปลอดภัย"

ลูกค้าต่อรอบ. หมายเหตุที่มีนัยสำคัญเพิ่มจำนวนของลูกค้าต่อรอบสามารถเปิดใช้งานคุ้มค่าขนาดเล็กสำหรับ quantization_bits จะทำงานได้ดีเพราะความไม่ถูกต้องสุ่มนำโดยควอนอาจจะคืนสู่สภาพปกติโดยเฉลี่ยในช่วงปรับปรุงไคลเอ็นต์เพิ่มเติม

การรวมที่ปลอดภัย

โดย Secure Aggregation (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. Zeroing
  2. คลิปหนีบ
  3. เทคนิคอื่นๆ

รวบรวมใน tff.aggregators โมดูลที่มีองค์ประกอบโดยห่อ "รวบรวมภายใน" (ซึ่งก่อนรวมผลกระทบที่เกิดขึ้นที่ผ่านมาและผลกระทบหลังการรวมตัวเกิดขึ้นครั้งแรก) ภายใน "รวบรวมนอก" ตัวอย่างเช่น ในการดำเนินการ zeroing, clipping และบีบอัด (ตามลำดับ) เราจะเขียนว่า:

# 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)

หมายเหตุว่าโครงสร้างนี้ตรงกับ รวบรวมเริ่มต้น สำหรับขั้นตอนวิธีการเรียนรู้

องค์ประกอบอื่น ๆ ก็เป็นไปได้เช่นกัน เราขยายเอกสารนี้เมื่อเรามั่นใจว่าเราสามารถจัดเตรียมการกำหนดค่าเริ่มต้นซึ่งทำงานในแอปพลิเคชันต่างๆ ได้หลายแบบ สำหรับการใช้ความคิดใหม่ให้ดู รวบรวมที่กำหนดเองการดำเนินการ กวดวิชา