这是我的代码。请大家过目。
而且我在用训练好的pth模型进行单独测试时总会是第0类正确率很高(也就是猫的识别率很高 狗的识别率很低)
测试集猫狗各500张,猫能识别出400多张而狗只能识别出十几张。
不知道问题出在哪里?
训练的loss会一直降,但是验真loss从0.7降到0.6,就趋于平滑,不再下降。
我试了调整学习率,但是没用。
import math
from torch import nn
from torchvision import models,datasets,transforms
import torch
import os
from torch.autograd import Variable
import csv
#import visdom
#viz = visdom.Visdom()
data_dir = 'VGGTrain'
data_transform = {
'train':transforms.Compose([transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485,0.456,0.406], [0.229,0.224,0.225]),
transforms.RandomHorizontalFlip(p=0.5),#水平翻转
transforms.RandomRotation(15), # 随机旋转
transforms.RandomCrop(224), #随机剪裁
transforms.Pad(padding=4, padding_mode='edge'),#边缘填充
]),
'valid':transforms.Compose([transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485,0.456,0.406], [0.229,0.224,0.225])
])
}
image_datasets = {x:datasets.ImageFolder(root=os.path.join(data_dir, x), transform=data_transform[x])
for x in ['train','valid']
}
dataloader = {x:torch.utils.data.DataLoader(dataset=image_datasets[x], batch_size=32, shuffle=True, num_workers=4)
for x in ['train','valid']
}
x_example, y_example = next(iter(dataloader['train']))
example_classes = image_datasets['train'].classes
index_classes = image_datasets['train'].class_to_idx
model = models.vgg16(pretrained=False)
# 遍历模型中的所有模块
for m in model.modules():
# 如果当前模块是卷积层或者线性层
if isinstance(m, nn.Conv2d):
#则进行xavier初始化
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight, 0, 0.01)
nn.init.constant_(m.bias, 0)
model.classifier = torch.nn.Sequential(
torch.nn.Linear(25088,512),
torch.nn.ReLU(),
torch.nn.Dropout(p=0.6),
torch.nn.Linear(512,256),
torch.nn.ReLU(),
torch.nn.Dropout(p=0.6),
torch.nn.Linear(256,2)
)
use_gpu = torch.cuda.is_available()
if use_gpu :
model = model.cuda()
loss_f = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.classifier.parameters(), lr=1e-4,weight_decay=0.01)
epochs = 99999
#viz.line([0], [-1], win='loss', opts=dict(title='loss'))
#viz.line([0], [-1], win='val_acc', opts=dict(title='val_acc'))
global_step = 0
best_acc = 0
best_epoch = 0
with open("loss2.txt", "w") as f:
for epoch in range(epochs):
print('----' * 10)
print('Epoch {}/{}'.format(epoch + 1, epochs))
for phase in ['train', 'valid']:
if phase == 'train':
print('Training...')
model.train(True)
else:
print('Validing...')
model.train(False)
running_loss = 0.0
running_corrects = 0
for batch, data in enumerate(dataloader[phase]):
x, y = data
x, y = Variable(x.cuda()), Variable(y.cuda())
y_pred = model(x)
_, pred = torch.max(y_pred.data, 1)
optimizer.zero_grad()
loss = loss_f(y_pred, y)
running_loss += loss.data
if phase == 'train':
global_step += 1
loss.backward()
optimizer.step()
running_corrects += torch.sum(pred == y.data)
epoch_loss = running_loss * 32 / len(image_datasets[phase])
epoch_acc = 100 * running_corrects / len(image_datasets[phase])
print('{} Loss:{} ACC:{}'.format(phase, epoch_loss, epoch_acc))
if(phase == 'train'):
f.writelines([str(epoch), ',', str(epoch_loss.item()),',',str(epoch_acc.item()), ','])
if(phase == 'valid'):
f.writelines([str(epoch_acc.item()),',',str(epoch_loss.item()), ';'])
f.flush()
if epoch_acc.item() > best_acc:
torch.save(model, 'best3.pth')
best_acc = epoch_acc.item()
best_epoch = epoch
print('最好的正确率是epoch:', best_epoch+1, ' 正确率为:', best_acc)
print('最好的模型在epoch:', best_epoch)
torch.save(model, 'vggmodel2.pth')