pytorch 我的模型在训练后预测完全相反的值(即预测圆的内部值为外部值,外部值为内部值)

qjp7pelc  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(80)

制作数据集

from sklearn.datasets import make_circles
n_samples=1000
x, y = make_circles(n_samples, noise=0.03, random_state=42)
X = torch.from_numpy(x).type(torch.float)
Y = torch.from_numpy(y).type(torch.float)
from sklearn.model_selection import train_test_split
xtrain, xtest, ytrain, ytest = train_test_split(X, Y, test_size=0.2, random_state=42)

字符串

模型(预测圆)(我们知道圆s的方程(x**2 + y**2 = r**2))

class cp(nn.Module):
    def __init__(self):
        super().__init__()
        self.r = nn.Parameter(torch.randn(1, requires_grad = True, dtype=torch.float))
    def forward(self, x):
        return x[:, 0]**2 + x[:, 1]**2 - self.r**2
torch.manual_seed(42)
m = cp()
loss_fn = nn.BCEWithLogitsLoss()
opt = torch.optim.SGD(params = m.parameters(), lr=0.1)

训练循环

e = 1000
for i in range(e+1):
    m.train()
    p = m(xtrain).squeeze()
    f = torch.round(torch.sigmoid(p))
    l = loss_fn(p, ytrain)
    acc = accuracy_fn(f, ytrain)
    opt.zero_grad()
    l.backward()
    opt.step()
    if(i%10==0):
        with torch.inference_mode():
            tp = m(xtest).squeeze()
            tf= torch.round(torch.sigmoid(tp))
            tl = loss_fn(tp, ytest)
            tacc = accuracy_fn(tf, ytest)
            print(f"epoch: {i} | train loss: {l:.4f} | train acc: {acc} | test loss: {tl:.4f} | test acc: {tacc}")
            if(i%100==0): print(m.state_dict())


如果我以上述方式训练我的模型,它预测1为0,O为1。即ytrain[:10] = tensor([1., 0., 0., 0., 1., 0., 1., 1., 0., 0.])。预测值为:torch.round(torch.sigmoid(m(xtrain[:10])))= tensor([0., 1., 1., 1., 0., 1., 0., 0., 1., 1.])但是,当我绘制圆时,它的预测正确(圆的半径预测正确)predicted circle
我试图预测一个圆.所有里面是0的和外面是1的.但经过训练,其预测在相反的顺序(即0的外面和1的里面).请检查一次.我提供了整个代码.

ni65a41a

ni65a41a1#

模型返回这个logit:
第一个月
上面的返回值是这样的,sample inside r_optimal返回负值,而sample outside of r_optimal返回正值。
我们可以按照这个方法来预测类yhat:

  • r_optimal ->模型内的样本返回负值
  • sigmoid(负)<0.5,因此yhat = round(<0.5)= 0

类似地,对于r_optimal之外的样本:

  • 样本在r_optimal ->模型之外返回正值
  • sigmoid(正)>0.5,因此yhat = round(>0.5)= 1

因此,在r_optimal内/外的样本将得到yhat=0/yhat=1 -但这与实际标签为y=1/y=0的训练集相反。
解决这个问题的一种方法是反转返回值的符号。这意味着圆内的样本返回一个 * 正 * 值,并将得到yhat = round(sigmoid(+ve)= 1的预测类。

return -(x[:, 0]**2 + x[:, 1]**2 - self.r**2)

字符串
x1c 0d1x的数据

相关问题