Pytorch_ReLU

Pytorch ReLU에 대하여

모두를 위한 딥러닝 - 파이토치 강의 참고

  • 이전 포스팅에서 두 가지 클래스를 분류하는 모델을 만들때 sigmoid함수를 사용했습니다.

  • 하지만, sigmoid함수에는 모델이 깊어질수록 vanishing Gradient문제가 발생하게 됩니다.

  • vanishing Gradient란, 역전파를 통해 gradient를 전파받을 때, 0에 근접한 값들이 곱해짐에 따라 앞단으로 갈수록 gradient가 사라지게 되는 문제입니다.

  • 이러한 문제가 생기는 이유는 sigmoid 함수 그래프를 통해 확인할 수 있습니다.

  • sigmoid 그래프

  • sigmoid 그래프의 양 극단으로 갈수록 기울기는 0에 수렴하게 되는것을 볼 수 있고, 이때문에 역전파를 통해 gradient가 곱해질 때마다 그 값 또한 0으로 수렴하게 됩니다.

  • 따라서 아래 그림과 같이 역전파가 깊이 전달될수록 gradient가 사라지는 vanishing gradient 문제가 발생하게 됩니다.

  • vanishing Gradient

  • 이러한 문제를 해결하기 위해 Hinton교수님이 찾아낸 방법이 바로 ReLU 입니다.

  • ReLU를 수식으로 나타내면 다음과 같습니다.

1
f(x) = max(0, x)
  • 입력값 x가 들어왔을때, 0보다 크다면 자기자신을 그렇지 않다면 0을 되돌려주는것이 바로 ReLU입니다.

  • 코드에서 활성화 함수만 sigmoid에서 ReLU로 바꾸면 되기때문에 ReLU를 이용한 MNIST classifier 를 만들어보겠습니다.

1
2
3
4
5
# nn Linear layer 만들기
linear1 = torch.nn.Linear(784, 256, bias=True)
linear2 = torch.nn.Linear(256, 256, bias=True)
linear3 = torch.nn.Linear(256, 10, bias=True)
relu = torch.nn.ReLU()
  • Linear layer와 활성화 함수로 사용할 ReLU를 정의해주고, Linear layer의 weight를 normalization 합니다.
1
2
3
4
# Linear layer의 weight를 normalization시켜주기
torch.nn.init.normal_(linear1.weight)
torch.nn.init.normal_(linear2.weight)
torch.nn.init.normal_(linear3.weight)
  • 위를 이용해 모델을 정의하고,
1
2
3
4
# 모델 정의
model = torch.nn.Sequential(linear1, relu, linear2, relu, linear3).to(device)
###>>> 왜 linear3다음에는 relu를 하지않는가
###>>> 우리가 사용할 criterion은 CrossEntropyLoss인데 여기에는 마지막에 softmax activation이 포함되어 있기 때문이다.
  • loss / optimizer 를 정의합니다.
1
2
3
# loss / optimizer 정의
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
  • 정한 epoch수만큼 모델을 학습시킵니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
total_batch = len(data_loader)
for epoch in range(epochs):
avg_loss = 0
for X, Y in data_loader:
X = X.view(-1, 28*28).to(device)
Y = Y.to(device)

hypothesis = model(X)
loss = criterion(hypothesis, Y)

optimizer.zero_grad()
loss.backward()
optimizer.step()

avg_loss += loss / total_batch

print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_loss))
  • 학습이 끝났다면 테스트 데이터에서 하나를 선택해 예측값과 실제값을 비교해 결과를 확인해봅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
with torch.no_grad(): # --> 여기에서는(test에서는) gradient를 계산하지 않고 진행한다는 뜻이다.
X_test = mnist_test.test_data.view(-1, 28*28).float().to(device)
Y_test = mnist_test.test_labels.to(device)

prediction = model(X_test)
correct_prediction = torch.argmax(prediction, dim=1) == Y_test
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())

r = random.randint(0, len(mnist_test) - 1)
X_single_data = mnist_test.test_data[r:r + 1].view(-1, 28 * 28).float().to(device)
Y_single_data = mnist_test.test_labels[r:r + 1].to(device)

print('Label: ', Y_single_data.item())
single_prediction = model(X_single_data)
print('Prediction: ', torch.argmax(single_prediction, 1).item())
  • 하나의 데이터를 통해 예측값과 실제값까지 확인해볼 수 있었습니다.

Full Code

Full Code

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×