ValueError:optimizer got an empty parameter list基本都跟__init__()及其里面的代码有关,比如下划线打错了、init拼错了、没有super、没在__init__函数内定义网络等。本次具体如下:
今天有一段代码总是跑不通,
Traceback (most recent call last):
File "1.py", line 28, in
optimizer=optim.SGD(model.parameters(),lr=1e-3)
File "/share2/home//anaconda3/envs/python36/lib/python3.6/site-packages/torch/optim/sgd.py", line 64, in __init__
super(SGD, self).__init__(params, defaults)
File "/share2/home//anaconda3/envs/python36/lib/python3.6/site-packages/torch/optim/optimizer.py", line 46, in __init__
raise ValueError("optimizer got an empty parameter list")
ValueError: optimizer got an empty parameter list
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import pdb
import torch.autograd.variable as Variable
import matplotlib.pyplot as plt
x_train = np.array([[3.3],[4.4],[5.5],[6.71],[6.93],[4.168],[9.779],[6.182],[7.59],[2.167],[7.042],[10.791],[5.313],[7.997],[3.1]],dtype=np.float32)
y_train = np.array([[1.7],[2.76], [2.09],[3.19],[1.694],[1.573],[3.366],[2.596],[2.53],[1.221],[2.827],[3.456],[1.65],[2.904],[1.3]],dtype=np.float32)
x_train = torch.from_numpy(x_train)
y_train = torch.from_numpy(y_train)
class LinearRegression(nn.Module):
def _init_(self):
super(LinearRegression,self)._init_()
self.linear=nn.Linear(1,1)
def forward(self,x):
out=self.linear(x)
return out
if torch.cuda.is_available():
model=LinearRegression().cuda()
else:
model=LinearRegression()
criterion=nn.MSELoss()
# pdb.set_trace()
optimizer=optim.SGD(model.parameters(),lr=1e-3)
#训练模型
num_epochs=1000
for epoch in range(num_epochs):
if torch.cuda.is_available():
inputs=Variable(x_train).cuda()
target=Variable(y_train).cuda()
else:
inputs=Variable(x_train)
target=Variable(y_train)
out=model(inputs)
loss=criterion(out,target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1)%20==0:
print('Epoch[{}/{}],loss:{:.6f}'.format(epoch+1,num_epochs,loss.item()))
model.eval()
predict=model(Variable(x_train).cuda())
predict=predict.cpu().data.numpy()
plt.plot(x_train.numpy(),y_train.numpy(),'ro',label='Original data')
plt.plot(x_train.numpy(),predict,label='Fitting Line')
plt.show()
之前从来没有遇到过这类错误,毕竟按理说只要将模型定义到__init__()里就ok了,所以同学来问没能调出来。后来要了代码自己调发现_init_竟然只有一个下划线!
将下划线_改为__即可解决问题。
在此复习一下下面五种情况:
单前导下划线:_var
以单个下划线开头的变量或方法仅供内部使用。 该约定在PEP 8中有定义。
单末尾下划线:var_
解决命名冲突:有时候,一个变量的最合适的名称已经被一个关键字所占用。 因此,像class或def这样的名称不能用作Python中的变量名称。 在这种情况下,你可以附加一个下划线来解决命名冲突。
双前导下划线:__var
双下划线前缀会导致Python解释器重写属性名称,以避免子类中的命名冲突。这也叫做名称修饰(name mangling) - 解释器更改变量的名称,以便在类被扩展的时候不容易产生冲突。
双前导和末尾下划线:__var__
如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。 由双下划线前缀和后缀包围的变量不会被Python解释器修改。但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ --- 它使得一个对象可以被调用(神奇方法)。最好避免在自己的程序中使用以双下划线("dunders")开头和结尾的名称,以避免与将来Python语言的变化产生冲突。
独立单下划线:_
按照习惯,有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。
ValueError:optimizer got an empty parameter list基本都跟__init__()及其里面的代码有关,比如下划线打错了、init拼错了、没有super、没在__init__函数内定义网络等。
具体到下划线的问题,
虽不常见,除了在学python的时候注意过后来就再也没注意,但在实际遇到的时候并没有快速发现。故以此文以记之。
ps: 附一张成都今天的雨
https://www.runoob.com/w3cnote/python-5-underline.html