欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ValueError:optimizer got an empty parameter list 的一个可能错误

程序员文章站 2022-05-31 20:49:46
...

ValueError:optimizer got an empty parameter list基本都跟__init__()及其里面的代码有关,比如下划线打错了、init拼错了、没有super、没在__init__函数内定义网络等。本次具体如下:

 

今天有一段代码总是跑不通,

报错如下

Traceback (most recent call last):
  File "1.py", line 28, in <module>
    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: 附一张成都今天的雨

ValueError:optimizer got an empty parameter list 的一个可能错误

 

Reference

https://www.runoob.com/w3cnote/python-5-underline.html