当我开始训练我的模型时,损失值在下降,但准确率值始终不变。我不知道为什么?
# -*- coding: utf-8 -*-#Librariesimport torchimport torch.nn.functional as Ffrom torch import autograd, nnfrom torch.autograd import Variableimport numpy as npimport matplotlib.pyplot as pltfrom torchvision import transforms, datasetsfrom torch.utils import data"""Olivetti face dataset"""from sklearn.datasets import fetch_olivetti_faces# Olivetti dataset downloadolivetti = fetch_olivetti_faces()train = olivetti.imageslabel = olivetti.targetX = trainY = labelprint("Format for X:", X.shape)print("Format for Y: ", Y.shape)print("\nDownload Ok")"""Set for train"""train_rate = 0.8X_train = np.zeros([int(train_rate * X.shape[0]),64,64], dtype=float)Y_train = np.zeros([int(train_rate * X.shape[0])], dtype=int)X_val = np.zeros([int((1-train_rate) * X.shape[0]+1),64,64], dtype=float)Y_val = np.zeros([int((1-train_rate) * X.shape[0]+1)], dtype=int)#Split data for train and validationfor i in range(X.shape[0]): ie=0 iv=0 if (i%10)/10 >= train_rate: X_train[ie] = X[i] Y_train[ie] = Y[i] ie += 1 else: X_val[iv] = X[i] Y_val[iv] = Y[i] iv += 1X_train = X_train.reshape(320,-1,64,64)X_val = X_val.reshape(80,-1,64,64)print(Y_train.shape)X_train = torch.Tensor(X_train)Y_train = torch.Tensor(Y_train)X_val = torch.Tensor(X_val)Y_val = torch.Tensor(Y_val) batch_size = 20train_loader = torch.utils.data.DataLoader(X_train, batch_size=batch_size, )val_loader = torch.utils.data.DataLoader(X_val, batch_size=batch_size, )class CNNModule(nn.Module): def __init__(self): super(CNNModule, self).__init__() self.conv1 = nn.Conv2d(1, 6, 5) self.pool = nn.MaxPool2d(2, 2) self.conv2 = nn.Conv2d(6, 16, 5) self.fc1 = nn.Linear(16 * 13 * 13, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 40) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 16 * 13 * 13) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return xdef make_train(model,dataset,n_iters,gpu): # Organize data X_train,Y_train,X_val,Y_val = dataset kriter = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(),lr=0.01) #Arrays to save loss and accuracy tl=np.zeros(n_iters) #For train loss ta=np.zeros(n_iters) #For train accuracy vl=np.zeros(n_iters) #For validation loss va=np.zeros(n_iters) #For validation accuracy # Convert labels to long Y_train = Y_train.long() Y_val = Y_val.long() # GPU control if gpu: X_train,Y_train = X_train.cuda(),Y_train.cuda() X_val,Y_val = X_val.cuda(),Y_val.cuda() model = model.cuda() # Parameters to GPU! print("Using GPU") else: print("Using CPU") # print(X_train.shape) # print(Y_train.shape) for i in range(n_iters): # train forward train_out = model.forward(X_train) train_loss = kriter(train_out,Y_train) # Backward and optimization train_loss.backward() optimizer.step() optimizer.zero_grad() # Compute train accuracy train_predict = train_out.cpu().detach().argmax(dim=1) train_accuracy = (train_predict.cpu().numpy()==Y_train.cpu().numpy()).mean() # For validation val_out = model.forward(X_val) val_loss = kriter(val_out,Y_val) # Compute validation accuracy val_predict = val_out.cpu().detach().argmax(dim=1) val_accuracy = (val_predict.cpu().numpy()==Y_val.cpu().numpy()).mean() tl[i] = train_loss.cpu().detach().numpy() ta[i] = train_accuracy vl[i] = val_loss.cpu().detach().numpy() va[i] = val_accuracy # Show result each 5 loop if i%5==0: print("Loop --> ",i) print("Train Loss :",train_loss.cpu().detach().numpy()) print("Train Accuracy :",train_accuracy) print("Validation Loss :",val_loss.cpu().detach().numpy()) print("Validation Accuracy :",val_accuracy) model = model.cpu() #Print result plt.subplot(2,2,1) plt.plot(np.arange(n_iters), tl, 'r-') plt.subplot(2,2,2) plt.plot(np.arange(n_iters), ta, 'b--') plt.subplot(2,2,3) plt.plot(np.arange(n_iters), vl, 'r-') plt.subplot(2,2,4) plt.plot(np.arange(n_iters), va, 'b--') dataset = X_train,Y_train,X_val,Y_valgpu = Truegpu = gpu and torch.cuda.is_available() model = CNNModule()make_train(model,dataset,100,gpu)
输出:
使用CPULoop –> 0训练损失 : 3.6302185训练准确率 : 0.0验证损失 : 3.6171098验证准确率 : 0.0Loop –> 5训练损失 : 3.557933训练准确率 : 0.996875验证损失 : 3.545982验证准确率 : 0.9875…Loop –> 95训练损失 : 0.04211783训练准确率 : 0.996875验证损失 : 0.13397054验证准确率 : 0.9875
回答:
从你的代码看,
train_accuracy = (train_predict.cpu().numpy()==Y_train.cpu().numpy()).mean()
你计算的是正确值的平均值,这就是为什么你在每个循环中得到相同的结果。相反,你应该用总的正确数除以总的样本数来计算准确率。