로그인 바로가기 하위 메뉴 바로가기 본문 바로가기
난이도
기본

텐서플로우로 시작하는 딥러닝 기초

임시 이미지 Deep Learning Zero To All
http://www.boostcourse.org/ai212/forum/23361
좋아요 1216 수강생 15011
Part-1 Basic ML - Lab 05-3  강의을 진행해주신 컨트리뷰터님의 상세 코드설명입니다. :)

- 부스트코스 운영진

__________

이번 강의에선 Logistic Classfication을 TensorFlow 2.x으로 구현하는 방법을 학습합니다 
아래 코드는 TensorFlow 2.2버전으로 실행하였습니다.

핵심 키워드
  • Logistic Classfication을 TensorFlow 2.x으로 구현하기

학습하기
  • Logistic Classfication은 True or False와 같은 boolean타입이나 Binary와 같은 0과 1만을 가지는 이진 분류에 쓰입니다 (0과 1의 두가지 결과가 나오는 베르누이 분포 : Bernoulli Distribution)
  • Logistic Classfication을 구현하기 위해 기본 Library 선언하고 및 Tensorflow 버전이 2.X인지 확인합니다.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

tf.random.set_seed(777)  # 실행할때 마다 일정한 결과값 출력을 위한 Seed 설정
print(tf.__version__) # 2.2.0
  • 강의에 설명할 Data입니다. 학습시킬 x의 데이터를 2차원 배열로 선언하여 2차원 공간에 표현하며 x1과 x2를 x_train 으로 정의하며 각 값들을 y_train의 0과 1로 선언하여 모델을 생성하는 예제입니다. (ex. 1,2 => 0 / 2,3 =>0 / 4,3=>1) 
  • 여기서 Test할 데이터는 5,2좌표에 1의 결과를 가지는 x_test와 y_test로 선언합니다.
    생성된 모델에서 5,2의 값을 Test하였때 1의 결과가 나오는지 확인하기 위함입니다.
x_train = [[1., 2.],
          [2., 3.],
          [3., 1.],
          [4., 3.],
          [5., 3.],
          [6., 2.]]
y_train = [[0.],
          [0.],
          [0.],
          [1.],
          [1.],
          [1.]]

x_test = [[5.,2.]]
y_test = [[1.]]


x1 = [x[0] for x in x_train]
x2 = [x[1] for x in x_train]

colors = [int(y[0] % 3) for y in y_train]
plt.scatter(x1,x2, c=colors , marker='^')
plt.scatter(x_test[0][0],x_test[0][1], c="red")

plt.xlabel("x1")
plt.ylabel("x2")
plt.show()
  • Logistic Classification 통해 보라색과 노란색 y_data(Label)을 그래프에 출력해 보았습니다. Test 데이터는 붉은색의 위치와 같이 추론시 1의 값을 가지게 됩니다. (보라색은 0의 값, 노란색은 1의 값)


  • 위 Data를 기준으로 가설의 검증을 통해 Logistic Classification 모델을 만들도록 하겠습니다
  • TensorFlow 1.x에서 데이터를 처리하는데 쓰이던 feed_dict를 대신하여 2.x에서 효율적인 데이터 처리를 위한 Dataset API로 학습시 데이터 처리를 효율적으로 할 수 있습니다.
  • TensorFlow data API를 통해 학습시킬 값(x_train)들을 from_tensor_slices를 통해 담습니다.  6개의 slices로 만들고 각각의 slice는 1행2열과 1행 크기를 갖게 됩니다.
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  • W와 b는 학습을 통해 생성되는 모델에 쓰이는 Wegith와 Bias로 초기값을 tf.zeros를 통해 0의 Tensor값으로 설정합니다. Weight와 bias초기화를 tf.random.normal을 통해 random 값으로도 선언이 가능합니다.
W = tf.Variable(tf.zeros([2,1]), name='weight')
b = tf.Variable(tf.zeros([1]), name='bias')
  • Sigmoid 함수를 가설로 선언합니다. Sigmoid는 아래 그래프와 같이 0과 1의 값만을 리턴합니다
  • tf.sigmoid(tf.matmul(X, W) + b)와 결과 값은 같습니다

Sigmoid function - Wikipedia

def logistic_regression(features):
    hypothesis  = tf.divide(1., 1. + tf.exp(-tf.matmul(features, W) + b))
    return hypothesis
  • 강의에서 배운 가설을 검증할 Logistic Regression의 Cost 함수를 정의합니다. (공통된 -값을 앞으로 빼줍니다)


def loss_fn(hypothesis, labels):
    cost = -tf.reduce_mean(labels * tf.math.log(hypothesis) + (1 - labels) * tf.math.log(1 - hypothesis))
    return cost

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
  • 추론한 값은 0.5를 기준(Sigmoid 그래프 참조)로 0과 1의 값을 리턴합니다. Sigmoid 함수를 통해 예측값이 0.5보다 크면 1을 반환하고 0.5보다 작으면 0으로 반환합니다. 가설을 통해 실재 값과 비교한 정확도를 측정합니다

def accuracy_fn(hypothesis, labels):
    predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
    accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, labels), dtype=tf.int32))
    return accuracy
  • 주어진 입력 변수에 대한 gradient를 계산하기 위해 tf.GradientTape API를 사용합니다. 실행된 단계별 모든 미분한 연산값들을 테이프(tape)에 기록할 수 있습니다.
def grad(features, labels):
    with tf.GradientTape() as tape:
        hypothesis = logistic_regression(features)
        loss_value = loss_fn(hypothesis,labels)
    return tape.gradient(loss_value, [W,b])
  • 학습을 실행합니다. 위의 dataset에 담긴 학습데이터를 batch만큼 나누는데 데이터양이 적기에 전체 크기(6)만큼 한번에 학습합니다. Cost함수를 통해 학습시킨 후 모델을 생성합니다. 
  • 1000 Epoch에서 100단위로 Loss 값을 출력하여 값이 감소하는 것을 통해 학습이 되는 것을 확인할 수 있습니다.
EPOCHS = 1001

for step in range(EPOCHS):
    for features, labels  in iter(dataset.batch(len(x_train))):
        hypothesis = logistic_regression(features)
        grads = grad(features, labels)
        optimizer.apply_gradients(grads_and_vars=zip(grads,[W,b]))
        if step % 100 == 0:
            print("Iter: {}, Loss: {:.4f}".format(step, loss_fn(hypothesis,labels)))

  # Iter: 0, Loss: 0.6931
  # Iter: 100, Loss: 0.5781
  # Iter: 200, Loss: 0.5352
  # Iter: 300, Loss: 0.5056
  # Iter: 400, Loss: 0.4840
  # Iter: 500, Loss: 0.4673
  # Iter: 600, Loss: 0.4537
  # Iter: 700, Loss: 0.4421
  # Iter: 800, Loss: 0.4320
  # Iter: 900, Loss: 0.4229
  # Iter: 1000, Loss: 0.4145
  • 새로운 Test Data를 통한 검증 수행을 [5,2]의 Data로 테스트 수행합니다.  (그래프상 1이 나와야 정상입니다)
test_acc = accuracy_fn(logistic_regression(x_test),y_test)
print("Test Result = {}".format(tf.cast(logistic_regression(x_test) > 0.5, dtype=tf.int32)))  
print("Testset Accuracy: {:.4f}".format(test_acc))

# Test Result = [[1]]
# Testset Accuracy: 1.0000
  • 정상적으로 결과가 출력되는 것을 확인할 수 있습니다.