티스토리 뷰

Multinomial classification

image

> 이전에 Logistic Regression는 두 개의 범주형 class를 분류하는 모델이었습니다.

> 예측해야하는 범주형 class가 두 개 이상이면 어떻게 분류하는게 좋을까요?

> 범주형 class가 3개 일때 예를 들어보겠습니다.


image

> 먼저 binary classification 방법을 활용하여 총 3개 binary classification[(A or not), (B or not), (C or not)] 모델을 완성합니다.

image

> 각각의 class를 구분하는 3개의 독립적인 모델은 계산을 각각 시행해주어야 하기에 구현이 번거롭습니다.

image

> 이때, 데이터를 따로 입력받지 말고 전체 데이터를 행렬로 입력을 받아서 구현 과정을 간편하게 만들어줍니다.

image

image

> Logistic regression에서 Class 예측 범위를 (0 ~ 1)로 맞추기 위해 sigmoid를 사용한 것 처럼 Multinomial classification에서는 softmax function을 사용하여 Class 예측 범위 값을 조정해줍니다.


image

> softmax function으로 구한 결과값을 one-hot encoding을 하여 최종적으로 class를 분류해준다.


image

> Cost function은 Cross-entropy function을 이용해준다.(softmax값과 실제 값을 통해 Update)

배운 것을 Pytorch code로 살펴보겠습니다.


IN[1]

z = torch.rand(3, 5 , requires_grad = True)
hypothesis = F.softmax(z, dim=1)
print(hypothesis)

> dim - softmax를 시행할 축 지정을 합니다.

> sample 3개, class 5개


OUT[1]

tensor([[0.2645, 0.1639, 0.1855, 0.2585, 0.1277],
[0.2430, 0.1624, 0.2322, 0.1930, 0.1694],
[0.2226, 0.1986, 0.2326, 0.1594, 0.1868]], grad_fn=<SoftmaxBackward>)

IN[2]

y = torch.randint(5, (3,)).long()
print(y)
y_one_hot = torch.zeros_like(hypothesis)
y_one_hot.scatter_(1, y.unsqueeze(1), 1)

OUT[2]

tensor([3, 1, 2])
tensor([[0., 0., 0., 1., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.]])

> torch.randint - 예제에선 지정된 target값이 없기 때문에 임의로 생성합니다.

> y_one_hot.scatter_ - dim = 1의 방향으로 unsqueeze한 뒤에 1을 대입

{ y = (3,) -> (3, 1) , tensor [3, 1, 2] -> [[3] [1] [2]], 인덱스 위치에 1이 들어감}


IN[3]

cost = (y_one_hot * -torch.log(hypothesis)).sum(dim=1).mean()
print(cost)

OUT[3]

tensor(1.5430, grad_fn=<MeanBackward0>)

> Cross_entropy를 직접 구현하는 것은 복잡하고 어렵기에 torch.nn.functional을 사용하겠습니다.


IN[4]

F.log_softmax(z, dim=1)
F.nll_loss(F.log_softmax(z, dim=1), y)
F.cross_entropy(z, y)

OUT[4]

tensor(1.5430, grad_fn=<NllLossBackward>)
tensor(1.5430, grad_fn=<NllLossBackward>)

> F.cross_entropy을 사용하는 것이 가장 간단한 방법입니다. 그러나 딥러닝을 하다보면 soft max 확률값을 Output으로 생성해야하는 경우가 발생합니다.

> F.cross_entropy는 중간과정 없이 loss값을 산출해주기 때문에 중간에 soft max값을 나타내기 어렵습니다. 상황에 따라 적절한 방법을 사용해주는것이 중요합니다.


IN[5]

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)

IN[6]

class SoftmaxClassifierModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(4, 3)
def forward(self, x):
return self.linear(x)
model = SoftmaxClassifierModel()

IN[7]

# optimizer 설정
optimizer = optim.SGD(model.parameters(), lr=0.1)
nb_epochs = 1000
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()
# 20번마다 로그 출력
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))

> 가장 간단한 코드로 Multinomial classification 모델을 돌려보았습니다.


  • 마지막으로 정리하자면

> Binomial classification : Binomial Cross Entropy, sigmoid function 사용하고

> Multinomial classification : Cross Entropy, softmax function 사용합니다.



참고링크:

[PyTorch] Lab-06 Softmax Classification
ML lec 6-1 - Softmax Regression: 기본 개념 소개
ML lec 6-2: Softmax classifier 의 cost함수

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함