簡體   English   中英

無法提高 model 精度

[英]Cannot improve model accuracy

我正在構建一個通用的神經網絡,可以對圖像(狗/沒有狗)和電影評論(好/壞)進行分類。 我必須堅持一個非常具體的架構並丟失 function 所以改變這兩個似乎不合情理。 我的架構是一個兩層網絡,帶有relu,后跟一個sigmoid和一個交叉熵損失function。 使用 1000 個 epoch 和大約.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

我的 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% 的訓練集准確率,您的 model 有效地記住了訓練集,然后無法泛化到未見過的樣本。 好消息是這是一個非常普遍的重大挑戰!

你需要正則化。 一種方法是dropout ,在不同的訓練時期,一組隨機的 NN 連接被丟棄,迫使網絡“學習”替代路徑和權重,並軟化參數空間中的尖峰。 由於您需要保持架構和損失 function 相同,因此您將無法在其中添加這樣的選項(盡管為了完整起見,請閱讀本文以獲取 PyTorch 中 dropout 的描述和實現)。

鑒於您的限制,您將需要使用L2 或 L1 weight regularization 之類的東西。 這通常表現為在成本/損失 function 中添加一個附加項,這會懲罰較大的權重。 在 PyTorch 中, L2 正則化是通過帶有選項weight_decaytorch.optim構造實現的。 (參見文檔: 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)
  ...

根據您的說法,您的訓練准確度為 100%,而您的測試准確度明顯低於 72%,看來您的數據集明顯過度擬合

簡而言之,這意味着您的 model 對您提供的訓練數據進行了過於專門的訓練,發現了訓練數據中可能存在但並非分類固有的怪癖。 例如,如果您的訓練數據中的狗都是白色的,那么 model 最終會學會將白色與狗聯系起來,並且很難識別在測試數據集中給它的其他 colors 的狗。

有很多方法可以解決這個問題:可以在此處找到以簡單術語編寫的、來源良好的主題概述。

如果沒有更多關於改變神經網絡架構的具體限制的信息,很難確定你會改變什么,不能改變什么。 但是,權重正則化和 dropout 通常會產生很大的效果(並在上面的文章中進行了描述。)您還應該自由地對 model 實施提前停止和權重約束。

我將留給您查找有關如何在 pytorch 中實施這些特定策略的資源,但這應該提供一個很好的起點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM