#!/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