یادگیری عمیق زبان آگاه از عدم قطعیت با BERT-SNGP

مشاهده در TensorFlow.org در Google Colab اجرا شود در GitHub مشاهده کنید دانلود دفترچه یادداشت مدل TF Hub را ببینید

در آموزش SNGP ، یاد گرفتید که چگونه مدل SNGP را بر روی یک شبکه باقیمانده عمیق بسازید تا توانایی آن را در تعیین کمیت عدم قطعیت آن بهبود بخشد. در این آموزش، SNGP را با ساختن آن بر روی یک رمزگذار BERT عمیق برای بهبود توانایی مدل NLU عمیق در تشخیص پرس و جوهای خارج از محدوده، برای یک کار درک زبان طبیعی (NLU) اعمال خواهید کرد.

به طور خاص، شما:

  • BERT-SNGP، یک مدل BERT افزوده شده با SNGP را بسازید.
  • مجموعه داده تشخیص هدف CLINC خارج از محدوده (OOS) را بارگیری کنید.
  • مدل BERT-SNGP را آموزش دهید.
  • عملکرد مدل BERT-SNGP در کالیبراسیون عدم قطعیت و تشخیص خارج از دامنه را ارزیابی کنید.

فراتر از CLINC OOS، مدل SNGP برای مجموعه داده های مقیاس بزرگ مانند تشخیص سمیت Jigsaw و مجموعه داده های تصویر مانند CIFAR-100 و ImageNet اعمال شده است. برای نتایج معیار SNGP و سایر روش‌های عدم قطعیت، و همچنین اجرای با کیفیت بالا با اسکریپت‌های آموزشی/ارزیابی سرتاسر، می‌توانید معیار Uncertainty Baselines را بررسی کنید.

برپایی

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,

این آموزش برای اجرای کارآمد به GPU نیاز دارد. بررسی کنید که آیا GPU موجود است یا خیر.

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."""

ابتدا یک طبقه‌بندی استاندارد BERT را به دنبال متن طبقه‌بندی با آموزش BERT پیاده‌سازی کنید. ما از رمزگذار BERT-base و ClassificationHead داخلی به عنوان طبقه‌بندی کننده استفاده خواهیم کرد.

مدل استاندارد BERT

ساخت مدل SNGP

برای پیاده سازی یک مدل BERT-SNGP، فقط باید ClassificationHead را با GaussianProcessClassificationHead داخلی جایگزین کنید. نرمال سازی طیفی از قبل در این سر طبقه بندی بسته بندی شده است. مانند آموزش SNGP ، یک بازخوانی مجدد کوواریانس به مدل اضافه کنید، بنابراین مدل به طور خودکار تخمین‌گر کوواریانس را در ابتدای یک دوره جدید بازنشانی می‌کند تا از دوبار شمارش داده‌های مشابه جلوگیری شود.

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()
class 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 را بارگیری کنید

اکنون مجموعه داده تشخیص قصد CLINC OOS را بارگیری کنید. این مجموعه داده شامل 15000 پرسش گفتاری کاربر است که بیش از 150 کلاس هدف جمع آوری شده است، همچنین شامل 1000 جمله خارج از دامنه (OOD) است که توسط هیچ یک از کلاس های شناخته شده پوشش داده نمی شود.

(clinc_train, clinc_test, clinc_test_oos), ds_info = tfds.load(
    'clinc_oos', split=['train', 'test', 'test_oos'], with_info=True, batch_size=-1)

داده های قطار و آزمایش را بسازید.

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'])

یک مجموعه داده ارزیابی OOD ایجاد کنید. برای این کار، داده‌های تست درون دامنه‌ای clinc_test و داده‌های خارج از دامنه clinc_test_oos را ترکیب کنید. همچنین برچسب 0 را به نمونه های درون دامنه و برچسب 1 را به نمونه های خارج از دامنه اختصاص می دهیم.

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

آموزش دهید و ارزیابی کنید

ابتدا تنظیمات اولیه آموزش را تنظیم کنید.

TRAIN_EPOCHS = 3
TRAIN_BATCH_SIZE = 32
EVAL_BATCH_SIZE = 256

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)
sngp_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 را ارزیابی کنید

ارزیابی کنید که مدل چقدر می تواند پرس و جوهای خارج از دامنه ناآشنا را تشخیص دهد. برای ارزیابی دقیق، از مجموعه داده ارزیابی OOD ood_eval_dataset ساخته شده قبلی استفاده کنید.

احتمالات OOD را به عنوان \(1 - p(x)\)محاسبه می کند، که در آن \(p(x)=softmax(logit(x))\) احتمال پیش بینی است.

sngp_probs, ood_labels = oos_predict(sngp_model, ood_eval_dataset)
ood_probs = 1 - sngp_probs

حال ارزیابی کنید که نمره عدم قطعیت مدل ood_probs چقدر خوب برچسب خارج از دامنه را پیش بینی می کند. ابتدا ناحیه تحت منحنی فراخوان دقیق (AUPRC) را برای احتمال OOD در مقابل دقت تشخیص OOD محاسبه کنید.

precision, recall, _ = sklearn.metrics.precision_recall_curve(ood_labels, ood_probs)
auprc = sklearn.metrics.auc(recall, precision)
print(f'SNGP AUPRC: {auprc:.4f}')
SNGP AUPRC: 0.9039

این با عملکرد SNGP گزارش شده در معیار CLINC OOS تحت خطوط پایه عدم قطعیت مطابقت دارد.

سپس، کیفیت مدل را در کالیبراسیون عدم قطعیت بررسی کنید، یعنی اینکه آیا احتمال پیش‌بینی مدل با دقت پیش‌بینی آن مطابقت دارد یا خیر. یک مدل خوب کالیبره شده قابل اعتماد در نظر گرفته می شود، زیرا، برای مثال، احتمال پیش بینی آن \(p(x)=0.8\) به این معنی است که مدل در 80٪ مواقع درست است.

prob_true, prob_pred = sklearn.calibration.calibration_curve(
    ood_labels, ood_probs, n_bins=10, strategy='quantile')
plt.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()

png

منابع و مطالعه بیشتر