Linear Regression의 cost 최소화
Linear Regression의 cost 최소화 를 구현하고자한다.
H(x) = Wx + b
여기서 bias는 잠시 생략하고 계산하도록 하자.
import tensorflow as tf
import matplotlib.pyplot as plt
X = [1, 2, 3]
Y = [1, 2, 3]
W = tf.placeholder(tf.float32)
hypothesis = X * W
cost = tf.reduce_mean(tf.square(hypothesis - Y))
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# 그래프를 그리기 위해 W, cost를 저장할 리스트
W_val = []
cost_val = []
for i in range(-30, 50):
feed_W = i * 0.1
curr_cost, curr_W = sess.run([cost, W], feed_dict={W: feed_W})
W_val.append(curr_W)
cost_val.append(curr_cost)
plt.plot(W_val, cost_val)
plt.show()
그래프를 보면 2차원 곡선 처럼 오목한 그래프가 나온다.
이 그래프와 미분을 이용해 Gradient descent를 적용해보면 W값이 cost function의 미분값과 learning rate를 곱한값을 빼면서 update시킨다. (미분값의 음양에 따라, 조절하기 위해 뺀다.)
# 수동 Gradient Descent
learning_rate = 0.1
gradient = tf.reduce_mean( ( W * X - Y ) * X )
descent = W – learning_rate * gradient
update = W.assign(descent)
tensorflow에서는 W에 assign할때, 단순히 = 을 쓰지 않고 assign
을 쓴다.
전체코드를 보면
import tensorflow as tf
x_data = [1,2,3]
y_data = [1,2,3]
W = tf.Variable(tf.random_normal([1]), name='weight')
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
hypothesis = X * W
cost = tf.reduce_sum(tf.square(hypothesis - Y))
learning_rate = 0.1
gradient = tf.reduce_mean((W * X - Y) * X)
descent = W - learning_rate * gradient
update = W.assign(descent)
# optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1)
# train = optimizer.minimize(cost)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for step in range(21):
# update 실행, X, Y를 주면서
sess.run(update, feed_dict={X: x_data, Y: y_data})
print(step, sess.run(cost, feed_dict={X: x_data, Y:y_data}), sess.run(W))
# for step in range(100):
# print(step, sess.run(W))
# sess.run(train)
optimizer
를 이용한 코드도 적어두었다.
결과는 다음과 같이 되며, W를 5.0 이나 -3.0과 같이 전혀 틀린 값을 주더라도, 업데이트가 된다는 것을 볼 수 있다.
또한, 단순히 GradientsDescent를 쓰는 것이 아니라, 이를 수정하고 싶을 때는 gvs라는 변수를 보면 된다. 바로 train 시키는 것이 아니라, apply_gradients를 만들어 수정 후 적용하면 된다.
import tensorflow as tf
X = [1,2,3]
Y = [1,2,3]
W = tf.Variable(5.)
hypothesis = X * W
gradient = tf.reduce_mean( ( W * X - Y ) * X ) * 2
cost = tf.reduce_sum(tf.square(hypothesis - Y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1)
gvs = optimizer.compute_gradients(cost)
# gvs를 수정 가능
apply_gradients = optimizer.apply_gradients(gvs)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for step in range(100):
# gradient, W, gvs를 출력 (손으로 계산)
print(step, sess.run([gradient, W, gvs]))
# apply_gradient를 출력해 비교
sess.run(apply_gradients)
gvs는 gradient와 Weight를 출력해준다. 위와 같이 비교해서 처리하면, 거의 같은 값으로 귀결된다.
Multi-variable Linear Regression
먼저, Multi-variable 에서 조심해야 할 점이 있는데,
Linear Regression 의 공식
H(x) = Wx + b
가 있을 때, bias를 우선 생략하고,
H(x1,x2,x3) = x1w1 + x2w2 + x3w3
라는 식의 적용을 위해 Matrix 를 쓰게 된다.
그때, Wx
가 아니라 XW
로 적용해야 Matrix 식이 그대로 적용이 된다.
import tensorflow as tf
x1_data = [73., 93., 89., 96., 73.]
x2_data = [80., 88., 91., 98., 66.]
x3_data = [75., 93., 90., 100., 70.]
y_data = [152., 185., 180., 196., 142.]
x1 = tf.placeholder(tf.float32)
x2 = tf.placeholder(tf.float32)
x3 = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
w1 = tf.Variable(tf.random_normal([1]), name='weight1')
w2 = tf.Variable(tf.random_normal([1]), name='weight2')
w3 = tf.Variable(tf.random_normal([1]), name='weight3')
b = tf.Variable(tf.random_normal([1]), name='bias')
hypothesis = x1 * w1 + x2 * w2 + x3 * w3 + b
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())
for step in range(2001):
cost_val, hy_val, _ = sess.run([cost, hypothesis, train], feed_dict={x1:x1_data, x2:x2_data, x3:x3_data, Y:y_data})
if step % 10 == 0:
print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)
이전 방법대로 구현해보면 위와 같다.
그런데 조금 코드가 복잡해졌다. 따라서, 이런 방법은 사용하지 않는다.
그래서 사용하는 것이 Matrix 다.
import tensorflow as tf
x_data = [[73.,80.,75.], [93.,88.,93.], [89.,91.,90], [96.,98.,100.], [73.,66.,70.]]
y_data = [[152.], [185.], [180.], [196.], [142.]]
# Shape를 주의
X = tf.placeholder(tf.float32, shape=[None, 3])
Y = tf.placeholder(tf.float32, shape=[None, 1])
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 = 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())
for step in range(10001):
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)
위 식을 보면, 이전에 매우 복잡했던 것들이 매우 간단히 처리되었다. 결과 역시 이전과 비슷하다.
이 후는 다음에 계속하겠다.