728x90
반응형



참고자료 : 텐서플로 첫걸음 2장 






1. 변수 간의 관계에 대한 모델



선형회귀분석(Linear Regression)은 변수들 사이의 관계를 분석하는 데 사용하는 통계학적 방법이다. 선형회귀분석은 독립변수 X

, 상수항 b, 종속변수 y 사이의 관계를 모델링하는 방법이다. 두 변수 사이의 관계일 경우 단순회귀라고 하며 여러개의 변수를 다루는 다중회귀도 있다.


텐서플로우를 이용하여 y = W * x + b 형태의 간단한 선형회귀분석 모델을 만들어볼 수 있다.


먼저 2차원 좌표계에 데이터를 생성하고 샘플 데이터에 들어맞는 최적의 직선을 텐서플로우를 이용하여 찾을 수 있다.


 

import numpy as np

num_points = 1000 vectors_set = [] for i in range(num_points): x1 = np.random.normal(0.0, 0.55) y1 = x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03) vectors_set.append([x1, y1]) x_data = [v[0] for v in vectors_set] y_data = [v[1] for v in vectors_set]

위 코드는 y = 0.1 * x + 0.3 관계를 가지는 데이터를 생성한다. 

여기에 np.random.normal 함수를 통해 정규분포를 따르는 약간의 변동 값을 더해 직선과 완전히 일치하지 않게 하였다.

(미관상)


데이터들을 점으로 그려보면 다음과 같다.









2. 비용함수와 경사 하강법 알고리즘




다음 단계는 입력데이터 x_data로부터 출력 값 y를 추정 할 수 있는 학습알고리즘을 훈련시키는 것이다. 입력데이터를 이용해 출력데이터를 만들 수있는 최적의 매개변수 W와 b를 찾도록 하는 텐서플로우 코드는 아래와 같다. 이러한 매개변수를 통한 직선 식은 y_data = W * x_data + b 와 같고, 최적의 매개변수를 찾기 위해 데이터 셋의 값들을 반복하여 적용하면서 매번 더 정확한 결과를 얻기 위해 W와 b를 조정해야한다. 


이러한 반복이 얼마나 좋은지, 나쁜지를 측정하기 위해 비용함수(Cost Function, 또는 오차함수 error function) 를 정의 해야한다. 이 함수는 W와 b를 매개변수로 받아 직선이 얼만나 데이터에 잘 맞는지를 기초로 하여 오차 값을 리턴한다. 


이 예제에서는 비용함수로 평균제곱오차(Mean square error) 를 사용한다. 평균제곱오차는 실제 값과 알고리즘이 반복마다 추정한 값 사이의 거리를 오차로 하는 값의 평균이다. 




아래 코드에서 Variable 메소드는 텐서플로우 내부의 그래프 자료구조에 만들어질 하나의 변수를 정의한다고 한다. 

import tensorflow as tf

W =  tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b




이 변수들을 사용해서 실제 값과 y = W * x + b 로 계산한 값 사이의 거리를 기반으로 한 비용함수는 다음과 같다. 이는 우리가 이미 알고 있는 값인 y_data 와 입력 데이터 x_data에 의해서 계산된 y 값 사이의 거리를 제곱한 것의 평균을 계산한다. 

loss = tf.reduce_mean(tf.square(y - y_data))

즉, 우리는 샘플 데이터에 가장 잘 맞는 직선은 오차 값이 가장 작은 직선이라는 것을 알 수 있다. 오차함수를 최소화하면 가장 최적화된 모델을 구할 수 있다.


이는 나중에 배울 경사하강법(Gradient descent) 이 하는 역할이다. 일련의 매개변수로 된 함수가 주어지면 초기 시작점에서 함수의 값이 최소화 되는 방향으로 매개변수를 변경하는 것을 반복적으로 수행하는 알고리즘이다. 


함수의 기울기를 음의 방향 쪽으로 진행하면서 반복적으로 최적화를 수행한다. 보통 야으이 값을 만들기 위해 거리 값을 제곱하며, 기울기를 게산해야 하므로 오차 함수는 미분 가능해야한다.


경사하강법 알고리즘은 매개변수의 초기 값에서 시작하여 W와 b를 수정해가면서 결국에는 오차함수를 최소화 하는 변수 값을 찾아낸다. 다음 코드와 같다.

optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

위 코드를 실행함으로써 텐서플로우가 내부 자료구조 안에 관련된 데이터를 생성하며, 이 구조 안에 train 에 의해 호출되는 옵티마이저가 구현되었고, 이 옵티마이저는 앞에서 정의한 비용함수에 경사 하강법 알고리즘을 적용하는 것이다. 










3. 알고리즘 실행



텐서플로우는 세션을 생성하고 run 메소드에 train 매개변수를 넣어 호출한다. 그리고 초기화도 수행해준다. 

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)




이제 입력데이터에 최적화 된 직선의 W와 b를 찾기 위해 반복적인 프로세스를 실행한다. 


8번을 반복하여 실행한다고 했을 때 코드는 다음과 같다.



for step in range(8):
    sess.run(train)
    print(step, sess.run(W), sess.run(b), sess.run(loss))
    #산포도
    plt.plot(x_data, y_data, 'ro')
    #직선
    plt.plot(x_data, sess.run(W) * x_data + sess.run(b))
    #x, y축 레이블링을 하고 각 축의 최대 최소 값의 범위를 지정
    plt.xlabel('x')
    plt.xlim(-2,2)
    plt.ylim(0.1, 0.6)
    plt.ylabel('y')
    plt.show()




출력된 결과 값들은 다음과 같다. (W, b, loss 값)



[ 0.65535772] [ 0.30855617] 0.0930702

[ 0.48979613] [ 0.30564895] 0.0463858

[ 0.3734678] [ 0.30365175] 0.0233386

[ 0.2917327] [ 0.30224845] 0.0119606

[ 0.23430364] [ 0.30126247] 0.00634357

[ 0.19395261] [ 0.30056968] 0.00357053

[ 0.16560099] [ 0.30008292] 0.00220153

[ 0.14568046] [ 0.29974091] 0.00152568



반복하면 할수록 loss 값이 줄어든다는 것을 확인 할 수 있으며 그 결과 그림들은 다음과 같다.






















728x90
반응형