![]() | ![]() | ![]() | ![]() | ![]() |
SNGP eğitiminde , belirsizliğini ölçme yeteneğini geliştirmek için derin bir artık ağın üzerine SNGP modelinin nasıl oluşturulacağını öğrendiniz. Bu öğreticide, derin NLU modelinin kapsam dışı sorguları algılama yeteneğini geliştirmek için derin bir BERT kodlayıcının üzerine kurarak SNGP'yi bir doğal dil anlama (NLU) görevine uygulayacaksınız.
Özellikle, şunları yapacaksınız:
- SNGP ile güçlendirilmiş bir BERT modeli olan BERT-SNGP'yi oluşturun.
- CLINC Kapsam Dışı (OOS) amaç algılama veri kümesini yükleyin.
- BERT-SNGP modelini eğitin.
- Belirsizlik kalibrasyonu ve alan dışı algılamada BERT-SNGP modelinin performansını değerlendirin.
CLINC OOS'un ötesinde, SNGP modeli Jigsaw toksisite tespiti gibi büyük ölçekli veri kümelerine ve CIFAR-100 ve ImageNet gibi görüntü veri kümelerine uygulanmıştır. SNGP ve diğer belirsizlik yöntemlerinin kıyaslama sonuçları ve ayrıca uçtan uca eğitim / değerlendirme komut dosyalarıyla yüksek kaliteli uygulama için Belirsizlik Temel Çizgileri karşılaştırmasına göz atabilirsiniz.
Kurmak
pip uninstall -y tensorflow tf-text
pip install -U tensorflow-text-nightly
pip install -U tf-nightly
pip install -U tf-models-nightly
import matplotlib.pyplot as plt
import sklearn.metrics
import sklearn.calibration
import tensorflow_hub as hub
import tensorflow_datasets as tfds
import numpy as np
import tensorflow as tf
import official.nlp.modeling.layers as layers
import official.nlp.optimization as optimization
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_addons/utils/ensure_tf_install.py:43: UserWarning: You are currently using a nightly version of TensorFlow (2.9.0-dev20220203). TensorFlow Addons offers no support for the nightly versions of TensorFlow. Some things might work, some other might not. If you encounter a bug, do not file an issue on GitHub. UserWarning,
Bu öğreticinin verimli çalışması için GPU'ya ihtiyacı vardır. GPU'nun kullanılabilir olup olmadığını kontrol edin.
tf.__version__
'2.9.0-dev20220203'
gpus = tf.config.list_physical_devices('GPU')
gpus
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
assert gpus, """
No GPU(s) found! This tutorial will take many hours to run without a GPU.
You may hit this error if the installed tensorflow package is not
compatible with the CUDA and CUDNN versions."""
İlk önce , BERT öğreticisi ile sınıflandırma metnini izleyerek standart bir BERT sınıflandırıcı uygulayın. BERT tabanlı kodlayıcıyı ve sınıflandırıcı olarak yerleşik ClassificationHead
kullanacağız.
Standart BERT modeli
PREPROCESS_HANDLE = 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3'
MODEL_HANDLE = 'https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3'
class BertClassifier(tf.keras.Model):
def __init__(self,
num_classes=150, inner_dim=768, dropout_rate=0.1,
**classifier_kwargs):
super().__init__()
self.classifier_kwargs = classifier_kwargs
# Initiate the BERT encoder components.
self.bert_preprocessor = hub.KerasLayer(PREPROCESS_HANDLE, name='preprocessing')
self.bert_hidden_layer = hub.KerasLayer(MODEL_HANDLE, trainable=True, name='bert_encoder')
# Defines the encoder and classification layers.
self.bert_encoder = self.make_bert_encoder()
self.classifier = self.make_classification_head(num_classes, inner_dim, dropout_rate)
def make_bert_encoder(self):
text_inputs = tf.keras.layers.Input(shape=(), dtype=tf.string, name='text')
encoder_inputs = self.bert_preprocessor(text_inputs)
encoder_outputs = self.bert_hidden_layer(encoder_inputs)
return tf.keras.Model(text_inputs, encoder_outputs)
def make_classification_head(self, num_classes, inner_dim, dropout_rate):
return layers.ClassificationHead(
num_classes=num_classes,
inner_dim=inner_dim,
dropout_rate=dropout_rate,
**self.classifier_kwargs)
def call(self, inputs, **kwargs):
encoder_outputs = self.bert_encoder(inputs)
classifier_inputs = encoder_outputs['sequence_output']
return self.classifier(classifier_inputs, **kwargs)
SNGP modeli oluşturun
Bir BERT-SNGP modelini uygulamak için ClassificationHead
yerleşik GaussianProcessClassificationHead
ile değiştirmeniz yeterlidir. Spektral normalizasyon zaten bu sınıflandırma başlığında önceden paketlenmiştir. SNGP eğitiminde olduğu gibi, modele bir kovaryans sıfırlama geri çağrısı ekleyin, böylece aynı verileri iki kez saymaktan kaçınmak için model yeni bir çağın başlangıcında kovaryans tahmin edicisini otomatik olarak sıfırlar.
class ResetCovarianceCallback(tf.keras.callbacks.Callback):
def on_epoch_begin(self, epoch, logs=None):
"""Resets covariance matrix at the begining of the epoch."""
if epoch > 0:
self.model.classifier.reset_covariance_matrix()
tutucu17 l10n-yerclass SNGPBertClassifier(BertClassifier):
def make_classification_head(self, num_classes, inner_dim, dropout_rate):
return layers.GaussianProcessClassificationHead(
num_classes=num_classes,
inner_dim=inner_dim,
dropout_rate=dropout_rate,
gp_cov_momentum=-1,
temperature=30.,
**self.classifier_kwargs)
def fit(self, *args, **kwargs):
"""Adds ResetCovarianceCallback to model callbacks."""
kwargs['callbacks'] = list(kwargs.get('callbacks', []))
kwargs['callbacks'].append(ResetCovarianceCallback())
return super().fit(*args, **kwargs)
CLINC OOS veri setini yükle
Şimdi CLINC OOS amaç algılama veri setini yükleyin. Bu veri seti, 150'den fazla amaç sınıfından toplanan 15000 kullanıcının sözlü sorgusunu içerir, ayrıca bilinen sınıfların hiçbirinde kapsanmayan 1000 alan dışı (OOD) cümle içerir.
(clinc_train, clinc_test, clinc_test_oos), ds_info = tfds.load(
'clinc_oos', split=['train', 'test', 'test_oos'], with_info=True, batch_size=-1)
Treni yapın ve verileri test edin.
train_examples = clinc_train['text']
train_labels = clinc_train['intent']
# Makes the in-domain (IND) evaluation data.
ind_eval_data = (clinc_test['text'], clinc_test['intent'])
Bir OOD değerlendirme veri seti oluşturun. Bunun için, alan içi test verilerini clinc_test
ve alan dışı verileri clinc_test_oos
. Ayrıca, alan içi örneklere 0 etiketi ve alan dışı örneklere 1 etiketi atayacağız.
test_data_size = ds_info.splits['test'].num_examples
oos_data_size = ds_info.splits['test_oos'].num_examples
# Combines the in-domain and out-of-domain test examples.
oos_texts = tf.concat([clinc_test['text'], clinc_test_oos['text']], axis=0)
oos_labels = tf.constant([0] * test_data_size + [1] * oos_data_size)
# Converts into a TF dataset.
ood_eval_dataset = tf.data.Dataset.from_tensor_slices(
{"text": oos_texts, "label": oos_labels})
Eğitin ve değerlendirin
İlk önce temel eğitim yapılandırmalarını ayarlayın.
TRAIN_EPOCHS = 3
TRAIN_BATCH_SIZE = 32
EVAL_BATCH_SIZE = 256
def bert_optimizer(learning_rate,
batch_size=TRAIN_BATCH_SIZE, epochs=TRAIN_EPOCHS,
warmup_rate=0.1):
"""Creates an AdamWeightDecay optimizer with learning rate schedule."""
train_data_size = ds_info.splits['train'].num_examples
steps_per_epoch = int(train_data_size / batch_size)
num_train_steps = steps_per_epoch * epochs
num_warmup_steps = int(warmup_rate * num_train_steps)
# Creates learning schedule.
lr_schedule = tf.keras.optimizers.schedules.PolynomialDecay(
initial_learning_rate=learning_rate,
decay_steps=num_train_steps,
end_learning_rate=0.0)
return optimization.AdamWeightDecay(
learning_rate=lr_schedule,
weight_decay_rate=0.01,
epsilon=1e-6,
exclude_from_weight_decay=['LayerNorm', 'layer_norm', 'bias'])
optimizer = bert_optimizer(learning_rate=1e-4)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metrics = tf.metrics.SparseCategoricalAccuracy()
fit_configs = dict(batch_size=TRAIN_BATCH_SIZE,
epochs=TRAIN_EPOCHS,
validation_batch_size=EVAL_BATCH_SIZE,
validation_data=ind_eval_data)
yer tutucu25 l10n-yersngp_model = SNGPBertClassifier()
sngp_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
sngp_model.fit(train_examples, train_labels, **fit_configs)
Epoch 1/3 469/469 [==============================] - 219s 427ms/step - loss: 1.0725 - sparse_categorical_accuracy: 0.7870 - val_loss: 0.4358 - val_sparse_categorical_accuracy: 0.9380 Epoch 2/3 469/469 [==============================] - 198s 422ms/step - loss: 0.0885 - sparse_categorical_accuracy: 0.9797 - val_loss: 0.2424 - val_sparse_categorical_accuracy: 0.9518 Epoch 3/3 469/469 [==============================] - 199s 424ms/step - loss: 0.0259 - sparse_categorical_accuracy: 0.9951 - val_loss: 0.1927 - val_sparse_categorical_accuracy: 0.9642 <keras.callbacks.History at 0x7fe24c0a7090>
OOD performansını değerlendirin
Modelin tanıdık olmayan alan dışı sorguları ne kadar iyi algılayabildiğini değerlendirin. Kesin değerlendirme için, daha önce oluşturulmuş OOD değerlendirme veri kümesi ood_eval_dataset
kullanın.
def oos_predict(model, ood_eval_dataset, **model_kwargs):
oos_labels = []
oos_probs = []
ood_eval_dataset = ood_eval_dataset.batch(EVAL_BATCH_SIZE)
for oos_batch in ood_eval_dataset:
oos_text_batch = oos_batch["text"]
oos_label_batch = oos_batch["label"]
pred_logits = model(oos_text_batch, **model_kwargs)
pred_probs_all = tf.nn.softmax(pred_logits, axis=-1)
pred_probs = tf.reduce_max(pred_probs_all, axis=-1)
oos_labels.append(oos_label_batch)
oos_probs.append(pred_probs)
oos_probs = tf.concat(oos_probs, axis=0)
oos_labels = tf.concat(oos_labels, axis=0)
return oos_probs, oos_labels
OOD olasılıklarını \(1 - p(x)\)olarak hesaplar, burada \(p(x)=softmax(logit(x))\) tahmine dayalı olasılıktır.
sngp_probs, ood_labels = oos_predict(sngp_model, ood_eval_dataset)
tutucu29 l10n-yerood_probs = 1 - sngp_probs
Şimdi modelin belirsizlik puanının ood_probs
alan dışı etiketi ne kadar iyi tahmin ettiğini değerlendirin. İlk önce, OOD olasılığına karşı OOD algılama doğruluğu için hassas geri çağırma eğrisi (AURPC) altındaki Alanı hesaplayın.
precision, recall, _ = sklearn.metrics.precision_recall_curve(ood_labels, ood_probs)
auprc = sklearn.metrics.auc(recall, precision)
print(f'SNGP AUPRC: {auprc:.4f}')
-yer tutucu32 l10n-yerSNGP AUPRC: 0.9039
Bu, Belirsizlik Temel Çizgileri altında CLINC OOS karşılaştırmasında rapor edilen SNGP performansıyla eşleşir.
Ardından, belirsizlik kalibrasyonunda modelin kalitesini inceleyin, yani modelin tahmine dayalı olasılığının tahmin doğruluğuna karşılık gelip gelmediğini. İyi kalibre edilmiş bir model güvenilir olarak kabul edilir, çünkü örneğin, \(p(x)=0.8\) tahmin olasılığı, modelin zamanın %80'inde doğru olduğu anlamına gelir.
prob_true, prob_pred = sklearn.calibration.calibration_curve(
ood_labels, ood_probs, n_bins=10, strategy='quantile')
tutucu34 l10n-yerplt.plot(prob_pred, prob_true)
plt.plot([0., 1.], [0., 1.], c='k', linestyle="--")
plt.xlabel('Predictive Probability')
plt.ylabel('Predictive Accuracy')
plt.title('Calibration Plots, SNGP')
plt.show()
Kaynaklar ve daha fazla okuma
- SNGP'yi sıfırdan uygulamaya ilişkin ayrıntılı bir adım için SNGP öğreticisine bakın.
- SNGP modelinin (ve diğer birçok belirsizlik yönteminin) çok çeşitli kıyaslama veri setlerinde (örneğin, CIFAR , ImageNet , Jigsaw toksisite tespiti vb.) uygulanması için Belirsizlik Temel Çizgilerine bakın.
- SNGP yöntemini daha iyi anlamak için, Mesafe Farkındalığı Yoluyla Deterministik Derin Öğrenme ile Basit ve İlkeli Belirsizlik Tahmini makalesine bakın.