nn.Parameter not getting updated not sure about the usage - pytorch

I have declared two nn.Parameter() variables with requires_grad=True and I am using those in a different function that's being called inside the init method of the class where variables are declared. lparam and rparam are not getting updated
My question is am I doing it the right way?
if not how it should be done?
here is the code example:
class LG(BaseNetwork):
def __init__(self, opt):
super().__init__()
self.opt = opt
self.lparam = nn.Parameter(torch.zeros(1), requires_grad=True).cuda(device=opt.gpu_ids[0])
self.rparam = nn.Parameter(torch.zeros(1), requires_grad=True).cuda(device=opt.gpu_ids[0])
def foo(self, a, b, k=1.0, lparam=0, rparam=0):
t = bar(a, b, k=k, lparam=lparam, rparam=rparam)
return t
def forward(self, a, b):
x = self.foo(a, b, k=self.opt.k, lparam=self.lparam, rparam=self.rparam)
return x
BaseNetwork is just initializing functions and uses nn.Module
def bar(a, b, k=1.0, lparam=0, rparam=0):
return n(a) * (b.std() * (k * lparam)) + (b.mean() * (k * rparam))
When I print the named params I can not get lparam and rparam

thanks, I got the solution here https://discuss.pytorch.org/t/nn-parameter-not-getting-updated-not-sure-about-the-usage/157226
I had to remove the cuda(device=opt.gpu_ids[0]) because it is supposed to get the device that the model is put on.

Related

Class Inheritance for the parent __int__ in Python

My code is provided in the end. I want to let the class general inherit all the variables of the constructor (_ init _) in the class LDA. It seems that when the method X_F in the class general calls the X_c, it just returns the objective rather than the array of np.random.rand(3,2) generated in the main. I tried to let the method X_F print the value of the variable m, but the printed result is a default value of 3, rather than 10.
class LDA:
def __init__(self, X_c, m = 3, K=1):
self.X_c =X_c
self.m =m
self.K = K
def Squared_L2_loss(self):
X_result = general(self).X_F()
return X_result
class general(LDA):
def X_F(self):
X = self.X_c[0]
print(self.m)
return X.T
if __name__ == '__main__':
X_c=np.random.rand(3,2)
X = LDA(X_c, m=10, K=30)

Efficiency in creating a variable in a deferred function

Consider the two classes below.
class Alpha:
def __init__(self):
pass
def Bar(self, x):
def Foo(mult):
return x * mult
self._Foo = Foo
def Foo(self, mult):
return self._Foo(mult)
class Beta:
def __init__(self):
pass
def Bar(self, x):
self._x = x
def Foo(self, mult):
return self._x * mult
For Alpha with a deferred function _Foo, I believe it is more efficient memory-wise since it only evaluates x when the function is called. For Beta on the other hand, x is stored explicitly as a class attribute.
The question is, where exactly is x stored in Alpha? How efficient is it compared to Beta?
x is not stored in alpha as a class attribute, it is only created when you call the function, Foo. This eliminates the need unnecessary data storage.

How to use two instances of a base class from a derived class

I want to use two instances of a base class from one derived class. I am not sure if the following code is technically correct or if there is a better way. Can the two instances mix up in any situation?
The base class A is intended to perform a common task: "changevar" which changes the variable "var" to "dv". The derived class B use this method but with two variables "var1", "var2" to change it to "dv1", and "dv2" respectively. class B then performs an "operation" over the changed variables "var1", and "var2" and return the result (in this case multiply).
test.py:
class A:
def __init__(self, var):
self.var = var
def changevar(self, dv):
self.var = self.var + dv
def getvar(self):
return self.var
class B(A):
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
A.__init__(self, var1)
self.inst1 = A(self.var)
A.__init__(self, var2)
self.inst2 = A(self.var)
def operation(self):
dv1 = 2
dv2 = -2
self.inst1.changevar(dv1)
self.inst2.changevar(dv2)
self.var1 = self.inst1.getvar()
self.var2 = self.inst2.getvar()
return self.var1, self.var2, self.var1 * self.var2
def main():
test = B(10, 10)
v1, v2, v3 = test.operation()
print (v1, v2, v3)
return
if __name__ == "__main__":
main()```
>>>python3 test.py
>>>12 8 96
In your code, you're not actually using the inheritance.
When you execute self.inst1 = A(self.var) you are creating a whole new instace of A, which is different from that which is the base for your B, and assigning it to a field.
Good news are: you don't need inheritance in your case. what you need (and de-facto do) is composition - having fields of type A in your type B.
Just remove A as a base from B at all, and use the inner fields of this type, the result will be the same:
class A:
def __init__(self, var):
self.var = var
def changevar(self, dv):
self.var = self.var + dv
def getvar(self):
return self.var
class B:
def __init__(self, var1, var2):
self.inst1 = A(var1)
self.inst2 = A(var2)
def operation(self):
dv1 = 2
dv2 = -2
self.inst1.changevar(dv1)
self.inst2.changevar(dv2)
var1 = self.inst1.getvar()
var2 = self.inst2.getvar()
return var1, var2, var1 * var2
def main():
test = B(10, 10)
v1, v2, v3 = test.operation()
print (v1, v2, v3)
return
if __name__ == "__main__":
main()
Inheritance should be used when you want to use instances of type B as if they were of type A (e.g., call A's methods on instances of type B).
Generally we say that B should inherit from A, ib B "is-a" A - e.g. a Dog is an Animal, a Square is a Shape.
Composition is more of "has-a" relationship, like a Car has a Radio
I hope I made it clear, it's a little hard to grasp that reasoning with meaningless class names like A and B :)

How to pass property methods as arugments in Python

First, let's consider this working example using get and set methods for the variable x
class Foo:
def __init__(self):
self._x = 0
def set_x(self, x):
self._x = x
def get_x(self):
return self._x
class Bar:
def __init__(self, set_method):
self._set_method = set_method
def set_x(self, x):
self._set_method(x)
f = Foo()
f.set_x(5)
print(f.get_x())
# Prints 5
b = Bar(f.set_x)
b.set_x(10)
print(f.get_x())
# Prints 10
As you can see I pass the possibility to set the variable x of the instance f of class Foo, to the instance b of class Bar.
Now, I would like to do the same, but with property decorators instead, roughly like this
class Foo:
def __init__(self):
self._x = 0
#property
def x(self):
return self._x
#x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self._x_property = x_property
def set_x(self, x):
self.x_property = x
f = Foo()
f.x = 5
print(f.x)
# Prints 5
b = Bar(f.x)
b.set_x(10)
print(f.x)
# Prints 5
What happens is that the value 5, instead of the property, gets passed to instance b, meaning that b can't access x in instance f. Is there a nice way to solve this?
I would then also like to do the same thing for the get method. In the first code that requires me to pass both methods, but if there is a way to get the second code to work I would hopefully only have to pass on the property which I then can set and get as a normal variable.
I would really want to use the property decorators or similar as it cleans up my code a lot. I use python 3.5.2.
Thanks,
Andreas
You can accomplish this by accessing the fset attribute of Foo.x. Note the use of class-dot notation rather than instance-dot. fset takes two arguments: the instance to access and the value to write. Here is a working example
class Foo:
#property
def x(self):
return self._x
#x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, foo, value):
self.x_property(foo, value)
f = Foo()
f.x = 5
print(f.x)
b = Bar(Foo.x.fset)
b.set_x(f, 10)
print(f.x)
Notice that we had to pass f to set_x because we need it to invoke the setter. You could eliminate the f param by using partial from the functools module to bind f to the property setter. Pass the partial binding in to the constructor of Bar.
class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, value):
self.x_property(value)
f = Foo()
b = Bar(partial(Foo.x.fset, f))
b.set_x(10)
print(f.x)
It might be wise to rename x_property and this point. It is really just a function as far as Bar is concerned. It wouldn't have to be a property.

How do I define a variable for all class methods use?

I need to define a variables that is to be used in all the methods of one class.
class A:
def method1(self):
for i in range(N):
*do something with M*
def method2(self):
for i in range(N):
*do other thing with M*
and so on.
All I need to do is define N and M variables somewhere in the begining of class describing. I tried to define it in constructor like this:
class A:
def __init__(N, M):
self.N=N
self.M=M
def method1(self):
...
in tend to call A with this parameters just once. But there was another error in case I don't really now how to use constructor for now. Then I add this variables as parameters of each method:
...
def method1(self, N, M):
...
And that time it worked perfectly. But I don't want to input values each time I call A.methodX() and I'm 100% sure there is one or two ways that accords my requests.
You were on the right track so I wrote a short version of what I suspect you wanted to do with a little 'debug' code embedded. Note the instantiation of the class aa = A(1,2)
class A:
def __init__(self, N, M):
self.N = N
self.M = M
def method1(self):
print ("iterate N")
for i in range(self.N):
print (str(i) + "\n")
def method2(self):
print ("iterate M")
for i in range(self.M):
print (str(i) + "\n")
aa = A(1, 2)
aa.method1()
aa.method2()
Note that what I've done here is create instance variables - you can also create class variables by instantiating them outside of the methods. So iVar becomes the class variable.
class A:
iVar = 0
def __init__(self, N, M):
self.N = N
self.M = M
......

Resources