본문 바로가기

[Pytorch] Softmax Regression (소프트맥스 회귀)

Derrick 발행일 : 2022-04-20
728x90
반응형

 

1. Softmax Regression 이해

앞선 Binary Classification 이후, 이번엔 Softmax Regression(소프트맥스)를 이용하여 3개 이상의 선택지 중 1개를 고르는 Multi-Class Classification 실습을 진행한다.

1-1. Review of Logisitc

Logistic regression에서는 Sigmoid 함수를 통해 예측값을 0 ~ 1 사이의 값을 출력한다.
그리고 두 확률의 합은 1이 된다. → ' H(X) = sigmoid(WX + B) '

 

[ Logistic Regression Process ]

1-2. Softmax (= Multi-Class Classification)

Softmax Regression각 클래스(=선택지)마다 확률을 할당하고, 그 확률의 총합이 1이 된다.
또한 각 클래스가 정답일 확률이 수치로 출력됨. → ' H(X) = softmax(WX + B) '

 

[ Softmax Regression Process ]

Softmax 함수란, Softmax regression에서 클래스의 개수만큼의 차원을 가진 벡터를 생성하고 "해당 벡터의 모든 원소의 합이 1이 되도록 변환시켜주는 함수"이다.

 

[ Softmax function의 도식도 ]

 

입력을 feature의 수만큼의 차원을 가진 입력벡터 ' X ' 라고 하고, Weight 행렬을 ' W ', bias를 ' b ' 라고 할 때, Softmax Regression에서 예측값을 구하는 과정은 위의 연산 도식표와 같다.
→ f : feature의 수,  c : class의 개수

 

2. Softmax 구현하기

F.cross_entropy를 사용하여 nn.Module, Class를 통해 모델 구현

2-1. nn.Module로 구현

nn.Linear( )를 사용하여 구현. output_dim은 클래스의 개수!

 

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

torch.manual_seed(1)

# Training data 선언
x_train = torch.FloatTensor([[1, 3, 2, 1],
                             [2, 2, 1, 1],
                             [4, 1, 2, 2],
                             [3, 3, 2, 6],
                             [1, 1, 5, 7],
                             [1, 4, 2, 3],
                             [6, 1, 2, 2],
                             [2, 5, 7, 7]])
y_train = torch.LongTensor([0, 0, 0, 1, 1, 1, 2, 2])
# x_train : 각 샘플은 4개의 특성(feature)을 가지고 있으며, 총 8개의 sample을 가진다. (8, 4)
# y_train : 각 샘플에 대한 Label. 0, 1, 2의 값으로 총 3개의 클래스(class)가 존재함

# 모델 선언
model = nn.Linear(4, 3)       # 4개의 특성을 가지고, 3개의 클래스로 분류 ( W = (4 x 3) )

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

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

  # H(x) 계산
  prediction = model(x_train)

  # cost 계산
  cost = F.cross_entropy(prediction, y_train)

  # cost로 H(x) 개선
  optimizer.zero_grad()
  cost.backward()
  optimizer.step()

  # 10번마다 결과 로그 출력
  if epoch % 10 == 0:
    print('Epoch {:4d}/{} Cost: {:.6f}'.format(
        epoch, nb_epochs, cost.item()
    ))

 

F.cross_entropy( )는 그 자체로 softmax 함수를 포함하고 있으며, 별도 사용할 필요가 없다.
→ Softmax Regression에서는 cost function으로 Cross-entropy function을 사용한다.

 

>>
Epoch    0/100 Cost: 1.063822
Epoch   10/100 Cost: 0.700953
Epoch   20/100 Cost: 0.581152
Epoch   30/100 Cost: 0.514297
Epoch   40/100 Cost: 0.470200
Epoch   50/100 Cost: 0.437842
Epoch   60/100 Cost: 0.412467
Epoch   70/100 Cost: 0.391693
Epoch   80/100 Cost: 0.374172
Epoch   90/100 Cost: 0.359076
Epoch  100/100 Cost: 0.345856

 

2-2. Class로 구현

Softmax regression를 nn.Module을 상속받는 클래스로 구현!

 

... Training dataset까지 동일

# 클래스로 모델 구현(nn.Module 상속)
class SoftmaxModel(nn.Module):
  def __init__(self):
    super().__init__()
    self.linear = nn.Linear(4, 3)     # input : 4, output : 3

  def forward(self, x):
    return self.linear(x)

# 모델 선언
model = SoftmaxModel()

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

# Training
nb_epochs = 100
for epoch in range(nb_epochs + 1):

  # H(x) 계산
  prediction = model(x_train)

  # cost 계산
  cost = F.cross_entropy(prediction, y_train)

  # cost로 H(x) 개선
  optimizer.zero_grad()
  cost.backward()
  optimizer.step()

  # 10번마다 결과 로그 출력
  if epoch % 10 == 0:
    print('Epoch {:4d}/{} Cost: {:.6f}'.format(
        epoch, nb_epochs, cost.item()
    ))

 

>>
Epoch    0/100 Cost: 2.558476
Epoch   10/100 Cost: 0.788115
Epoch   20/100 Cost: 0.651052
Epoch   30/100 Cost: 0.573643
Epoch   40/100 Cost: 0.521027
Epoch   50/100 Cost: 0.481937
Epoch   60/100 Cost: 0.451217
Epoch   70/100 Cost: 0.426131
Epoch   80/100 Cost: 0.405075
Epoch   90/100 Cost: 0.387036
Epoch  100/100 Cost: 0.371331



댓글