Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upPredictor.get_gradients fails when an embedding sets trainable = False #3679
Comments
|
You need to be sure that you actually have labels. Do your test instances have labels in them? Our demos use the If your instances have labels, this should work, because this is the same predictor that we're using for our demo. As a sanity check, you could see if you can get your code to work with our demo model: https://github.com/allenai/allennlp-demo/blob/9580a2d97911e794c7a936262bba4dc41b30bbcf/models.json#L95-L99. If it works, and you're sure that your instances have labels, then my next guess is that the predictor's I'm also not sure what batching is available for any of this. It might work, but I'm not sure - I only ever used it in our demo, one instance at a time. If you run into issues with batching things, let us know. |
|
Hi @matt-gardner. I tried all of your code modification suggestions, including manually turning my validation instances into JSON and trying predictions that way. The gradient dictionary is always empty! My succinct test: archive = load_archive(model_path)
predictor = Predictor.from_archive(archive, 'text_classifier')
validation_instances = predictor._dataset_reader.read('/.../datasets/SST/test.txt')
test_instance = validation_instances[0]
print(test_instance)
# Instance with fields:
# tokens: TextField of length 21 with text:
# [If, you, sometimes, like, to, go, to, the, movies, to, have, fun, ,, Wasabi, is, a, good, place,
# to, start, .]
# and TokenIndexers : {'tokens': 'SingleIdTokenIndexer'}
# label: LabelField with label: 1 in namespace: 'labels'.'
prediction = predictor.predict_instance(instance)
# {'probs': [0.56487637758255, 0.43512362241744995], 'loss': 0.5711482763290405, 'label': '0'}
predicted_labeled_instance = predictor.predictions_to_labeled_instances(test_instance, prediction)
print(predicted_labeled_instance)
# Instance with fields:
# tokens: TextField of length 21 with text:
# [If, you, sometimes, like, to, go, to, the, movies, to, have, fun, ,, Wasabi, is, a, good, place,
# to, start, .]
# and TokenIndexers : {'tokens': 'SingleIdTokenIndexer'}
# label: LabelField with label: 0 in namespace: 'labels'.'
gradients, outputs = predictor.get_gradients(predicted_labeled_instance)
print(gradients)
# {}
print(outputs)
# {'probs': tensor([[0.5649, 0.4351]], grad_fn=<CatBackward>), 'loss': tensor(0.5711, grad_fn=<BinaryCrossEntropyWithLogitsBackward>), 'label': ['0']} |
|
I put some print statements in |
|
Can you confirm that you can get this to work locally with our demo model? |
|
@matt-gardner I ran the demo sentiment classifier locally and found my problem. Setting I had copied the format of the embedding configuration from the paper prediction tutorial without realizing the ramifications. Hopefully if anyone else has this problem they can learn from my mistake. Thank you for your help! |
|
Huh, we should ideally be robust to that setting, as we typically only get gradients like this after a model is trained, anyway, when all of the parameters are "frozen". I'm going to re-open this and rename it. I have higher-priority stuff to work on for the next while, but I'll label this as contributions welcome in case anyone wants to pick it up. This issue should give a pretty easy minimal test case - just create a small embedding layer with I believe a potential solution here would be to just force all parameters to require gradients at the top of |
Describe the bug
Calling Predictor.get_gradients() returns an empty dictionary
To Reproduce
I am replicating the binary sentiment classification tasked described in the paper 'Attention is not Explanation ' (Jain and Wallace 2019 - https://arxiv.org/pdf/1902.10186.pdf).
My first experiment is on the Stanford Sentiment TreeBank Dataset. I need to measure the correlation between the attention weights and the gradients of the loss with respect to the model inputs. I define the following experiment file:
{ "dataset_reader": { "type": "sst_tokens", "granularity": "2-class" }, "train_data_path": std.join("/", [std.extVar("PWD"), "ane_research/datasets/SST/train.txt"]), "validation_data_path": std.join("/", [std.extVar("PWD"), "ane_research/datasets/SST/dev.txt"]), "test_data_path": std.join("/", [std.extVar("PWD"), "ane_research/datasets/SST/test.txt"]), "model": { "type": "jain_wallace_attention_binary_classifier", "word_embeddings": { "token_embedders": { "tokens": { "type": "embedding", "pretrained_file": "https://dl.fbaipublicfiles.com/fasttext/vectors-english/wiki-news-300d-1M.vec.zip", "embedding_dim": 300, "trainable": false } } }, "encoder": { "type": "lstm", "bidirectional": true, "input_size": 300, "hidden_size": 128, "num_layers": 1, }, "decoder": { "input_dim": 256, "num_layers": 1, "hidden_dims": 1, "activations": ["linear"] } }, "iterator": { "type": "bucket", "sorting_keys": [['tokens', 'num_tokens']], "batch_size": 64 }, "trainer": { "num_epochs": 40, "patience": 10, "cuda_device": -1, "validation_metric": "+auc", "optimizer": { "type": "adam", "weight_decay": 1e-5, "amsgrad": true } } }And the following model:
Once the model has trained, I attempt to extract the gradients using a predictor:
Expected behavior
Gradient dictionary contains gradients of the loss with respect to the input tokens
System (please complete the following information):
Additional context
As per Jain and Wallace, I use the pretrained fasttext embeddings. Attention is computed via the 'Additive variant' (tanh).