บทนำ
เมื่อใช้งาน MinDiff คุณจะต้องทำการตัดสินใจที่ซับซ้อนในขณะที่คุณเลือกและกำหนดรูปแบบข้อมูลของคุณก่อนที่จะส่งต่อไปยังโมเดล การตัดสินใจเหล่านี้จะกำหนดพฤติกรรมของ MinDiff ภายในโมเดลของคุณเป็นส่วนใหญ่
คู่มือนี้จะครอบคลุมแง่มุมทางเทคนิคของกระบวนการนี้ แต่จะไม่อภิปรายถึงวิธีการประเมินแบบจำลองเพื่อความเป็นธรรม หรือวิธีการระบุส่วนและตัวชี้วัดเฉพาะสำหรับการประเมิน โปรดดู คำแนะนำความเป็นธรรมชี้วัด สำหรับรายละเอียดเกี่ยวกับเรื่องนี้
เพื่อแสดงให้เห็น MinDiff คู่มือนี้ใช้ ชุดข้อมูลรายได้ UCI งานต้นแบบคือการทำนายว่าบุคคลมีรายได้เกิน 50,000 ดอลลาร์หรือไม่ โดยพิจารณาจากคุณลักษณะส่วนบุคคลต่างๆ คู่มือนี้จะถือว่ามีช่องว่างที่มีปัญหาใน FNR (อัตราการลบเท็จ) ระหว่าง "Male"
และ "Female"
ชิ้นและเจ้าของโมเดล (คุณ) ได้ตัดสินใจที่จะใช้ MinDiff เพื่อแก้ไขปัญหา สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสถานการณ์ในที่หนึ่งอาจเลือกที่จะใช้ MinDiff ดูที่ หน้าความต้องการ
MinDiff ทำงานโดยลงโทษความแตกต่างในคะแนนการกระจายระหว่างตัวอย่างในข้อมูลสองชุด คู่มือนี้จะสาธิตวิธีการเลือกและสร้างชุด MinDiff เพิ่มเติมเหล่านี้ รวมทั้งวิธีการจัดแพคเกจทุกอย่างเข้าด้วยกัน เพื่อให้สามารถส่งต่อไปยังแบบจำลองสำหรับการฝึกอบรมได้
ติดตั้ง
pip install -q --upgrade tensorflow-model-remediation
import tensorflow as tf
from tensorflow_model_remediation import min_diff
from tensorflow_model_remediation.tools.tutorials_utils import uci as tutorials_utils
ข้อมูลต้นฉบับ
เพื่อจุดประสงค์ในการสาธิตและเพื่อลดรันไทม์ คู่มือนี้ใช้เพียงเศษส่วนของชุดข้อมูล UCI Income ในการตั้งค่าการผลิตจริง ชุดข้อมูลทั้งหมดจะถูกใช้
# Sampled at 0.3 for reduced runtimes.
train = tutorials_utils.get_uci_data(split='train', sample=0.3)
print(len(train), 'train examples')
9768 train examples
แปลงไป tf.data.Dataset
MinDiffModel
ต้องการให้ป้อนข้อมูลที่เป็น tf.data.Dataset
หากคุณใช้อินพุตรูปแบบอื่นก่อนที่จะรวม MinDiff คุณจะต้องแปลงข้อมูลอินพุตของคุณ
ใช้ tf.data.Dataset.from_tensor_slices
แปลง tf.data.Dataset
dataset = tf.data.Dataset.from_tensor_slices((x, y, weights))
dataset.shuffle(...) # Optional.
dataset.batch(batch_size)
ดู Model.fit
เอกสารสำหรับรายละเอียดเกี่ยว equivalences ระหว่างสองวิธีการป้อนข้อมูล
ในคู่มือนี้ อินพุตจะถูกดาวน์โหลดเป็น Pandas DataFrame ดังนั้นจึงต้องมีการแปลงนี้
# Function to convert a DataFrame into a tf.data.Dataset.
def df_to_dataset(dataframe, shuffle=True):
dataframe = dataframe.copy()
labels = dataframe.pop('target')
ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
if shuffle:
ds = ds.shuffle(buffer_size=5000) # Reasonable but arbitrary buffer_size.
return ds
# Convert the train DataFrame into a Dataset.
original_train_ds = df_to_dataset(train)
การสร้างข้อมูล MinDiff
ในระหว่างการฝึกอบรม MinDiff จะสนับสนุนให้โมเดลลดความแตกต่างในการคาดการณ์ระหว่างชุดข้อมูลเพิ่มเติมสองชุด (ซึ่งอาจรวมถึงตัวอย่างจากชุดข้อมูลเดิม) การเลือกชุดข้อมูลสองชุดนี้เป็นการตัดสินใจหลักซึ่งจะกำหนดผลกระทบที่ MinDiff มีต่อแบบจำลอง
ควรเลือกชุดข้อมูลสองชุดในลักษณะที่ความแตกต่างในประสิทธิภาพที่คุณพยายามแก้ไขนั้นชัดเจนและเป็นตัวแทนอย่างดี เนื่องจากเป้าหมายคือการลดช่องว่างในการ FNR ระหว่าง "Male"
และ "Female"
ชิ้นนี้หมายถึงการสร้างชุดข้อมูลที่มีเพียงป้ายกำกับบวก "Male"
ตัวอย่างและอื่น ๆ ที่มีเพียงป้ายกำกับบวก "Female"
ตัวอย่าง; สิ่งเหล่านี้จะเป็นชุดข้อมูล MinDiff
ขั้นแรก ตรวจสอบข้อมูลที่มีอยู่
female_pos = train[(train['sex'] == ' Female') & (train['target'] == 1)]
male_pos = train[(train['sex'] == ' Male') & (train['target'] == 1)]
print(len(female_pos), 'positively labeled female examples')
print(len(male_pos), 'positively labeled male examples')
385 positively labeled female examples 2063 positively labeled male examples
เป็นที่ยอมรับอย่างสมบูรณ์ในการสร้างชุดข้อมูล MinDiff จากชุดย่อยของชุดข้อมูลดั้งเดิม
ในขณะที่มีไม่ได้ 5,000 หรือบวกมากขึ้น "Male"
ตัวอย่างตามคำแนะนำใน การแนะนำความต้องการ มีมากกว่า 2,000 และมันก็มีเหตุผลที่จะลองกับหลาย ๆ ว่าก่อนที่จะเก็บรวบรวมข้อมูลได้มากขึ้น
min_diff_male_ds = df_to_dataset(male_pos)
บวก "Female"
ตัวอย่าง แต่มีเวชภัณฑ์มากที่ 385 นี้น่าจะเป็นขนาดเล็กเกินไปสำหรับผลงานที่ดีและอื่น ๆ จะต้องมีการดึงตัวอย่างเพิ่มเติม
full_uci_train = tutorials_utils.get_uci_data(split='train')
augmented_female_pos = full_uci_train[((full_uci_train['sex'] == ' Female') &
(full_uci_train['target'] == 1))]
print(len(augmented_female_pos), 'positively labeled female examples')
1179 positively labeled female examples
การใช้ชุดข้อมูลแบบเต็มมีจำนวนตัวอย่างที่สามารถใช้สำหรับ MinDiff ได้มากกว่าสามเท่า มันยังต่ำอยู่ แต่พอลองผ่านครั้งแรก
min_diff_female_ds = df_to_dataset(augmented_female_pos)
ชุดข้อมูล MinDiff ทั้งสองชุดมีขนาดเล็กกว่าตัวอย่างที่แนะนำ 5,000 รายการขึ้นไปอย่างมีนัยสำคัญ แม้ว่าจะสมเหตุสมผลที่จะพยายามใช้ MinDiff กับข้อมูลปัจจุบัน แต่คุณอาจต้องพิจารณารวบรวมข้อมูลเพิ่มเติมหากคุณสังเกตเห็นประสิทธิภาพต่ำหรือไม่เหมาะสมระหว่างการฝึก
ใช้ tf.data.Dataset.filter
หรือคุณสามารถสร้างทั้งสองชุดข้อมูล MinDiff โดยตรงจากแปลงเดิม Dataset
# Male
def male_predicate(x, y):
return tf.equal(x['sex'], b' Male') and tf.equal(y, 0)
alternate_min_diff_male_ds = original_train_ds.filter(male_predicate).cache()
# Female
def female_predicate(x, y):
return tf.equal(x['sex'], b' Female') and tf.equal(y, 0)
full_uci_train_ds = df_to_dataset(full_uci_train)
alternate_min_diff_female_ds = full_uci_train_ds.filter(female_predicate).cache()
ส่งผลให้ alternate_min_diff_male_ds
และ alternate_min_diff_female_ds
จะเทียบเท่าในการส่งออกไปยัง min_diff_male_ds
และ min_diff_female_ds
ตามลำดับ
การสร้างชุดข้อมูลการฝึกอบรมของคุณ
ในขั้นตอนสุดท้าย ชุดข้อมูลสามชุด (ชุดข้อมูลที่สร้างขึ้นใหม่และชุดเดิม 2 ชุด) จะต้องรวมกันเป็นชุดข้อมูลเดียวที่สามารถส่งผ่านไปยังแบบจำลองได้
แบทช์ชุดข้อมูล
ก่อนรวมชุดข้อมูลจะต้องแบทช์
- ชุดข้อมูลดั้งเดิมสามารถใช้ชุดงานเดียวกันกับที่ใช้ก่อนที่จะรวม MinDiff
- ชุดข้อมูล MinDiff ไม่จำเป็นต้องมีขนาดชุดงานเดียวกันกับชุดข้อมูลดั้งเดิม อันที่เล็กกว่าก็จะทำงานได้ดีเช่นกัน แม้ว่าไม่จำเป็นต้องมีขนาดแบทช์เท่ากัน แต่ขอแนะนำให้ทำเช่นนี้เพื่อประสิทธิภาพที่ดีที่สุด
ในขณะที่ไม่จำเป็นอย่างเคร่งครัดก็จะแนะนำให้ใช้ drop_remainder=True
สำหรับสองชุดข้อมูล MinDiff เช่นนี้จะให้แน่ใจว่าพวกเขามีขนาดชุดที่สอดคล้องกัน
original_train_ds = original_train_ds.batch(128) # Same as before MinDiff.
# The MinDiff datasets can have a different batch_size from original_train_ds
min_diff_female_ds = min_diff_female_ds.batch(32, drop_remainder=True)
# Ideally we use the same batch size for both MinDiff datasets.
min_diff_male_ds = min_diff_male_ds.batch(32, drop_remainder=True)
บรรจุชุดข้อมูลที่มี pack_min_diff_data
เมื่อเตรียมชุดข้อมูลแล้ว ให้แพ็คเป็นชุดข้อมูลเดียวซึ่งจะถูกส่งต่อไปยังโมเดล ชุดเดียวจากชุดข้อมูลที่เป็นผลลัพธ์จะมีหนึ่งชุดงานจากแต่ละชุดข้อมูลสามชุดที่คุณเตรียมไว้ก่อนหน้านี้
คุณสามารถทำได้โดยใช้ที่มีให้ utils
ฟังก์ชั่นใน tensorflow_model_remediation
แพคเกจ:
train_with_min_diff_ds = min_diff.keras.utils.pack_min_diff_data(
original_dataset=original_train_ds,
sensitive_group_dataset=min_diff_female_ds,
nonsensitive_group_dataset=min_diff_male_ds)
และนั่นแหล่ะ! คุณจะสามารถที่จะใช้อื่น ๆ util
ฟังก์ชั่นในแพคเกจที่จะแกะแต่ละชุดถ้าจำเป็น
for inputs, original_labels in train_with_min_diff_ds.take(1):
# Unpacking min_diff_data
min_diff_data = min_diff.keras.utils.unpack_min_diff_data(inputs)
min_diff_examples, min_diff_membership = min_diff_data
# Unpacking original data
original_inputs = min_diff.keras.utils.unpack_original_inputs(inputs)
ด้วยข้อมูลที่สร้างขึ้นใหม่ ตอนนี้คุณพร้อมที่จะใช้ MinDiff ในแบบจำลองของคุณแล้ว! ต้องการเรียนรู้วิธีนี้จะทำโปรดดูที่คำแนะนำอื่น ๆ ที่เริ่มต้นด้วย การบูรณาการกับ MinDiff MinDiffModel
การใช้รูปแบบการบรรจุแบบกำหนดเอง (ตัวเลือก)
คุณอาจตัดสินใจแพ็คชุดข้อมูลสามชุดเข้าด้วยกันในแบบที่คุณเลือก ข้อกำหนดเพียงอย่างเดียวคือ คุณจะต้องตรวจสอบให้แน่ใจว่าแบบจำลองรู้วิธีตีความข้อมูล เริ่มต้นใช้งาน MinDiffModel
อนุมานว่าข้อมูลที่ถูกบรรจุโดยใช้ min_diff.keras.utils.pack_min_diff_data
วิธีการหนึ่งที่ง่ายต่อการจัดรูปแบบการป้อนข้อมูลของคุณตามที่คุณต้องการคือการแปลงข้อมูลเป็นขั้นตอนสุดท้ายหลังจากที่คุณได้ใช้ min_diff.keras.utils.pack_min_diff_data
# Reformat input to be a dict.
def _reformat_input(inputs, original_labels):
unpacked_min_diff_data = min_diff.keras.utils.unpack_min_diff_data(inputs)
unpacked_original_inputs = min_diff.keras.utils.unpack_original_inputs(inputs)
return {
'min_diff_data': unpacked_min_diff_data,
'original_data': (unpacked_original_inputs, original_labels)}
customized_train_with_min_diff_ds = train_with_min_diff_ds.map(_reformat_input)
โมเดลของคุณจะต้องรู้วิธีการอ่านการป้อนข้อมูลที่กำหนดเองนี้เป็นรายละเอียดใน คู่มือการปรับแต่ง MinDiffModel
for batch in customized_train_with_min_diff_ds.take(1):
# Customized unpacking of min_diff_data
min_diff_data = batch['min_diff_data']
# Customized unpacking of original_data
original_data = batch['original_data']
แหล่งข้อมูลเพิ่มเติม
- สำหรับในการอภิปรายเชิงลึกเกี่ยวกับการประเมินผลความเป็นธรรมดู คำแนะนำความเป็นธรรมชี้วัด
- สำหรับข้อมูลทั่วไปเกี่ยวกับการฟื้นฟูและ MinDiff ดูที่ ภาพรวมของการฟื้นฟู
- สำหรับรายละเอียดเกี่ยวกับข้อกำหนดโดยรอบ MinDiff ดู คำแนะนำนี้
- หากต้องการดูแบบ end-to-end กวดวิชาเกี่ยวกับการใช้ MinDiff ใน Keras ดู การกวดวิชานี้
ฟังก์ชันยูทิลิตี้สำหรับไกด์อื่นๆ
คู่มือนี้สรุปกระบวนการและการตัดสินใจที่คุณสามารถปฏิบัติตามทุกครั้งที่ใช้ MinDiff คู่มือที่เหลือสร้างจากกรอบนี้ เพื่อให้ง่ายขึ้น ตรรกะที่พบในคู่มือนี้ได้ถูกแยกออกเป็นฟังก์ชันตัวช่วย:
-
get_uci_data
: ฟังก์ชันนี้ถูกใช้ไปแล้วในคู่มือนี้ มันส่งกลับDataFrame
มีข้อมูลรายได้ UCI จากแยกที่ระบุตัวอย่างในอัตราสิ่งที่จะชี้ให้เห็น (100% ถ้าไม่ได้ระบุ) -
df_to_dataset
: ฟังก์ชันนี้แปลงDataFrame
เป็นtf.data.Dataset
ตามรายละเอียดในคู่มือนี้กับการทำงานที่เพิ่มขึ้นของความสามารถในการส่งผ่าน batch_size เป็นพารามิเตอร์ -
get_uci_with_min_diff_dataset
: ผลตอบแทนที่ฟังก์ชั่นนี้tf.data.Dataset
มีทั้งข้อมูลเดิมและข้อมูล MinDiff บรรจุเข้าด้วยกันโดยใช้ฟื้นฟูห้องสมุดรุ่น util ฟังก์ชั่นตามที่อธิบายไว้ในคู่มือนี้
คู่มือที่เหลือจะต่อยอดจากสิ่งเหล่านี้เพื่อแสดงวิธีใช้ส่วนอื่นๆ ของห้องสมุด