Replies: 2 comments
|
fwiw To actually test import mlx.core as mx
a = mx.array([1.0, 2.0, 3.0])
def f(x):
b = mx.where(x == 3, mx.stop_gradient(x), x)
return mx.sum(b)
grad_f = mx.grad(f)
print(grad_f(a)) # array([1, 1, 0], dtype=float32)That gives the (Side note: |
|
The fix in the comment above is right, and it holds on mlx 0.32.0: the Using a cube instead of a plain sum so the live entries are not all 1 and the masking is actually visible: import mlx.core as mx
a = mx.array([1.0, 2.0, 3.0])
mask = mx.array([False, False, True])
def g(x):
y = mx.where(mask, mx.stop_gradient(x), x)
return mx.sum(y ** 3)
print(mx.grad(g)(a)) # array([3, 12, 0], dtype=float32)
print(3 * a ** 2) # array([3, 12, 27], dtype=float32)The forward pass is untouched ( On the int32 arrays in your snippet: the gradient is cast back to the input dtype, so it does not merely look odd, it can come out zero. print(mx.grad(lambda x: mx.sum(mx.sqrt(x)))(mx.array([1, 2, 3])))
# array([0, 0, 0], dtype=int32)
print(mx.grad(lambda x: mx.sum(mx.sqrt(x)))(mx.array([1.0, 2.0, 3.0])))
# array([0.5, 0.353553, 0.288675], dtype=float32)One thing that bit me putting this in an actual training loop: a zero gradient is not the same as a frozen parameter for every optimizer. AdamW scales the parameter before handing it to Adam, whatever the gradient is ( return super().apply_single(
gradient, parameter * (1 - lr * self.weight_decay), state
)20 steps on The masked rows have exactly zero gradient in all three, but under AdamW they still drift. So if what you are freezing is part of a weight rather than part of an intermediate, use |
Uh oh!
There was an error while loading. Please reload this page.
I'm trying to gradients off for a subset of a tensor. Take the example
In this, I'm trying to turn off gradients for the 3rd element of
a. When I evaluate this, I get the resultI would have expected this to produce
Can you turn off gradients for part of a tensor?
All reactions