-
Notifications
You must be signed in to change notification settings - Fork 62
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
Allow ProjectTo
on non-differential types?
#442
Comments
Maybe worth saying that the reason for this restriction was just that we weren't completely sure, and leaving it an error in version 1.0 meant we could make it do anything later. I do think it would be nice if it could be applied more widely. One argument for this came up in the discussion of Functors.jl integration. If Zygote applies ProjectTo to everything, even if this is trivial for unknown types, then this lets you command it to apply a particular projection to your type. Whereas if it only applies ProjectTo to known-safe arrays etc, then you cannot as easily over-ride that. For this weird number type, I think the defaults will work, i.e. allow any Real as its tangent. I think the projector above with For non-number, non-array types, the easy class is non-differentiable things like strings & Symbols. The other class is things which are treated as a struct, and thus I think their tangents will always be The original design of ProjectTo was going to recurse into arbitrary structs. I think that a current version of that idea would look something like this:
But the question then is whether we need that at all, or should simply trust that anything inside a Are there functions which accept a Tuple, for which we want to define a rule, where we want projection to happen to all elements? Maybe functions which accept a Pair, ditto? |
special case of this is #440 |
In that case, the gradient of
But if it did, then projection on the array of tuples would not be necessary. |
So the thing we are seeing right now is where The ideal behavour would be if we could detect that code would MethodError eventually and then it would be as if no So the pragmatic solution seems to be to make it generically fallback to |
Next question is whether it should be literally |
pro of pro of
|
If the gradient is a vector, then the primal was too, right? So it will have a nontrivial projector. Even for Right now we do Sounds like If |
How would |
Not a real example to be clear. |
I'm not sure it's strictly worse. I agree it would make some things work that ought to, but it would presumably also make some things that ought not? Otherwise I agree that the |
(It is inferior to if |
At the moment we only define
ProjectTo
for differential types. (With Ref being the first exception)Consider a generic
rrule(*, a::Number, b::Number)
which usesProjectTo
to ensure that the tangents are in the right subspace, i.e. something likewhich looks perfectly reasonable.
However, if we create a type like
which is not its own differential type (the natural differential for this is a
Float64
) we are in trouble.The problem is that since we only promise
ProjectTo
to project onto valid differential types, so we can't just definesince
PositiveReal
is not a valid differential type (does not have a zero). For similar reason we do not defineProjectTo(::Tuple)
, which would solve issues like #440.The question is: should we loosen this requirement to only project onto differential types? By keeping the requirement we are restricting the use of
ProjectTo
to functions with arguments that are their own differentials. What bad things happen if we scratch thisProjectTo
requirement?The text was updated successfully, but these errors were encountered: