클래스가 k(위 식에선 3개)개 일때, k차원의 벡터를 입력받아 모든 벡터 원소의 값을 0과 1사이의 값으로 변경하여 다시 k차원의 벡터를 리턴
- 위 그림은 아이리스 꽃의 4개의 특성을 통해 3개의 품종 중 무엇일지 예측하는 모델이다.
- 4개의 독립변수를 모델이 4차원 벡터로 입력받아 소프트맥스 함수를 통해 3차원 벡터로 표현함
import torch
import torch.nn.functional as F
torch.manual_seed(1)
<torch._C.Generator at 0x278878b55f0>
# 임의의 3x5 크기의 텐서 생성
z = torch.rand(3, 5, requires_grad=True)
# 각 샘플에 임의의 레이블 생성
y = torch.randint(5, (3,)).long()
print(y)
tensor([3, 1, 2])
F.cross_entropy(z, y)
tensor(1.4992, grad_fn=<NllLossBackward0>)
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
torch.manual_seed(1)
<torch._C.Generator at 0x278878b55f0>
# 훈련 데이터와 레이블 텐서로 선언
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)
y_one_hot = torch.zeros(8, 3)
y_one_hot.scatter_(1, y_train.unsqueeze(1), 1)
print(y_one_hot.shape)
torch.Size([8, 3])
# 모델 초기화
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()
))
Epoch 0/1000 Cost: 1.098612
Epoch 100/1000 Cost: 0.761050
Epoch 200/1000 Cost: 0.689991
Epoch 300/1000 Cost: 0.643229
Epoch 400/1000 Cost: 0.604117
Epoch 500/1000 Cost: 0.568255
Epoch 600/1000 Cost: 0.533922
Epoch 700/1000 Cost: 0.500291
Epoch 800/1000 Cost: 0.466908
Epoch 900/1000 Cost: 0.433507
Epoch 1000/1000 Cost: 0.399962