데이터가 많아지면 소스코드에 직접 데이터를 입력하는 것이 불가능해지므로 콤마로 이루어진 csv 파일로 저장하고 그것을 불러와서 처리하는 방식을 취해야 한다.

파일을 불러올 때는 Numpy의 loadtxt 함수를 이용한다.

 

아래와 같은 csv 파일을 만들고 실제 소스코드에서 불러와서 학습에 이용해보자.

# EXAM1, EXAM2, EXAM3, FINAL
73,80,75,152
93,88,93,185
89,91,90,180
96,98,100,196
73,66,70,142
53,46,55,101

 

소스코드

import tensorflow as tf
import numpy as np
tf.set_random_seed(777)

# numpy의 loadtxt를 이용하여 float32 데이터 형식의 csv 파일을 읽어온다.
xy = np.loadtxt('data-01-test-score.csv', delimiter=',', dtype=np.float32)
x_data = xy[:, 0:-1] # 전체행, 0부터 마지막 전까지
y_data = xy[:, [-1]] # 전체행, 마지막

# 불러온 데이터가 올바른지 확인
print(x_data.shape, x_data, len(x_data))
print(y_data.shape, y_data)

# placeholder 생성
X = tf.placeholder(tf.float32, shape=[None, 3])
Y = tf.placeholder(tf.float32, shape=[None, 1])

# W는 [X의 갯수, Y의 갯수] b는 [Y의 갯수]의 크기를 가진다.
W = tf.Variable(tf.random_normal([3, 1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

# 가설
hypothesis = tf.matmul(X, W) + b

# cost function
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# 학습 알고리즘 선택
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)

# 세션을 이용한 그래프 출력
sess = tf.Session()
sess.run(tf.global_variables_initializer())

# feed_dict를 활용하여 placeholder에 데이터 입력
for step in range(2001):
    cost_val, hy_val, _ = sess.run([cost, hypothesis, train],
                                   feed_dict={X: x_data, Y: y_data})
    if step % 10 == 0:
        print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)

print("Your score will be ", sess.run(hypothesis, feed_dict={X : [[100, 70, 101]]}))

print("Other scores will be ", sess.run(hypothesis, feed_dict={X: [[60, 70, 110], [90, 100, 80]]}))

 

결과

 

 

Queue Runners

파일의 용량이 커서 메모리에 한 번에 올려 처리하는 것이 불가능할 경우를 대비하여 TensorFlow에서는 Queue Runners라는 시스템을 마련하였다.

 

 

위와 같은 과정이 끝나면 csv 파일을 읽어와서 record 형식에 따라 Queue에 담겨지고 그 담긴 데이터를 batch만큼 읽어와서 학습한다.

한 번에 batch_size 만큼의 데이터를 가져와서 이용한다고 생각.

 

import tensorflow as tf

# TensorFlow Queue Runner 방식 사용
filename_queue = tf.train.string_input_producer(['data-01-test-score.csv'], shuffle=False, name='filename_queue')

reader = tf.TextLineReader()
key, value = reader.read(filename_queue)

record_defaults = [[0.], [0.], [0.], [0.]]
xy = tf.decode_csv(value, record_defaults=record_defaults)

train_x_batch, train_y_batch = tf.train.batch([xy[0:-1], xy[-1:]], batch_size=10)

# placeholder 생성
X = tf.placeholder(tf.float32, shape=[None, 3])
Y = tf.placeholder(tf.float32, shape=[None, 1])

# W는 [X의 갯수, Y의 갯수] b는 [Y의 갯수]의 크기를 가진다.
W = tf.Variable(tf.random_normal([3, 1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

# 가설
hypothesis = tf.matmul(X, W) + b

# cost function
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# 학습 알고리즘 선택
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)

# 세션을 이용한 그래프 출력
sess = tf.Session()
sess.run(tf.global_variables_initializer())

coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)

# feed_dict를 활용하여 placeholder에 데이터 입력
for step in range(2001):
    x_batch, y_batch = sess.run([train_x_batch, train_y_batch])
    cost_val, hy_val, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_batch, Y: y_batch})
    if step % 10 == 0:
        print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)

coord.request_stop()
coord.join(threads)

결과

(Numpy 코드에서는 seed 값을 정해주었기 때문에 cost 값이 동일하게 수렴하지만 위의 코드와 같이 주어주지 않으면 실행할 때마다 다른 점에서 시작하기 때문에 cost 값이 다르게 나온다.)

 

'Machine Learning & Deep Learning' 카테고리의 다른 글

8. Softmax classification  (0) 2020.04.22
7. Logistic Regression  (0) 2020.04.20
5. Multi-variable linear regression  (0) 2020.04.17
4. Hypothesis and Cost  (0) 2020.04.16
3. Linear Regression  (0) 2020.04.15

이제까지는 하나의 Input일 때의 경우에 Hypothesis를 정의하는 법과 Cost function의 Minimize를 구하는 법을 공부하였지만 실제의 Input 데이터는 하나가 아닌 여러 개일 경우가 많다.

 

그렇다면 이제 하나의 Input이 아닌 여러 개의 Input일 경우 가설과 cost function을 아래와 같은 식으로 나타낼 수 있다.

 

 

그런데 Input이 많아지면 각각의 항을 일일이 구현하는 것이 불편하고 이는 Matrix를 사용함으로 아래와 같이 간편하게 구현할 수 있다.

 

 

또한, Matrix로 구현하는 hypothesis는 학습 데이터의 개수인 instance가 늘어나도 아래와 같이 간편하게 구현할 수 있는 장점을 가지고 있다.

 

여기서 확인할 수 있는 하나의 특징은 instance가 늘어나도 W의 Matrix는 원래의 모양을 유지한다는 것이다.

이렇듯이 전체의 데이터를 하나의 Matrix로 관리할 수 있기 때문에 편리하다.

 

 

또한, 여러 개의 input이 존재할 수 있다면 여러 개의 output 역시 존재할 수 있다.

n개의 input과 2개의 output이 존재하는 가설을 세우고 싶다면 아래와 같은 Matrix 형태가 될 것이다.

TensorFlow에서는 n을 None으로 표시하고 Numpy는 -1이라 표시한다.

그렇다면 [?, ?]에 들어갈 값은 앞 행렬의 열을 행으로 뒷 행렬의 열을 열으로 가져서 [3, 2]가 될 것이다.

이런 방식으로 input과 output을 통해 W의 Matrix 형태를 정해줄 수 있다.

 

그렇다면, 공부했던 것들을 TensorFlow를 이용하여 실습하며 이해해보자.

우선, Matrix를 사용하지 않고 구현을 해보겠다.

import tensorflow as tf

# 데이터 셋, label(y)
x1 = [ 73.,  93.,  89.,  96.,  73.]
x2 = [ 80.,  88.,  91.,  98.,  66.]
x3 = [ 75.,  93.,  90., 100.,  70.]
Y = [152., 185., 180., 196., 142.]

# weight(W), bias(b)
w1 = tf.Variable(tf.random.normal([1]))
w2 = tf.Variable(tf.random.normal([1]))
w3 = tf.Variable(tf.random.normal([1]))
b = tf.Variable(tf.random.normal([1]))

learning_rate = 0.000001

for i in range(1000+1):
    # tf.GradientTape()를 통한 Gradient descent 구현
    with tf.GradientTape() as tape:
        hypothesis = w1 * x1 + w2 * x2 + w3 * x3 + b
        cost = tf.reduce_mean(tf.square(hypothesis - Y))
    # tape을 이용하여 반환된 w1, w2, w3, b의 기울기를 변수에 저장
    w1_grad, w2_grad, w3_grad, b_grad = tape.gradient(cost, [w1, w2, w3, b])

    # w1, w2, w3, b를 업데이트
    w1.assign_sub(learning_rate * w1_grad)
    w2.assign_sub(learning_rate * w2_grad)
    w3.assign_sub(learning_rate * w3_grad)
    b.assign_sub(learning_rate * b_grad)

    if i % 50 == 0:
        print("{:5} | {:12.4f}".format(i, cost))

 

결과

 

위의 결과를 보면 cost 값이 작은 값으로 수렴되고 있음을 확인할 수 있다.

 

그렇다면 이제, Matrix를 이용하여 학습을 구현해보자.

import tensorflow as tf
import numpy as np

# 데이터 행렬
data = np.array([
    [73., 80., 75., 152.],
    [93., 88., 93., 185.],
    [89., 91., 90., 180.],
    [96., 98., 100., 196.],
    [73., 66., 70., 142.]
], dtype=np.float32)

# slice data
# X 데이터는 행렬의 전체행, 마지막 열 제외 값
# Y 데이터는 행렬의 전체행, 마지막 열
X = data[:, :-1]
Y = data[:, [-1]]

# W의 값은 앞선 이론에서 공부했듯이 [X의 열 갯수, Y의 열 갯수]로 나타낼 수 있다.
W = tf.Variable(tf.random.normal([3, 1]))
b = tf.Variable(tf.random.normal([1]))

learning_rate = 0.000001


# 우리의 가설을 행렬곱을 이용하여 반환
def predict(X):
    return tf.matmul(X, W) + b


# 2000번의 순회 (epoch는 순회의 횟수를 의미)
n_epochs = 2000
for i in range(n_epochs + 1):
    with tf.GradientTape() as tape:
        cost = tf.reduce_mean(tf.square(predict(X) - Y))

    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 % 100 == 0:
        print("{:5} | {:10.4f}".format(i, cost.numpy()))

 

결과

위에서 Matrix 방식을 쓴 코드와 쓰지 않은 코드를 비교해보면 Matrix를 쓴 코드가 훨씬 간편하게 구현하였음을 직관적으로 확인할 수 있고 데이터가 더욱 많아질수록 이런 차이는 극심해질 것이다.

따라서 우리는 Matrix로 우리의 가설을 세우는 방식을 추구해야 한다.

'Machine Learning & Deep Learning' 카테고리의 다른 글

7. Logistic Regression  (0) 2020.04.20
6. Loading Data from File  (0) 2020.04.18
4. Hypothesis and Cost  (0) 2020.04.16
3. Linear Regression  (0) 2020.04.15
2. Tensorflow 사용 환경 구축  (0) 2020.04.15

Simplified hypothesis

이전의 가설에서 b 부분을 생략한 간략화한 가설을 세워 Cost를 구하고 Minimize 하는 것까지 수행해보겠다.

 

 

위와 같이 간략화한 가설의 Cost 값을 임의로 구해보면 아래와 같은 결과를 가질 것이다.

위와 같은 그래프를 좀 더 조밀한 간격의 그래프로 나타내면 Cost function은 아래와 같은 형태를 띠게 된다.

우리가 원하는 Cost가 minimize 되는 부분은 W=0인 부분이 될 것이다.

Gradient descent algorithm

Cost Function에서 Cost 값을 최적화(최소화)하는 알고리즘

위와 같은 어느 시점에 최소 값을 가진 그래프의 한 시점에서 시작하여 Cost가 줄어드는 방향으로 움직여서 Cost 값이 최저가 되었다고 판단되었을 때까지 W와 b 값을 지속적으로 바꾼다.

 

여기서, Cost가 줄어드는 방향으로 움직이는 방법은 해당 시점에서의 기울기를 이용한다. 기존의 W 값에서 기울기를 빼줌으로써 만약 그래프의 오른쪽 부분에서 시작하였다면 기울기가 양수가 되고 이것을 W 값에서 빼주면 W 값이 줄어들어 그래프상에서 왼쪽으로 이동하는 형태가 될 것이고 만약 그래프의 왼쪽 부분에서 시작하였다면 기울기가 음수가 되고 W 값이 늘어나며 그래프상에서는 오른쪽으로 이동하는 형태가 되어 기울기가 0인 부분에 도달하면 W 값에 변화가 없어질 것이고 그 부분을 minimum이라고 결정 지을 것이다.

또한, 그래프의 기울기가 크다면 (경사지다면) 더 많은 이동을 할 것이고 그래프의 기울기가 작다면 (완만하다면) 적은 이동을 할 것이다.

 

 

위와 같은 미분 방식을 통해 W를 지속적으로 업데이트하여 Cost 값이 최소일 때를 구해 줄 수 있다.

W 값에 기울기를 빼줌으로써 기울기가 양수일 때는 W는 - 방향으로, 기울기가 음수일 때는 + 방향으로 바뀌어야 됨을 알 수 있다.

여기서 알파 값은 Learning rate이라고 하는 상수이며 이 값을 지정하여 우리가 구한 기울기 값을 통해 얼마만큼을 이동할 것인지 결정할 수 있다. ( Learning rate이 크면 한 번에 많이 이동, 작으면 적게 이동하며 보통 0.001이나 0.0001과 같은 작은 값을 이용한다. )

 

 

 

Convex function

우리가 Cost function을 설계할 때, 어느 지점에서 시작하든 같은 결과가 나와야 하며 Local minimum에 도달하는 일이 없도록 하여야 한다.

그런 문제점들이 생기지 않도록 하기 위해 우리는 Cost function을 설계할 때 Convex function의 형태를 띠는지 확인하여야 한다. Convex function이란, Local minimum과 Global minimum이 일치하는 아래와 같은 모양을 띠는 함수이다.

 

 

그렇다면, Cost minimize을 Tensorflow로 구현하면서 이해해보자.

 

우선 Numpy를 이용하여 Cost function의 식을 직접 구현하는 방법은 아래와 같다.

 

import numpy as np

# 데이터 셋
X = np.array([1, 2, 3])
Y = np.array([1, 2, 3])


# cost function 구현
def cost_func(W, X, Y):
    c = 0
    # 데이터 갯수만큼 for문
    for i in range(len(X)):
        # W * X[i]는 우리가 세운 가설 (모델)
        # cost 함수를 직접 구현하고 각각을 더해준 뒤 데이터 개수를 나누어 평균(cost)을 반환
        c += (W * X[i] - Y[i]) ** 2
    return c / len(X)


# cost function 실행
# np.linspace 함수를 이용하여 -3 ~ 5의 값을 15개의 구간으로 나누어서 for문 구현
for feed_W in np.linspace(-3, 5, num=15):
    # -3에서 5까지의 W 값을 가지고 cost function을 이용해 cost 값을 구해준다.
    curr_cost = cost_func(feed_W, X, Y)
    print("{:6.3f} | {:10.5f}".format(feed_W, curr_cost))

 

결과

 

위와 같은 W와 cost 값의 변화를 보고도 알 수 있겠지만 그래프를 통하여 좀 더 직관적으로 확인해 보자.

 

앞서 이론을 공부하면서도 봤겠지만 결론적으로 위와 같은 그래프 형태를 띠게 될 것이며 역시나 W=1 일 때 cost 값이 최소가 됨을 확인할 수 있다.

 

 

이제, Numpy를 이용하여 코드를 구현하는 대신 Tensorflow의 함수를 이용하여 구현하여 보자.

import tensorflow as tf
import numpy as np

# 데이터 셋
X = np.array([1, 2, 3])
Y = np.array([1, 2, 3])


# cos function 구현
def cost_func(W, X, Y):
    # 가설(모델) 설정
    hypothesis = X * W
    # tf.reduce_mean을 이용한 평균, tf.sqaure을 이용한 제곱
    return tf.reduce_mean(tf.square(hypothesis - Y))


# W 값을 -3 ~ 5로 임의로 주어줌
W_values = np.linspace(-3, 5, num=15)
cost_values = []

# 실행
for feed_W in W_values:
    # 임의로 지정해준 W 값(feed_W)을 통해 cost function의 cost 값을 반환
    curr_cost = cost_func(feed_W, X, Y)
    # cost 값을 리스트에 추가
    cost_values.append(curr_cost)
    # 출력
    print("{:6.3f} | {:10.5f}".format(feed_W, curr_cost))

결과는 앞선 코드와 동일하며 동일한 그래프 형태를 가진다.

 

위의 결과까지 도출하였다면 우리는 Cost function을 만드는 것까지 완료한 것이다. 그렇다면 이제 무엇을 해야겠는가?

바로 이 Cost function을 활용하여 cost가 최저인 점을 구하고 그 부분의 W 값을 도출해 내면 되는 것이다. ( Cost minimize 수행 )

그렇다면 minimize 하는 부분을 Gradient descent 알고리즘을 이용하여 구현

import tensorflow as tf

# 코드를 재실행 했을 때도 같은 결과를 얻기 위해 사용
tf.compat.v1.set_random_seed(0)

# 데이터 셋
X = [1., 2., 3., 4.]
Y = [1., 3., 5., 7.]

# 1개의 데이터를 가진 형태의 랜덤값을 W에 할당하여 정의
W = tf.Variable(tf.random.normal([1], -100., 100.))

# 300 스탭 구현
for step in range(300):
    hypothesis = W * X
    cost = tf.reduce_mean(tf.square(hypothesis - Y))

    # Learning rate 값을 0.01로 지정
    alpha = 0.01
    # cost function을 구현
    gradient = tf.reduce_mean(tf.multiply(tf.multiply(W, X) - Y, X))
    # cost function을 이용하여 Gradient descent 구현
    descent = W - tf.multiply(alpha, gradient)
    W.assign(descent)

    # 스탭 10번당 한번 출력
    if step % 10 == 0:
        print('{:5} | {:10.4f} | {:10.6f}'.format(step, cost.numpy(), W.numpy()[0]))

 

결과

 

결과 값을 보면 cost 값과 W 값은 큰 값으로 시작하여 점점 일정한 값으로 수렴하는 것을 확인할 수 있다.

또한, W의 초기값을 임의로 지정하여도 결과적으로 같은 값으로 수렴하는 것을 확인할 수 있다.

 

위의 과정까지 마쳤다면 우리는 cost 함수를 만들고 minimize 함을 통해 우리가 세운 가설(모델)을 구현한 것이다.

'Machine Learning & Deep Learning' 카테고리의 다른 글

6. Loading Data from File  (0) 2020.04.18
5. Multi-variable linear regression  (0) 2020.04.17
3. Linear Regression  (0) 2020.04.15
2. Tensorflow 사용 환경 구축  (0) 2020.04.15
1. Machine Learning  (0) 2020.04.14

Linear Regression?

세상에 있는 많은 현상, 데이터들은 Linear 한 경우가 많다.

(예를 들어, 공부하는 시간이 늘어날수록 점수가 높아진다던가 집의 크기가 클수록 가격이 올라가는 등)

수식으로 표현하면 H(x) = Wx + b ( y = ax + b )와 같은 형태가 될 것이며 이 것을 가설(Hypothesis) 또는 모델(Model)이라 부른다. 

이런 데이터들을 가장 잘 대변하는 직선 방정식을 찾는 것을 Linear Regression이라 한다.

한마디로, 어떤 직선이 우리의 데이터에 가장 근접할 것인가?라는 생각을 가지고 W와 b 값을 결정해 주는 것을 의미한다.

 

Cost function

Cost( Loss, Error )란, 우리가 생각하는 가설( H(x) = Wx +b )과 실제 데이터와의 차이라고 할 수 있다.

 

위와 같이 단순히 차이라고 한다면 가설에서 실제 데이터인 y를 빼는 H(x) - y라고 생각할 수 있지만 수식의 결괏값이 양수가 나올 수도 있고 음수가 나올 수도 있기 때문에 차이 값의 합을 구하는 것은 의미가 없어질 수 있다.

따라서 우리는 ( H(x) - y ) 값을 제곱해서 그것을 평균을 낸 값을 Cost로 사용하고 그 수식을 Cost function이라 한다.

우리가 원하는 직선은 실제 데이터와 가장 근접해야 하기 때문에 이런 Cost 값이 가장 적은 것을 목표로 W 값과 b 값을 구해주어야 한다. 이렇게 W, b 값을 정해 주는 것을 "학습한다."라고 말할 수 있다.

 

 

그렇다면 TensorFlow를 이용하여 이런 Linear Regression을 구현하고 이해해보자.

import tensorflow as tf

# input data, output data
# x값과 y값이 같으므로 H(x) = x 모양의 가설이 되야하고 그렇다면 W=1, b=0가 되어야한다.
# 결과값에서 W와 b를 출력해보고 실제로 1과 0이 되는지를 확인해 보자.
x_data = [1, 2, 3, 4, 5]
y_data = [1, 2, 3, 4, 5]

# Variable() 함수를 이용하여 W와 b 선언, 초기 값은 임의로 주어줌
W = tf.Variable(2.9)
b = tf.Variable(0.5)

learning_rate = 0.01


for i in range(100+1):

    # 경사 하강 알고리즘 구현 ( 경사가 하강하면서 cost가 minimize 되는 W와 b 값을 찾는다. )
    # with 함수를 이용하여 구문 내의 변화를 tape에 기록
    with tf.GradientTape() as tape:
    
        # 가설 설정 ( H(x) = WX +b )
        hypothesis = W * x_data + b
        
        # tf.square()은 제곱을 수행해준다.
        # tf.reduce_mean()은 평균을 내주는데 이때, reduce는 "차원을 내려준다"라는 의미를 내포하고 있다.
        # 실제로 1차원의 list 내의 값들의 평균을 내서 0차원의 Scalar 값으로 반환시켜준다.
        cost = tf.reduce_mean(tf.square(hypothesis - y_data))
        
    # cost에 대한 W 값과 b 값을 미분하여 각각 반환
    W_grad, b_grad = tape.gradient(cost, [W, b])
    
    # W와 b 값 업데이트
    # learning_rate은 gradient 값을 얼만큼 반영할 것인지 결정
    # assign_sub() 함수는 A -= B 의 형태
    W.assign_sub(learning_rate * W_grad)
    b.assign_sub(learning_rate * b_grad)
   
   # 결과 출력
    if i % 10 ==0:
        print("{:5}|{:10.4f}|{:10.4}|{:10.6f}".format(i, W.numpy(), b.numpy(), cost))

해당 코드에서 cost 값이 Minimize 되어야 하니 (hypothesis - y_data) 값은 실질적으로 0에 가까워져야 하고

W는 1, b는 0에 가까워져야 하는 것을 직관적으로 생각할 수 있다.

cost -> hypothesis -> W, b와 같은 순서로 해당하는 값을 구하는 것을 알 수 있다.

 

결과

 

결과 값을 보면 우리가 예상한 대로 W 값은 1에 수렴하고 b 값은 0에 수렴하는 것을 볼 수 있다.

또한, cost 값이 처음에는 큰 값을 가지지만 급격하게 0에 수렴하며 실제 데이터와 우리의 모델의 차이가 줄어드는 것을 확인할 수 있다.

그렇다면 이 W와 b 값을 가진 우리의 hypothesis 즉, 우리의 model이 어떻게 변화하였는지 그림으로 확인해보자.

 

처음에는 우리의 가설인 직선과 실제 데이터 간의 차이가 큰 것을 확인할 수 있는데 학습 과정이 끝난 후에는 우리의 모델이 실제 데이터와 밀접하게 변경되었음을 확일할 수 있다.

 

 

아래의 코드는 tensorflow 1.5 버전에서 진행한 코드이다.

import tensorflow as tf

# Variable는 tensorflow가 자체적으로 변경시키는 값(trainable하다..)
# w와 b에 [1] 형태의 random 값을 주어줌
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
X = tf.placeholder(tf.float32, shape=[None])
Y = tf.placeholder(tf.float32, shape=[None])

hypothesis = X * W + b

# cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - Y))

# Minimize
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

#Session
sess = tf.Session()

# variable 초기화
sess.run(tf.global_variables_initializer())

# Fit the Line
for step in range(2001):
    cost_val, W_val, b_val, _ = sess.run([cost, W, b, train],
        feed_dict={X: [1, 2, 3, 4, 5],
                   Y: [2.1, 3.1, 4.1, 5.1, 6.1]})
    if step % 20 == 0:
        print(step, cost_val, W_val, b_val)

# Testing our model
print(sess.run(hypothesis, feed_dict={X: [1, 5]}))

결과

 

결과 값을 보면 우리가 하고자 했던 training이 성공적으로 이루어져서 모델을 만들었다고 할 수 있다.

X = 1 -> Y = 2.1

X = 5 -> Y = 6.1

'Machine Learning & Deep Learning' 카테고리의 다른 글

6. Loading Data from File  (0) 2020.04.18
5. Multi-variable linear regression  (0) 2020.04.17
4. Hypothesis and Cost  (0) 2020.04.16
2. Tensorflow 사용 환경 구축  (0) 2020.04.15
1. Machine Learning  (0) 2020.04.14

Tensorflow?

머신러닝을 위해 많이 사용되는 오픈 소스 라이브러리이며 Python 언어에 특화되어 있다.

 

Tensorflow 설치

파이썬을 공부할 때 PyCharm이라는 툴을 사용해 본 경험이 있기 때문에 PyCharm을 이용하기로 결정하고 Tensorflow 사용을 위한 환경을 구축하였다.

 

우선 https://www.python.org/downloads/windows/ 에서 Python3을 환경에 맞게 설치한다.

(텐서 플로우는 Python 3.7 버전에 제공되지 않으므로 3.6 이하 버전을 설치해주어야 한다.)

 

Python 설치가 완료되면 https://www.anaconda.com/distribution/#download-section 에서 Anaconda를 다운로드하여 준다.

 

Anaconda 설치가 완료되었다면 Anaconda Prompt를 실행하고 아래의 코드를 순서대로 입력하고 진행한다.

 

1. 우선 Tensorflow를 위한 Conda Environmnet를 생성한다.

conda create -n TensorFlow python=3.6

 

2. Tensorflow env를 활성화한다.

conda activate TensorFlow

 

 

3. pip를 이용하여 Tensorflow를 설치한다.

(cpu)
pip install tensorflow==2.0

(gpu)
pip install tensorflow-gpu

Anaconda Prompt에서는 Tensorflow가 되는데 Pycharm에서는 안되는 문제가 발생..

필자는 Tensorflow 1.5 버전과 Numpy 1.6 버전을 설치해서 해결하였다.

# 모두를 위한 딥러닝1을 기준으로 tensorflow 1.5 버전을 가지고 시작하였으나 최신 버전에 대한 설명이 있는 모두를 위한 딥러닝2에 맞춰 최신버전인 tensorflow 2.x 버전을 새로 설치하여 진행하였음.

 

Pycharm을 사용할 거면 Pycharm 툴에서 텐서 플로우를 설치할 수 있으니 구글링을 통해 설치해보길 바란다.

 

 

Tensorflow 설치가 완료되었다면 간단한 테스트를 해보자 ( tensorflow 1.5 버전의 경우 )

import tensorflow as tf


hello = tf.constant("Hello, TensorFlow!")
sess = tf.Session()
print(sess.run(hello))

 

결과

Tensorflow에 최적화된 CPU를 사용 중이지 않기 때문에 경고문이 뜨지만 실행에는 큰 문제가 없다.

 

Computational Graph

Tensorflow는 기본적으로 (그래프를 만들고 > sess.run을 통해 실행 > 그래프의 값들이 업데이트) 과정을 거친다.

 

import tensorflow as tf

node1 = tf.constant(3.0, tf.float32)
node2 = tf.constant(4.0)
node3 = tf.add(node1, node2) # node3 = node1 + node2

# print문 이용 시 노드 값이 아닌 정보 출력
print("node1:", node1, "node2:", node2)
print("node3:", node3)

# Session을 이용하여 노드의 값 출력
sess = tf.Session()
print("sess.run(node1, node2):", sess.run([node1, node2]))
print("sess.run(node3):", sess.run(node3))

 

결과

Placeholder

그래프를 만드는 단계가 아닌 그래프를 실행시키는 단계에서 값을 던져주고 싶다면 노드를 Placeholder라는 특별한 노드로 만들어 주어야 한다.

import tensorflow as tf

# placeholder 노드 만들기
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b

sess = tf.Session()

print(sess.run(adder_node, feed_dict={a: 3, b: 4.5}))
print(sess.run(adder_node, feed_dict={a: [1,3], b: [2,4]}))

 

결과

 

Tensor

기본적으로 array를 의미함

 

Ranks

몇 차원의 array인가?

Scalar 1차원

Vector 2차원

n-Tensor n차원

 

Shapes

각각의 Element에 몇 개의 데이터가 있는지

[3, 3]와 같은 배열의 크기라고 생각하면 될 듯

 

Types

데이터 타입

tf.float32

tf.int8 등..

'Machine Learning & Deep Learning' 카테고리의 다른 글

6. Loading Data from File  (0) 2020.04.18
5. Multi-variable linear regression  (0) 2020.04.17
4. Hypothesis and Cost  (0) 2020.04.16
3. Linear Regression  (0) 2020.04.15
1. Machine Learning  (0) 2020.04.14

딥러닝에 관심을 가지게 되면서 머신러닝/딥러닝에 관련된 좋은 강좌를 알게 되어 해당 강좌를 보면서 개인적으로 필기 및 정리를 하기 위해서 쓴 글입니다.

https://www.youtube.com/user/hunkims

(모두를 위한 딥러닝 강좌)

 

머신러닝(Machine Learning) 이란?

어떤 소프트웨어에서 input과 output이 존재한다면 모든 output을 인간이 정해줄 수 없는 상황에 학습 데이터를 이용한 컴퓨터의 학습을 통해 output을 정해줄 수 있도록 고안된 기술

예를 들어, 스팸 메일을 분류하는 소프트웨어가 있고 모든 메일을 input이라고 생각하고 스팸 메일을 output이라고 생각한다면 스팸 메일이라는 output이 너무 광범위한 룰을 적용해야 하기 때문에 인간이 모든 input에 대하여 output을 정해줄 수가 없고 이런 상황에 대해 컴퓨터가 학습 데이터를 이용한 반복적인 학습을 통해(머신러닝을 통해) 스팸메일을 분류하는 소프트웨어(모델)를 만들 수 있다.

 

머신 러닝의 종류?

이런 머신러닝의 학습에는 크게 두 가지 종류가 있는데 지도 학습(Supervised Learning)과 비지도 학습(Unsupervised Learning)이다.

 

1. 지도학습(Supervised Learning)

지도 학습이란, label이 정해진 학습 데이터를 이용한 학습을 하는 것인데 쉽게 말해 정답이 정해져 있는 학습 데이터를 사용하는 것이다. 

예를 들어, 어떤 이미지를 통해 이것이 개인지 고양이인지 등을 판단하는 Image labeling이 있다면 이때의 label은 개, 고양이 등이 될 것이며 또한, 앞서 말했던 스팸 메일 필터의 경우 스팸 메일이 label이 될 것이다.

이전에 오세돌 9단과 대국을 했던 AlphaGo의 경우도 이런 지도 학습을 이용하였다. 이 경우 기존에 사람들이 했던 대국의 정보를 학습 데이터로 사용하여 다음 수를 둘 곳을 label로 정하였다고 생각할 수 있을 것이다.

 

2. 비지도학습(Unsupervised Learning)

비지도 학습은 지도 학습과 반대로 label을 정해주기 어려운 것들을 대상으로 label을 정해주는 것이 아닌 데이터 자체를 보고 학습하는 것이다.

예를 들어, 비슷한 뉴스끼리 그룹을 형성시키는 Google news grouping은 미리 label을 정해주는 것이 어렵기 때문에 이런 경우에 비지도 학습을 사용했다고 할 수 있다.

 

지도 학습의 종류

지도학습도 결과에 따라 크게 regression(회귀) 방식과 classification(분류) 방식으로 나뉠 수 있다.

예를 들어, 공부한 시간에 따라 성적이나 합격 여부를 판단하는 프로그램이 있다고 가정한다면

regression 방식은 0에서 100까지의 성적을 예견하는 것과 같이 특정 정수가 아닌 범위가 결과 값으로 주어지는 형식이며,

classification 방식 중 binary classification 방식은 PASS, FAIL 두 가지의 결과 값이 주어지는 형태이며

multi-label classification은 A,B,C,D,F 와 같이 세 가지 이상의 결과 값이 주어지는 형식이다.

'Machine Learning & Deep Learning' 카테고리의 다른 글

6. Loading Data from File  (0) 2020.04.18
5. Multi-variable linear regression  (0) 2020.04.17
4. Hypothesis and Cost  (0) 2020.04.16
3. Linear Regression  (0) 2020.04.15
2. Tensorflow 사용 환경 구축  (0) 2020.04.15

동기식(Synchronous) 전송?

동기라는 말 그대로 요청과 그 결과가 동시에 일어나는 방식, 요청을 하면 시간이 얼마나 걸리던지 요청한 자리에 결과가 주어져야 함

송신 측과 수신 측이 하나의 클럭을 기준으로 동기 신호를 맞춰 동작하는 전송 방식

요청을 보낸 스레드는 응답이 도착하기 전까지는 아무것도 하지 못하는 상태가 됨

동기식 통신은 통신속도가 빠르나 결과가 주어질 때까지 아무것도 못하고 대기해야 하는 단점이 있음

 

비동기(Asynchronous) 전송?

동기식과는 반대로 요청과 결과가 동시에 일어나지 않을 수 있음

스타트비트와 스탑 비트를 통한 Start-Stop 전송 방식

요청을 보낸 스레드는 응답을 기다리지 않으니 다른 일을 할 수 있음

비동기식 통신 속도는 느리나 회로 복잡도가 단순하고 구축비용이 동기식에 비해 저렴

'기타' 카테고리의 다른 글

컴퓨터 구조  (0) 2020.04.12

부트로더?

부트로더란 운영체제가 시동되기 이전에 미리 실행되면서 커널이 올바르게 시동되기 위해 필요한 모든 관련 작업을 마무리하고 최종적으로 운영체제를 시동시키기 위한 목적을 가진 프로그램

 

BIOS -> 1차 부트로더 -> 2차 부트로더 -> 커널 -> 운영체제

 

컴퓨터가 실행되면 BIOS가 로드되고 BIOS에 연결된 저장 매체에서 설정된 부팅 순서대로 부트로더들을 불러온다.

BIOS는 MBR에 존재하는 하드디스크 파티션 테이블을 읽은 후 활성화되어있는 파티션의 PBR을 읽어 그 데이터로 부팅하게 된다. 여기서 MBR, PBR이 바로 1차 부트로더이다.

 

윈도우와 같은 큰 용량이 필요한 운영체제는 2차 부트로더가 필요하며 1차 부트로더가 2차 부트로더를 로드하고 다시 2차 부트로더가 커널을 로드하는 방식이다.

2차 부트로더에는 GRUB(리눅스, 윈도우), SYSLINUX(리눅스), LILO(리눅스) 등이 있다.

 

 

커널?

커널은 컴퓨터의 운영체제의 핵심이 되는 컴퓨터 프로그램의 하나로 운영체제의 전체적인 시스템을 통제하고 시스템 자원을 효율적으로 관리하여 응용 프로그램 수행에 필요한 서비스를 제공

 

커널이 하는 일

 

프로세스 관리 : 프로세스에 CPU를 배분하고 작업에 필요한 환경 제공

메모리 관리 : 프로세스에 작업 공간을 배치하고 실제 메모리보다 큰 가상공간을 제공

파일 시스템 관리 : 데이터를 저장하고 접근할 수 있는 인터페이스 제공

입출력 관리 : 필요한 입력과 출력 서비스 제공

프로세스 간 통신 관리 : 공동 작업을 위한 각 프로세스 간 통신 환경 제공

 

 

포팅?

어느 한 운영체제에서 작동하는 프로그램을 다른 운영체제에서 작동하도록 프로그램을 변경하는 것 또는 운영체제 자체를 이식하는 것

 

한 운영체제에서 작동하는 프로그램을 크로스 컴파일러를 통해 타겟 운영체제에서 실행될 수 있는 실행파일을 생성할 수 있다.

 

CPU나 메모리, 기타 장치가 탑재된 시스템에는 포팅과정을 통해 OS를 설치하여야 한다.

예를 들어, 리눅스를 보드에 포팅한다고 하면 부트로더를 통해 4개의 파일(응용 프로그램, 파일 시스템, 램 디스크, 커널)로 분할하여 플래시 메모리에 저장해 주어야 한다.

이후, 보드를 부팅시키면 플래시 메모리에 저장되어 있는 시스템 파일을 모두 RAM으로 불러와 저장되고 OS를 이용할 수 있게 된다.

'Linux' 카테고리의 다른 글

파일 시스템 / 파티션  (0) 2020.04.11

+ Recent posts