Giới thiệu
Khi triển khai MinDiff, bạn sẽ cần phải đưa ra các quyết định phức tạp khi bạn chọn và định hình đầu vào của mình trước khi chuyển nó cho mô hình. Những quyết định này sẽ xác định phần lớn hành vi của MinDiff trong mô hình của bạn.
Hướng dẫn này sẽ đề cập đến các khía cạnh kỹ thuật của quy trình này, nhưng sẽ không thảo luận về cách đánh giá mô hình cho công bằng, hoặc cách xác định các phần và số liệu cụ thể để đánh giá. Xin vui lòng xem các hướng dẫn chỉ số Công bằng để biết chi tiết về vấn đề này.
Để chứng minh MinDiff, hướng dẫn này sử dụng số liệu thu nhập UCI . Nhiệm vụ của mô hình là dự đoán liệu một cá nhân có thu nhập vượt quá $ 50k hay không, dựa trên các thuộc tính cá nhân khác nhau. Hướng dẫn này giả định có một khoảng cách có vấn đề trong FNR (tỷ lệ âm tính giả) giữa "Male"
và "Female"
lát và chủ sở hữu mô hình (bạn) đã quyết định áp dụng MinDiff để giải quyết vấn đề này. Để biết thêm thông tin về các tình huống trong đó người ta có thể chọn áp dụng MinDiff, xem trang yêu cầu .
MinDiff hoạt động bằng cách phạt sự khác biệt về điểm phân phối giữa các ví dụ trong hai bộ dữ liệu. Hướng dẫn này sẽ trình bày cách chọn và xây dựng các bộ MinDiff bổ sung này cũng như cách gói mọi thứ lại với nhau để có thể chuyển nó đến một mô hình để đào tạo.
Thành lập
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
Dữ liệu gốc
Đối với mục đích trình diễn và để giảm thời gian chạy, hướng dẫn này chỉ sử dụng một phần mẫu của tập dữ liệu Thu nhập UCI. Trong cài đặt sản xuất thực, tập dữ liệu đầy đủ sẽ được sử dụng.
# 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
Chuyển đổi sang tf.data.Dataset
MinDiffModel
yêu cầu đầu vào là một tf.data.Dataset
. Nếu bạn đang sử dụng định dạng đầu vào khác trước khi tích hợp MinDiff, bạn sẽ phải chuyển đổi dữ liệu đầu vào của mình.
Sử dụng tf.data.Dataset.from_tensor_slices
chuyển đổi sang tf.data.Dataset
.
dataset = tf.data.Dataset.from_tensor_slices((x, y, weights))
dataset.shuffle(...) # Optional.
dataset.batch(batch_size)
Xem Model.fit
tài liệu hướng dẫn để biết chi tiết về tương đồng giữa hai phương pháp đầu vào.
Trong hướng dẫn này, đầu vào được tải xuống dưới dạng Pandas DataFrame và do đó, cần chuyển đổi này.
# 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)
Tạo dữ liệu MinDiff
Trong quá trình đào tạo, MinDiff sẽ khuyến khích mô hình giảm bớt sự khác biệt về dự đoán giữa hai tập dữ liệu bổ sung (có thể bao gồm các ví dụ từ tập dữ liệu gốc). Việc lựa chọn hai tập dữ liệu này là quyết định quan trọng sẽ xác định tác động của MinDiff đối với mô hình.
Hai tập dữ liệu nên được chọn sao cho sự chênh lệch về hiệu suất mà bạn đang cố gắng khắc phục là rõ ràng và được thể hiện tốt. Vì mục đích là để giảm bớt một khoảng trống trong FNR giữa "Male"
và "Female"
lát, điều này có nghĩa là tạo ra một bộ dữ liệu với chỉ dán nhãn một cách tích cực "Male"
ví dụ và khác với chỉ dán nhãn một cách tích cực "Female"
ví dụ; đây sẽ là các tập dữ liệu MinDiff.
Đầu tiên, hãy kiểm tra dữ liệu hiện tại.
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
Hoàn toàn có thể chấp nhận được việc tạo tập dữ liệu MinDiff từ các tập con của tập dữ liệu gốc.
Trong khi không có 5.000 hoặc tích cực hơn "Male"
ví dụ như đề nghị trong hướng dẫn yêu cầu , có hơn 2.000 và nó là hợp lý để cố gắng với nhiều trước khi thu thập nhiều dữ liệu hơn.
min_diff_male_ds = df_to_dataset(male_pos)
Tích cực "Female"
ví dụ, tuy nhiên, nhiều khan hiếm tại 385. Đây có lẽ là quá nhỏ so với hiệu suất tốt và như vậy sẽ đòi hỏi kéo trong ví dụ bổ sung.
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
Việc sử dụng tập dữ liệu đầy đủ đã tăng hơn gấp ba lần số lượng ví dụ có thể được sử dụng cho MinDiff. Nó vẫn còn thấp nhưng nó là đủ để cố gắng như một lần vượt qua đầu tiên.
min_diff_female_ds = df_to_dataset(augmented_female_pos)
Cả hai tập dữ liệu MinDiff đều nhỏ hơn đáng kể so với 5.000 ví dụ được đề xuất trở lên. Mặc dù việc cố gắng áp dụng MinDiff với dữ liệu hiện tại là hợp lý, nhưng bạn có thể cần cân nhắc thu thập thêm dữ liệu nếu bạn quan sát thấy hiệu suất kém hoặc trang bị quá mức trong quá trình đào tạo.
Sử dụng tf.data.Dataset.filter
Ngoài ra, bạn có thể tạo ra hai tập dữ liệu MinDiff trực tiếp từ bản gốc được chuyển đổi 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()
Kết quả alternate_min_diff_male_ds
và alternate_min_diff_female_ds
sẽ tương đương với sản lượng để min_diff_male_ds
và min_diff_female_ds
tương ứng.
Xây dựng tập dữ liệu đào tạo của bạn
Bước cuối cùng, ba tập dữ liệu (hai tập dữ liệu mới được tạo và tập dữ liệu ban đầu) cần được hợp nhất thành một tập dữ liệu duy nhất có thể được chuyển đến mô hình.
Kết hợp các bộ dữ liệu
Trước khi hợp nhất, các tập dữ liệu cần phải được phân lô.
- Tập dữ liệu ban đầu có thể sử dụng cùng một lô đã được sử dụng trước khi tích hợp MinDiff.
- Tập dữ liệu MinDiff không cần phải có cùng kích thước lô với tập dữ liệu gốc. Trong tất cả các khả năng, một cái nhỏ hơn cũng sẽ hoạt động tốt. Mặc dù chúng thậm chí không cần phải có cùng kích thước lô với nhau, nhưng bạn nên làm như vậy để có hiệu suất tốt nhất.
Mặc dù không thực sự cần thiết, nó được khuyến khích để sử dụng drop_remainder=True
cho hai tập dữ liệu MinDiff vì điều này sẽ đảm bảo rằng họ có kích thước hàng loạt quán.
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)
Đóng gói các Datasets với pack_min_diff_data
Khi các tập dữ liệu được chuẩn bị, hãy đóng gói chúng thành một tập dữ liệu duy nhất, sau đó sẽ được chuyển đến mô hình. Một lô duy nhất từ tập dữ liệu kết quả sẽ chứa một lô từ mỗi trong ba tập dữ liệu mà bạn đã chuẩn bị trước đó.
Bạn có thể làm điều này bằng cách sử dụng cung cấp utils
chức năng trong tensorflow_model_remediation
gói:
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)
Và đó là nó! Bạn sẽ có thể sử dụng khác util
chức năng trong gói đến lô cá nhân giải nén nếu cần thiết.
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)
Với dữ liệu mới được hình thành của bạn, bây giờ bạn đã sẵn sàng áp dụng MinDiff trong mô hình của mình! Để tìm hiểu cách này được thực hiện, xin hãy xem các hướng dẫn khác bắt đầu với Lồng ghép MinDiff với MinDiffModel .
Sử dụng định dạng đóng gói tùy chỉnh (tùy chọn)
Bạn có thể quyết định gói ba bộ dữ liệu lại với nhau theo bất kỳ cách nào bạn chọn. Yêu cầu duy nhất là bạn sẽ cần đảm bảo mô hình biết cách diễn giải dữ liệu. Việc thực hiện mặc định của MinDiffModel
giả định rằng các dữ liệu đã được đóng gói bằng min_diff.keras.utils.pack_min_diff_data
.
Một cách dễ dàng để định dạng đầu vào của bạn như bạn muốn là để chuyển đổi dữ liệu như một bước cuối cùng sau khi bạn đã sử dụng 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)
Mô hình của bạn sẽ cần phải biết làm thế nào để đọc đầu vào tùy chỉnh này được nêu chi tiết trong hướng dẫn Tuỳ chỉnh 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']
Tài nguyên bổ sung
- Đối với một trong cuộc thảo luận sâu về đánh giá công bằng xem các hướng dẫn chỉ số Công bằng
- Để biết thông tin chung về Xử lý ô nhiễm và MinDiff, xem tổng quan về khắc phục hậu quả .
- Để biết chi tiết về các yêu cầu xung quanh MinDiff thấy hướng dẫn này .
- Để xem một end-to-end hướng dẫn về sử dụng MinDiff trong Keras, xem hướng dẫn này .
Chức năng Tiện ích cho các Hướng dẫn khác
Hướng dẫn này phác thảo quy trình và việc ra quyết định mà bạn có thể làm theo bất cứ khi nào áp dụng MinDiff. Phần còn lại của các hướng dẫn xây dựng dựa trên khuôn khổ này. Để làm cho việc này dễ dàng hơn, logic tìm thấy trong hướng dẫn này đã được phân tích thành các hàm trợ giúp:
-
get_uci_data
: Chức năng này đã được sử dụng trong hướng dẫn này. Nó trả về mộtDataFrame
chứa dữ liệu thu nhập UCI từ sự chia rẽ chỉ định lấy mẫu tại bất kỳ tỷ lệ được chỉ định (100% nếu không xác định). -
df_to_dataset
: Chức năng này chuyển đổi mộtDataFrame
thành mộttf.data.Dataset
được nêu chi tiết trong hướng dẫn này với các tính năng bổ sung của việc có thể để vượt qua batch_size như một tham số. -
get_uci_with_min_diff_dataset
: Chức năng này trả về mộttf.data.Dataset
chứa cả dữ liệu gốc và dữ liệu MinDiff đóng gói lại với nhau bằng cách sử dụng mẫu Xử lý ô nhiễm Library util chức năng như mô tả trong hướng dẫn này.
Phần còn lại của các hướng dẫn sẽ dựa trên những hướng dẫn này để chỉ ra cách sử dụng các phần khác của thư viện.