Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[MXNET-978] n-th order gradient test support. #15611

Merged

Conversation

kshitij12345
Copy link
Contributor

@kshitij12345 kshitij12345 commented Jul 19, 2019

Description

n-th order gradient test support function.

Checklist

Essentials

Please feel free to remove inapplicable items for your PR.

  • The PR title starts with [MXNET-$JIRA_ID], where $JIRA_ID refers to the relevant JIRA issue created (except PRs with tiny changes)
  • Changes are complete (i.e. I finished coding on this PR)
  • All changes have test coverage:
  • Unit tests are added for small changes to verify correctness (e.g. adding a new operator)
  • Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)
  • Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)
  • Code is well-documented:
  • For user-facing API changes, API doc string has been updated.
  • For new C++ functions in header files, their functionalities and arguments are documented.
  • For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable
  • Check the API doc at http://mxnet-ci-doc.s3-accelerate.dualstack.amazonaws.com/PR-$PR_ID/$BUILD_ID/index.html
  • To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change

Changes

  • Support test for n-th order.

@kshitij12345
Copy link
Contributor Author

kshitij12345 commented Jul 19, 2019

@apeforest @larroy

While working on a PR (I don't exactly remember which one), test for incorrect implementation of second order gradient was passing due to the very small values. However as sanity check, when I checked for its third order gradient, the assertion failed allowing to catch the issue.

So I think it would be better to check for the order being implemented and one more (computed by autograd) as a sanity check.

Would like to know your thoughts about the same.

Thank You.

@marcoabreu marcoabreu added the pr-work-in-progress PR is still work in progress label Jul 19, 2019
Copy link
Contributor

@larroy larroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice approach.

head_grad = nd.random.normal(shape=x.shape)
y = autograd.grad(heads=y, variables=x, head_grads=head_grad,
create_graph=True, retain_graph=True)[0]
if current_order in orders:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If current_order is not in orders we might have problem zipping? Is there a case where you wou want 1st and 3rd order but not second?

Copy link
Contributor Author

@kshitij12345 kshitij12345 Jul 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there would be an issue in that case (will confirm it later though).
If current_order is not in orders case is checked here,
https://github.com/apache/incubator-mxnet/blob/1f74614391e182e299e2fdcce1036515c4e5fb4f/tests/python/unittest/test_higher_order_grad.py#L41-L42
where first order is not asserted (as per the arguments).

The main thing is that elements in orders should be monotonically increasing and they should correspond to elements of the grad_ops.
We can also use a dictionary {order: corresponding grad op, ... } which removes the above requirement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have confirmed, that

check_nth_order_unary(array, sin, [grad_op, grad_grad_grad_op], [1, 3])

following works.

assert_almost_equal(expected_grad_grad, x.grad.asnumpy())
for current_order in range(1, order+1):
head_grad = nd.random.normal(shape=x.shape)
y = autograd.grad(heads=y, variables=x, head_grads=head_grad,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better name instead of mutating y?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option I can think of is, at the start of for loop we'll have computed_grad = y (which is deceiving) and replace y by computed_grad in the for loop.
Up for suggestions.

check_nth_order_unary(x, op, grad_grad_op, 2)


def check_nth_order_unary(x, op, grad_ops, orders):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add docstring?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the docstring. Could you please take a look to see if it needs more polishing.
Thank You.

Copy link
Contributor

@larroy larroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kshitij12345 kshitij12345 changed the title [MXNET-978] n-th order gradient test support [MXNET-978] n-th order gradient test support. Jul 26, 2019
Copy link
Contributor

@apeforest apeforest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

# Manual head_grads.
y_grad = nd.random.normal(shape=x.shape)
head_grad_grads = nd.random.normal(shape=x.shape)
order = max(orders)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If orders is monotonically increasing, should this just be orders[-1]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That will work as well. But I felt max(orders) stated the intent more clearly.

@apeforest
Copy link
Contributor

Ping @sxjscience for review.

@apeforest apeforest added pr-awaiting-review PR is waiting for code review and removed pr-work-in-progress PR is still work in progress labels Sep 14, 2019
@kshitij12345
Copy link
Contributor Author

@sxjscience Gentle ping for review:)

@apeforest apeforest merged commit 3950a47 into apache:master Sep 28, 2019
larroy pushed a commit to larroy/mxnet that referenced this pull request Sep 28, 2019
* n-th order grad test support

* use check_nth_order_unary for second order check

* add docstring to check_nth_order_unary

* retrigger CI

* add assertions for requirements of orders

* fix assert condition

* retrigger CI
sojiadeshina pushed a commit to sojiadeshina/incubator-mxnet that referenced this pull request Sep 30, 2019
* n-th order grad test support

* use check_nth_order_unary for second order check

* add docstring to check_nth_order_unary

* retrigger CI

* add assertions for requirements of orders

* fix assert condition

* retrigger CI
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pr-awaiting-review PR is waiting for code review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants