4 minute read

모두를 위한 딥러닝 lab5

1. Logistic (Regression) classification

Logistic Regression 이번에는 많은 부분을 정우일님 블로그를 통해 포스팅 내용이 작성되었습니다.


Hypothesis

\[H(X) = \frac{1}{1 + {e}^{-XW}} \]

Cost Function

\[Cost(W) = {1\over m} \sum_{i=1}^m c(H(x_i), y_i) \]

Cross Entropy in Logistic Classification

\[c(H(x),y) = \begin{cases} -log(H(x)) : y =1 \\ -log(1 - H(x)) : y = 0 \end{cases} = -ylog(H(x)) - (1 - y)log(1 - H(x))\]


우리가 배웠던 Logistic regression에 대한 손실함수의 명칭은 cross entropy 손실 함수라고 합니다. (정확히는 Binary Cross Entropy(BCE)라고 합니다.) Cost를 작게하는 W를 구하는 것이 학습과정입니다.

Minimizing cost

\[W_{new} = W_{old} - \alpha\frac{\partial}{\partial w}Cost(W)\]

로그 함수를 통해 매끈한 형태로 코스트함수를 만들어 주었으므로 경사하강법을 사용하면 됩니다.

2. Sigmoid Function, Hypothesis of Logistic regression Model

image image

위의 Desmos에서 그려진 그래프를 보면 시그모이드 함수처럼 보이진 않지만, 이미지의 x범위를 -1 ~ 1로 보고 있기 때문입니다.

image

이 처럼 범위를 -4 ~ 4로 시그모이드 함수를 보면 시그모이드 함수의 모양이 나옵니다.

Sigmoid

로지스틱 회귀 모델에서는 선형 회귀 모델의 가설이 Sigmoid 함수에 적용됩니다. \[Sigmoid(x) = \frac{1}{1 + {e}^{-x}} \]

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5, 5, 0.1)
y = 1 / (1 + np.exp(-x))

# Numpy의 numpy.exp() 함수는 밑이 자연상수 e인 지수함수(e^x)로 변환해줍니다.
# 결과값이 inf라면, 해당 값이 무한대(infinite)라는 것입니다.

plt.title("Sigmoid Function", size = 15, weight = 'bold')
plt.plot(x, y, color = 'orange', label = 'Sigmoid')
plt.axhline(0.5, color = 'red', label = 'Decision Boundaray = 0.5')
plt.legend(loc = 'upper left')
plt.show()

image

3. Cross Entropy Function, Logistic regression Model의 Cost

\[c(H(x),y) = \begin{cases} -log(H(x)) : y =1 \\ -log(1 - H(x)) : y = 0 \end{cases} = -ylog(H(x)) - (1 - y)log(1 - H(x))\]
x = np.arange(0.01, 1, 0.01)
y1 = -np.log(x)
y0 = -np.log(1-x)

plt.title('Cross Entropy Function', size = 15, weight = 'bold')
plt.plot(x, y1, color = 'dodgerblue', label = 'when y=1')
plt.plot(x, y0, color = 'tomato', label = 'when y = 0')
plt.xlabel('H(x)')
plt.ylabel('Cost')
plt.legend(loc = 'upper center')
plt.show()

cross entropy cost function

Implement

import tensorflow as tf
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

print("TensorFlow Version : %s" % (tf.__version__))

Data

# Data
# Data for train
x_train = np.array([
                    [1., 1.],
                    [1., 2.],
                    [2., 1.],
                    [3., 2.],
                    [3., 3.],
                    [2., 3.],
                    ], dtype = np.float32)

y_train = np.array(
    [
     [0.],
     [0.],
     [0.],
     [1.],
     [1.],
     [1.],
    ], dtype = np.float32)

# Data for test
x_test = np.array([
                   [3., 0.],
                   [4., 1.]
], dtype = np.float32)

y_test = np.array([
                   [0.],
                   [1.]
], dtype = np.float32)

Visualization

# df = pd.DataFrame(x_train) # x_train 데이터로 DataFrame생성
df = pd.DataFrame(x_train, columns = ['x1', 'x2']) # 각 컬럼값에 이름 붙이기
df['y'] = y_train # 컬럼의 이름을 y로 두고 데이터를 데이터 프레임에 추가 

df_test = pd.DataFrame(x_test, columns = ['x1', 'x2'])
df_test['y'] = y_test

plt.figure(figsize = (6,6)) # 이미지 전체의 영역을 확보한다. figsize의 단위는 인치이다.
sns.scatterplot(x='x1', y='x2', hue='y', data=df, s=500)  # scatterplot()함수는 산점도를 그래프에 그려준다. 매개변수로는 생성된 dataframe의 키값을 사용한다.
sns.scatterplot(x='x1', y='x2', color='red', data=df_test, s=500)
plt.xlim(0, 5) # x축의 시작과 끝 포인트를 지정한다
plt.ylim(-1, 4) # y축의 시작과 끝 포인트를 지정한다
plt.legend(loc='lower right')
plt.show()

scatter plot

Initializing Weights

tf.random.set_seed(2020)
W = tf.Variable(tf.random.normal([2,1], mean = 0.0))
b = tf.Variable(tf.random.normal([1], mean = 0.0))

print("# Weights: \n", W.numpy(), '\n\n# Bias: \n', b.numpy())

Trian the model

learning_rate = 0.01

# Hypothesis and Prediction Function
def predict(X) :
    z = tf.matmul(X, W) + b
    hypothesis = 1 / (1 + tf.exp(-z))
    return hypothesis

# Training
for i in range(2000 + 1):

    with tf.GradientTape() as tape : 

        hypothesis = predict(x_train)
        cost = tf.reduce_mean(-tf.reduce_sum(y_train * tf.math.log(hypothesis) + (1 - y_train) * tf.math.log(1-hypothesis)))
        W_grad, b_grad = tape.gradient(cost, [W, b])

        W.assign_sub(learning_rate * W_grad)
        b.assign_sub(learning_rate * b_grad)

    if i % 400 == 0:
        print(">>> #%s \n Weights: \n%s \n Bias: \n%s \n cost: %s\n" % (i, W.numpy(), b.numpy(), cost.numpy()))

predict

hypo = predict(x_test)
print("Prob: \n", hypo.numpy())
print("Result: \n", tf.cast(hypo > 0.5, dtype=tf.float32).numpy())

Accuracy

def acc(hypo, label):
    predicted = tf.cast(hypo > 0.5, dtype=tf.float32)
    accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, label), dtype=tf.float32))
    return accuracy

accuracy = acc(predict(x_test), y_test).numpy()
print("Accuracy: %s" % accuracy)

ACcuracy: 1.0 => 정확도 100% (y데이터의 값이 0과 1밖에 없기 때문)


Logistic regression with Keras

1. Logistic regression

import tensorflow as tf

x_data = [[1, 2],
          [2, 3],
          [3, 1],
          [4, 3],
          [5, 3],
          [6, 2]]
y_data = [[0],
          [0],
          [0],
          [1],
          [1],
          [1]]

tf.model = tf.keras.Sequential()
tf.model.add(tf.keras.layers.Dense(units = 1, input_dim = 2))
tf.model.add(tf.keras.layers.Activation('sigmoid'))

# 손실 함수 == 'binary_crossentropy'로 더 나은 결과를 얻으려면 'mse'를 직접 시도하십시오.
# 훈련 중 정확도 보고서를 얻기 위해 정확도 메트릭 추가
tf.model.compile(loss = 'binary_crossentropy', optimizer = tf.keras.optimizers.SGD(lr = 0.01), metrics = ['accuracy'])
tf.model.summary()

history = tf.model.fit(x_data, y_data, epochs = 5000)
import matplotlib.pyplot as plt

# print("Accuracy: ", history.history['accuracy'][-1])
# print("Accuracy: ", history.history['accuracy'][0])
print("Accuracy: ", history.history['accuracy'])
plt.plot(history.history['accuracy'])
  • metric: 평가지표, 훈련을 모니터링 하기 위해 사용됩니다.
  • 분류: accuracy
  • 회귀: mse, rmse, r2, mae, mspe, mape, msle 등이 있습니다.

사용자가 메트릭을 정의해서 사용할 수도 있습니다.

2. Logistic regression diabetes

import tensorflow as tf
import numpy as np

from google.colab import drive
drive.mount('/content/drive')

filename = "/Data/data-03-diabetes.csv"

xy = np.loadtxt(filename, delimiter = ',', dtype = np.float32)
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]

print(x_data.shape, y_data.shape)

tf.model = tf.keras.Sequential()

# multi-variable, x_data.shape[1] == feature counts == 8 in this case
tf.model.add(tf.keras.layers.Dense(units = 1, input_dim = x_data.shape[1], activation = 'sigmoid'))
tf.model.compile(loss = 'binary_crossentropy', optimizer = tf.keras.optimizers.SGD(learning_rate = 0.01), metrics = ['accuracy'])
tf.model.summary()

history = tf.model.fit(x_data, y_data, epochs = 500)

# Accurcay
print("Accuracy: {0}".format(history.history['accuracy'][-1]))

y_predict = tf.model.predict([[0.176471, 0.155779, 0, 0, 0, 0.052161, -0.952178, -0.733333]])
print("Predict: {0}".format(y_predict))

# evaluating model
evaluate = tf.model.evaluate(x_data, y_data)
print("loss: {0}. accuracy: {1}".format(evaluate[0], evaluate[1]))

구글 코랩환경에서 실습하여 코랩관련 추가코드가 있습니다.

참고자료

모두를 위한 딥러닝 ML Lab 05
Logistic Regression
model.compile(),metrics