read

Linear Regression의 cost 최소화


ML

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)

위 식을 보면, 이전에 매우 복잡했던 것들이 매우 간단히 처리되었다. 결과 역시 이전과 비슷하다.

이 후는 다음에 계속하겠다.

Blog Logo

구찌


Published

Image

구찌의 나도한번 해블로그

구찌의 개발 블로그 입니다.

Back to Overview