차밍이

[텐서플로우/기초] 단순 선형회귀 모델 및 손실함수 시각화 본문

파이썬/Tensorflow & Keras

[텐서플로우/기초] 단순 선형회귀 모델 및 손실함수 시각화

2020. 4. 16. 13:08
반응형

텐서플로우 기초 실습하기 #1

Tensorflow

Tensorflow 에 대한 기초적인 내용을 공부하고 실습한 내용을 바탕으로 글을 작성할 예정입니다. 기존 텐서플로 1.x 버전들에 대한 자료들이 훨씬 많이 있기 때문에 1.x 버전 내용을 먼저 공부하고 이후에 2.x 버전을 공부할 예정입니다.

import tensorflow as tf
tf.__version__
>> 1.15.0

본 글에서는 텐서플로 1.15.0 버전을 사용하였습니다.

선형 회귀

통계학에서, 선형 회귀(linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 x와의 선형 상관관계를 모델링하는 회귀분석 기법을 의미합니다.

독립 변수 x가 한 개이면 단일 변수 선형 회귀 or 단순 선형 회귀 모델이라고 부릅니다. 둘 이상의 설명 변수에 기반한 경우는 다중 선형 회귀 모델이라고 합니다.

선형 귀는 예측 함수를 통해서 회귀식을 모델링하여, 알려지지 않은 파라미터를 데이터로부터 추정합니다. 즉 데이터들을 쫙 놓아놓고 각 데이터들과 가장 오차가 적은 선을 찾는 것입니다.

위의 그림과 같이 데이터들이 빨간 점으로 나타나 있습니다. 빨간 데이터들과의 차이가 가장 적은 직선을 찾는 것입니다. 위의 그림의 경우 파란 선을 찾으면, 파란 선의 기울기(weight)와 y절편(bias)을 찾을 수 있습니다. 이를 바탕으로 수식을 작성할 수 있습니다.

Tensor flow를 활용해서 단일 변수 선형 회귀 모델을 만들어볼 예정입니다. 간단하게 생각하면 일차방정식의 모습을 생각하시면 됩니다.
$$
y = ax + b
$$
딥러닝에서는 a 대신에 w를 사용해서 weight를 의미하고 b는 그래도 b로 작성하며 bias를 의미합니다.
$$
y = w
x + b
$$
이러한 형태로 작성될 것입니다.

단순 선형 회귀

이번 글에서는 단순 선형 회귀를 통해서 간단한 텐서 플로 사용방법을 익혀보겠습니다.

import pandas as pd
import numpy as np
import tensorflow as tf

path = "../data"
df = pd.read_csv(path+"/cars.csv")
df.head()
  mpg cylinders cubicinches hp weightlbs time-to-60 year brand
0 14.0 8 350 165 4209 12 1972 US.
1 31.9 4 89 71 1925 14 1980 Europe.
2 17.0 8 302 140 3449 11 1971 US.
3 15.0 8 400 150 3761 10 1971 US.
4 30.5 4 98 63 2051 17 1978 US.
corr = df.corr()
corr
  mpg cylinders hp time-to-60 year
mpg 1.000000 -0.776710 -0.774905 0.509070 0.550441
cylinders -0.776710 1.000000 0.845155 -0.578161 -0.322239
hp -0.774905 0.845155 1.000000 -0.744873 -0.383869
time-to-60 0.509070 -0.578161 -0.744873 1.000000 0.312311
year 0.550441 -0.322239 -0.383869 0.312311 1.000000
import seaborn as sns
import matplotlib.pyplot as plt

plt.figure(figsize=(10,10))

cmap = sns.diverging_palette(220, 10, as_cmap=True)
sns.heatmap(corr, cmap=cmap, annot=True, square=True, linewidths=.5, cbar_kws={'shrink': .5})

cylindershp가 강한 양의 상관관계를 가지고 있습니다. 0.85 정도의 양의 상관관계를 가지고 있습니다. 그러므로, cylinders를 통해서 hp를 예측하는 선형 회귀 모델을 만들어 보겠습니다.

# 데이터 불러오기
xtrain = list(df[' cylinders'])
ytrain = list(df[' hp'])
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
w = tf.Variable(tf.random_normal([1]))
b = tf.Variable(tf.random_normal([1]))

# 가설 함수
hf = x*w + b

# 비용 함수
cost = tf.reduce_mean(tf.square(hf-ytrain))

# 최적화 : 가장 기본이 되는 GradientDescent를 옵티마이저로 사용
opt = tf.train.GradientDescentOptimizer(learning_rate=0.001)

train = opt.minimize(cost)
# 기본 세션시행
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# 학습 수행
for step in range(150):
    sess.run(train, feed_dict={x:xtrain})
    if step % 10 == 0:
        wv, bv, cv = sess.run([w, b, cost], feed_dict={x:xtrain, y:ytrain})
        print(f'weight : {wv}, bias : {bv}, cost : {cv}')
weight : [1.1753361], bias : [1.6487181], cost : 11130.875
weight : [10.072178], bias : [3.0899506], cost : 2952.85546875
weight : [14.364864], bias : [3.7776883], cost : 1050.061767578125
weight : [16.436695], bias : [4.1019845], cost : 607.3232421875
weight : [17.437277], bias : [4.2509847], cost : 504.2949523925781
weight : [17.92113], bias : [4.3154407], cost : 480.3072814941406
weight : [18.155733], bias : [4.33913], cost : 474.7099914550781
weight : [18.270105], bias : [4.343167], cost : 473.3915100097656
weight : [18.326479], bias : [4.337736], cost : 473.06878662109375
weight : [18.354876], bias : [4.3277526], cost : 472.9776306152344
weight : [18.369778], bias : [4.315585], cost : 472.9405822753906
weight : [18.378168], bias : [4.3023763], cost : 472.916015625
weight : [18.383413], bias : [4.288678], cost : 472.89447021484375
weight : [18.38714], bias : [4.2747555], cost : 472.8738098144531
weight : [18.390131], bias : [4.2607374], cost : 472.85321044921875

현재 상황에서 더 이상 weightbias값이 변하지 않으므로 학습을 종료하였습니다. 처음에는 쭉쭉 바뀌다가 더 이상 바뀌지 않는 모습을 보이고 있습니다.

임의의 실린더 값을 입력했을 때

임의의 실린더 값이 들어갔을 때, 예측되는 hp의 값을 확인해 보았습니다.

x_list = [5,11,21,37]
for x_ in x_list:
    yhat = sess.run(w)[0]*x_ + sess.run(b)[0]
    print(f'cylinder is {x_} then, hp would be : {yhat}')
cylinder is 5 then, hp would be : 96.21066761016846
cylinder is 11 then, hp would be : 206.56575870513916
cylinder is 21 then, hp would be : 390.49091053009033
cylinder is 37 then, hp would be : 684.7711534500122

Cost 함수 시각화

학습이 진행됨에 따라서 어떻게 cost값이 변하는지를 시각화하여보았습니다. step값과 cost값을 list에 저장한 후, 최종 학습이 완료되고 나서 plot을 그려서 확인할 수 있습니다.

sess = tf.Session()
sess.run(tf.global_variables_initializer())
cost_history = []
steps = []
for step in range(100):
    _, cval = sess.run([train,cost], feed_dict={x:xtrain})
    cost_history.append(cval)
    steps.append(step)
import matplotlib.pyplot as plt

plt.plot(steps, cost_history)
plt.show()

마무리

여기까지 단순 선형 회귀 모델을 텐서 플로를 사용해서 만들고 예측을 진행해보았습니다. 아주 기초적인 문법을 연습하기 위한 과정이었습니다.

 

반응형

관련된 글 보기

Comments