Skip to content

Latest commit

 

History

History
206 lines (152 loc) · 5.99 KB

6. Softmax Classification.md

File metadata and controls

206 lines (152 loc) · 5.99 KB

1. Softmax

  • Softmax Classification도 Logistic Regression의 연장선이다.
  • max 값을 얻고 싶은데, soft하게 얻고 깊은게 softmax이다.
  • Softmax 값들의 총 합은 1이다.
  • ex) (1, 2, 3)의 max 값을 (0.09, 0.24, 0.66)의 확률 값으로 찾는다!



2. Discrete Probability Distribution

  • Discrete Probability Distribution은 이산적인 확률 분포를 뜻한다.
  • 우리는 이산 확률 분포를 바탕으로 머신러닝을 수행하게 된다. 상대방이 '가위, 바위, 보'를 낼 확률을 예측한다고 하면, 이전의 패턴을 참고하게 된다. 확률 분포에 근사하기 위해 머신러닝을 이용한다.



3. Softmax code - Simple

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

torch.manual_seed(1) # 재현을 위함

z = torch.FloatTensor([1, 2, 3]) # 1, 2, 3

hypothesis = F.softmax(z, dim = 0) # 1, 2, 3 중 max를 soft하게 얻자.
print(hypothesis) # 0.09, 0.24, 0.66
hypothesis.sum() # 1. Softmax들의 총 합은 1



4. Cross Entropy

  • 두 개의 확률 분포가 주어졌을 때, 두 개가 얼마나 다른지 나타내는 수치.
  • Cross Entropy 손실함수를 minimize 하는 것이 중요하다!



5. Cross Entropy Loss : Low-level Implementation

z = torch.rand(3, 5, requires_grad = True) # 3 * 5의 크기로 z를 만든다.
hypothesis = F.softmaz(z, dim=1) # 3 * 5의 3개의 행 중 2번째 행, 즉 2번째 dimension에 대해 softmax를 실행한다.
print(hypothesis) # 예측값

y = torch.randint(5, (3,)).long() # 정답 값 (실습이라 정답 값을 랜덤하게 생성함)
print(y) # 0 2 1. 각 행 별로 0번째 2번째 1번째 인덱스가 정답

y_one_hot = torch.zeros_like(hypothesis) # hypothesis와 같은 3 * 5의 벡터를 만들어 준다.
y_one_hot.scatter_(1, y.unsqueeze(1), 1) # dim = 1에 대해서, y.unsqueeze(1)을 통해 y가 (3,) 이었던 것을 (3,1)로 만들어 [0, 2, 1] => [[0], [2], [1]]로 만든 후 그 자리에 1을 뿌린다.

cost = (y_one_hot * -torch.log(hypothesis)).sum(dim=1).mean() # 3 * 5의 크기인 y_one_hot과 hypothesis를 dim = 1에 대해서 sum 해 준다. dimension 1이 없어지므로 (3, 5)가 (3,)이 되어 mean() 되면 scalar 값이 나온다.
print(cost) # 1.4689



6. Cross Entropy Loss : High-level Implementation

  • 위는 Cross-entropy를 직접 수작업으로 구현한 것이다. 하지만 PyTorch에서는 편한 함수를 제공하고 있다.
 # 소프트맥스 Low / High
 torch.log(F.softmax(z, dim=1)) # Low-level 소프트맥스 
 F.log_softmax(z, dim=1) # High-level 소프트맥스이다. torch.log 안 취해도 됨!
 
 # Cross entropy Low / High
 (y_one_hot * -torch.log(F.softmax(z, dim=1))).sum(dim=1).mean() # Low-level cross entropy 방법 1
 F.nll_loss(F.log_softmax(z, dim=1), y) # Low-level cross entropy 방법 2
 F.cross_entropy(z, y) # High-level cross entropy



7. Training Example : Low-level Cross Entropy Loss

x_train = [[1, 2, 1, 1], # m * 4차원
           [2, 1, 3, 2],
           [3, 1, 3, 4],
           [4, 1, 5, 5],
           [1, 7, 5, 5],
           [1, 2, 5, 6],
           [1, 6, 6, 6],
           [1, 7, 7, 7]]
y_train = [2, 2, 2, 1, 1, 1, 0, 0] # m개. one-hot encoding을 했을 때의 인덱스의 위치를 나타내는 것임.
x_train = torch.FloatTensor(x_train)
y_train = torch.LongTensor(y_train)

# 모델 초기화
W = torch.zeros((4, 3), requires_grad = True) # 학습 파라미터 W. samples = 3, classes = 3, dim = 4
b = torch.zeros(1, requires_grad = True) # 학습 파라미터 b

# optimizer
optimizer = optim.SGD((W, b), lr = 0.1)

nb_epochs = 1000
for epoch in range(nb_epochs + 1):
  # Cost 계산
  hypothesis = F.softmax(x_train.matmul(W) + b, dim=1) # 모델
  y_one_hot = torch.zeros_like(hypothesis) # One-hot
  y_one_hot.scatter_(1, y_train.unsqueeze(1), 1)
  cost = (y_one_hot * -torch.log(F.softmax(hypothesis, dim=1))).sum(dim=1) # loss
  
  # Cost로 Gradient 개선
  optimizer.zero_grad()
  cost.backward()
  optimizer.step()
  
  # 100번마다 로그 출력
  if epoch % 100 == 0:
   print('Epoch {:4d}/{} Cost : {1.6f}'.format(epoch, nb_epochs, cost.item()))



8. Training Example : High-level Cross Entropy Loss

x_train = [[1, 2, 1, 1], 
           [2, 1, 3, 2],
           [3, 1, 3, 4],
           [4, 1, 5, 5],
           [1, 7, 5, 5],
           [1, 2, 5, 6],
           [1, 6, 6, 6],
           [1, 7, 7, 7]]
y_train = [2, 2, 2, 1, 1, 1, 0, 0]
x_train = torch.FloatTensor(x_train)
y_train = torch.LongTensor(y_train)

W = torch.zeros((4, 3), requires_grad = True)
b = torch.zeros(1, requires_grad = True)

optimizer = optim.SGD((W, b), lr = 0.1)

nb_epochs = 1000
for epoch in range(nb_epochs + 1):

  # 변형된 부분!
  z = x_train.matmul(W) + b
  cost = F.cross_entropy(z, y_train) # cross entropy에는 softmax도 들어있음. one-hot encoding도 생략됨.
  
  optimizer.zero_grad()
  cost.backward()
  optimizer.step()
  
  if epoch % 100 == 0:
   print('Epoch {:4d}/{} Cost : {1.6f}'.format(epoch, nb_epochs, cost.item()))



9. Training Example : High-level Implementation (위 보다 더 쉽게 구현!)

# 모델 정의
class SoftmaxClassifierModel(nn.Module): #nn.Module 상속받아 모델 정의
 def __init_(self):
  super().__init__()
  self.linear = nn.Linear(4, 3) # 4차원의 인풋을 받아 Output이 3!
  
 def forward(self, w):
  return self.linear(x) #linear를 통과시키는 모델을 만들어라. x는 m * 4이고 return 값은 m * 3이 됨.
  
model = SoftmaxClassifierModel()

optimizer = optim.SGD(model.parameters(), lr = 0.1)

nb_epochs = 1000
for epoch in range(nb_epochs + 1):

  # 변형된 부분!
  prediction = model(x_train) # prediction size는 m * 3
  cost = F.cross_entropy(prediction, y_train)
  
  optimizer.zero_grad()
  cost.backward()
  optimizer.step()
  
  if epoch % 100 == 0:
   print('Epoch {:4d}/{} Cost : {1.6f}'.format(epoch, nb_epochs, cost.item()))