일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 백트래킹
- 컴공복전
- 김건우
- 삼성기출
- paging
- 구현
- 가상메모리
- segmentation
- BFS
- 삼성리서치
- 동기화문제
- ascii_easy
- Deadlock
- 프로세스
- exec
- higunnew
- 백준
- 스케줄링
- fork
- dfs
- Brute Force
- pwnable.kr
- 알고리즘
- Memory Management
- 시뮬레이션
- samsung research
- BOJ
- 운영체제
- 완전탐색
- 데드락
- Today
- Total
gunnew의 잡설
3. Multi-variable linear regression 본문
저번에는 하나의 변수와 결괏값의 관계를 예측하는 것을 배웠다. 가장 기초적인 선형 회귀였다. 그러면 이번엔 변수가 여러 개일 때를 생각해보자.
(1) 가설 설정
변수가 하나일 때, 우리는 가설 설정을 Y = W * X + b로 하였다. 그러면 변수가 여러 개일 때는? 변수가 3개라고 하자. 그러면 Y = w1 * x1 + w2 * x2 + w3 * x3 + b로 설정할 수 있을 것이다. 그런데 w1 * x1 + w2 * x2 + w3 * x3. 이 형태 어디서 많이 본 적 있던 것 같은데... 아! 바로 벡터의 내적이다.
벡터의 내적을 처음 들어본다면 뒤로 가기를 누르자. 벡터의 내적은 아주 쉬운 개념이므로 구글링을 해 보면 정말 금방 이해할 수 있다. 그렇다면 w = [w1, w2, w3]로 두고 x = [x1, x2, x3]로 둔다면 x * wT가 될 것이다. 아니 그럼 T는 또 뭔가? Transpose를 모른다면 다시 뒤로 가기를 누르자. T는 행과 열을 서로 바꾼다는 뜻이다. 여기에서 wT는 w가 세로로 세워져 있는 상태가 된다는 것을 뜻한다.
자, 그럼 정리해보자. 우리의 가설 H(x) = x * wT + b로 정리할 수 있을 것이다. 그럼 x 벡터가 여러 개일 때는 어떻게 생각하면 될까? x 벡터 5개일 때를 생각해보자. 그러면 다음과 같은 행렬의 형태로 나타낼 수 있을 것이다.
이 경우에 notation을 소문자에서 대문자로 바꿔서 행렬로 나타내보자면
H(X) = XW + b로 나타내어질 것이다.
(2) 바로 텐서플로우로 구현하기
백날 이론으로 떠들어봤자 한 번 해보느니만 못하다. 바로 파이썬을 켜보자.
자, 이제 다음과 같은 데이터를 다중 선형 회귀 분석을 해볼 것이다.
x1 |
x2 |
x3 |
Y |
73 |
80 |
75 |
162 |
93 |
88 |
93 |
185 |
89 |
91 |
90 |
180 |
96 |
98 |
100 |
196 |
73 |
66 |
70 |
142 |
가설을 세우자.
H(x1, x2, x3) = x1*w1 + x2*w2 + x3*w3 + b
자 그럼 지난 번의 x_data 대신에 x1_data, x2_data, x3_data에 각각 정보를 담고 y_data에도 담는다. 그리고 w1, w2, w3 모두 Variable로 선언할 수 있을 것이다.
아 참, 지난 번에 설명하지 않았던 것이 placeholder라는 개념이다. 이것은 어떤 자료형이 들어갈지만 선언해놓고 값은 이후에 채우게 하는 것이다. 즉, 그릇만 만들어 놓겠다는 것이다. 여기서 분석할 데이터 x1, x2, x3, Y를 앞에서 미리 만들어 놓고 나중에 트레이닝을 할 때 넣어주는 형태로 만들었기 때문에 placeholder를 사용한 것이다. 따라서 placeholder를 사용할 때는 추후 트레이닝을 할 때 feed_dict라는 dictionary 자료형을 통해 값을 넣어주어야 한다. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# multi variable linear regression
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")
hypothesis = x1*w1 + x2*w2 + x3*w3 + b
cost = tf.reduce_mean(tf.square(hypothesis- Y))
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)
|
1600 cost: 1.3447645
Prediction :
[153.1095 183.73505 181.43095 194.70752 142.41785]
1700 cost: 1.326948
Prediction :
[153.08806 183.74927 181.42381 194.70691 142.43268]
1800 cost: 1.3098308
Prediction :
[153.06715 183.76315 181.4168 194.7064 142.44705]
1900 cost: 1.2934353
Prediction :
[153.04675 183.77667 181.40997 194.706 142.46095]
2000 cost: 1.2776887
Prediction :
[153.02686 183.78986 181.4033 194.7057 142.47444]
위와 같은 결과가 나올 것이다. 점차 cost가 줄어들며, hypothesis의 값이 y_data와 거의 근사해 감을 확인할 수 있다.
(3) placeholder를 통한 행렬 표현
하지만 위 코드는 너무 지저분하다. x1_data : ~, x2_data : ~, x3_data : ~, w1 : ~ , w2 : ~
x가 142,562개라면 어떻게 할까. 생각만 해도 너무 끔찍한 코드가 될 것이다. 이 반복적인 작업을 대체할 수 있는 방법이 placeholder의 shape인자를 활용하는 것이다. 즉, 행렬로 데이터를 처리한다는 것이다. 사용법은 아주 간단하다. 우리가 분석하고자 하는 변수의 개수를 열의 개수로 둔다. 그리고 행의 개수는 input data의 개수이다. 위에서는 5개가 주어졌지만 100개가 주어진다면 그때마다 100으로 고치고 실행할 수는 없는 노릇이다. 이렇듯, 미정 개수를 나타내는 python의 심벌은 None이다. 바로 파이썬 코드로 살펴보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# multi variable linear regression
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.]]
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(2001):
cost_val, hy_val, _ = sess.run([cost, hypothesis, train], feed_dict = {X : x_data,
Y : y_data})
if step % 1000== 0:
print(step, "cost: ", cost_val, "\nPrediction : \n", hy_val)
|
이전 코드와 다른 점은 X와 Y를 입력받을 데이터 집합의 개수에 따라 맞추기 위해 [None, 3], [None, 1]로 설정하였다는 점과 W를 행렬의 곱셈을 위해 X의 열의 개수와 W의 행의 개수를 맞추어 설정하여, W를 column vector로 썼다는 점이다. hypothesis = tf.matmul(X, W) + b에서 matmul은 두 행렬의 곱셈 연산을 도와주는 메소드이고, 행렬의 모든 원소에 b를 더해준다는 뜻이다. 이 코드의 실행 결과는 다음과 같다.
0 cost: 28822.744
Prediction :
[[-5.355444 ]
[ 7.73403 ]
[ 0.08409286]
[ 2.2326295 ]
[ 7.7828655 ]]
1000 cost: 9.391671
Prediction :
[[146.55464]
[187.84892]
[178.8429 ]
[196.70135]
[144.7128 ]]
2000 cost: 5.8673368
Prediction :
[[147.55893]
[187.16501]
[179.1564 ]
[196.88307]
[143.85333]]
cost도 계속해서 줄어들며, prediction도 주어진 y_data와의 차이가 줄어들고 있음을 확인할 수 있다.
(4) 결론
variable이 여러 개일 때의 선형 회귀에 대해 알아보았다. 어려운 것은 없었다. placeholder의 적절한 활용과 행렬의 곱셈을 위해 행의 개수와 열의 개수를 잘 맞추는 테크닉을 필요로 했다. 또한, 데이터를 미리 주는 것이 아니라 트레이닝을 할 때에 dictionary 형태로 데이터를 제공하는 dictionary형 인자 feed_dict에 주목할 필요가 있겠다.
세 줄 요약 :
|
'TensorFlow' 카테고리의 다른 글
2. Linear Regression Using Tensor Flow (0) | 2019.11.10 |
---|---|
1. Why Tensor Flow? (2) | 2019.11.10 |