# 4-6-1-15. Validation Solution

I’ve set to 30 epochs so we can see like how this trains or how the training loss drops,

and how the validation loss changes over time.

The way this works is that after each pass,

after each epoch, after each pass through the training set,

then we’re going to do a validation pass.

That’s what this else here means.

So, basically, four of this stuff and then

else basically says after this four loop completes,

then run this code.

That’s what this else here means.

As seen before, we want to turn off our gradients so with torch.no_grad,

and then we’re going to get our images and labels from a test set,

pass it into the images into our model to get our log probabilities, calculate our loss.

So, here, I am going to just be updating our test_loss.

So, test_loss is just an integer that’s going to count

up our loss on our test set as we’re training,

as we’re doing more of these validation passes.

So, this way, we can actually track

the test loss over all the epochs that we’re training.

So, from the law of probabilities,

I can get our actual probability distributions using torch.exponential.

Again, topk1 gives us our predicted classes and we can measure,

we can calculate the equalities.

So, here, we can get our probabilities from our log probabilities using torch.exp,

taking the exponential of a log gives you back into the probabilities.

From that, we do ps.topk, so one,

and this gives us the top_class or predicted class from the network.

Then, using checking for equality,

we can see where our predicted classes match with the true classes from labels.

Again, measure our calculator accuracy.

So, using torch.mean and changing equals into a FloatTensor.

So, I’m going to run this and then let it run for a while,

and then we can see what the actual training

and validation losses look like as we were training this network.

Now, the network is trained, we can see how

the validation loss and the training loss actually

changed over time like as we continue training on more and more data.

So, we see is the training loss drops but

the validation loss actually starts going up over time.

There’s actually a clear sign of overfitting

so our network is getting better and better and better on the training data,

but it’s actually starting to get worse on the validation data.

This is because as it’s learning the training data,

it’s failing to generalize the data outside of that.

Okay. So, this is what the phenomenon of overfitting looks like.

The way that we combine it,

the way that we try to avoid this and prevent it is by

using regularization and specifically, dropout.

So, deep behind dropout is that we randomly drop input units between our layers.

What this does is it forces the network to share information between the weights,

and so this increases this ability to generalize to new data.

PyTorch adding dropout is pretty straightforward.

We just use this nn.Dropout module.

So, we can basically create our classifier like we had before

using the linear transformations to do our hidden layers,

and then we just add self.dropout,

nn.Dropout, and then you give it some drop probability.

In this case, this is 20 percent,

so this is the probability that you’ll drop a unit.

In the forward method, it’s pretty similar.

So, we just pass in x,

which is our input tensor,

we’re going to make sure it’s flattened,

and then we pass this tensor through each of

our fully connected layers into an activation,

relu activation and then through dropout.

Our last layer is the output layer so we’re not going to use dropout here.

So, when we’re actually doing inference,

if we’re trying to make predictions with our network,

we want to have all of our units available, right?

So, in this case,

we want to turn off dropout when we’re doing validation,

testing, when we’re trying to make predictions.

So, to do that, we do model.eval.

So, model.eval will turn off dropout and this will allow us to get the most power,

the highest performance out of our network when we’re doing inference.

Then, to go back in the train mode, use model.train.

So, then, the validation pass looks like this now.

So, first, we’re going to turn off our gradients.

So, with torch.no_grad, and then we set our model to evaluation mode,

and then we do our validation pass through the test data.

Then, after all this,

we want to make sure the model is set back to train mode so we do model.train.

Okay. So, now, I’m going to leave it up to you to create your new model.

Try adding dropout to it and then try training your model with dropout.

Then, again, checkout the training progress of validation using dropout. Cheers.

다시 오신 것을 환영합니다. 여기 유효성 검사 통과에 대한 제 솔루션이 있습니다.

여기에서 우리의 모델이 정의되었습니다.

우리의 손실, 최적화 프로그램, 그리고 이 모든 것.

30 Epoch로 설정하여 이것이 어떻게 훈련되는지 또는 훈련 손실이 어떻게 떨어지는지 볼 수 있습니다.

시간이 지남에 따라 유효성 검사 손실이 어떻게 변하는지.

이것이 작동하는 방식은 각 패스 후에,

각 에포크 후, 각 훈련 세트를 통과한 후,

그런 다음 유효성 검사를 수행합니다.

이것이 여기서 다른 의미입니다.

그래서 기본적으로 이 4가지를

else는 기본적으로 이 네 개의 루프가 완료된 후에 말합니다.

그런 다음 이 코드를 실행합니다.

이것이 여기서 다른 의미입니다.

이전에 보았듯이 우리는 토치.no_grad를 사용하여 그라디언트를 끄고 싶습니다.

그런 다음 테스트 세트에서 이미지와 레이블을 가져옵니다.

로그 확률을 얻기 위해 모델에 이미지를 전달하고 손실을 계산합니다.

그래서 여기서는 test_loss를 업데이트하려고 합니다.

따라서 test_loss는 계산할 정수일 뿐입니다.

우리가 훈련할 때 테스트 세트에 대한 손실을 늘리고,

이러한 유효성 검사를 더 많이 수행하기 때문입니다.

따라서 이 방법으로 실제로 추적할 수 있습니다.

우리가 훈련하는 모든 에포크에 대한 테스트 손실입니다.

따라서 확률의 법칙으로부터,

Torch.exponential을 사용하여 실제 확률 분포를 얻을 수 있습니다.

다시, topk1은 예측된 클래스를 제공하고 측정할 수 있습니다.

평등을 계산할 수 있습니다.

그래서 여기서 우리는 torch.exp를 사용하여 로그 확률에서 확률을 얻을 수 있습니다.

로그의 지수를 취하면 확률로 되돌아갑니다.

거기에서 우리는 ps.top을 하므로 하나,

이것은 우리에게 네트워크에서 top_class 또는 예측된 클래스를 제공합니다.

그런 다음 같음 검사를 사용하여

예측된 클래스가 레이블의 실제 클래스와 일치하는 위치를 확인할 수 있습니다.

다시 계산기 정확도를 측정합니다.

따라서 torch.mean을 사용하고 equals를 FloatTensor로 변경합니다.

그래서 저는 이것을 실행한 다음 잠시 동안 실행하도록 할 것입니다.

그러면 실제 교육 내용을 확인할 수 있습니다.

검증 손실은 이 네트워크를 훈련하는 것처럼 보입니다.

이제 네트워크가 훈련되었으며 어떻게

유효성 검사 손실과 훈련 손실은 실제로

점점 더 많은 데이터에 대한 교육을 계속하는 것처럼 시간이 지남에 따라 변경되었습니다.

따라서 훈련 손실이 감소하지만

유효성 검사 손실은 실제로 시간이 지남에 따라 증가하기 시작합니다.

실제로 과적합의 명백한 징후가 있습니다.

그래서 우리의 네트워크는 훈련 데이터에 대해 점점 더 좋아지고 있습니다.

그러나 실제로 유효성 검사 데이터에서 악화되기 시작했습니다.

이는 학습 데이터를 학습하면서

그 밖의 데이터를 일반화하는 데 실패하고 있습니다.

괜찮아. 이것이 과적합 현상의 모습입니다.

우리가 그것을 결합하는 방법,

우리가 이것을 피하고 예방하는 방법은

정규화, 특히 드롭아웃을 사용합니다.

따라서 드롭아웃의 이면에는 레이어 사이에 입력 유닛을 무작위로 드롭한다는 것입니다.

이것이 하는 일은 네트워크가 가중치 간에 정보를 공유하도록 하는 것입니다.

그래서 이것은 새로운 데이터로 일반화하는 능력을 증가시킵니다.

드롭아웃을 추가하는 PyTorch는 매우 간단합니다.

우리는 이 nn.Dropout 모듈을 사용합니다.

따라서 기본적으로 이전과 같이 분류기를 만들 수 있습니다.

선형 변환을 사용하여 숨겨진 레이어를 수행하고,

그런 다음 self.dropout을 추가합니다.

nn.Dropout을 선택하고 드롭 확률을 지정합니다.

이 경우 2

이것은 당신이 유닛을 떨어뜨릴 확률입니다.

forward 방식에서는 꽤 비슷합니다.

그래서, 우리는 x를 전달합니다.

입력 텐서인

평평한지 확인하겠습니다.

그리고 우리는 이 텐서를 각각의

우리의 완전히 연결된 레이어를 활성화로,

relu 활성화 및 드롭아웃을 통해.

마지막 레이어는 출력 레이어이므로 여기서는 드롭아웃을 사용하지 않습니다.

이와 관련하여 한 가지 더 주의해야 할 사항이 있습니다.

따라서 실제로 추론을 할 때

네트워크로 예측을 하려는 경우

우리는 모든 단위를 사용할 수 있기를 원합니다. 맞습니까?

따라서 이 경우,

유효성 검사를 수행할 때 드롭아웃을 끄고 싶습니다.

테스트, 예측을 하려고 할 때.

이를 위해 model.val을 수행합니다.

그래서 model.eval은 dropout을 끄고 이것은 우리가 가장 많은 힘을 얻을 수 있게 해 줄 것입니다.

추론을 수행할 때 네트워크에서 가장 높은 성능을 발휘합니다.

그런 다음 기차 모드로 돌아가려면 model.train을 사용합니다.

이제 유효성 검사 패스가 다음과 같이 보입니다.

따라서 먼저 그라디언트를 끕니다.

따라서 torch.no_grad를 사용하여 모델을 평가 모드로 설정합니다.

그런 다음 테스트 데이터를 통해 유효성 검사를 수행합니다.

그런 다음 이 모든 후에,

model.train을 수행하기 위해 모델이 다시 학습 모드로 설정되었는지 확인하고 싶습니다.

괜찮아. 이제 새 모델을 만드는 것은 여러분에게 맡기겠습니다.

드롭아웃을 추가한 다음 드롭아웃으로 모델을 훈련시키십시오.

그런 다음 다시 dropout을 사용하여 validation의 학습 진행 상황을 확인하십시오. 건배.

import torch
from torchvision import datasets, transforms

# Define a transform to normalize the data
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))])

from torch import nn, optim
import torch.nn.functional as F

class Classifier(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 256)
self.fc2 = nn.Linear(256, 128)
self.fc3 = nn.Linear(128, 64)
self.fc4 = nn.Linear(64, 10)

def forward(self, x):
# make sure input tensor is flattened
x = x.view(x.shape[0], -1)

x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = F.relu(self.fc3(x))
x = F.log_softmax(self.fc4(x), dim=1)

return x

model = Classifier()

images, labels = next(iter(testloader))
# Get the class probabilities
ps = torch.exp(model(images))
# Make sure the shape is appropriate, we should get 10 class probabilities for 64 examples
print(ps.shape)

## torch.Size([64, 10])

top_p, top_class = ps.topk(1, dim=1)
# Look at the most likely classes for the first 10 examples
print(top_class[:10,:])

"""
tensor([[5],
[3],
[5],
[9],
[5],
[9],
[5],
[5],
[9],
[5]])
"""

equals = top_class == labels.view(*top_class.shape)

accuracy = torch.mean(equals.type(torch.FloatTensor))
print(f'Accuracy: {accuracy.item()*100

"""
Accuracy: 14.062
"""

####### solution  #########

model = Classifier()
criterion = nn.NLLLoss(reduction='sum')
optimizer = optim.Adam(model.parameters(), lr=0.003)

epochs = 30

train_losses, test_losses = [], []
for e in range(epochs):
tot_train_loss = 0
for images, labels in trainloader:

log_ps = model(images)
loss = criterion(log_ps, labels)
tot_train_loss += loss.item()

loss.backward()
optimizer.step()
else:
tot_test_loss = 0
test_correct = 0  # Number of correct predictions on the test set

# Turn off gradients for validation, saves memory and computations
for images, labels in testloader:
log_ps = model(images)
loss = criterion(log_ps, labels)
tot_test_loss += loss.item()

ps = torch.exp(log_ps)
top_p, top_class = ps.topk(1, dim=1)
equals = top_class == labels.view(*top_class.shape)
test_correct += equals.sum().item()

# Get mean loss to enable comparison between train and test sets
train_loss = tot_train_loss / len(trainloader.dataset)
test_loss = tot_test_loss / len(testloader.dataset)

# At completion of epoch
train_losses.append(train_loss)
test_losses.append(test_loss)

print("Epoch: {}/{}.. ".format(e+1, epochs),
"Training Loss: {:.3f}.. ".format(train_loss),
"Test Loss: {:.3f}.. ".format(test_loss),
"Test Accuracy: {:.3f}".format(test_correct / len(testloader.dataset)))

################################

plt.plot(train_losses, label='Training loss')
plt.plot(test_losses, label='Validation loss')
plt.legend(frameon=False)

import matplotlib.pyplot as plt
class Classifier(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 256)
self.fc2 = nn.Linear(256, 128)
self.fc3 = nn.Linear(128, 64)
self.fc4 = nn.Linear(64, 10)

# Dropout module with 0.2 drop probability
self.dropout = nn.Dropout(p=0.2)

def forward(self, x):
# make sure input tensor is flattened
x = x.view(x.shape[0], -1)

# Now with dropout
x = self.dropout(F.relu(self.fc1(x)))
x = self.dropout(F.relu(self.fc2(x)))
x = self.dropout(F.relu(self.fc3(x)))

# output so no dropout here
x = F.log_softmax(self.fc4(x), dim=1)

return x

## TODO: Define your model with dropout added

## TODO: Train your model with dropout, and monitor the training progress with the validation loss and accuracy

import matplotlib.pyplot as plt

plt.plot(train_losses, label='Training loss')
plt.plot(test_losses, label='Validation loss')
plt.legend(frameon=False)

# Import helper module (should be in the repo)
import helper

# Test out your network!

model.eval()

helper.view_classify(img.view(1, 28, 28), ps, version='Fashion')