06. softmax classification
λ³Έ κΈμ 'λͺ¨λλ₯Ό μν λ₯λ¬λ μμ¦ 2'μ 'pytorchλ‘ μμνλ λ₯ λ¬λ μ λ¬Έ'μ 보며 곡λΆν λ΄μ©μ μ 리ν κΈμ λλ€.
νμμ μκ²¬μ΄ μμ¬ λ€μ΄κ° λΆμ νν λ΄μ©μ΄ μ‘΄μ¬ν μ μμ΅λλ€.
3κ° μ΄μμ μ νμ§μμ 1κ°λ₯Ό μ ν! (softνκ² maxκ°μ λ½μμ£Όλ)
⇒ λ€μ€ ν΄λμ€ λΆλ₯ (Multi-class classification)
μΈ κ° μ΄μμ λ΅ μ€ νλλ₯Ό κ³ λ₯΄λ λ¬Έμ .
μκ·Έλͺ¨μ΄λ ν¨μλ λ‘μ§μ€ν± ν¨μμ ν μΌμ΄μ€λΌ λ³Ό μ μκ³ , μΈνμ΄ νλμΌ λ μ¬μ©λλ μκ·Έλͺ¨μ΄λ ν¨μλ₯Ό μΈνμ΄ μ¬λ¬κ°μΌ λλ μ¬μ©ν μ μλλ‘ μΌλ°ν ν κ²μ΄ μννΈλ§₯μ€ ν¨μμ λλ€.
0. μ-ν« μΈμ½λ©(one-Hot Encoding)
- μ νμ§μ κ°μλ§νΌ μ°¨μμ κ°μ§λ€.
- μ νμ§μ ν΄λΉνλ μΈλ±μ€λ 1, λλ¨Έμ§λ 0μΌλ‘ νννλ€.
ex)
κ°μμ§ = [1, 0, 0]
κ³ μμ΄ = [0, 1, 0]
λμ₯κ³ = [0, 0, 1]
-
μ μ μΈμ½λ©(1, 2, 3)κ³Όμ μ°¨μ΄μ
⇒ μ μ μΈμ½λ©μ κ° ν΄λμ€κ° μμ μ 보λ₯Ό νμλ‘ ν λ μ μ©νλ€.
⇒ μ ν« μΈμ½λ©μ μΌλ°μ μΈ λΆλ₯λ¬Έμ , μ¦ μμκ° μλ―Έμκ³ λ¬΄μμμ±μ΄ μμ λ μ μ©νλ€.
(λͺ¨λ ν΄λμ€μ κ΄κ³λ₯Ό κ· λ±νκ² λΆλ°°νκΈ° λλ¬Έ!)
1. softmax function
κ° μ νμ§λ§λ€ μμλ₯Ό ν λΉν΄μ κ·Έ ν©μ΄ 1μ΄ λκ² λ§λλ ν¨μ.
for i = 1, 2, ..., k
piλ iλ² ν΄λμ€κ° μ λ΅μΌ νλ₯ μ λ»νλ€. pi(i=1~k)λ₯Ό λ€ λνλ©΄, κ·Έ ν©μ 1μ΄ λλ€. μ¦, μννΈ λ§₯μ€ ν¨μλ μ΄λ ΅κ² μκ°ν νμ μμ΄ μ£Όμ΄μ§ κ°λ€μ λν΄ ν©μ΄ 1μ΄ λλλ‘ κ·Έ κ°λ€μ λΉμ¨μ λ§μΆ° μμλ‘ μ κ·ν μμΌμ£Όλ ν¨μλΌκ³ μκ°νλ©΄ λλ€.
Softmax( ( 1xf ) * ( fxC ) + ( Cx1 ) ) = C x 1
μ°¨λ‘λ‘ μ λ ₯κ°, κ°μ€μΉ, νΈν₯, μμΈ‘κ°μ΄λ€. (fλ νΉμ±μ μ, Cλ ν΄λμ€μ κ°μ)
λ°μ΄ν°μ κ°μμ λ°λΌμ μ λ ₯κ°μ 1μ΄ λ°λλ€.
2. cost function
logistic regresstionμμλ binary cross-entropyλ₯Ό μ¬μ©νλ€. μλ 2κ° μ€ νλλ₯Ό κ²°κ³Όκ°μΌλ‘ λ΄ λμμλλ°, μ΄ BCE λ³΄λ€ λ κ·Όμμ μΈ? ν¨μκ° μλ€. λ°λ‘ CE! cross entropy!
CEλ 3κ° μ΄μμ κ° μ€ νλλ₯Ό λ΄μ΄ λλλ€.
μ¬κΈ°μ μ΅λκ°μΈ Kλ₯Ό 2λ‘ μ§μ νκ² λλ€λ©΄, BCEμ μμ΄ λμ€κ² λλ€!
3. Code ꡬν
softmaxμ cross-entropyμ ꡬν λ°©λ²μλ 3κ°μ§κ° μλ€.
#1
F.softmax() + torch.log() # = F.log_softmax()
#2
F.log_softmax() + F.nll_loss() # = F.cross_entropy()
#3
F.cross_entropy()
κ²°λ‘ μ μΌλ‘λ νΈνκ² 3λ²λ§ μ¬μ©νλ©΄ λλ€! νΉμ΄νκ² κ°μ€ ν¨μμ μμ€ ν¨μλ₯Ό νλ²μ μΈ μ μλ€! μ΄λ΄ κ²½μ°, μ€μ codeμμλ νλ ¬μ κ³±λ§ μμΌμ£Όκ³ , μμ ν©μ΄ 1μ΄ λλλ‘ μ κ·ν μμΌμ£Όλ κ³Όμ μ μμ€ν¨μλ₯Ό μΈ λ κ°μ΄ ν μ μλ μ F.cross_entropy()μ λ§κ²¨μ£Όλ©΄ λλ€.
4. Full Code
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
x_train = [[1, 2, 1, 1], #4κ°μ νΉμ±μ κ°μ§κ³ μλ 8κ°μ ν
μ€νΈ μΌμ΄μ€
[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)
#μμ 8μ ν
μ€νΈ μΌμ΄μ€ κ°μ, λ€μ 3μ λ΅μ΄ 2μΌλ [0 0 1] μ΄λ°μμΌλ‘ λνλΌ κ²(μ§κΈμ μλ¦¬λ§ λ§λ¦)
y_one_hot.scatter_(1, y_train.unsqueeze(1), 1) #μ€μ κ° yλ₯Ό μ-ν« λ²‘ν°λ‘ λ°κΏ
print(y_one_hot.shape)
# λͺ¨λΈ μ΄κΈ°ν
W = torch.zeros((4, 3), requires_grad=True) #νΉμ±μ 4κ°, κ²°κ³Ό κ°μ§μλ 3κ°
b = torch.zeros(1, requires_grad=True) #1λ‘ νλ©΄ 3κ°μ κ°μ κ°μ΄ λν΄μ§, 3μΌλ‘ ν΄λ μκ΄μμ!
# optimizer μ€μ
optimizer = optim.SGD([W, b], lr=0.1)
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
# κ°μ€
hypothesis = F.softmax(x_train.matmul(W) + b, dim=1)
# λΉμ© ν¨μ - μ§μ κ³μ° λ²μ
cost = (y_one_hot * -torch.log(hypothesis)).sum(dim=1).mean()
# 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()
))
4-1. Full Code with nn,Module
class SoftmaxClassifierModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(4, 3) # μΈνμ 4, Outputμ΄ 3!
def forward(self, x):
return self.linear(x)
model = SoftmaxClassifierModel() #λͺ¨λΈ μμ±
# 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 κ³μ° - μ΄ ν¨μμ softmaxμλμΌλ‘ μ μ©λ¨
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()
))
<Reference>
https://deeplearningzerotoall.github.io/season2/lec_pytorch.html