Skip to content
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

Add support for Value ** Value #41

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Weikang01
Copy link

a = Value(2.0)
b = Value(3.0)
c = a ** b
print(c.data)
c.backward()
print(a.grad)
print(b.grad)

output now:

8.0
12.0
5.545177444479562

@conscell
Copy link

conscell commented Jun 8, 2023

@Weikang01
If self.data is negative and other is a Value, this implementation will cause a ValueError: math domain error.
Division is implemented as follows:

def __truediv__(self, other): # self / other
    return self * other**-1

fixed problem for negative base value
@Weikang01
Copy link
Author

@Weikang01 If self.data is negative and other is a Value, this implementation will cause a ValueError: math domain error. Division is implemented as follows:

def __truediv__(self, other): # self / other
    return self * other**-1

Thank you @conscell!

I added support for negative values now! Thank you again for pointing out my problem!

    a = Value(-2.0)
    b = Value(-3.0)
    c = a ** b
    d = c ** a
    e = d / c
    f = 0.001 * e
    print(f.data)
    f.backward()
    print(c.grad)
    print(a.grad)
    print(b.grad)

output:

-0.512
-12.288
3.3686740693400763
1.064674069340076

@conscell
Copy link

@Weikang01
In negative case perhaps it makes sense to set gradient to math.nan, something like this:

>>> import torch
>>> a = torch.tensor(-2.0, requires_grad=True)
>>> b = torch.tensor(-3.0, requires_grad=True)
>>> c = a ** b
>>> c.backward()
>>> a.grad
tensor(-0.1875)
>>> b.grad
tensor(nan)

@Weikang01
Copy link
Author

Thank you @conscell!
You are absolutely right, the exponent of negative numbers should have no derivatives! Now the code works like this:

a = Value(-2.0)
b = Value(3.0)
c = a ** b
print(c.data)
d = c ** a
print(d.data)
e = d / c  # 0.015625 / -8.0
e.backward()
print(a.grad)
print(b.grad)
print(c.grad)
print(d.grad)

output:

-8.0
0.015625
nan
nan
-0.000732421875
-0.125

and this is the code of pytorch:

a = torch.tensor(-2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)
c = a ** b
c.retain_grad()
print(c)
d = c ** a
d.retain_grad()
print(d)
e = d / c

e.backward()
print(a.grad)
print(b.grad)
print(c.grad)
print(d.grad)

outputs:

tensor(-8., grad_fn=<PowBackward1>)
tensor(0.0156, grad_fn=<PowBackward1>)
tensor(nan)
tensor(nan)
tensor(-0.0007)
tensor(-0.1250)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants