I am working on the face recognition project of the fer-2013 dataset. The output loss is always 0 and the accuracy is always 100. How can I solve it
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
from tqdm import tqdm
BATCH_SIZE = 128
LR = 0.01
EPOCH = 60
DEVICE = torch.device(‘cpu’)
path_train = ‘face_images/train_set’
path_vaild = ‘face_images/vaild_set’
transforms_train = transforms.Compose([
transforms.Grayscale(),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.5, contrast=0.5),
transforms.ToTensor()
])
transforms_vaild = transforms.Compose([
transforms.Grayscale(),
transforms.ToTensor()
])
data_train = torchvision.datasets.ImageFolder(root=path_train,transform=transforms_train)
data_vaild = torchvision.datasets.ImageFolder(root=path_vaild,transform=transforms_vaild)
train_set = torch.utils.data.DataLoader(dataset=data_train,batch_size=BATCH_SIZE,shuffle=True)
vaild_set = torch.utils.data.DataLoader(dataset=data_vaild,batch_size=BATCH_SIZE,shuffle=False)
class VGG(nn.Module):
def init(self, *args):
super(VGG, self).init()
def forward(self, x):
return x.view(x.shape[0],-1)
def vgg_block(num_convs, in_channels, out_channels):
blk = []
for i in range(num_convs):
if i == 0:
blk.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1))
else:
blk.append(nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1))
blk.append(nn.ReLU())
blk.append(nn.MaxPool2d(kernel_size=2, stride=2)) # 这里会使宽高减半
return nn.Sequential(*blk)
conv_arch = ((2, 1, 32), (3, 32, 64), (3, 64, 128))
fc_features = 128 * 6* 6 # c * w * h
fc_hidden_units = 4096 # 任意
def vgg(conv_arch, fc_features, fc_hidden_units):
net = nn.Sequential()
for i, (num_convs, in_channels, out_channels) in enumerate(conv_arch):
net.add_module("vgg_block_" + str(i+1), vgg_block(num_convs, in_channels, out_channels))
net.add_module("fc", nn.Sequential(
VGG(),
nn.Linear(fc_features, fc_hidden_units),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(fc_hidden_units, fc_hidden_units),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(fc_hidden_units, 7)
))
return net
model = vgg(conv_arch, fc_features, fc_hidden_units)
model.to(DEVICE)
optimizer = optim.SGD(model.parameters(),lr=LR,momentum=0.9)
#optim.Adam(model.parameters())
criterion = nn.CrossEntropyLoss()
train_loss = []
train_ac = []
vaild_loss = []
vaild_ac = []
y_pred = []
def train(model,device,dataset,optimizer,epoch):
model.train()
correct = 0
for i,(x,y) in tqdm(enumerate(dataset)):
x , y = x.to(device), y.to(device)
optimizer.zero_grad()
output = model(x)
pred = output.max(1,keepdim=True)[1]
correct += pred.eq(y.view_as(pred)).sum().item()
loss = criterion(output,y)
loss.backward()
optimizer.step()
train_ac.append(correct/len(data_train))
#train_loss.append(loss.item())
print("Epoch {} Loss {:.4f} Accuracy {}/{} ({:.0f}%)".format(epoch,loss,correct,len(data_train),100*correct/len(data_train)))
def vaild(model,device,dataset):
model.eval()
correct = 0
with torch.no_grad():
for i,(x,y) in tqdm(enumerate(dataset)):
x,y = x.to(device) ,y.to(device)
output = model(x)
loss = criterion(output,y)
pred = output.max(1,keepdim=True)[1]
global y_pred
y_pred += pred.view(pred.size()[0]).cpu().numpy().tolist()
correct += pred.eq(y.view_as(pred)).sum().item()
#vaild_ac.append(correct/len(data_vaild))
vaild_loss.append(loss.item())
print("Test Loss {:.4f} Accuracy {}/{} ({:.0f}%)".format(loss,correct,len(data_vaild),100.*correct/len(data_vaild)))
def RUN():
for epoch in range(1,EPOCH+1):
‘’‘if epoch==15 :
LR = 0.1
optimizer=optimizer = optim.SGD(model.parameters(),lr=LR,momentum=0.9)
if(epoch>30 and epoch%15==0):
LR*=0.1
optimizer=optimizer = optim.SGD(model.parameters(),lr=LR,momentum=0.9)
‘’’
train(model,device=DEVICE,dataset=train_set,optimizer=optimizer,epoch=epoch)
vaild(model,device=DEVICE,dataset=vaild_set)
torch.save(model,'model/model_vgg.pkl')
if name == ‘main’:
RUN()