PyTorch NN 未训练
pytorch 718
原文标题 :PyTorch NN not training
我有一个定制的 NN 模型,它可以工作并希望将其移至 PyTorch 框架。然而,由于一些错误配置,网络可能没有训练。如果您看到奇怪/错误或可能是促成原因的东西,请告知。
import torch
from torch import nn, optim
import torch.nn.functional as F
X_train_t = torch.tensor(X_train).float()
X_test_t = torch.tensor(X_test).float()
y_train_t = torch.tensor(y_train).long().reshape(y_train_t.shape[0], 1)
y_test_t = torch.tensor(y_test).long().reshape(y_test_t.shape[0], 1)
class Classifier(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(22, 10)
self.fc2 = nn.Linear(10, 1)
def forward(self, x):
# make sure input tensor is flattened
x = x.view(x.shape[0], -1)
x = F.relu(self.fc1(x))
x = F.log_softmax(self.fc2(x), dim=1)
return x
model = Classifier()
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.003)
epochs = 2000
steps = 0
train_losses, test_losses = [], []
for e in range(epochs):
# training loss
optimizer.zero_grad()
log_ps = model(X_train_t)
loss = criterion(log_ps, y_train_t.type(torch.float32))
loss.backward()
optimizer.step()
train_loss = loss.item()
# test loss
# Turn off gradients for validation, saves memory and computations
with torch.no_grad():
log_ps = model(X_test_t)
test_loss = criterion(log_ps, y_test_t.to(torch.float32))
ps = torch.exp(log_ps)
train_losses.append(train_loss/len(X_train_t))
test_losses.append(test_loss/len(X_test_t))
if (e % 100 == 0):
print("Epoch: {}/{}.. ".format(e, epochs),
"Training Loss: {:.3f}.. ".format(train_loss/len(X_train_t)),
"Test Loss: {:.3f}.. ".format(test_loss/len(X_test_t)))
培训未进行:
Epoch: 0/2000.. Training Loss: 0.014.. Test Loss: 0.082..
Epoch: 100/2000.. Training Loss: 0.014.. Test Loss: 0.082..
...
回复
我来回复-
CountTracula 评论
我相信我找到了解决方案。我错误地使用了 log_softmax 而不是简单的 sigmoid。这解决了问题。
1年前 -
Tomer Geva 评论
问题的根源在于您对 self.fc2 的输出应用了 softmax 操作。self.fc2 的输出大小为 1,因此无论输入如何,softmax 的输出都将为 1。阅读更多关于这里的pytorch包中的softmax激活函数。我怀疑你想使用Sigmoid函数将最后一个线性层的输出转换为区间[0,1],然后应用某种对数函数。
因为无论输入如何,softmax 的输出都是 1,因此模型训练得不好。我无权访问您的数据,所以我无法准确模拟它,但根据我拥有的信息,用 sigmoid 替换 softmaxactivation 应该可以解决这个问题。
更好和更稳定的方法是使用 BCEWITHLOGITSLOSS 代替criteria = nn.BCELoss() 中的标准,并在最后删除激活函数,因为该标准将 sigmoid 与 BCE 损失一起应用以实现更稳定的数值计算。
总而言之,我的建议是将标准 = nn.BCELoss() 更改为标准 = nn.BCEWithLogitsLoss() 并将 forawrd 函数更改如下:
def forward(self, x): # make sure input tensor is flattened x = x.view(x.shape[0], -1) x = F.relu(self.fc1(x)) x = self.fc2(x)
1年前