Group Study (2022-2023)/Machine Learning

[Machine Learning] 3주차 스터디 - Softmax Regression

spring_sunshine 2022. 10. 31. 13:58

6-1) Softmax Regression: 기본 개념 소개

Logistic Regression

H(x) = Wx

  • 리턴 값이 실수이기 때문에 binaray classification에 적합하지 않음 
  • g(z) = sigmoid (logistic) 함수를 통해 1과 0 사이로 값을 압축해서 변형

 

Multinomial Classification

  • 여러개의 클래스가 존재
  • a or not a / b or not b / c or not c로 3번의 binary classification로 학습 가능
  • w를 하나로 합쳐서 하나의 행렬곱으로 만든다.


6-2) Softmax Classifier의 Cost 함수

다중 클래스 분류모델을 만들 때 사용하는 함수이다.

Softmax 함수

  • Softmax 함수는 확률값으로 변환하기 때문에 전체 총합이 1이 되어야 한다.
  • one-hot encoding을 이용하여 가장 큰 확률값을 답(1)으로 고른다. 

 

Cost Function

  • 예측한 값과 실제 값의 차이를 확인하는 Cost Function
  • Cross-Entropy 함수를 사용 → 정답일 경우:0 / 오답일 경우: 발산
def cost_fn(X, Y):
    logits = hypothesis(X)
    cost = -tf.reduce_sum(Y * tf.math.log(logits), axis=1)
    cost_mean = tf.reduce_mean(cost)
    
    return cost_mean # cost 평균 

print(cost_fn(x_data, y_data))

 

[여러 개의 training set이 존재하는 경우]


실습 코드 - Softmax Classifier: Animal Classification

import tensorflow as tf
import numpy as np
#tf.enable_eager_execution()
tf.random.set_seed(777)

# Sample DataSet
xy = np.loadtxt('data-04-zoo.csv', delimiter=',', dtype=np.int32)
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]

# tf.one_hot and reshape
nb_classes = 7  # 0 ~ 6

Y_one_hot = tf.one_hot(list(y_data), nb_classes) # one hot shape(?, 1, 7)
Y_one_hot = tf.reshape(Y_one_hot, [-1, nb_classes]) # shape = (?,7)

Implementation - Softmax Classifier, Training

#Weight and bias setting
W = tf.Variable(tf.random.normal([16, nb_classes]), name='weight')
b = tf.Variable(tf.random.normal([nb_classes]), name='bias')
variables = [W, b]

# tf.nn.softmax computes softmax activations
def logit_fn(X):
    return tf.matmul(X, W) + b

def hypothesis(X):
    return tf.nn.softmax(logit_fn(X))

def cost_fn(X, Y):
    logits = logit_fn(X)
    cost_i = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits,
                                                           labels=Y)
    cost = tf.reduce_mean(cost_i)
    
    return cost

def grad_fn(X, Y):
    with tf.GradientTape() as tape:
        loss = cost_fn(X, Y)
        grads = tape.gradient(loss, variables)
        return grads
    
def prediction(X, Y):
    pred = tf.argmax(hypothesis(X), 1)
    correct_prediction = tf.equal(pred, tf.argmax(Y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    return accuracy
    
# Training
def fit(X, Y, epochs=500, verbose=50):
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
    
    for i in range(epochs):
        grads = grad_fn(X, Y)
        optimizer.apply_gradients(zip(grads, variables))
        if (i==0) | ((i+1)%verbose==0):
            print('Loss & Acc at {} epoch {}, {}'.format(i+1, loss,acc))
            
fit(x_data,Y_one_hot)