Python 我在Pytorch中的自定义丢失函数未训练
我在Pytorch中的自定义丢失功能在培训期间不会更新。损失保持不变。我试图根据假阳性率和假阴性率编写这个自定义损失函数。我给你一个简化版的代码。知道会发生什么吗?反向传播是否变为0?这不是定义自定义损失函数的正确方法吗 我已经检查过,在反向传播过程中,梯度始终保持为真(断言需要_grad)。我还尝试创建一个函数false\u pos\u neg\u rate的类(torch.nn.module),但没有成功。断言结果是否定的,后来我把它省略了。 没有错误,培训仍在继续Python 我在Pytorch中的自定义丢失函数未训练,python,neural-network,pytorch,gradient-descent,loss-function,Python,Neural Network,Pytorch,Gradient Descent,Loss Function,我在Pytorch中的自定义丢失功能在培训期间不会更新。损失保持不变。我试图根据假阳性率和假阴性率编写这个自定义损失函数。我给你一个简化版的代码。知道会发生什么吗?反向传播是否变为0?这不是定义自定义损失函数的正确方法吗 我已经检查过,在反向传播过程中,梯度始终保持为真(断言需要_grad)。我还尝试创建一个函数false\u pos\u neg\u rate的类(torch.nn.module),但没有成功。断言结果是否定的,后来我把它省略了。 没有错误,培训仍在继续 def false_po
def false_pos_neg_rate(outputs, truths):
y = truths
y_predicted = outputs
cut_off= torch.tensor(0.5, requires_grad=True)
y_predicted =torch.where(y_predicted <= cut_off, zeros, ones)
tp, fp, tn, fn = confusion_matrix(y_predicted, y)
fp_rate = fp / (fp+tn).float()
fn_rate = fn / (fn+tp).float()
loss = fn_rate + fp_rate
return loss
for i, (samples, truths) in enumerate(train_loader):
samples = Variable(samples)
truths = Variable(truths)
outputs = model(samples)
loss = false_pos_neg_rate_torch(outputs, truths)
loss.backward()
optimizer.step()
def false\u pos\u neg\u rate(输出、真相):
y=真理
y_预测=输出
切断=火炬。张量(0.5,需要梯度=真)
y_predicted=torch。其中(y_predicted,正如你的损失函数所指出的,是不可微的。如果你从数学上写下你要做的,你会发现你的损失几乎处处都是零梯度,它的行为就像一个“阶跃函数”。
为了使用梯度下降法训练模型,你必须为损失函数设置有意义的梯度。根据你的提示,我更新了我的损失函数。我制作了一个假人,这样你也可以检查前两个函数。我添加了其余的,这样你就可以看到它是如何实现的。然而,在某些地方,梯度仍然会变成out为零。现在梯度变为零的步骤是什么,或者我如何检查这个?我想知道如何修复这个:)
我试着给你提供更多的信息,这样你也可以到处玩,但是如果你错过了什么,请告诉我
y = Variable(torch.tensor((0, 0, 0, 1, 1,1), dtype=torch.float), requires_grad = True)
y_pred = Variable(torch.tensor((0.333, 0.2, 0.01, 0.99, 0.49, 0.51), dtype=torch.float), requires_grad = True)
def binary_y_pred(y_pred):
y_pred.register_hook(lambda grad: print(grad))
y_pred = y_pred+torch.tensor(0.5, requires_grad=True, dtype=torch.float)
y_pred = y_pred.pow(5) # this is my way working around using torch.where()
y_pred = y_pred.pow(10)
y_pred = y_pred.pow(15)
m = nn.Sigmoid()
y_pred = m(y_pred)
y_pred = y_pred-torch.tensor(0.5, requires_grad=True, dtype=torch.float)
y_pred = y_pred*2
y_pred.register_hook(lambda grad: print(grad))
return y_pred
def confusion_matrix(y_pred, y):
TP = torch.sum(y*y_pred)
TN = torch.sum((1-y)*(1-y_pred))
FP = torch.sum((1-y)*y_pred)
FN = torch.sum(y*(1-y_pred))
k_eps = torch.tensor(1e-12, requires_grad=True, dtype=torch.float)
FN_rate = FN/(TP + FN + k_eps)
FP_rate = FP/(TN + FP + k_eps)
cost = FN_rate + FP_rate
return cost
class FeedforwardNeuralNetModel(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(FeedforwardNeuralNetModel, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(hidden_dim, output_dim)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.fc1(x)
out = self.relu1(out)
out = self.fc2(out)
out = self.sigmoid(out)
return out
model = FeedforwardNeuralNetModel(input_dim, hidden_dim, output_dim)
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001, betas=[0.9, 0.99], amsgrad=True)
criterion = torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
samples= Variable(samples)
truths = Variable(truths)
outputs = model(samples)
loss = confusion_matrix(outputs, truths)
loss.backward()
optimizer.step()
为什么要使用变量
?不推荐使用的,请改用张量。此外,这里不需要梯度,只需对输出
和真相
执行操作即可。循环中的示例和真相也是如此……这是您实际运行的代码吗?似乎至少有一个打字错误:f
infn\u rate=fn/(f+tp).float()
我猜是torch.
不可微,因此不会计算梯度?在新帖子中发布最后一个问题!