-
Notifications
You must be signed in to change notification settings - Fork 616
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
Fix PrepSelPrep
differentiability with parameter-shift
#6423
Conversation
Hello. You may have forgotten to update the changelog!
|
PrepSelPrep
differentiability with parameter-shift
PrepSelPrep
differentiability with parameter-shift
PrepSelPrep
differentiability with parameter-shift
PrepSelPrep
differentiability with parameter-shift
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6423 +/- ##
==========================================
- Coverage 99.70% 99.38% -0.32%
==========================================
Files 447 447
Lines 42428 42429 +1
==========================================
- Hits 42303 42169 -134
- Misses 125 260 +135 ☔ View full report in Codecov by Sentry. |
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.
LGTM! 🚀
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.
👍
**Context:** Prior to this fix, differentiating `PrepSelPrep` with `diff_method="parameter-shift"` resulted in zeros (which was inconsistent with `backprop`), ```python @qml.qnode(qml.device("default.qubit"), diff-method="parameter-shift") def circuit(params): H = qml.Hamiltonian(params, [qml.Z(2), qml.X(1) @ qml.X(2)]) qml.PrepSelPrep(H, control=[0]) return qml.expval(qml.PauliZ(0)) >>> x = qml.numpy.array([0.25, 0.75]) >>> qml.jacobian(circuit)(x) array([0., 0.]) ``` **Description of the Change:** One line change to add `PrepSelPrep.grad_method=None` 😺. This results in, ```python @qml.qnode(qml.device("default.qubit"), diff-method="parameter-shift") def circuit(params): H = qml.Hamiltonian(params, [qml.Z(2), qml.X(1) @ qml.X(2)]) qml.PrepSelPrep(H, control=[0]) return qml.expval(qml.PauliZ(0)) >>> x = qml.numpy.array([0.25, 0.75]) >>> qml.jacobian(circuit)(x) array([-1.5, 0.5]) ``` _Reason this works:_ It seems that parameter-shift tries to update the parameters and fails to do so. Setting `grad_method=None` forces it to decompose the operator before differentiating it's data. This does suggest some areas of improvement for `Operator.grad_method`. The `xfails` were also removed from the relevant tests. Also, certain test cases would result in `NaN`s upon differentiation with *any* method, so I skipped those cases as they are a *known* limitation of `MottonenStatePreparation`. **Benefits:** Gradient results are now consistent with `backprop`. **Possible Drawbacks:** None. **Related GitHub Issues:** Fixes #6331 [sc-74920]
Context:
Prior to this fix, differentiating
PrepSelPrep
withdiff_method="parameter-shift"
resulted in zeros (which was inconsistent withbackprop
),Description of the Change:
One line change to add
PrepSelPrep.grad_method=None
😺. This results in,Reason this works: It seems that parameter-shift tries to update the parameters and fails to do so. Setting
grad_method=None
forces it to decompose the operator before differentiating it's data. This does suggest some areas of improvement forOperator.grad_method
.The
xfails
were also removed from the relevant tests. Also, certain test cases would result inNaN
s upon differentiation with any method, so I skipped those cases as they are a known limitation ofMottonenStatePreparation
.Benefits: Gradient results are now consistent with
backprop
.Possible Drawbacks: None.
Related GitHub Issues: Fixes #6331
[sc-74920]