Issue
making datasets
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)
model(predicting circle) (we know equation of circle 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)
training loop
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())
IF I TRAIN MY MODEL IN ABOVE WAY, ITS PREDICTING 1 AS 0, AND O AS 1.
I.E. ytrain[:10] = tensor([1., 0., 0., 0., 1., 0., 1., 1., 0., 0.])
. predicted values are: torch.round(torch.sigmoid(m(xtrain[:10]))) = tensor([0., 1., 1., 1., 0., 1., 0., 0., 1., 1.])
But, when i plot the circle, its predicting correctly (radius of circle is predicted correctly)
predicted circle
i tried to predict a circle. all inside are 0's and outside are 1's. But after training, its predicting in reverse order( i.e. outside 0's and inside 1's). please check it once. i have provided entire code.
Solution
The model returns this logit:
x0 ** 2 + x1 ** 2 - r_optimal ** 2
The return value above is such that samples inside r_optimal return a negative value, and samples outside of r_optimal return a positive value.
We can follow this through to the predicted class yhat:
- sample inside r_optimal -> model returns negative value
- sigmoid(negative) is <0.5, so yhat = round(<0.5) = 0
Similarly, for a sample outside r_optimal:
- sample outside r_optimal -> model returns positive value
- sigmoid(positive) is >0.5, so yhat = round(>0.5) = 1
So samples that are inside/outside r_optimal will get yhat=0/yhat=1 - but this is the reverse of your training set where the actual labels are y=1/y=0.
One way to fix this is to reverse the sign of the return value. That will mean samples inside the circle return a positive value and will get a predicted class of yhat = round(sigmoid(+ve))) = 1.
return -(x[:, 0]**2 + x[:, 1]**2 - self.r**2)
Answered By - user3128
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.