ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
ในตัวอย่างนี้ เราพิจารณางานในการทำนายว่าข้อคิดเห็นในการอภิปรายที่โพสต์บนหน้าพูดคุยของ Wiki มีเนื้อหาที่เป็นพิษหรือไม่ (กล่าวคือ มีเนื้อหาที่ “หยาบคาย ไม่สุภาพ หรือไม่มีเหตุผล”) เราใช้ประชาชน ชุดข้อมูลที่ ปล่อยออกมาจาก การสนทนา AI โครงการซึ่งมีมากกว่า 100k ความเห็นจากวิกิพีเดียภาษาอังกฤษที่มีข้อเขียนโดยคนงานฝูงชน (ดู กระดาษ สำหรับวิธีการติดฉลาก)
ความท้าทายประการหนึ่งของชุดข้อมูลนี้คือความคิดเห็นที่มีส่วนน้อยครอบคลุมหัวข้อที่ละเอียดอ่อน เช่น เรื่องเพศหรือศาสนา ดังนั้น การฝึกโมเดลโครงข่ายประสาทเทียมในชุดข้อมูลนี้จะนำไปสู่ประสิทธิภาพการทำงานที่แตกต่างกันในหัวข้อที่มีความละเอียดอ่อนที่มีขนาดเล็กกว่า ซึ่งอาจหมายความว่าข้อความที่ไม่เป็นอันตรายเกี่ยวกับหัวข้อเหล่านั้นอาจถูกทำเครื่องหมายว่า 'เป็นพิษ' อย่างไม่ถูกต้องในอัตราที่สูงขึ้น ทำให้คำพูดถูกเซ็นเซอร์อย่างไม่เป็นธรรม
โดยการจัดเก็บภาษีข้อ จำกัด ในระหว่างการฝึกเราสามารถฝึกรูปแบบเป็นธรรมที่มีประสิทธิภาพมากขึ้นอย่างเท่าเทียมกันทั่วกลุ่มหัวข้อที่แตกต่างกัน
เราจะใช้ห้องสมุด TFCO เพื่อเพิ่มประสิทธิภาพเป้าหมายความเป็นธรรมของเราในระหว่างการฝึกอบรม
การติดตั้ง
ขั้นแรกให้ติดตั้งและนำเข้าไลบรารีที่เกี่ยวข้องกัน โปรดทราบว่าคุณอาจต้องรีสตาร์ท colab หนึ่งครั้งหลังจากเรียกใช้เซลล์แรกเนื่องจากแพ็กเกจที่ล้าสมัยในรันไทม์ หลังจากดำเนินการดังกล่าวแล้ว จะไม่มีปัญหากับการนำเข้าอีกต่อไป
pip ติดตั้ง
pip install -q -U pip==20.2
pip install git+https://github.com/google-research/tensorflow_constrained_optimization
pip install git+https://github.com/tensorflow/fairness-indicators
โปรดทราบว่าขึ้นอยู่กับเมื่อคุณเรียกใช้เซลล์ด้านล่าง คุณอาจได้รับคำเตือนเกี่ยวกับเวอร์ชันเริ่มต้นของ TensorFlow ใน Colab ที่เปลี่ยนเป็น TensorFlow 2.X ในไม่ช้า คุณสามารถเพิกเฉยต่อคำเตือนนั้นได้อย่างปลอดภัย เนื่องจากสมุดบันทึกนี้ได้รับการออกแบบมาให้เข้ากันได้กับ TensorFlow 1.X และ 2.X
นำเข้าโมดูล
import io
import os
import shutil
import sys
import tempfile
import time
import urllib
import zipfile
import apache_beam as beam
from IPython.display import display
from IPython.display import HTML
import numpy as np
import pandas as pd
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import layers
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.preprocessing import text
import tensorflow_constrained_optimization as tfco
import tensorflow_model_analysis as tfma
import fairness_indicators as fi
from tensorflow_model_analysis.addons.fairness.view import widget_view
from tensorflow_model_analysis.model_agnostic_eval import model_agnostic_evaluate_graph
from tensorflow_model_analysis.model_agnostic_eval import model_agnostic_extractor
from tensorflow_model_analysis.model_agnostic_eval import model_agnostic_predict as agnostic_predict
แม้ว่า TFCO จะเข้ากันได้กับความกระตือรือร้นและการใช้กราฟ แต่โน้ตบุ๊กนี้จะถือว่าการเรียกใช้งานแบบกระตือรือร้นนั้นเปิดใช้งานโดยค่าเริ่มต้น เพื่อให้แน่ใจว่าไม่มีอะไรเสียหาย การดำเนินการอย่างกระตือรือร้นจะเปิดใช้งานในเซลล์ด้านล่าง
เปิดใช้งาน Eager Execution และ Print Versions
if tf.__version__ < "2.0.0":
tf.enable_eager_execution()
print("Eager execution enabled.")
else:
print("Eager execution enabled by default.")
print("TensorFlow " + tf.__version__)
print("TFMA " + tfma.__version__)
print("FI " + fi.version.__version__)
Eager execution enabled by default. TensorFlow 2.3.2 TFMA 0.26.0 FI 0.27.0.dev
ไฮเปอร์พารามิเตอร์
อันดับแรก เราตั้งค่าไฮเปอร์พารามิเตอร์บางอย่างที่จำเป็นสำหรับการประมวลผลข้อมูลล่วงหน้าและการฝึกโมเดล
hparams = {
"batch_size": 128,
"cnn_filter_sizes": [128, 128, 128],
"cnn_kernel_sizes": [5, 5, 5],
"cnn_pooling_sizes": [5, 5, 40],
"constraint_learning_rate": 0.01,
"embedding_dim": 100,
"embedding_trainable": False,
"learning_rate": 0.005,
"max_num_words": 10000,
"max_sequence_length": 250
}
โหลดและประมวลผลชุดข้อมูลล่วงหน้า
ต่อไป เราดาวน์โหลดชุดข้อมูลและประมวลผลล่วงหน้า ชุดฝึก การทดสอบ และการตรวจสอบมีให้ในรูปแบบไฟล์ CSV แยกต่างหาก
toxicity_data_url = ("https://raw.githubusercontent.com/conversationai/"
"unintended-ml-bias-analysis/master/data/")
data_train = pd.read_csv(toxicity_data_url + "wiki_train.csv")
data_test = pd.read_csv(toxicity_data_url + "wiki_test.csv")
data_vali = pd.read_csv(toxicity_data_url + "wiki_dev.csv")
data_train.head()
comment
คอลัมน์ประกอบด้วยข้อคิดเห็นอภิปรายและ is_toxic
คอลัมน์บ่งชี้หรือไม่แสดงความคิดเห็นเป็นข้อเขียนเป็นพิษ
ต่อไปนี้เรา:
- แยกฉลากออก
- Tokenize แสดงความคิดเห็นข้อความ
- ระบุความคิดเห็นที่มีคำศัพท์หัวข้อที่ละเอียดอ่อน
ขั้นแรก เราแยกฉลากออกจากรถไฟ ชุดทดสอบ และการตรวจสอบ เลเบลทั้งหมดเป็นเลขฐานสอง (0 หรือ 1)
labels_train = data_train["is_toxic"].values.reshape(-1, 1) * 1.0
labels_test = data_test["is_toxic"].values.reshape(-1, 1) * 1.0
labels_vali = data_vali["is_toxic"].values.reshape(-1, 1) * 1.0
ต่อไปเรา tokenize ความคิดเห็นเกี่ยวกับใจใช้ Tokenizer
ให้โดย Keras
เราใช้ข้อคิดเห็นของชุดฝึกอบรมเพียงอย่างเดียวเพื่อสร้างคำศัพท์ของโทเค็น และใช้เพื่อแปลงความคิดเห็นทั้งหมดเป็นลำดับ (เสริม) ของโทเค็นที่มีความยาวเท่ากัน
tokenizer = text.Tokenizer(num_words=hparams["max_num_words"])
tokenizer.fit_on_texts(data_train["comment"])
def prep_text(texts, tokenizer, max_sequence_length):
# Turns text into into padded sequences.
text_sequences = tokenizer.texts_to_sequences(texts)
return sequence.pad_sequences(text_sequences, maxlen=max_sequence_length)
text_train = prep_text(data_train["comment"], tokenizer, hparams["max_sequence_length"])
text_test = prep_text(data_test["comment"], tokenizer, hparams["max_sequence_length"])
text_vali = prep_text(data_vali["comment"], tokenizer, hparams["max_sequence_length"])
สุดท้าย เราระบุความคิดเห็นที่เกี่ยวข้องกับกลุ่มหัวข้อที่ละเอียดอ่อนบางกลุ่ม เราพิจารณาส่วนย่อยของที่ แง่ตัวตน ให้กับชุดข้อมูลและกลุ่มพวกเขาเป็นสี่กลุ่มหัวข้อกว้าง: เพศอัตลักษณ์ทางเพศ, ศาสนาและการแข่งขัน
terms = {
'sexuality': ['gay', 'lesbian', 'bisexual', 'homosexual', 'straight', 'heterosexual'],
'gender identity': ['trans', 'transgender', 'cis', 'nonbinary'],
'religion': ['christian', 'muslim', 'jewish', 'buddhist', 'catholic', 'protestant', 'sikh', 'taoist'],
'race': ['african', 'african american', 'black', 'white', 'european', 'hispanic', 'latino', 'latina',
'latinx', 'mexican', 'canadian', 'american', 'asian', 'indian', 'middle eastern', 'chinese',
'japanese']}
group_names = list(terms.keys())
num_groups = len(group_names)
จากนั้นเราจะสร้างเมทริกซ์สมาชิกภาพกลุ่มแยกต่างหากสำหรับชุดฝึก การทดสอบ และการตรวจสอบ โดยที่แถวสอดคล้องกับความคิดเห็น คอลัมน์สอดคล้องกับกลุ่มที่มีความละเอียดอ่อนสี่กลุ่ม และแต่ละรายการเป็นบูลีนที่ระบุว่าความคิดเห็นมีคำศัพท์จากกลุ่มหัวข้อหรือไม่
def get_groups(text):
# Returns a boolean NumPy array of shape (n, k), where n is the number of comments,
# and k is the number of groups. Each entry (i, j) indicates if the i-th comment
# contains a term from the j-th group.
groups = np.zeros((text.shape[0], num_groups))
for ii in range(num_groups):
groups[:, ii] = text.str.contains('|'.join(terms[group_names[ii]]), case=False)
return groups
groups_train = get_groups(data_train["comment"])
groups_test = get_groups(data_test["comment"])
groups_vali = get_groups(data_vali["comment"])
ดังที่แสดงด้านล่าง กลุ่มหัวข้อทั้งสี่กลุ่มเป็นเพียงส่วนเล็กๆ ของชุดข้อมูลโดยรวม และมีสัดส่วนของความคิดเห็นที่เป็นพิษต่างกัน
print("Overall label proportion = %.1f%%" % (labels_train.mean() * 100))
group_stats = []
for ii in range(num_groups):
group_proportion = groups_train[:, ii].mean()
group_pos_proportion = labels_train[groups_train[:, ii] == 1].mean()
group_stats.append([group_names[ii],
"%.2f%%" % (group_proportion * 100),
"%.1f%%" % (group_pos_proportion * 100)])
group_stats = pd.DataFrame(group_stats,
columns=["Topic group", "Group proportion", "Label proportion"])
group_stats
Overall label proportion = 9.7%
เราเห็นว่ามีเพียง 1.3% ของชุดข้อมูลที่มีความคิดเห็นเกี่ยวกับเรื่องเพศ ในหมู่พวกเขา 37% ของความคิดเห็นได้รับการระบุว่าเป็นพิษ โปรดทราบว่าความคิดเห็นนี้มากกว่าสัดส่วนโดยรวมของความคิดเห็นที่มีหมายเหตุว่าเป็นพิษอย่างมาก อาจเป็นเพราะความคิดเห็นบางส่วนที่ใช้คำระบุตัวตนเหล่านั้นทำในบริบทที่ดูหมิ่น ดังที่กล่าวไว้ข้างต้น การทำเช่นนี้อาจทำให้แบบจำลองของเราจัดประเภทความคิดเห็นผิดอย่างผิดสัดส่วนว่าเป็นพิษเมื่อรวมคำเหล่านั้น ตั้งแต่นี้เป็นกังวลเราจะทำให้แน่ใจว่าจะดูที่อัตราการเท็จบวกเมื่อเราประเมินประสิทธิภาพของแบบจำลอง
สร้างแบบจำลองการคาดการณ์ความเป็นพิษของ CNN
มีการจัดทำชุดข้อมูลที่ตอนนี้เราสร้าง Keras
แบบจำลองสำหรับการเป็นพิษทำนาย แบบจำลองที่เราใช้คือ Convolutional Neural Network (CNN) ที่มีสถาปัตยกรรมเดียวกันกับที่ใช้ในโปรเจ็กต์ Conversation AI สำหรับการวิเคราะห์แบบ debiasing เราปรับตัวเข้ากับ รหัส ให้พวกเขาในการสร้างชั้นรูปแบบ
โมเดลใช้เลเยอร์การฝังเพื่อแปลงโทเค็นข้อความเป็นเวกเตอร์ที่มีความยาวคงที่ เลเยอร์นี้แปลงลำดับข้อความที่ป้อนเข้าเป็นลำดับของเวกเตอร์ และส่งผ่านเลเยอร์ของการบิดและการรวมหลายชั้น ตามด้วยเลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์ขั้นสุดท้าย
เราใช้การฝังเวกเตอร์คำของ GloVe ที่ผ่านการฝึกอบรมมาแล้ว ซึ่งเราดาวน์โหลดด้านล่าง การดำเนินการนี้อาจใช้เวลาสักครู่
zip_file_url = "http://nlp.stanford.edu/data/glove.6B.zip"
zip_file = urllib.request.urlopen(zip_file_url)
archive = zipfile.ZipFile(io.BytesIO(zip_file.read()))
เราใช้ embeddings ถุงมือที่ดาวน์โหลดมาเพื่อสร้างเมทริกซ์ฝังที่แถวประกอบด้วย embeddings คำสำหรับราชสกุลในที่ Tokenizer
คำศัพท์ 's
embeddings_index = {}
glove_file = "glove.6B.100d.txt"
with archive.open(glove_file) as f:
for line in f:
values = line.split()
word = values[0].decode("utf-8")
coefs = np.asarray(values[1:], dtype="float32")
embeddings_index[word] = coefs
embedding_matrix = np.zeros((len(tokenizer.word_index) + 1, hparams["embedding_dim"]))
num_words_in_embedding = 0
for word, i in tokenizer.word_index.items():
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
num_words_in_embedding += 1
embedding_matrix[i] = embedding_vector
ตอนนี้เราพร้อมที่จะระบุ Keras
ชั้น เราเขียนฟังก์ชันเพื่อสร้างโมเดลใหม่ ซึ่งเราจะเรียกใช้เมื่อใดก็ตามที่เราต้องการฝึกโมเดลใหม่
def create_model():
model = keras.Sequential()
# Embedding layer.
embedding_layer = layers.Embedding(
embedding_matrix.shape[0],
embedding_matrix.shape[1],
weights=[embedding_matrix],
input_length=hparams["max_sequence_length"],
trainable=hparams['embedding_trainable'])
model.add(embedding_layer)
# Convolution layers.
for filter_size, kernel_size, pool_size in zip(
hparams['cnn_filter_sizes'], hparams['cnn_kernel_sizes'],
hparams['cnn_pooling_sizes']):
conv_layer = layers.Conv1D(
filter_size, kernel_size, activation='relu', padding='same')
model.add(conv_layer)
pooled_layer = layers.MaxPooling1D(pool_size, padding='same')
model.add(pooled_layer)
# Add a flatten layer, a fully-connected layer and an output layer.
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(1))
return model
เรายังกำหนดวิธีการตั้งเมล็ดสุ่ม สิ่งนี้ทำเพื่อให้แน่ใจว่าได้ผลลัพธ์ที่ทำซ้ำได้
def set_seeds():
np.random.seed(121212)
tf.compat.v1.set_random_seed(212121)
ตัวชี้วัดความเป็นธรรม
เรายังเขียนฟังก์ชันเพื่อแสดงตัวบ่งชี้ความเป็นธรรม
def create_examples(labels, predictions, groups, group_names):
# Returns tf.examples with given labels, predictions, and group information.
examples = []
sigmoid = lambda x: 1/(1 + np.exp(-x))
for ii in range(labels.shape[0]):
example = tf.train.Example()
example.features.feature['toxicity'].float_list.value.append(
labels[ii])
example.features.feature['prediction'].float_list.value.append(
sigmoid(predictions[ii])) # predictions need to be in [0, 1].
for jj in range(groups.shape[1]):
example.features.feature[group_names[jj]].bytes_list.value.append(
b'Yes' if groups[ii, jj] else b'No')
examples.append(example)
return examples
def evaluate_results(labels, predictions, groups, group_names):
# Evaluates fairness indicators for given labels, predictions and group
# membership info.
examples = create_examples(labels, predictions, groups, group_names)
# Create feature map for labels, predictions and each group.
feature_map = {
'prediction': tf.io.FixedLenFeature([], tf.float32),
'toxicity': tf.io.FixedLenFeature([], tf.float32),
}
for group in group_names:
feature_map[group] = tf.io.FixedLenFeature([], tf.string)
# Serialize the examples.
serialized_examples = [e.SerializeToString() for e in examples]
BASE_DIR = tempfile.gettempdir()
OUTPUT_DIR = os.path.join(BASE_DIR, 'output')
with beam.Pipeline() as pipeline:
model_agnostic_config = agnostic_predict.ModelAgnosticConfig(
label_keys=['toxicity'],
prediction_keys=['prediction'],
feature_spec=feature_map)
slices = [tfma.slicer.SingleSliceSpec()]
for group in group_names:
slices.append(
tfma.slicer.SingleSliceSpec(columns=[group]))
extractors = [
model_agnostic_extractor.ModelAgnosticExtractor(
model_agnostic_config=model_agnostic_config),
tfma.extractors.slice_key_extractor.SliceKeyExtractor(slices)
]
metrics_callbacks = [
tfma.post_export_metrics.fairness_indicators(
thresholds=[0.5],
target_prediction_keys=['prediction'],
labels_key='toxicity'),
tfma.post_export_metrics.example_count()]
# Create a model agnostic aggregator.
eval_shared_model = tfma.types.EvalSharedModel(
add_metrics_callbacks=metrics_callbacks,
construct_fn=model_agnostic_evaluate_graph.make_construct_fn(
add_metrics_callbacks=metrics_callbacks,
config=model_agnostic_config))
# Run Model Agnostic Eval.
_ = (
pipeline
| beam.Create(serialized_examples)
| 'ExtractEvaluateAndWriteResults' >>
tfma.ExtractEvaluateAndWriteResults(
eval_shared_model=eval_shared_model,
output_path=OUTPUT_DIR,
extractors=extractors,
compute_confidence_intervals=True
)
)
fairness_ind_result = tfma.load_eval_result(output_path=OUTPUT_DIR)
# Also evaluate accuracy of the model.
accuracy = np.mean(labels == (predictions > 0.0))
return fairness_ind_result, accuracy
def plot_fairness_indicators(eval_result, title):
fairness_ind_result, accuracy = eval_result
display(HTML("<center><h2>" + title +
" (Accuracy = %.2f%%)" % (accuracy * 100) + "</h2></center>"))
widget_view.render_fairness_indicator(fairness_ind_result)
def plot_multi_fairness_indicators(multi_eval_results):
multi_results = {}
multi_accuracy = {}
for title, (fairness_ind_result, accuracy) in multi_eval_results.items():
multi_results[title] = fairness_ind_result
multi_accuracy[title] = accuracy
title_str = "<center><h2>"
for title in multi_eval_results.keys():
title_str+=title + " (Accuracy = %.2f%%)" % (multi_accuracy[title] * 100) + "; "
title_str=title_str[:-2]
title_str+="</h2></center>"
# fairness_ind_result, accuracy = eval_result
display(HTML(title_str))
widget_view.render_fairness_indicator(multi_eval_results=multi_results)
ฝึกโมเดลที่ไม่มีข้อจำกัด
สำหรับรถไฟรุ่นแรกที่เราเราเพิ่มประสิทธิภาพการสูญเสียข้ามเอนโทรปีที่เรียบง่ายโดยไม่ จำกัด ใด ๆ ..
# Set random seed for reproducible results.
set_seeds()
# Optimizer and loss.
optimizer = tf.keras.optimizers.Adam(learning_rate=hparams["learning_rate"])
loss = lambda y_true, y_pred: tf.keras.losses.binary_crossentropy(
y_true, y_pred, from_logits=True)
# Create, compile and fit model.
model_unconstrained = create_model()
model_unconstrained.compile(optimizer=optimizer, loss=loss)
model_unconstrained.fit(
x=text_train, y=labels_train, batch_size=hparams["batch_size"], epochs=2)
Epoch 1/2 748/748 [==============================] - 51s 69ms/step - loss: 0.1590 Epoch 2/2 748/748 [==============================] - 48s 65ms/step - loss: 0.1217 <tensorflow.python.keras.callbacks.History at 0x7f55603a1d30>
หลังจากฝึกโมเดลที่ไม่มีข้อจำกัด เราจึงพล็อตเมตริกการประเมินต่างๆ สำหรับโมเดลในชุดทดสอบ
scores_unconstrained_test = model_unconstrained.predict(text_test)
eval_result_unconstrained = evaluate_results(
labels_test, scores_unconstrained_test, groups_test, group_names)
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features. WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> INFO:tensorflow:ExampleCount post export metric: could not find any of the standard keys in predictions_dict (keys were: dict_keys(['prediction'])) INFO:tensorflow:ExampleCount post export metric: could not find any of the standard keys in predictions_dict (keys were: dict_keys(['prediction'])) INFO:tensorflow:Using the first key from predictions_dict: prediction INFO:tensorflow:Using the first key from predictions_dict: prediction WARNING:apache_beam.io.tfrecordio:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:113: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version. Instructions for updating: Use eager execution and: `tf.data.TFRecordDataset(path)` WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:113: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version. Instructions for updating: Use eager execution and: `tf.data.TFRecordDataset(path)`
ตามที่ได้อธิบายไว้ข้างต้น เรากำลังเพ่งความสนใจไปที่อัตราผลบวกลวง ในเวอร์ชันปัจจุบัน (0.1.2) ตัวบ่งชี้ความเป็นธรรมจะเลือกอัตราการติดลบที่ผิดพลาดโดยค่าเริ่มต้น หลังจากเรียกใช้บรรทัดด้านล่างแล้ว ให้ดำเนินการต่อและยกเลิกการเลือก false_negative_rate และเลือก false_positive_rate เพื่อดูเมตริกที่เราสนใจ
plot_fairness_indicators(eval_result_unconstrained, "Unconstrained")
แม้ว่าอัตราการบวกลวงโดยรวมจะน้อยกว่า 2% แต่อัตราการบวกลวงของความคิดเห็นเกี่ยวกับเรื่องเพศนั้นสูงขึ้นอย่างมาก เนื่องจากกลุ่มเพศวิถีมีขนาดเล็กมาก และมีสัดส่วนความคิดเห็นที่สูงขึ้นอย่างไม่สมส่วนซึ่งมีหมายเหตุระบุว่าเป็นพิษ ดังนั้น การฝึกโมเดลโดยไม่มีข้อจำกัดส่งผลให้โมเดลเชื่อว่าคำศัพท์ที่เกี่ยวข้องกับเรื่องเพศเป็นตัวบ่งชี้ถึงความเป็นพิษ
ฝึกโดยมีข้อจำกัดเรื่องอัตราการบวกลวง
เพื่อหลีกเลี่ยงความแตกต่างอย่างมากของอัตราผลบวกลวงในกลุ่มต่างๆ เราจึงฝึกแบบจำลองโดยจำกัดอัตราผลบวกลวงสำหรับแต่ละกลุ่มให้อยู่ภายในขีดจำกัดที่ต้องการ ในกรณีนี้เราจะเพิ่มอัตราความผิดพลาดของเรื่องรูปแบบการต่อกลุ่มอัตราบวกปลอมเป็นน้อยกว่าหรือเท่ากับ 2%
การฝึกอบรมเกี่ยวกับมินิแบตช์ที่มีข้อจำกัดสำหรับแต่ละกลุ่มอาจเป็นสิ่งที่ท้าทายสำหรับชุดข้อมูลนี้ อย่างไรก็ตาม เนื่องจากกลุ่มที่เราต้องการจำกัดนั้นมีขนาดเล็กทั้งหมด และมีแนวโน้มว่ามินิแบตช์แต่ละรายการจะมีตัวอย่างน้อยมากจากแต่ละกลุ่ม ดังนั้นการไล่ระดับสีที่เราคำนวณระหว่างการฝึกจะมีเสียงรบกวน และส่งผลให้แบบจำลองมาบรรจบกันช้ามาก
เพื่อลดปัญหานี้ เราขอแนะนำให้ใช้มินิแบตช์สองสตรีม โดยที่สตรีมแรกจะเกิดขึ้นเหมือนเมื่อก่อนจากชุดการฝึกทั้งหมด และสตรีมที่สองสร้างจากตัวอย่างกลุ่มที่มีความละเอียดอ่อนเท่านั้น เราจะคำนวณวัตถุประสงค์โดยใช้มินิแบตช์จากสตรีมแรกและข้อจำกัดต่อกลุ่มโดยใช้มินิแบตช์จากสตรีมที่สอง เนื่องจากแบทช์จากสตรีมที่สองมักจะมีตัวอย่างจำนวนมากจากแต่ละกลุ่ม เราจึงคาดว่าการอัปเดตของเราจะมีเสียงรบกวนน้อยลง
เราสร้างคุณลักษณะ ป้ายกำกับ และกลุ่มเทนเซอร์แยกกันเพื่อเก็บมินิแบตช์จากสตรีมทั้งสอง
# Set random seed.
set_seeds()
# Features tensors.
batch_shape = (hparams["batch_size"], hparams['max_sequence_length'])
features_tensor = tf.Variable(np.zeros(batch_shape, dtype='int32'), name='x')
features_tensor_sen = tf.Variable(np.zeros(batch_shape, dtype='int32'), name='x_sen')
# Labels tensors.
batch_shape = (hparams["batch_size"], 1)
labels_tensor = tf.Variable(np.zeros(batch_shape, dtype='float32'), name='labels')
labels_tensor_sen = tf.Variable(np.zeros(batch_shape, dtype='float32'), name='labels_sen')
# Groups tensors.
batch_shape = (hparams["batch_size"], num_groups)
groups_tensor_sen = tf.Variable(np.zeros(batch_shape, dtype='float32'), name='groups_sen')
เราสร้างโมเดลใหม่ และคำนวณการคาดการณ์สำหรับมินิแบตช์จากสตรีมทั้งสอง
# Create model, and separate prediction functions for the two streams.
# For the predictions, we use a nullary function returning a Tensor to support eager mode.
model_constrained = create_model()
def predictions():
return model_constrained(features_tensor)
def predictions_sen():
return model_constrained(features_tensor_sen)
จากนั้นเราตั้งค่าปัญหาการปรับให้เหมาะสมที่มีข้อจำกัด โดยมีอัตราข้อผิดพลาดเป็นวัตถุประสงค์และด้วยข้อจำกัดในอัตราผลบวกเท็จต่อกลุ่ม
epsilon = 0.02 # Desired false-positive rate threshold.
# Set up separate contexts for the two minibatch streams.
context = tfco.rate_context(predictions, lambda:labels_tensor)
context_sen = tfco.rate_context(predictions_sen, lambda:labels_tensor_sen)
# Compute the objective using the first stream.
objective = tfco.error_rate(context)
# Compute the constraint using the second stream.
# Subset the examples belonging to the "sexuality" group from the second stream
# and add a constraint on the group's false positive rate.
context_sen_subset = context_sen.subset(lambda: groups_tensor_sen[:, 0] > 0)
constraint = [tfco.false_positive_rate(context_sen_subset) <= epsilon]
# Create a rate minimization problem.
problem = tfco.RateMinimizationProblem(objective, constraint)
# Set up a constrained optimizer.
optimizer = tfco.ProxyLagrangianOptimizerV2(
optimizer=tf.keras.optimizers.Adam(learning_rate=hparams["learning_rate"]),
num_constraints=problem.num_constraints)
# List of variables to optimize include the model weights,
# and the trainable variables from the rate minimization problem and
# the constrained optimizer.
var_list = (model_constrained.trainable_weights + problem.trainable_variables +
optimizer.trainable_variables())
เราพร้อมที่จะฝึกโมเดล เรารักษาตัวนับแยกต่างหากสำหรับสตรีมมินิแบตช์ทั้งสองรายการ เวลาที่เราดำเนินการปรับปรุงการไล่ระดับสีทุกคนเราจะมีการคัดลอกเนื้อหา minibatch จากกระแสคนแรกที่จะเทนเซอร์ features_tensor
และ labels_tensor
และเนื้อหา minibatch จากกระแสที่สองที่จะเทนเซอร์ features_tensor_sen
, labels_tensor_sen
และ groups_tensor_sen
# Indices of sensitive group members.
protected_group_indices = np.nonzero(groups_train.sum(axis=1))[0]
num_examples = text_train.shape[0]
num_examples_sen = protected_group_indices.shape[0]
batch_size = hparams["batch_size"]
# Number of steps needed for one epoch over the training sample.
num_steps = int(num_examples / batch_size)
start_time = time.time()
# Loop over minibatches.
for batch_index in range(num_steps):
# Indices for current minibatch in the first stream.
batch_indices = np.arange(
batch_index * batch_size, (batch_index + 1) * batch_size)
batch_indices = [ind % num_examples for ind in batch_indices]
# Indices for current minibatch in the second stream.
batch_indices_sen = np.arange(
batch_index * batch_size, (batch_index + 1) * batch_size)
batch_indices_sen = [protected_group_indices[ind % num_examples_sen]
for ind in batch_indices_sen]
# Assign features, labels, groups from the minibatches to the respective tensors.
features_tensor.assign(text_train[batch_indices, :])
labels_tensor.assign(labels_train[batch_indices])
features_tensor_sen.assign(text_train[batch_indices_sen, :])
labels_tensor_sen.assign(labels_train[batch_indices_sen])
groups_tensor_sen.assign(groups_train[batch_indices_sen, :])
# Gradient update.
optimizer.minimize(problem, var_list=var_list)
# Record and print batch training stats every 10 steps.
if (batch_index + 1) % 10 == 0 or batch_index in (0, num_steps - 1):
hinge_loss = problem.objective()
max_violation = max(problem.constraints())
elapsed_time = time.time() - start_time
sys.stdout.write(
"\rStep %d / %d: Elapsed time = %ds, Loss = %.3f, Violation = %.3f" %
(batch_index + 1, num_steps, elapsed_time, hinge_loss, max_violation))
Step 747 / 747: Elapsed time = 180s, Loss = 0.068, Violation = -0.020
หลังจากฝึกโมเดลที่มีข้อจำกัดแล้ว เราจึงพล็อตเมตริกการประเมินต่างๆ สำหรับโมเดลในชุดทดสอบ
scores_constrained_test = model_constrained.predict(text_test)
eval_result_constrained = evaluate_results(
labels_test, scores_constrained_test, groups_test, group_names)
WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> INFO:tensorflow:ExampleCount post export metric: could not find any of the standard keys in predictions_dict (keys were: dict_keys(['prediction'])) INFO:tensorflow:ExampleCount post export metric: could not find any of the standard keys in predictions_dict (keys were: dict_keys(['prediction'])) INFO:tensorflow:Using the first key from predictions_dict: prediction INFO:tensorflow:Using the first key from predictions_dict: prediction WARNING:apache_beam.io.filebasedsink:Deleting 1 existing files in target path matching: WARNING:apache_beam.io.filebasedsink:Deleting 1 existing files in target path matching: WARNING:apache_beam.io.filebasedsink:Deleting 1 existing files in target path matching:
เช่นเดียวกับครั้งที่แล้ว อย่าลืมเลือก false_positive_rate
plot_fairness_indicators(eval_result_constrained, "Constrained")
multi_results = {
'constrained':eval_result_constrained,
'unconstrained':eval_result_unconstrained,
}
plot_multi_fairness_indicators(multi_eval_results=multi_results)
ดังที่เราเห็นได้จากตัวบ่งชี้ความเป็นธรรม เมื่อเทียบกับแบบจำลองที่ไม่มีข้อจำกัด โมเดลที่มีข้อจำกัดจะให้อัตราผลบวกที่ผิดพลาดที่ต่ำกว่าอย่างมีนัยสำคัญสำหรับความคิดเห็นเกี่ยวกับเรื่องเพศ และทำได้โดยลดลงเพียงเล็กน้อยในความแม่นยำโดยรวม