>기술 주변기기 >일체 포함 >훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

WBOY
WBOY앞으로
2023-04-08 21:31:071412검색

이 글에서는 훈련과 검증 중에 발생할 수 있는 상황을 요약하고 이 차트가 우리에게 어떤 정보를 제공할 수 있는지 소개하겠습니다.

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

몇 가지 간단한 코드부터 시작해 보겠습니다. 다음 코드는 기본 학습 프로세스 프레임워크를 설정합니다.

from sklearn.model_selection import train_test_split<br>from sklearn.datasets import make_classification<br>import torch<br>from torch.utils.data import Dataset, DataLoader<br>import torch.optim as torch_optim<br>import torch.nn as nn<br>import torch.nn.functional as F<br>import numpy as np<br>import matplotlib.pyplot as pltclass MyCustomDataset(Dataset):<br>def __init__(self, X, Y, scale=False):<br>self.X = torch.from_numpy(X.astype(np.float32))<br>self.y = torch.from_numpy(Y.astype(np.int64))<br><br>def __len__(self):<br>return len(self.y)<br><br>def __getitem__(self, idx):<br>return self.X[idx], self.y[idx]def get_optimizer(model, lr=0.001, wd=0.0):<br>parameters = filter(lambda p: p.requires_grad, model.parameters())<br>optim = torch_optim.Adam(parameters, lr=lr, weight_decay=wd)<br>return optimdef train_model(model, optim, train_dl, loss_func):<br># Ensure the model is in Training mode<br>model.train()<br>total = 0<br>sum_loss = 0<br>for x, y in train_dl:<br>batch = y.shape[0]<br># Train the model for this batch worth of data<br>logits = model(x)<br># Run the loss function. We will decide what this will be when we call our Training Loop<br>loss = loss_func(logits, y)<br># The next 3 lines do all the PyTorch back propagation goodness<br>optim.zero_grad()<br>loss.backward()<br>optim.step()<br># Keep a running check of our total number of samples in this epoch<br>total += batch<br># And keep a running total of our loss<br>sum_loss += batch*(loss.item())<br>return sum_loss/total<br>def train_loop(model, train_dl, valid_dl, epochs, loss_func, lr=0.1, wd=0):<br>optim = get_optimizer(model, lr=lr, wd=wd)<br>train_loss_list = []<br>val_loss_list = []<br>acc_list = []<br>for i in range(epochs): <br>loss = train_model(model, optim, train_dl, loss_func)<br># After training this epoch, keep a list of progress of <br># the loss of each epoch <br>train_loss_list.append(loss)<br>val, acc = val_loss(model, valid_dl, loss_func)<br># Likewise for the validation loss and accuracy<br>val_loss_list.append(val)<br>acc_list.append(acc)<br>print("training loss: %.5f valid loss: %.5f accuracy: %.5f" % (loss, val, acc))<br><br>return train_loss_list, val_loss_list, acc_list<br>def val_loss(model, valid_dl, loss_func):<br># Put the model into evaluation mode, not training mode<br>model.eval()<br>total = 0<br>sum_loss = 0<br>correct = 0<br>batch_count = 0<br>for x, y in valid_dl:<br>batch_count += 1<br>current_batch_size = y.shape[0]<br>logits = model(x)<br>loss = loss_func(logits, y)<br>sum_loss += current_batch_size*(loss.item())<br>total += current_batch_size<br># All of the code above is the same, in essence, to<br># Training, so see the comments there<br># Find out which of the returned predictions is the loudest<br># of them all, and that's our prediction(s)<br>preds = logits.sigmoid().argmax(1)<br># See if our predictions are right<br>correct += (preds == y).float().mean().item()<br>return sum_loss/total, correct/batch_count<br>def view_results(train_loss_list, val_loss_list, acc_list):<br>plt.rcParams["figure.figsize"] = (15, 5)<br>plt.figure()<br>epochs = np.arange(0, len(train_loss_list)) plt.subplot(1, 2, 1)<br>plt.plot(epochs-0.5, train_loss_list)<br>plt.plot(epochs, val_loss_list)<br>plt.title('model loss')<br>plt.ylabel('loss')<br>plt.xlabel('epoch')<br>plt.legend(['train', 'val', 'acc'], loc = 'upper left')<br><br>plt.subplot(1, 2, 2)<br>plt.plot(acc_list)<br>plt.title('accuracy')<br>plt.ylabel('accuracy')<br>plt.xlabel('epoch')<br>plt.legend(['train', 'val', 'acc'], loc = 'upper left')<br>plt.show()<br><br>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):<br># We'll make a fictitious dataset, assuming all relevant<br># EDA / Feature Engineering has been done and this is our <br># resultant data<br>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)<br><br>if break_it: # Specifically mess up the data<br>X = np.random.rand(n_samples,n_features)<br>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)<br>valid_ds = MyCustomDataset(X_val, y_val)<br>train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True)<br>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)<br>view_results(train_loss_list, val_loss_list, acc_list)

위 코드는 매우 간단합니다. 데이터 획득, 교육 및 검증의 기본 프로세스입니다.

시나리오 1 - 모델이 학습하는 것처럼 보이지만 검증이나 정확도가 좋지 않습니다.

모델 Train loss는 하이퍼파라미터에 관계없이 천천히 감소하지만 Val loss는 감소하지 않으며 Accuracy는 학습 중임을 나타내지 않습니다. .

예를 들어 이 경우 이진 분류의 정확도는 약 50% 정도입니다.

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

데이터에 '학습'을 허용할 만큼 충분한 정보가 없습니다. 학습 데이터에 모델이 '학습'할 수 있을 만큼 충분한 정보가 포함되어 있지 않을 수 있습니다.

이 경우(코드에서 데이터를 학습할 때 임의의 데이터) 이는 실질적인 내용을 학습할 수 없음을 의미합니다.

데이터에는 학습할 수 있는 충분한 정보가 있어야 합니다. EDA와 기능 엔지니어링이 핵심입니다! 모델은 존재하지 않는 것을 만들어내는 것이 아니라 학습할 수 있는 것을 학습합니다.

시나리오 2 - 학습, 검증 및 정확도 곡선이 모두 매우 불안정합니다.

예를 들어 다음 코드는 lr=0.1, bs=128

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

"학습률이 너무 높습니다." 또는 "배치가 너무 높습니다." 작게" 시도해 볼 수 있습니다. 학습률이 0.1에서 0.001로 감소합니다. 즉, "바운스"되지 않고 부드럽게 감소한다는 의미입니다.

get_data_train_and_show(Scenario_1_Model_1(), lr=0.001)

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

학습률을 낮추는 것 외에도 배치 크기를 늘리면 더 부드러워집니다.

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

시나리오 3 - 훈련 손실이 0에 가깝고 정확도가 좋아 보이지만 검증도 떨어지지 않고 올라갑니다

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

이것은 확실히 과적합입니다. 훈련 손실이 낮습니다. 정확도가 높고 검증 손실과 훈련 손실이 점점 커지고 있는데 이는 전형적인 과적합 지표입니다.

기본적으로 모델 학습 능력이 너무 강해요. 훈련 데이터를 너무 잘 기억하므로 새 데이터로 일반화할 수도 없습니다.

가장 먼저 시도할 수 있는 것은 모델의 복잡성을 줄이는 것입니다.

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

이렇게 하면 더 좋아지고 L2 가중치 감소 정규화가 도입되어 다시 더 좋아질 수 있습니다(얕은 모델의 경우).

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

모델의 깊이와 크기를 유지하려면 드롭아웃(더 깊은 모델의 경우)을 사용해 볼 수 있습니다.

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

场景 4 - 训练和验证表现良好,但准确度没有提高

lr = 0.001,bs = 128(默认,分类类别= 5

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

没有足够的学习能力:模型中的其中一层的参数少于模型可能输出中的类。 在这种情况下,当有 5 个可能的输出类时,中间的参数只有 2 个。

这意味着模型会丢失信息,因为它不得不通过一个较小的层来填充它,因此一旦层的参数再次扩大,就很难恢复这些信息。

所以需要记录层的参数永远不要小于模型的输出大小。

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

훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?

总结

以上就是一些常见的训练、验证时的曲线的示例,希望你在遇到相同情况时可以快速定位并且改进。


위 내용은 훈련 및 검증 측정항목 그래프는 머신러닝에서 무엇을 알려줄 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 51cto.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제