-
Notifications
You must be signed in to change notification settings - Fork 476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update tutorials to use Layer IG #222
Conversation
99f8aef
to
b0487d9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just a few nits.
if ( | ||
(hook_inputs is None or len(hook_inputs) == 0) | ||
and (hook_outputs is None or len(hook_outputs) == 0) | ||
and len(list((module.parameters()))) == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It might be a little cleaner to either move this check into extract_device, since it already does some of these, or just check that returned device is not None and return an error?
return hook_inputs[0].device | ||
if hook_outputs is not None and len(hook_outputs) > 0: | ||
return hook_outputs[0].device | ||
return next(module.parameters()).device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Could add a check for length of module.parameters here, and either return None otherwise or raise the exception here itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the check into this function (haven't pushed the change yet). So, if we have the check on top of this function we don't need to check the length of module.parameters()
, do we ? Because otherwise the check will fail ?
(hook_inputs is None or len(hook_inputs) == 0) and (hook_outputs is None or len(hook_outputs) == 0) and len(list((module.parameters()))) == 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually len(list((module.parameters())))
is going to exhaust all elements - it is not the right way of checking the length - let me fix that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, yeah if you move the check you don't need to check length again! But I guess inputs and output checks are already there, so might be easier to just add the last check to the end, and just raise an exception if none of the return conditions hit as opposed to putting the full check above? But either way works!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also doesn't each separate call to module.parameters() return a new iterator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- For
module.parameters()
, it looks like it is creating a new iterator every time. Good point. But it's better to create it once in our case. - Yeah, I could have the last check on the parameters later but in that case, I'll need to raise new error with a new message and it is probably better to combine the checks in one place.
if hook_outputs is not None and len(hook_outputs) > 0: | ||
return hook_outputs[0].device | ||
return next(module.parameters()).device | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might also be helpful to make this a utility method in common to potentially be used by other layer methods? I think layer feature ablation could hit a similar problem, since it checks the device based on inputs, but it's possible inputs is None if attributing with respect to outputs.
@@ -79,8 +79,6 @@ | |||
"metadata": {}, | |||
"outputs": [], | |||
"source": [ | |||
"# replace <PATH-TO-SAVED-MODEL> with the real path of the saved model\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: did you intend to remove this instruction?
Addressed the comments! Thank you! |
6b0c6c5
to
6d1a48e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NarineK has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
Summary: 1. Updated tutorials for IMDB and Bert to use `LayerIntegratedGradients`. In case of Bert it uses LayerIG only for interpreting parent `BertEmbeddings` layer. 2. Added a fix for extracting devices in case inputs and/or outputs are missing. Currently it is checking three things: hook inputs, outputs and module.parameters() 3. In the case of Bert I was printing pandas styled DataFrame. In that case, it contained auto- generated ids for each html element. Now, I formatted it differently so that there is no ID in the HTML divs etc. Pull Request resolved: pytorch#222 Differential Revision: D19251959 Pulled By: NarineK fbshipit-source-id: e28ecb53a7bd5e71cc6c5df210729004da8f3a1e
LayerIntegratedGradients
. In case of Bert it usesLayerIG only for interpreting parent
BertEmbeddings
layer.Currently it is checking three things: hook inputs, outputs and module.parameters()
generated ids for each html element. Now, I formatted it differently so that there is no ID in the
HTML divs etc.