본문 바로가기

유니티 ML Agents/머신러닝과 강화학습 코딩

5 텐서플로우 회귀분석 모델



테스트 데이터 만들기


앞 장에서 1차 방정식을 사용해서 머신 러닝 개념에 대해 알아봤다. 1차 방정식에서 가중치와 편항을 예측하는 회귀분석 모델을 만들기 위해 먼저 테스트 데이터를 만들어보자. 다양한 방법이 있겠지만 sklearn 패키지에서 제공하는 make_regression 함수를 사용하면 아주 쉽게 테스트 데이터를 만들 수 있다.


(1) n_features 인자는 몇 개의 변수를 사용할 지 결정한다. 우리가 만들고자 하는 것은 변수를 1개 사용하는 1차원 함수이므로 1로 지정한다. noise1차원 그래프에서 데이터가 얼마나 벗어날지를 결정한다. 숫자가 클 수록 데이터가 직선 그래프에서 많이 벗어난다. 4로 설정한다.


(2) 만들어진 데이터를 저장하기 위해 pandas 패키지에서 제공하는 DataFrame을 사용한다. DataFrame에 데이터를 저장하면 데이터를 엑셀과 같은 형식으로 조회할 수 있으며 데이터 가공 및 분석에 다양한 함수를 제공한다. 또한 데이터 분석을 위한 다양한 그래프를 손쉽게 사용할 수 있다.


(3) X 데이터와 y 데이터를 두 축으로 하는 산점도를 그려보자. DataFramematplotlib 라이브러리를 활용해서 그래프를 그릴 수 있는 인터페이스를 제공한다. 한 줄의 코드 만으로 간단한 그래프를 그릴 수 있다.


모델 정의

(1) 학습 과정에서 테스트 데이터 X, Y를 입력 받은 플레이스 홀더를 정의한다. (2) 변수 X에 곱할 가중치를 정의한다. 초기 값은 -1보다 크고 1보다 작은 범위에서 랜덤으로 생성한다. (3) Y의 절편을 나타내는 편향을 정의한다. 초기에는 0을 넣어준다. (4) 마지막으로 학습할 모델을 정의한다. 입력하는 테스트 데이터가 실수형이므로 matmul대신 multiply를 사용한다.


손실 함수 정의


(1) 이제 손실 함수를 정의해야 한다. 오차를 측정하고 어떻게 오차를 정의할지를 결정한다. 오차는 계산 값(model)과 실제 값(Y)의 차이이고 손실 함수는 오차의 제곱에 대한 평균이라 정의한다. reduce_mean 함수는 인수로 들어오는 값에 대한 전체적인 평균을 구해 하나의 스칼라 값을 리턴한다.


(2) 손실함수에서 사용할 최적화 함수는 그레디언트 디센트를 사용하고 학습 속도(learning_rate)0.0001로 정의한다. 물론 학습 속도는 학습을 하면서 결과를 보면서 조절해야 한다. (3) 이제 학습을 시킬 함수를 정의 한다. 앞에서 정의한 손실함수를 최소화하는 방향으로 학습하도록 함수를 정의한다


학습


(1) 학습을 진행하기 위해서는 그래프를 실행할 수 있는 세션 객체를 생성해야 한다. global_variables_initializer 함수는 그래프에 정의된 모든 변수를 초기화하는 역할을 한다. (2) 학습을 몇 번 수행할 지 결정한다. 예제에서 30000만 수행하도록 설정했다.


(3) run 함수를 사용해 학습을 진행한다. run함수에서 첫번째 인자는 실행할 대상이다. 예제에서는 trainingcost를 실행하는데 training은 손실 함수를 최소화 되도록 학습하는 함수이고, cost는 현재 오차가 얼마인지 계산하는 함수이다. 두 함수에 대한 실행 결과가 run 함수의 리턴 값이 되어 각각 nonecost_val 변수에 저장된다. training 함수의 결과는 사용하지 않기 때문에 아무 의미가 없다는 뜻으로 none이라 정했고 cost 함수의 실행 결과를 출력을 통해 학습의 효과성을 검증하기 위해 cost_val로 이름을 붙였다.


(4) 3000번 학습할 때마다 오차와, 가중치, 편향을 출력해 학습의 효과성을 확인해 보자. for 문 밖에서 가중치와 편향을 출력해서 학습된 모델의 최종 값을 확인해보자.


학습결과 분석


(1) 초기 오차 7366.141에서 시작해서 학습이 종료될 때는 오차가 17.85289로 줄어들었다. 가중치와 편향은 80.74747-0.36864462를 얻었다. 최종적으로 모델은 Y = 80.74747 * X - 0.36864462가 되며 텐서플로우에서는 모델을 저장에서 나중에 다시 사용할 수 있는 기능을 지원하고 있다. 이 부분은 이 장의 마지막 부분인 DQN에서 다루도록 한다.



import tensorflow as tf
import pandas as pd
from sklearn.datasets import make_regression
X, Y = make_regression(n_samples=100, n_features=1, noise=4)
df = pd.DataFrame(dict(label_x=X[:,0], label_y=Y))
df.plot.scatter(x='label_x', y='label_y')
x_array = df[['label_x']].values
y_array = df[['label_y']].values
X = tf.placeholder(tf.float32, name="X")
Y = tf.placeholder(tf.float32, name="Y")
w = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
a = tf.Variable(tf.zeros([1]))
model = tf.add(tf.multiply(X, w), a)
cost = tf.reduce_mean(tf.square(model - Y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0001)
trainnig = optimizer.minimize(cost)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for step in range(30000):
none, cost_val = sess.run([trainnig, cost], feed_dict={X: x_array, Y: y_array})
if(step % 3000 == 0):
print(step, cost_val, sess.run(w), sess.run(a))
print(step, cost_val, sess.run(w), sess.run(a))
sess.close()