I’m working on a project integrating custom pytorch objects in to the fastai training api. Right now I’m a little confused about using a custom loss function. Two problems, firstly I’m just getting nans in the learner and secondly it won’t print out from my print statements for debugging. Anybody have any idea what’s going on?
Custom loss function:
def multitaskloss(preds, targets):
print(preds)
print(targets)
loss = 0
for ii, targ_loc in enumerate(targets['locs']):
loss += nn.MSELoss(preds[0][ii], targ_loc)
for ii, targ_label in enumerate(targets['labels']):
loss += nn.BCEWithLogitsLoss(preds[1][ii], targ_label)
return loss
Some more of the code in case it’s helpful
class llni_Dataset(torch.utils.data.Dataset):
def __init__(self, df):
self.X = df[cont_names]
self.y = df[targets]
def __len__(self): return len(self.y)
def __getitem__(self, idx):
# convert X
X = torch.as_tensor(self.X.loc[idx].values, dtype=torch.float32)
# set up the target
target = {}
target['locs'] = torch.as_tensor(self.y.loc[idx, target_locs], dtype=torch.float32)
target['labels'] = torch.as_tensor(self.y.loc[idx, target_labels].map(mapdict), dtype=torch.int64)
return X, target
train_ds = llni_Dataset(df.loc[~df['is_valid']])
valid_ds = llni_Dataset(df.loc[df['is_valid']].reset_index(drop = True))
# set up the PyTorch dataloaders
train_dl = DataLoader(train_ds, batch_size=32, shuffle=True, num_workers=2)
valid_dl = DataLoader(valid_ds, batch_size=32, shuffle=True, num_workers=2)
# set up the fastai dataloaders
dls = DataLoaders(train_dl, valid_dl, device = 'cuda')
class Net(nn.Module):
def __init__(self, input_size):
super(Net, self).__init__()
self.lin1 = nn.Linear(input_size, 200)
self.lin2 = nn.Linear(200, 100)
self.lin3 = nn.Linear(100, 50)
self.lin4_1 = nn.Linear(50, 13)
self.lin4_2 = nn.Linear(50, 13)
self.bn1 = nn.BatchNorm1d(200)
self.bn2 = nn.BatchNorm1d(100)
self.bn3 = nn.BatchNorm1d(50)
self.drops = nn.Dropout(0.2)
def forward(self, x):
x = self.bn1(F.relu(self.lin1(x)))
x = self.drops(x)
x = self.bn2(F.relu(self.lin2(x)))
x = self.drops(x)
x = self.bn3(F.relu(self.lin3(x)))
x = self.drops(x)
labels = self.lin4_1(x)
locs = self.lin4_2(x)
return locs, labels
net = Net(len(cont_names))
opt_func = partial(OptimWrapper, opt=torch.optim.Adam)
learn = Learner(dls, model = net, loss_func = multitaskloss, opt_func=opt_func)
learn.fit(1)
which gives