自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

人工智能 機器學(xué)習(xí)
我們在訓(xùn)練和驗證模型時都會將訓(xùn)練指標(biāo)保存成起來制作成圖表,這樣可以在結(jié)束后進行查看和分析,但是你真的了解這些指標(biāo)的圖表的含義嗎?

在本文中將對訓(xùn)練和驗證可能產(chǎn)生的情況進行總結(jié)并介紹這些圖表到底能為我們提供什么樣的信息。

讓我們從一些簡單的代碼開始以下代碼建立了一個基本的訓(xùn)練流程框架。

from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
import torch
from torch.utils.data import Dataset, DataLoader
import torch.optim as torch_optim
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as pltclass MyCustomDataset(Dataset):
def __init__(self, X, Y, scale=False):
self.X = torch.from_numpy(X.astype(np.float32))
self.y = torch.from_numpy(Y.astype(np.int64))

def __len__(self):
return len(self.y)

def __getitem__(self, idx):
return self.X[idx], self.y[idx]def get_optimizer(model, lr=0.001, wd=0.0):
parameters = filter(lambda p: p.requires_grad, model.parameters())
optim = torch_optim.Adam(parameters, lr=lr, weight_decay=wd)
return optimdef train_model(model, optim, train_dl, loss_func):
# Ensure the model is in Training mode
model.train()
total = 0
sum_loss = 0
for x, y in train_dl:
batch = y.shape[0]
# Train the model for this batch worth of data
logits = model(x)
# Run the loss function. We will decide what this will be when we call our Training Loop
loss = loss_func(logits, y)
# The next 3 lines do all the PyTorch back propagation goodness
optim.zero_grad()
loss.backward()
optim.step()
# Keep a running check of our total number of samples in this epoch
total += batch
# And keep a running total of our loss
sum_loss += batch*(loss.item())
return sum_loss/total
def train_loop(model, train_dl, valid_dl, epochs, loss_func, lr=0.1, wd=0):
optim = get_optimizer(model, lr=lr, wd=wd)
train_loss_list = []
val_loss_list = []
acc_list = []
for i in range(epochs):
loss = train_model(model, optim, train_dl, loss_func)
# After training this epoch, keep a list of progress of
# the loss of each epoch
train_loss_list.append(loss)
val, acc = val_loss(model, valid_dl, loss_func)
# Likewise for the validation loss and accuracy
val_loss_list.append(val)
acc_list.append(acc)
print("training loss: %.5f valid loss: %.5f accuracy: %.5f" % (loss, val, acc))

return train_loss_list, val_loss_list, acc_list
def val_loss(model, valid_dl, loss_func):
# Put the model into evaluation mode, not training mode
model.eval()
total = 0
sum_loss = 0
correct = 0
batch_count = 0
for x, y in valid_dl:
batch_count += 1
current_batch_size = y.shape[0]
logits = model(x)
loss = loss_func(logits, y)
sum_loss += current_batch_size*(loss.item())
total += current_batch_size
# All of the code above is the same, in essence, to
# Training, so see the comments there
# Find out which of the returned predictions is the loudest
# of them all, and that's our prediction(s)
preds = logits.sigmoid().argmax(1)
# See if our predictions are right
correct += (preds == y).float().mean().item()
return sum_loss/total, correct/batch_count
def view_results(train_loss_list, val_loss_list, acc_list):
plt.rcParams["figure.figsize"] = (15, 5)
plt.figure()
epochs = np.arange(0, len(train_loss_list)) plt.subplot(1, 2, 1)
plt.plot(epochs-0.5, train_loss_list)
plt.plot(epochs, val_loss_list)
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'val', 'acc'], loc = 'upper left')

plt.subplot(1, 2, 2)
plt.plot(acc_list)
plt.title('accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'val', 'acc'], loc = 'upper left')
plt.show()

def get_data_train_and_show(model, batch_size=128, n_samples=10000, n_classes=2, n_features=30, val_size=0.2, epochs=20, lr=0.1, wd=0, break_it=False):
# We'll make a fictitious dataset, assuming all relevant
# EDA / Feature Engineering has been done and this is our
# resultant data
X, y = make_classification(n_samples=n_samples, n_classes=n_classes, n_features=n_features, n_informative=n_features, n_redundant=0, random_state=1972)

if break_it: # Specifically mess up the data
X = np.random.rand(n_samples,n_features)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_size, random_state=1972) train_ds = MyCustomDataset(X_train, y_train)
valid_ds = MyCustomDataset(X_val, y_val)
train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True)
valid_dl = DataLoader(valid_ds, batch_size=batch_size, shuffle=True) train_loss_list, val_loss_list, acc_list = train_loop(model, train_dl, valid_dl, epochs=epochs, loss_func=F.cross_entropy, lr=lr, wd=wd)
view_results(train_loss_list, val_loss_list, acc_list)

以上的代碼很簡單,就是獲取數(shù)據(jù),訓(xùn)練,驗證這樣一個基本的流程,下面我們開始進入正題。

場景 1 - 模型似乎可以學(xué)習(xí),但在驗證或準(zhǔn)確性方面表現(xiàn)不佳

無論超參數(shù)如何,模型 Train loss 都會緩慢下降,但 Val loss 不會下降,并且其 Accuracy 并不表明它正在學(xué)習(xí)任何東西。

比如在這種情況下,二進制分類的準(zhǔn)確率徘徊在 50% 左右。

class Scenario_1_Model_1(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, out_features)
def forward(self, x):
x = self.lin1(x)
return x
get_data_train_and_show(Scenario_1_Model_1(), lr=0.001, break_it=True)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

數(shù)據(jù)中沒有足夠的信息來允許‘學(xué)習(xí)’,訓(xùn)練數(shù)據(jù)可能沒有包含足夠的信息來讓模型“學(xué)習(xí)”。

在這種情況下(代碼中訓(xùn)練數(shù)據(jù)時隨機數(shù)據(jù)),這意味著它無法學(xué)習(xí)任何實質(zhì)內(nèi)容。

數(shù)據(jù)必須有足夠的信息可以從中學(xué)習(xí)。 EDA 和特征工程是關(guān)鍵! 模型學(xué)習(xí)可以學(xué)到的東西,而不是不是編造不存在的東西。

場景 2 — 訓(xùn)練、驗證和準(zhǔn)確度曲線都非常不穩(wěn)

例如下面代碼: lr=0.1,bs=128

class Scenario_2_Model_1(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, out_features)
def forward(self, x):
x = self.lin1(x)
return x
get_data_train_and_show(Scenario_2_Model_1(), lr=0.1)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

“學(xué)習(xí)率太高”或“批量太小”可以嘗試將學(xué)習(xí)率從 0.1 降低到 0.001,這意味著它不會“反彈”,而是會平穩(wěn)地降低。

get_data_train_and_show(Scenario_1_Model_1(), lr=0.001)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

除了降低學(xué)習(xí)率外,增加批量大小也會使其更平滑。

get_data_train_and_show(Scenario_1_Model_1(), lr=0.001, batch_size=256)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

場景 3——訓(xùn)練損失接近于零,準(zhǔn)確率看起來還不錯,但驗證 并沒有下降,并且還上升了

class Scenario_3_Model_1(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, 50)
self.lin2 = nn.Linear(50, 150)
self.lin3 = nn.Linear(150, 50)
self.lin4 = nn.Linear(50, out_features)
def forward(self, x):
x = F.relu(self.lin1(x))
x = F.relu(self.lin2(x))
x = F.relu(self.lin3(x))
x = self.lin4(x)
return x
get_data_train_and_show(Scenario_3_Model_1(), lr=0.001)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

這肯定是過擬合了:訓(xùn)練損失低和準(zhǔn)確率高,而驗證損失和訓(xùn)練損失越來越大,都是經(jīng)典的過擬合指標(biāo)。

從根本上說,你的模型學(xué)習(xí)能力太強了。 它對訓(xùn)練數(shù)據(jù)的記憶太好,這意味著它也不能泛化到新數(shù)據(jù)。

我們可以嘗試的第一件事是降低模型的復(fù)雜性。

class Scenario_3_Model_2(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, 50)
self.lin2 = nn.Linear(50, out_features)
def forward(self, x):
x = F.relu(self.lin1(x))
x = self.lin2(x)
return x
get_data_train_and_show(Scenario_3_Model_2(), lr=0.001)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

這讓它變得更好了,還可以引入 L2 權(quán)重衰減正則化,讓它再次變得更好(適用于較淺的模型)。

get_data_train_and_show(Scenario_3_Model_2(), lr=0.001, wd=0.02)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

如果我們想保持模型的深度和大小,可以嘗試使用 dropout(適用于更深的模型)。

class Scenario_3_Model_3(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, 50)
self.lin2 = nn.Linear(50, 150)
self.lin3 = nn.Linear(150, 50)
self.lin4 = nn.Linear(50, out_features)
self.drops = nn.Dropout(0.4)
def forward(self, x):
x = F.relu(self.lin1(x))
x = self.drops(x)
x = F.relu(self.lin2(x))
x = self.drops(x)
x = F.relu(self.lin3(x))
x = self.drops(x)
x = self.lin4(x)
return x
get_data_train_and_show(Scenario_3_Model_3(), lr=0.001)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

場景 4 - 訓(xùn)練和驗證表現(xiàn)良好,但準(zhǔn)確度沒有提高

lr = 0.001,bs = 128(默認,分類類別= 5

class Scenario_4_Model_1(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, 2)
self.lin2 = nn.Linear(2, out_features)
def forward(self, x):
x = F.relu(self.lin1(x))
x = self.lin2(x)
return x
get_data_train_and_show(Scenario_4_Model_1(out_features=5), lr=0.001, n_classes=5)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

沒有足夠的學(xué)習(xí)能力:模型中的其中一層的參數(shù)少于模型可能輸出中的類。 在這種情況下,當(dāng)有 5 個可能的輸出類時,中間的參數(shù)只有 2 個。

這意味著模型會丟失信息,因為它不得不通過一個較小的層來填充它,因此一旦層的參數(shù)再次擴大,就很難恢復(fù)這些信息。

所以需要記錄層的參數(shù)永遠不要小于模型的輸出大小。

class Scenario_4_Model_2(nn.Module):
def __init__(self, in_features=30, out_features=2):
super().__init__()
self.lin1 = nn.Linear(in_features, 50)
self.lin2 = nn.Linear(50, out_features)
def forward(self, x):
x = F.relu(self.lin1(x))
x = self.lin2(x)
return x
get_data_train_and_show(Scenario_4_Model_2(out_features=5), lr=0.001, n_classes=5)

機器學(xué)習(xí)中訓(xùn)練和驗證指標(biāo)曲線圖能告訴我們什么?

總結(jié)

以上就是一些常見的訓(xùn)練、驗證時的曲線的示例,希望你在遇到相同情況時可以快速定位并且改進。


責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2009-06-12 13:59:04

2013-11-11 11:10:03

WE大會馬化騰

2013-04-26 17:48:04

WWDC

2013-05-20 16:12:23

2021-05-22 06:56:18

OpenWrt 路由器刷機

2021-01-04 11:10:14

鴻蒙HarmonyOSCanvas

2024-04-09 09:08:09

Kafka消息架構(gòu)

2020-09-08 12:15:40

應(yīng)用程序安全DevSecOps漏洞

2013-06-09 11:18:44

C++程序員

2021-11-10 11:46:49

《魷魚游戲》網(wǎng)絡(luò)安全安全觀察

2013-08-05 10:19:34

小時代電影大數(shù)據(jù)

2018-08-28 16:35:57

2023-11-23 13:50:26

AI模型

2017-02-10 11:56:00

2021-03-18 18:38:48

邊緣計算云計算數(shù)字化

2020-04-24 09:35:46

機器學(xué)習(xí)技術(shù)模型

2018-08-05 06:48:34

2022-01-13 10:24:53

供應(yīng)鏈攻擊供應(yīng)商第三方攻擊

2016-09-20 09:36:33

外媒速遞DevOps自動化工具

2019-12-04 15:30:22

Android 11谷歌手機
點贊
收藏

51CTO技術(shù)棧公眾號