본문 바로가기

Pytorch

SoftMax Regression

소프트맥스 회귀

 

선택지 개수만큼의 차원을 가지는 벡터 생성, 그 벡터가 각 벡터의 모든 원소 합이 1이 되도록 원소들의 값 변환 시키는 어떤 함수 지니게 만들어야함. 

분류하고자 하는 클래스가 k개일 때, k차원의 벡터를 입력 받아서 모든 벡터 원소의 값을 0과 1 사이의 값으로 값 변경 후에 다시 k개의 벡터 리턴. 

 

 

소프트맥스 함수의 입력으로 사용되는 벡터는 벡터의 차원이 분류하고자 하는 클래스 개수가 되어야 하므로 가중치 연산을 통해서 3차원 벡터로 변환되어야 함.

이때 가중치 곱을 진행한다. 이러한 과정으로 소프트맥스 함수의 입력으로 바꾼다.

 

오차 계산은 어떻게 할까?

그 전에 소프트맥스 함수의 출력은 어떠한 형태를 띄고 있는지 확인 해야한다. 소프트맥스 함수의 출력은 분류하고자 하는 클래스 개수만큼 차원을 가지는 벡터이고 각 원소는 0과 1 사이의 값을 가진다. 각각은 특정 클래스가 정답일 확률 나타냄. 

이 예측값들과 실제값을 어떻게 비교하는가?

-> 실제값을 원-핫 벡터로 수치화해서 표현

 

 

원-핫 벡터와 예측값 벡터의 오차를 계산하기 위해서 크로스 엔트로피 함수를 사용한다. 

또한 오차로부터 가중치를 업데이 해야한다. 

 

인공지능 중간고사에서 나온거다...

 

 

cost function

 

import torch
import torch.nn.functional as F

torch.manual_seed(1)

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

hypo = F.softmax(z, dim=0)
print(hypothesis)
z = torch.rand(3, 5, requires_grad=True)
#3x5 행렬 텐서 생성

hypo = F.softmax(z, dim=1) #두번째 차원에 대해서 소프트맥스 함수 적용 
print(hypo)

##################output###################

tensor([[0.2128, 0.2974, 0.2574, 0.1173, 0.1150],
        [0.1486, 0.2933, 0.1740, 0.2342, 0.1499],
        [0.2880, 0.1427, 0.2565, 0.1774, 0.1355]], grad_fn=<SoftmaxBackward0>)

output : 3개의 샘플에 대해서 5개의 클래스 중 어떤 클래스가 정답인지를 예측한 결과 

 

<low level>

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

 

<high level>

F.log_softmax(z, dim=1)

 

- cross entropy by F.cross_Entropy

F.cross_entropy(z, y)

 

구현 - high level

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

torch.manual_seed(1)

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] #0,1,2 값을 가지므로 총 3개의 클래스 존재 
x_train = torch.FloatTensor(x_train)
y_train = torch.LongTensor(y_train)

print(x_train.shape)
print(y_train.shape)
y_one_hot = torch.zeros(8, 3)
y_one_hot.scatter_(1, y_train.unsqueeze(1), 1)
print(y_one_hot.shape)
W = torch.zeros((4, 3), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
# optimizer 설정
optimizer = optim.SGD([W, b], lr=0.1)

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

    # Cost 계산
    z = x_train.matmul(W) + b
    cost = F.cross_entropy(z, y_train)

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

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

 

구현 - nn.Module

model = nn.Linear(4, 3) #4개의 features로 3개의 클래스로 분류 

# 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()
        ))

 

구현 - class

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()

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()
        ))
        
##################output###################

Epoch    0/1000 Cost: 2.637636
Epoch  100/1000 Cost: 0.647903
Epoch  200/1000 Cost: 0.564643
Epoch  300/1000 Cost: 0.511043
Epoch  400/1000 Cost: 0.467249
Epoch  500/1000 Cost: 0.428280
Epoch  600/1000 Cost: 0.391924
Epoch  700/1000 Cost: 0.356742
Epoch  800/1000 Cost: 0.321577
Epoch  900/1000 Cost: 0.285617
Epoch 1000/1000 Cost: 0.250818

 

 

 

 

참고 https://wikidocs.net/59427

 

02. 소프트맥스 회귀(Softmax Regression) 이해하기

앞서 로지스틱 회귀를 통해 2개의 선택지 중에서 1개를 고르는 이진 분류(Binary Classification)를 풀어봤습니다. 이번 챕터에서는 소프트맥스 회귀를 통해 3개 이…

wikidocs.net

 

'Pytorch' 카테고리의 다른 글

퍼셉트론과 딥러닝, 활성화 함수, 손실 함수, 순전파와 역전파  (0) 2023.01.02
MNIST 분류 by softmax regression  (0) 2022.12.29
Logistic Regression  (0) 2022.12.29
Mini Batch and Data Load  (0) 2022.12.29
Linear Regression  (0) 2022.12.27