Я использую Pytorch для классификации серии изображений. NN определяется следующим образом:
model = models.vgg16(pretrained=True)
model.cuda()
for param in model.parameters(): param.requires_grad = False
classifier = nn.Sequential(OrderedDict([
('fc1', nn.Linear(25088, 4096)),
('relu', nn.ReLU()),
('fc2', nn.Linear(4096, 102)),
('output', nn.LogSoftmax(dim=1))
]))
model.classifier = classifier
Критериями и оптимизаторами являются:
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.classifier.parameters(), lr=0.001)
Моя функция проверки выглядит следующим образом:
def validation(model, testloader, criterion):
test_loss = 0
accuracy = 0
for images, labels in testloader:
images.resize_(images.shape[0], 784)
output = model.forward(images)
test_loss += criterion(output, labels).item()
ps = torch.exp(output)
equality = (labels.data == ps.max(dim=1)[1])
accuracy += equality.type(torch.FloatTensor).mean()
return test_loss, accuracy
Это кусок кода, который вызывает следующую ошибку:
RuntimeError: вход имеет меньше размеров, чем ожидалось
epochs = 3
print_every = 40
steps = 0
running_loss = 0
testloader = dataloaders['test']
# change to cuda
model.to('cuda')
for e in range(epochs):
running_loss = 0
for ii, (inputs, labels) in enumerate(dataloaders['train']):
steps += 1
inputs, labels = inputs.to('cuda'), labels.to('cuda')
optimizer.zero_grad()
# Forward and backward passes
outputs = model.forward(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if steps % print_every == 0:
model.eval()
with torch.no_grad():
test_loss, accuracy = validation(model, testloader, criterion)
print("Epoch: {}/{}.. ".format(e+1, epochs),
"Training Loss: {:.3f}.. ".format(running_loss/print_every),
"Test Loss: {:.3f}.. ".format(test_loss/len(testloader)),
"Test Accuracy: {:.3f}".format(accuracy/len(testloader)))
running_loss = 0
Любая помощь?
Мне нужно было изменить функцию проверки следующим образом:
def validation(model, testloader, criterion):
test_loss = 0
accuracy = 0
for inputs, classes in testloader:
inputs = inputs.to('cuda')
output = model.forward(inputs)
test_loss += criterion(output, labels).item()
ps = torch.exp(output)
equality = (labels.data == ps.max(dim=1)[1])
accuracy += equality.type(torch.FloatTensor).mean()
return test_loss, accuracy
входные данные необходимо преобразовать в 'cuda': inputs.to('cuda')
На всякий случай это кому-то поможет.
Если у вас нет системы графического процессора (скажем, вы разрабатываете на ноутбуке и в конечном итоге будете тестировать на сервере с графическим процессором), вы можете сделать то же самое, используя:
if torch.cuda.is_available():
inputs =inputs.to('cuda')
else:
inputs = inputs.to('cuda')
Кроме того, если вы задаетесь вопросом, почему есть LogSoftmax
, вместо того, чтобы Softmax
это потому, что он использует NLLLoss как его функции потерь. Вы можете прочитать больше о softmax здесь