#!/usr/bin/env python3


TensorFlow Way of LinearRegression




이번 예제에서는 tensorflow를 통해 일괄적으로 데이터에 대한 루프를 돌면서 기울기와 y절편을  갱신할 것입니다.

Petal width꽃잎 폭을 x로 Sepal length길이를 y로하는 데이터를 대상으로 최적 직선을 찾아보겠습니다. L2 비용 함수를 사용하겠습니다.


iris데이터셋으로 Linear Regression을 해결하기 위해서는 역시 아래 방정식을 풀어야 합니다.

$$y = Ax+b$$


linear regression computational graph를 사용하기 위해서서는 input으로 $x$ 를 넣었을 때, 

$Ax+b$가 만들어져야 하고 $A$, $b$는 손실값이 최소가 되어야 합니다.

import numpy as np

import tensorflow as tf

from sklearn.datasets import load_iris

from tensorflow.python.framework import ops


iris = load_iris()


print(iris.keys())

# dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])


print(iris.feature_names)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']


x_vals = np.array([x[3] for x in iris.data])

y_vals = iris.data[:,0]


batch_size = 25


x_data = tf.placeholder(shape=[None, 1], dtype=tf.float32)

y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)


A = tf.Variable(tf.random_normal(shape=[1, 1]))

b = tf.Variable(tf.random_normal(shape=[1, 1]))



데이터가 준비되었으니 tensorflow 방식으로 algorithm을 구현하면 다음과 같습니다.

with tf.Session() as sess:

    model_output = tf.add(tf.matmul(x_data, A), b) # linear regression fomula

    loss = tf.reduce_mean(tf.square(y_target - model_output)) # L2 loss

    my_opt = tf.train.GradientDescentOptimizer(learning_rate=0.05) 

    train_step = my_opt.minimize(loss) # loss가 최소인 방향으로 다음 단계 이동


    init = tf.global_variables_initializer()

    init.run()


    loss_vec = []

    for i in range(100):

        rand_idx = np.random.choice(len(x_vals), size=batch_size) 

        rand_x = x_vals[rand_idx].reshape(-1, 1)

        rand_y = y_vals[rand_idx].reshape(-1, 1)


        fedict={x_data: rand_x, y_target:rand_y}


        sess.run(train_step, feed_dict=fedict) # step 반복

        temp_loss = sess.run(loss, feed_dict=fedict)

        loss_vec.append(temp_loss)


        if (i+1)%20==0:

            print('Step {}\nA={}, b={}   Loss={:.5f}'.format(i+1, A.eval(), b.eval(), temp_loss))

            # Step 20

            # A=[[2.4062862]], b=[[2.4534268]]   Loss=1.78677

            # Step 40

            # A=[[1.9556967]], b=[[3.2615643]]   Loss=0.92836

            # Step 60

            # A=[[1.5368886]], b=[[3.698664]]   Loss=0.53148

            # Step 80

            # A=[[1.4006948]], b=[[4.085002]]   Loss=0.46051

            # Step 100

            # A=[[1.1938996]], b=[[4.331669]]   Loss=0.31104


    [slope] = A.eval()

    print('slope: {}'.format(slope))

    # slope: [1.1938996]


    [cept] = b.eval()

    print('intercept: {}'.format(cept))

    # intercept: [4.331669]



위의 결과를 시각화하는 코드는 다음과 같습니다.

import matplotlib.pyplot as plt


best_params = []

for i in x_vals.ravel():

    poly = i*slope+cept

    best_params.append(poly)


plt.scatter(x_vals, y_vals, label='Data Points', edgecolors='k')

plt.plot(x_vals, best_params, 'red')

plt.xlabel('Petal Width', size=15)

plt.ylabel('Sepal Length', size=15)

plt.title('Petal Width vs Sepal Length')

plt.show()



plt.plot(loss_vec, c='k')

plt.xlabel('Generation')

plt.ylabel('L2 Loss')

plt.title('L2 Loss per Generation')

plt.show()





참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

#!/usr/bin/env python3


Inverse Matrix Method


일반적인 linear regression의 식은 다음과 같이 쓸 수있습니다.

$ y = ax + b $, 그러나 이 식을 행렬로 확장하면 $AX = Y$로 쓸 수 있습니다.

$$X=A^{-1}(A^{-T}A^{T})Y$$

$$X=(A^{T}A)^{-1}A^{T}Y$$


$$A = \left[ {\begin{array}{cc}   x_{ 11 } & x_{ 12 } & x_{ 13 } & \cdots  & 1 \\  x_{ 21 } & x_{ 22 } & x_{ 23 } & \cdots  & 1 \\  \vdots&\vdots   &\vdots  &\ddots   & \vdots \\x_{ 31 } & x_{ 32 } & x_{ 33 } & \cdots  & 1 \end{array} } \right]$$


$$ point_{i}=(y_{i}, x_{i1}, x_{i2}, \cdots, x_{iF})$$


간단한 데이터를 만들어 이를 구현해보겠습니다.

import tensorflow as tf

import numpy as np


x_vals = np.linspace(0, 10, 100).reshape(-1, 1)

y_vals = x_vals + np.random.normal(0, 1, size=100).reshape(-1, 1)

ones = np.ones(100).reshape(-1, 1)


A = np.c_[x_vals, ones]


A_tsr = tf.constant(A, dtype=tf.float32)

y_tsr = tf.convert_to_tensor(y_vals, dtype=tf.float32)


init = tf.global_variables_initializer()

with tf.Session() as sess:

    init.run()

    tA_A = tf.matmul(tf.transpose(A_tsr), A_tsr)

    tA_A_inv = tf.matrix_inverse(tA_A)

    prod = tf.matmul(tA_A_inv, tf.transpose(A_tsr))

    sol = tf.matmul(prod, y_tsr)

    solution = sol.eval()


slope = solution[0][0]

cept = solution[1][0]


print('slope :{:.3f}'.format(slope))

# slope :1.000


print('intercept :{:.3f}'.format(cept))

# intercept :0.012



이 결과를 시각화하는 코드는 다음과 같습니다.

import matplotlib.pyplot as plt


reg_params = []

for i in x_vals.ravel():

    poly = slope*i + cept

    reg_params.append(poly)


plt.scatter(x_vals, y_vals, c='orange')

plt.plot(x_vals, reg_params, c='blue', lw=2)

plt.show()

inverse matrix를 이용한 Linear Regression

이런 방법은 데이터셋이 커지게 되면 느려진다는 단점이 있습니다.




참고 자료: 

[1]TensorFlow Machine Learning Cookbook, Nick McClure

[2]https://github.com/nfmcclure/tensorflow_cookbook

+ Recent posts