import torch
import torch.nn.functional as F
torch.manual_seed(1)
# 텐서 선언
z = torch.FloatTensor([1,2,3])
# softmax 함수 실행
hypothesis = F.softmax(z, dim = 0)
print(hypothesis) # 3개의 원소 값이 0과 1사이의 값을 가지는 벡터로 변환됨.
print(hypothesis.sum()) # 이 원소들의 합은 1
<torch._C.Generator at 0x2594337a230>
tensor([0.0900, 0.2447, 0.6652])
tensor(1.)
# 텐서 선언
z = torch.FloatTensor([1,2,3])
# softmax 함수 실행
hypothesis = F.softmax(z, dim = 0)
print(hypothesis) # 3개의 원소 값이 0과 1사이의 값을 가지는 벡터로 변환됨.
print(hypothesis.sum()) # 이 원소들의 합은 1
tensor([0.0900, 0.2447, 0.6652])
tensor(1.)
# 임의의 3 x 5 행렬 크기를 가진 텐서를 만들었음.
z = torch.rand(3, 5, requires_grad=True)
hypothesis = F.softmax(z, dim=1) # 두번째 차원에 대해서 softmax 함수 적용
print(hypothesis)
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=<SoftmaxBackward0>)
# 각 샘플에 대한 임의의 테이블 생성
y = torch.randint(5,(3,)).long()
print(y)
tensor([2, 1, 0])
# 원-핫 인코딩 생성
# 모든 원소가 0의 값을 가진 3 * 5 텐서 생성
y_one_hot = torch.zeros_like(hypothesis)
y_one_hot.scatter_(1, y.unsqueeze(1),1)
tensor([[0., 0., 1., 0., 0.],
[0., 1., 0., 0., 0.],
[1., 0., 0., 0., 0.]])
y_one_hot = torch.zero_like(hypothesis)
y_one_hot
에 저장y_one_hot.scatter_(1, y.unsqueeze(1),1)
y.unsqueeze(1)
를 하면 (3,)의 크기를 가졌던 y 텐서는 (3 x 1) 텐서가 됨. scatter
의 첫번째 인자로 dim=1
에 대해서 수행하라고 알려주고, 세번째 인자에 숫자 1을 넣어 y_unsquezze(1)
이 알려주는 위치에 1을 넣어주어 one-hot encodingy_one_hot
에 값을 넣어줌. print(y_one_hot)
tensor([[0., 0., 1., 0., 0.],
[0., 1., 0., 0., 0.],
[1., 0., 0., 0., 0.]])
sum(dim=1)
으로 구현하고, $ \frac{1}{n} \sum_{i=1}^{n}$ mean()
으로 구현함. cost = (y_one_hot * -torch.log(hypothesis)).sum(dim=1).mean()
print(cost)
tensor(1.6682, grad_fn=<MeanBackward0>)
앞서 low-level에서 함수의 결과에 로그를 씌울때 다음과 같이 사용하였음. : torch.log(F.softmax())
파이토치에서는 두 개의 함수를 결합한 F.log_softmax()
라는 도구를 제공함.
F.log_softmax(z, dim=1)
tensor([[-1.3301, -1.8084, -1.6846, -1.3530, -2.0584],
[-1.4147, -1.8174, -1.4602, -1.6450, -1.7758],
[-1.5025, -1.6165, -1.4586, -1.8360, -1.6776]],
grad_fn=<LogSoftmaxBackward0>)
torch.log(F.softmax(z, dim=1))
tensor([[-1.3301, -1.8084, -1.6846, -1.3530, -2.0584],
[-1.4147, -1.8174, -1.4602, -1.6450, -1.7758],
[-1.5025, -1.6165, -1.4586, -1.8360, -1.6776]], grad_fn=<LogBackward0>)
# Low Level
# 첫번째 수식
(y_one_hot * -torch.log(F.softmax(z,dim=1))).sum(dim=1).mean()
tensor(1.6682, grad_fn=<MeanBackward0>)
# 두번째 수식
(y_one_hot * -F.log_softmax(z,dim=1)).sum(dim=1).mean()
tensor(1.6682, grad_fn=<MeanBackward0>)
# 세번째 수식
F.nll_loss(F.log_softmax(z,dim=1),y)
tensor(1.6682, grad_fn=<NllLossBackward0>)
Negative Log Likelihood
의 약자nll_loss
는 F.log_softmax()
를 수행한 후에 남은 수식들을 수행함. F.cross_entropy()
는 F.log_softmax()
와 F.null_loss()
를 포함하고 있음. # 네번째 수식
F.cross_entropy(z,y)
tensor(1.6682, grad_fn=<NllLossBackward0>)
F.cross_entropy
는 비용 함수에 소프트맥스 함수까지 포함하고 있음.