![](/img/trans.png)
[英]Cannot improve the accuracy of my Multilayer Perceptron (MLP) model in classification
[英]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_decay
的torch.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.