Python 无法提高模型精度

Python 无法提高模型精度,python,machine-learning,computer-vision,pytorch,Python,Machine Learning,Computer Vision,Pytorch,我正在建立一个通用的神经网络,将图像(狗/没有狗)和电影评论(好/坏)进行分类。我必须坚持一个非常具体的架构和损失函数,所以改变这两个似乎是不可能的。我的体系结构是一个两层网络,relu后跟一个sigmoid和一个交叉熵损失函数。有1000个时代,学习率约为.001,我的训练准确率为100%,测试准确率为.72。我一直在寻找提高测试准确率的建议。以下是我的布局: def train_net(epochs,batch_size,train_x,train_y,model_size,lr): n

我正在建立一个通用的神经网络,将图像(狗/没有狗)和电影评论(好/坏)进行分类。我必须坚持一个非常具体的架构和损失函数,所以改变这两个似乎是不可能的。我的体系结构是一个两层网络,relu后跟一个sigmoid和一个交叉熵损失函数。有1000个时代,学习率约为.001,我的训练准确率为100%,测试准确率为.72。我一直在寻找提高测试准确率的建议。以下是我的布局:

def train_net(epochs,batch_size,train_x,train_y,model_size,lr):
  n_x,n_h,n_y=model_size
  model = Net(n_x, n_h, n_y)
  optim = torch.optim.Adam(model.parameters(),lr=0.005)
  loss_function = nn.BCELoss() 
  train_losses = []
  accuracy = []
  for epoch in range(epochs):
    count=0
    model.train() 
    train_loss = []
    batch_accuracy = []
    for idx in range(0, train_x.shape[0], batch_size):

      batch_x = torch.from_numpy(train_x[idx : idx + batch_size]).float() 
      batch_y = torch.from_numpy(train_y[:,idx : idx + batch_size]).float()    
      model_output = model(batch_x) 
      batch_accuracy=[]  
      loss = loss_function(model_output, batch_y) 
      train_loss.append(loss.item())

      preds = model_output > 0.5
      nb_correct = (preds == batch_y).sum()
      count+=nb_correct.item()                            
      optim.zero_grad()
      loss.backward()
# Scheduler made it worse 
# scheduler.step(loss.item())  
  optim.step()

    if epoch % 100 == 1:
      train_losses.append(train_loss)
      print("Iteration : {}, Training loss: {} ,Accuracy %: {}".format(epoch,np.mean(train_loss),(count/train_x.shape[0])*100))              
  plt.plot(np.squeeze(train_losses))
  plt.ylabel('loss')
  plt.xlabel('iterations (per tens)')
  plt.title("Learning rate =" + str(lr))
  plt.show()
  return model
我的模型参数:

batch_size = 32
lr = 0.0001
epochs = 1500

n_x = 12288     # num_px * num_px * 3
n_h = 7
n_y = 1
model_size=n_x,n_h,n_y
model=train_net(epochs,batch_size,train_x,train_y,model_size,or)
这是测试阶段

model.eval()  #Setting the model to eval mode, hence making it deterministic.
test_loss = []
count=0;
loss_function = nn.BCELoss()

for idx in range(0, test_x.shape[0], batch_size):
  with torch.no_grad():   
    batch_x = torch.from_numpy(test_x[idx : idx + batch_size]).float() 
    batch_y = torch.from_numpy(test_y[:,idx : idx + batch_size]).float()
    model_output = model(batch_x)
    preds = model_output > 0.5
    loss = loss_function(model_output, batch_y)
    test_loss.append(loss.item())
    nb_correct = (preds == batch_y).sum()
    count+=nb_correct.item()  

print("test loss: {},test accuracy: {}".format(np.mean(test_loss),count/test_x.shape[0]))
我尝试过的事情:
搅乱学习速度、增加动力、使用调度程序和改变批量大小。当然,这些主要是猜测,而不是基于任何有效的假设。

根据您的陈述,您的培训准确率为100%,而您的测试准确率则明显低于72%,您似乎明显地过度拟合了数据集

简言之,这意味着您的模型正在针对您提供给它的训练数据对其自身进行过专门的训练,从而发现训练数据中可能存在但并非分类固有的怪癖。例如,如果训练数据中的狗都是白色的,那么模型最终将学会将白色与狗关联,并且很难识别测试数据集中其他颜色的狗

有很多方法可以解决这个问题:可以找到一个用简单术语编写的关于这个主题的源代码丰富的概述

如果没有更多关于改变神经网络结构的具体约束的信息,很难说你会改变什么,也不能改变什么。但是,权重正则化和退出通常会产生很大的效果(在上面的文章中进行了描述)。您还可以自由地对模型实施提前停止和权重约束


我将让您在pytorch中查找有关如何实施这些特定策略的资源,但这应该是一个很好的起点。

您面临的问题是过度拟合。由于训练集的准确率为100%,您的模型有效地记住了训练集,然后未能将其推广到看不见的样本。好消息是这是一个非常常见的重大挑战

你需要正规化。一种方法是
退出,即在不同的训练时期,随机丢弃一组NN连接,迫使网络“学习”交替路径和权重,并软化参数空间中的尖峰。由于您需要保持架构和功能不变,因此无法在中添加这样的选项(不过为了完整起见,请阅读PyTorch中的dropout描述和实现)

根据您的约束条件,您需要使用类似于L2或L1权重正则化的方法。这通常表现为在成本/损失函数中添加一个附加项,这会惩罚较大的权重。在PyTorch中,L2正则化是通过
torch.optim
构造实现的,带有
权重衰减
选项。(请参阅文档:,搜索“L2”)

对于您的代码,请尝试以下操作:

def train_net(epochs,batch_size,train_x,train_y,model_size,lr):
  ...
  optim = torch.optim.Adam(model.parameters(),...,weight_decay=0.01)
  ...

“我将留给你去寻找如何在pytorch中实现这些特定策略的资源”-OP提供他们的代码,因此关于这方面的一些代码建议应该是一个好答案的一部分;否则,你会大量重复链接文章中的内容,而评论中的链接本身就足够了。谢谢。我的损失被卡住了,并没有从它卡住的地方移动。有趣!你试过正规化吗?如果您的模型在训练集上达到100%的准确性,那么就没有更多的空间来改变损失,因为您已经找到了给定数据集的全局最优参数。如果是这样的话,你已经完全记住了这个集合,这是不理想的,也不能概括。是这样吗?你能贴一张你的损失和准确性的图吗?@Aliman如果你觉得这个回答很有价值(或其他),你介意选择它作为你问题的合适答案吗?