我一直在使用对象检测训练图像分类模型,然后将图像分类应用于图像。我的数据中有87个自定义类(不是ImageNet类(,总共有7000多个图像(每个类大约有60个图像(。我对我的目标检测代码很满意,我认为它运行得很好,然而,对于分类,我一直在使用ResNet和AlexNet。我尝试过AlexNet、ResNet18、ResNet50和ResNet101进行训练,但我的测试准确率很低(约10%(,而且我的训练准确率对所有模型都很高。我也尝试过规范化和改变学习率,但我没有获得所需的更高准确率(>80%(。我想知道我的代码中是否有漏洞,尽管我还没能弄清楚。
这是我的训练代码,我还以Pytorch预训练模型所期望的方式处理了图像:
import torch.nn as nn
import torch.optim as optim
from typing import Callable
import numpy as np
EPOCHS=100
resnet = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50')
resnet.eval()
resnet.fc = nn.Linear(2048, 87)
res_loss = nn.CrossEntropyLoss()
res_optimiser = optim.SGD(resnet.parameters(), lr=0.01, momentum=0.9, weight_decay=1e-5)
def train_model(model, loss_fn, optimiser, modelsavepath):
train_acc = 0
for j in range(EPOCHS):
running_loss = 0.0
correct = 0
total = 0
for i, data in enumerate(training_generator, 0):
model.train()
inputs, labels, paths = data
total += 1
optimizer.zero_grad()
outputs = model(inputs)
_, predicted = torch.max(outputs, 1)
if(predicted.int() == labels.int()):
correct += 1
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
train_acc = train_correct / len(training_generator)
print("Epoch:{}/{} AVG Training Loss:{:.3f} AVG Training Acc {:.2f}% ".format(j + 1, EPOCHS, train_loss, train_acc))
torch.save(model, modelsavepath)
train_model(resnet, res_loss, res_optimiser, 'resnet.pth')
以下是用于单个图像的测试代码,它是一个类的一部分:
self.model.eval()
outputs = self.model(img[None, ...]) #models expect batches, so give it a singleton batch
scores, predictions = torch.max(outputs, 1)
predictions = predictions.numpy()[0]
possible_scores= np.argmax(scores.detach().numpy())
我的代码中是否存在错误,无论是测试还是训练,或者我的模型只是过拟合?此外,有没有更好的图像分类模型可以尝试?
您的数据集非常小,因此很可能会过拟合。尝试:
- 降低学习率(尝试0.001、0.0001、0.00001(
- 增加weight_decay(尝试1e-4、1e-3、1e-2(
- 如果还没有,请使用图像增强(至少是默认的增强,如随机裁剪和翻转(
- 微调模型时,请观察训练/测试损失曲线,一旦发现测试精度下降,而训练精度上升,请立即停止训练