선형 회귀분석은 하나 이상의 독립변수들이 종속변수에 미치는 영향을 추정할 수 있는 통계기법입니다. tensorflow로 선형 회귀분석방법을 직접 구현해보면서 더 자세하게 알아보겠습니다.
다음은 x_data = [1,2,3,4,5,6,7], y_data = [2,3,4,5,6,7,8]의 경우를 점으로 찍은 그래프입니다.
위의 경우에서 주어진 정보를 가장 잘 대변하는 직선 그래프는 무엇일까요? 바로 <그림 2>에서 볼 수 있듯이 y = x + 1입니다.
이렇듯 선형 회귀분석은 <그림 1>에서 <그림 2>로 가는 과정입니다. 정답과 정보만을 가지고 규칙을 찾을 수 있다는 것이 정말 매력적으로 느껴집니다.
다음과 같이 H(x) = wx+b라고 정의하겠습니다.
x와 그에 따른 결과는 이미 알고 있으므로 tensorflow를 활용하여 구해야 하는 값은 w와 b입니다. 최적의 w와 b를 구하기 위해서는 손실이라는 것을 알아야 합니다. 손실은 예측값 H(x)와 실제 값 y의 차이를 나타내는 지표로 아래와 같이 정의됩니다.
다음 그림에서 빨간 부분이 바로 cost값에 해당되는 부분입니다. 최적의 w, b를 구한다는 의미는 손실을 가장 적게 하는 w, b를 구한다는 것과 마찬가지로 생각할 수 있습니다.
하지만 <그림 4>는 손실이 양수도 나올 수 있고, 음수도 나올 수 있습니다. 서로 다른 부호를 가지고 있으면 정확한 손실을 계산함에 있어 어려움이 있기 때문에 전부 양수로 바꿔주도록 제곱을 사용합니다. 양수로 변환된 손실 값을 평균을 내어주는 것으로 학습의 방향성을 알 수 있는 지표로 변환시켜줍니다. 식은 다음과 같습니다.
예측한 값에 대해서 정확한 값인지 알 수 있는 방법까지 확인하였으므로 다음은 손실 값에 따른 w, b의 값 변경에 대해서 알아보겠습니다. 대표적인 방법으로는 경사 하강법(Gradient Descent)이 있습니다. 경사 하강법은 함수의 기울기를 구하고 기울기의 절댓값이 낮은 쪽으로 이동시키는 방법입니다. 다음은 경사 하강법을 코드로 구현한 것입니다.
learning_rate = 0.01
with tf.GradientTape() as tape:
hypothesis = W * x_data + b
cost = tf.reduce_mean(tf.square(hypothesis - y_data))
W_grad, b_grad = tape.gradient(cost, [W, b])
W.assign_sub(learning_rate * W_grad)
b.assign_sub(learning_rate * b_grad)
여기서 hypothesis는 H(x)에 y_data는 y에 대응됩니다. hypothesis를 정의해주고 <그림 6>의 식을 구현하여 cost에 저장해줍니다. 이렇게 계산된 cost에 대한 변수들(w, b)의 미분 값을 반환하여 줍니다. 반환된 값을 assign_sub와 미분 값을 얼마큼 반영할 것인지 나타나는 learning_rate를 통해 w, b의 값을 갱신해줍니다.
x_data = [1,2,3,4,5,6,7]
y_data = [2,3,4,5,6,7,8]
W = tf.Variable(7.0)
b = tf.Variable(5.0)
learning_rate = 0.01
epochs = 1000
for i in range(epochs+1):
with tf.GradientTape() as tape:
hypothesis = W * x_data + b
cost = tf.reduce_mean(tf.square(hypothesis - y_data))
W_grad, b_grad = tape.gradient(cost, [W, b])
W.assign_sub(learning_rate * W_grad)
b.assign_sub(learning_rate * b_grad)
if i % 100 == 0:
print("{:5}|{:10.4}|{:10.4}|{:10.6f}".format(i, W.numpy(), b.numpy(), cost))
앞서 설명한 과정을 코드로 구현하면 위와 같습니다. x와 y값을 주고 임의의 w, b의 값을 설정합니다. 또한 경사 하강법 반영률을 나타내는 learning_rate와 학습 횟수 epochs의 값을 설정해줍니다. 그리고 100번째 학습마다 학습의 진행도를 알 수 있도록 epochs, weight, bias, cost를 출력해줍니다. 출력 결과는 다음과 같습니다.
epochs= 0|weight= 4.28|bias= 4.44|cost=928.000000
epochs= 100|weight=0.6334|bias= 2.816|cost=0.664629
epochs= 200|weight=0.7506|bias= 2.235|cost=0.307601
epochs= 300|weight=0.8303|bias= 1.84|cost=0.142363
epochs= 400|weight=0.8846|bias= 1.572|cost=0.065888
epochs= 500|weight=0.9215|bias= 1.389|cost=0.030494
epochs= 600|weight=0.9466|bias= 1.265|cost=0.014113
epochs= 700|weight=0.9637|bias= 1.18|cost=0.006532
epochs= 800|weight=0.9753|bias= 1.122|cost=0.003023
epochs= 900|weight=0.9832|bias= 1.083|cost=0.001399
epochs=1000|weight=0.9886|bias= 1.057|cost=0.000648
학습이 진행됨에 따라 cost의 값이 작아지는 것을 확인할 수 있고, y = x + 1에 맞게 w는 1에 가까운 값 b도 1에 가까운 값으로 변경되고 있는 것을 알 수 있습니다. 처음 w=7, b=5일 경우에 직선 그래프를 나타내면 아래의 그림에서 빨간색 직선과 같이 표현됩니다.
그렇다면 1,000번의 학습 과정은 직선 그래프에 어떠한 변화를 가져왔을까? 결과는 다음과 같습니다.
최초 파란색의 직선에서 청록색의 그래프까지의 변화입니다. <그림 2>와 비교하였을 때 거의 동일한 모습을 하고 있는 것을 알 수 있습니다.
선형 회귀의 구현 방법부터 tensorflow를 활용한 구현까지에 대해서 알아보았습니다.
참고자료
텐서플로우로 시작하는 딥러닝 기초 강의 - edwith
'Artificial Intelligence > Tensorflow' 카테고리의 다른 글
[Tensorflow] 다중 선형회귀분석이 뭐야? (0) | 2021.05.14 |
---|---|
[Tensorflow] 경사 하강법이 뭐야? (0) | 2021.05.07 |
[Tensorflow] 김치 이미지 분류기 - 모델학습 (0) | 2021.04.23 |
[Tensorflow] 김치 이미지 분류기 - 데이터 분류 (0) | 2021.04.22 |
[Tensorflow] 김치 이미지 분류기 전체 과정 (0) | 2021.04.19 |