Будьте осторожны при использовании nn.CrossEntropyLoss
и nn.NLLLoss
без путаницы.
Не думаю, что у вашего кода есть проблемы, я пытался запустить его точно так же, как вы определили. Возможно, вы не дали нам другие строки кода для инициализации других частей, и это может быть проблемой.
log_ps
предполагается равным log_softmax
значениям, но ваша сеть выдает только logits
значения (как вы сказали, вы использовали CrossEntropyLoss
. Эти строки можно изменить, как показано ниже:
log_ps = model(images)
prob = torch.exp(log_ps)
top_probs, top_classes = prob.topk(1, dim=1)
# Change into simple code:
logits = model(images)
output = logits.argmax(dim=-1) # should give you the class of predicted label
import torch
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
self.fc1 = nn.Linear(in_features=12 * 4 * 4, out_features=120)
self.fc2 = nn.Linear(in_features=120, out_features=60)
self.out = nn.Linear(in_features=60, out_features=10)
#the output will be 0~9 (10)
def forward(self, t):
# implement the forward pass
# (1)input layer
t = t
# (2) hidden conv layer
t = self.conv1(t)
t = F.relu(t)
t = F.max_pool2d(t, kernel_size=2, stride=2)
# (3) hidden conv layer
t = self.conv2(t)
t = F.relu(t)
t = F.max_pool2d(t, kernel_size=2, stride=2)
# (4) hidden linear layer
t = t.reshape(-1, 12 * 4 * 4)
t = self.fc1(t)
t = F.relu(t)
# (5) hidden linear layer
t = self.fc2(t)
t = F.relu(t)
# (6) output layer
t = self.out(t)
return t
- Подготовьте ваш набор данных
import torchvision
import torchvision.transforms as T
train_dataset = torchvision.datasets.FashionMNIST('./data', train=True,
transform=T.ToTensor(),
download=True)
test_dataset = torchvision.datasets.FashionMNIST('./data', train=False,
transform=T.ToTensor(),
download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
- Начало тренировки
epoch = 5
model = Model();
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())
train_losses, test_losses = [], []
for e in range(epoch):
train_loss = 0
test_loss = 0
accuracy = 0
for images, labels in train_loader:
optimizer.zero_grad()
logits = model(images) #output
loss = criterion(logits, labels)
train_loss += loss.item()
loss.backward()
optimizer.step()
else:
with torch.no_grad():
model.eval()
for images,labels in test_loader:
logits = model(images)
output = logits.argmax(dim=-1)
equals = (labels == output)
accuracy += equals.to(torch.float).mean()
test_loss += criterion(logits, labels)
model.train()
print("Epoch: {}/{}.. ".format(e+1, epoch),
"Training Loss: {:.3f}.. ".format(train_loss/len(train_loader)),
"Test Loss: {:.3f}.. ".format(test_loss/len(test_loader)),
"Test Accuracy: {:.3f}".format(accuracy/len(test_loader)))
train_losses.append(train_loss/len(train_loader))
test_losses.append(test_loss/len(test_loader))
И вот результат, он сходится как минимум:
Epoch: 1/5.. Training Loss: 0.721.. Test Loss: 0.525.. Test Accuracy: 0.809
Epoch: 2/5.. Training Loss: 0.473.. Test Loss: 0.464.. Test Accuracy: 0.829
Epoch: 3/5.. Training Loss: 0.408.. Test Loss: 0.391.. Test Accuracy: 0.858
Epoch: 4/5.. Training Loss: 0.370.. Test Loss: 0.396.. Test Accuracy: 0.858
Epoch: 5/5.. Training Loss: 0.348.. Test Loss: 0.376.. Test Accuracy: 0.858