Using NLPExplainer¶
NLPExplainer is the simplest way to create explanations from your text model and data. It supports Huggingface, PyTorch, Tensorflow, and Keras models. Import the NLPExplainer with:
from truera.client.nn.explain import NLPExplainer
Quickstarts¶
The simplest way to use the NLPExplainer is to pass your model, tokenizer, and other set_model()
arguments into the NLPExplainer constructor. See the examples below using HuggingFace (PyTorch) and Tensorflow models.
Huggingface (PyTorch)¶
Huggingface models are supported right out of the box. Just pass in the model and tokenizer to the NLPExplainer constructor. We can pass the model and tokenizer into the NLPExplainer constructor and call NLPExplainer.explain()
to retrieve explanations in the form of a pandas DataFrame.
import transformers
tokenizer = transformers.DistilBertTokenizerFast.from_pretrained("distilbert-base-uncased")
model = transformers.DistilBertForSequenceClassification.from_pretrained(
"distilbert-base-uncased-finetuned-sst-2-english"
)
explainer = NLPExplainer(model=model, tokenizer=tokenizer)
explanation = explainer.explain("I love this movie!")
Tensorflow 2¶
import tensorflow as tf
import tensorflow_text
import tensorflow_hub as hub
Here, we define a BERT-style Tensorflow 2 model and Tokenizer using Tensorflow Hub and Keras.
def get_bert_model(n_classes: int = 2):
text_input = tf.keras.layers.Input(shape=(), dtype=tf.string)
preprocessor = hub.KerasLayer(
"https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3")
encoder_inputs = preprocessor(text_input)
encoder = hub.KerasLayer(
"https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/2",
trainable=True)
pooled_output = encoder(encoder_inputs)["pooled_output"] # [batch_size, 512].
output = tf.keras.layers.Dense(n_classes)(pooled_output)
softmax = tf.keras.layers.Softmax(axis=-1)(output)
return tf.keras.Model(text_input, softmax)
def get_bert_tokenizer():
text_input = tf.keras.layers.Input(shape=(), dtype=tf.string)
preprocessor = hub.KerasLayer(
"https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3")
tokenizer_output = preprocessor(text_input)
return tf.keras.Model(text_input, tokenizer_output)
tf_bert = get_bert_model()
tf_bert_tokenizer = get_bert_tokenizer()
Wrapping the model in trulens.nn.models.get_model_wrapper()
and calling print_layer_names()
lists all referenceable operations that can be used to configure the NLPExplainer.
from trulens.nn.models import get_model_wrapper
w = get_model_wrapper(tf_bert)
w.print_layer_names()
Ingesting this model requires providing the model, tokenizer, the word embedding layer, and sequence length parameters to the NLPExplainer.
To find out what the required parameters are for your use case, see Debugging NLPExplainer
from truera.client.nn.explain import NLPExplainer
explainer = NLPExplainer()
explainer.set_model(
model=tf_bert,
tokenizer=tf_bert_tokenizer,
token_embeddings_layer="keras_layer_1/bert_encoder/word_embeddings",
n_tokens=512
)
explanation = explainer.explain("I love this movie!")
Debugging NLPExplainer¶
The NLPExplainer is compatible across some of the most popular NLP architectures, frameworks, and implementations. Where possible, NLPExplainer will attempt to infer argument values from other user inputs to simplify the ingestion process. When the inference fails, the NLPExplainer provides tips on how to best resolve issues.
from truera.client.nn.explain import NLPExplainer
explainer = NLPExplainer(
model=tf_bert,
tokenizer=tf_bert_tokenizer,
n_tokens=512
)
Running the quickstart above without the token_embeddings_layer
attribute will throw the following error due to missing parameters.
TypeError: Failed all `set_model` definitions. Given arguments:
args=(,)
kwargs=
model: str
FAILURE: Exception .../truera/client/nn/wrappers/infer.py:186:hook:raise Exception(f"Could not infer optional arguments.")
Could not infer optional arguments. File ".../truera/client/util/overload.py", line 353, in __call__
bindings = sig_bind(
File ".../truera/client/util/overload.py", line 198, in sig_bind
acc, bindings = hook(acc=acc, func=func, sig=sig, bindings=bindings)
File ".../truera/client/nn/wrappers/infer.py", line 186, in hook
raise Exception(f"Could not infer optional arguments.")
❌ P(token_embeddings_layer:str)
.../truera/client/nn/wrappers/psys.py:1658: failed ❌
WARNING: optional parameter P(text_to_spans:Function) could not be inferred. Will use default value `None`.
🚨 NOTE: You may be able to resolve some of these issues by adding the following arguments to set_model(). Replace the sample values your own:
from truera.client.nn.explain import NLPExplainer
e = NLPExplainer()
# Define missing sample arguments used in set_model
# token_embeddings_layer represents the name of the layer where token embeddings are computed
token_embeddings_layer = 'embedding' # TODO: Replace me
# Call set_model
e.set_model(token_embeddings_layer=token_embeddings_layer)
The code below provides additional context around what missing information needs to be provided and how it should be added to the NLPExplainer.
To resolve the error, add token_embeddings_layer
to the function call.
from truera.client.nn.explain import NLPExplainer
explainer = NLPExplainer()
explainer.set_model(
model=tf_bert,
tokenizer=tf_bert_tokenizer,
n_tokens=512,
token_embeddings_layer="keras_layer_1/bert_encoder/word_embeddings"
)
Callable Methods¶
For advanced configuration, NLPExplainer has four primary methods:
You can learn about each method through their __doc__
attribute.
print(NLPExplainer.set_model.__doc__)
Method: set_model()
¶
Used to specify a model and related model arguments used for generating explanations.
Common Arguments
Name | Required | Type | Description | Default |
---|---|---|---|---|
model | ✅ | Varies (see signatures below) | The model object to explain | |
tokenizer | ✅ | Varies (see signatures below) | The tokenizer object | |
model_name | str |
The model name for a managed truera workspace. | ||
token_embeddings_layer | str |
The model layer where token embeddings are computed. | ||
token_embeddings_anchor | str |
The side of token_embeddings_layer where token embeddings are computed. Must be either out or in . |
out |
|
output_layer | str |
The model layer from which a quantity of interest is defined. | ||
output_anchor | str |
The side of output_layer where the output is calculated. Must be either out or in . |
out |
|
n_output_neurons | int |
Number of neurons in the output layer. | ||
n_embeddings | int |
The number of dimensions in a token embedding vector. | ||
n_tokens | int |
The number of tokens accepted by a model. | ||
score_type | str |
The score type for your model. Must be one of (probits , logits , regression , classification ). |
probits |
|
classification_threshold | float |
Threshold for binary classifiers. Must be between [0, 1] | .5 | |
vocab | dict[str, int] |
A mapping of tokens (str) to token IDs (int). This may be inferrable from some tokenizers. | ||
unk_token_id | int |
The ID of the token used to represent unknown/out of vocabulary tokenizations. | ||
pad_token_id | int |
The ID of the padding token. | ||
special_tokens | list[int] |
A list of 'special' tokens that should not be considered when computing influences. This may include, PAD, SOS, EOS, UNK, etc. |
Valid Signatures
This method is an overloaded function with multiple valid signatures, depending on which framework is being used.
Wrap a HuggingFace Torch model
NLPExplainer.set_model(
model,
tokenizer,
token_embeddings_layer: str,
token_embeddings_anchor: LayerAnchor,
output_layer: str,
output_anchor: LayerAnchor,
n_output_neurons: int,
n_embeddings: int,
n_tokens: int,
model_name: str,
vocab: Dict,
unk_token_id: int,
pad_token_id: int,
special_tokens: List,
get_model: Function,
eval_model: Function,
text_to_inputs: Function,
text_to_token_ids: Function,
text_to_spans: Function,
score_Type: str,
classification_threshold: float
) -> str
Wrap a PyTorch Module
NLPExplainer.set_model(
model: Module,
tokenizer,
token_embeddings_layer: str,
token_embeddings_anchor: Union[LayerAnchor, str],
output_layer: str,
output_anchor: Union[LayerAnchor, str],
n_output_neurons: int,
n_embeddings: int,
n_tokens: int,
model_name: str,
vocab: Dict,
unk_token_id: int,
pad_token_id: int,
special_tokens: List,
get_model: Function,
eval_model: Function,
text_to_inputs: Function,
text_to_token_ids: Function,
text_to_spans: Function,
score_Type: str,
classification_threshold: float
) -> str
Wrap a Tensorflow 2 Model
NLPExplainer.set_model(
model,
tokenizer,
vocab: Dict,
unk_token: int,
pad_token: int,
text_to_inputs: Function,
text_to_token_ids: Function,
text_to_spans: Function,
get_model: Function,
eval_model: Function,
special_tokens: List,
token_embeddings_layer: str,
token_embeddings_anchor: Union[LayerAnchor, str],
output_layer: str,
output_anchor: Union[LayerAnchor, str],
n_output_neurons: int,
model_name: str,
n_embeddings: int,
n_tokens: int,
score_Type: str
) -> str
Method: set_data()
¶
Specify data to be explained.
Common Arguments
Name | Required | Type | Description | Default |
---|---|---|---|---|
data_split_name | str |
Data split name for managed truera workspace. | ||
data | ✅ | Varies (see signatures below) | Source of data. Additional arguments may be necessary. | |
label/label_field | Varies (see signatures below) | Source of labels (if not part of data ) |
||
metadata | Varies (see signatures below) | Source of metadata (if any) |
Valid Signatures
Load a single string
NLPExplainer.set_data(
data: str,
label: int,
data_split_name: str
) -> str
Load instances from a pandas DataFrame — the given DataFrame must contain text inputs; labels are optional.
NLPExplainer.set_data(
data: pd.DataFrame,
text_field: str,
label_field: str,
meta_fields: Sequence,
data_split_name: str
) -> str
Load instances from a PyTorch DataLoader — assumes wrapped dataset is a mapping from column names to iterables of text and labels.
NLPExplainer.set_data(
data: torch.utils.data.DataLoader,
text_field: str,
label_field: str,
meta_fields: Sequence,
data_split_name: str
) -> str
Load instances from an Iterable
NLPExplainer.set_data(
data: Sequence,
labels: Sequence,
metadata: DataFrame,
data_split_name: str
) -> str
Load instances from a lazy Iterable (e.g., Generators)
NLPExplainer.set_data(
data: Iterable,
labels: Iterable,
metadata: DataFrame,
data_split_name: str
) -> str
Method: config()
¶
Set explanation parameters, controlling its quality, among other options.
Arguments
Name | Required | Type | Description | Default |
---|---|---|---|---|
rebatch_size | int |
The number of instances to send to a model at once. May result in out-of-memory error if set too large. | ||
ref_token | str |
A semantically 'neutral' token used for generating baselines for influences. | ||
resolution | int |
Baseline-to-instance interpolation resolution. Higher produces more accurate influences, but takes longer to compute. | 16 |
|
n_metrics_records | int |
The number of records in the metrics dataset. | 128 |
|
use_training_mode | bool |
Use training mode when computing gradients. | False |
Method: explain()
¶
Produce an explanation. The data to explain must be specified via data kwarg or by a prior set_data()
call.
Arguments
Name | Required | Type | Description | Default |
---|---|---|---|---|
data | One of str , list[str] , pd.DataFrame |
Data to explain. Can also be provided via a prior call to set_data . |
None |
|
token_type | str |
Determines the level of granularity for the explanations computed. Can be "token" or "word". | word |
|
verify | bool |
If True, runs validation on provided arguments. | True |
Returns pd.DataFrame
— a pandas DataFrame consisting of explanations for each token along with additional record information.