donut

'regression'에 해당되는 글 3건

  1. Tensorflow 다중선형회귀 공부
  2. Python Logistic Regression
  3. Python Tensorflow 단순선형회귀

Tensorflow 다중선형회귀 공부

Tensorflow/ML

 

 

 

다중 선형회귀 복습

지난번포스팅했던 다중 선형회귀를 복습하는 시간을 가지겠습니다.
자세한 포스팅은 이전에 했기때문에 주석을 최소화 하였습니다.

In [280]:
import tensorflow as tf
import numpy as np
print(tf.__version__)
 
2.1.0
 

변수 만들기(컴프리헨션 복습)

In [281]:
test1 = [i for i in range(0,10) if i>2]
test1
Out[281]:
[3, 4, 5, 6, 7, 8, 9]
In [282]:
test1 = list(range(0,10))
test2 = list(range(10,20))
print(test1)
print(test2)
 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
In [283]:
test3 = []
for i,v in zip(test1,test2):
    test3.append([i,v])
test3
Out[283]:
[[0, 10],
 [1, 11],
 [2, 12],
 [3, 13],
 [4, 14],
 [5, 15],
 [6, 16],
 [7, 17],
 [8, 18],
 [9, 19]]
 

x,y, 값 나눠주기

In [284]:
x1 = [x[0] for x in test3]
x2 = [x[1] for x in test3]
y = [i for i in range(100,110)]
In [285]:
print(x1)
print(x2)
print(y)
 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
In [288]:
#x변수가 2개이기 때문에 W도 2개 설정
tf.random.set_seed(0)
W1 = tf.Variable(tf.random.uniform((1,),1., 10.0 ))
W2 = tf.Variable(tf.random.uniform((1,),1., 10.0 ))
b = tf.Variable(tf.random.uniform((1,),1., 10.0 ))
In [287]:
learning_rate = tf.Variable(0.001)
for i in range(1001):
    with tf.GradientTape() as tape:
        hypothesis = W1 * x1 + W2* x2 + b
        cost = tf.reduce_mean(tf.square(hypothesis - y))
    W1_grad, W2_grad, b_grad = tape.gradient(cost, [W1,W2,b])
    W1.assign_sub(learning_rate * W1_grad)
    W2.assign_sub(learning_rate * W2_grad)
    b.assign_sub(learning_rate * b_grad)
    
    if i % 50 ==0:
        print("{:5} | {:10.6f} | {:10.4f} | {:10.4f} | {:10.6f}".format(
        i, cost.numpy(), W1.numpy()[0], W2.numpy()[0], b.numpy()[0]))
 
    0 | 616.380981 |     3.4714 |     5.8110 |   2.753797
   50 | 282.371643 |    -0.0978 |     6.7484 |   3.204454
  100 | 141.552185 |    -2.5705 |     7.5713 |   3.534010
  150 |  70.959732 |    -4.3213 |     8.1539 |   3.767345
  200 |  35.571896 |    -5.5608 |     8.5664 |   3.932551
  250 |  17.832087 |    -6.4385 |     8.8585 |   4.049521
  300 |   8.939185 |    -7.0599 |     9.0652 |   4.132339
  350 |   4.481170 |    -7.4998 |     9.2117 |   4.190976
  400 |   2.246401 |    -7.8113 |     9.3153 |   4.232491
  450 |   1.126115 |    -8.0319 |     9.3887 |   4.261886
  500 |   0.564514 |    -8.1880 |     9.4407 |   4.282698
  550 |   0.282984 |    -8.2986 |     9.4775 |   4.297431
  600 |   0.141857 |    -8.3769 |     9.5035 |   4.307865
  650 |   0.071112 |    -8.4323 |     9.5220 |   4.315252
  700 |   0.035649 |    -8.4715 |     9.5350 |   4.320483
  750 |   0.017869 |    -8.4993 |     9.5443 |   4.324186
  800 |   0.008958 |    -8.5190 |     9.5508 |   4.326808
  850 |   0.004490 |    -8.5329 |     9.5554 |   4.328665
  900 |   0.002251 |    -8.5428 |     9.5587 |   4.329979
  950 |   0.001129 |    -8.5498 |     9.5610 |   4.330909
 1000 |   0.000566 |    -8.5547 |     9.5627 |   4.331569
 

변수 3개 메트릭스 활용

변수만들기

In [289]:
x1 = [x for x in range(0,10)]
x2 = [x for x in range(10,20)]
x3 = [x for x in range(30,40)]
y = [x for x in range(100,110)]
In [290]:
print(x1)
print(x2)
print(x3)
print(y)
 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
In [291]:
#변수를 한 메트릭스로 만들기
data =np.array([[i,v,z,h] for i,v,z,h in zip(x1,x2,x3,y)],dtype =np.float32)
data
Out[291]:
array([[  0.,  10.,  30., 100.],
       [  1.,  11.,  31., 101.],
       [  2.,  12.,  32., 102.],
       [  3.,  13.,  33., 103.],
       [  4.,  14.,  34., 104.],
       [  5.,  15.,  35., 105.],
       [  6.,  16.,  36., 106.],
       [  7.,  17.,  37., 107.],
       [  8.,  18.,  38., 108.],
       [  9.,  19.,  39., 109.]], dtype=float32)
In [321]:
#X, Y 로 데이터 나눠주기
X = data[:,:-1]
Y = data[:,[-1]]
print(X)
print(Y)
 
[[ 0. 10. 30.]
 [ 1. 11. 31.]
 [ 2. 12. 32.]
 [ 3. 13. 33.]
 [ 4. 14. 34.]
 [ 5. 15. 35.]
 [ 6. 16. 36.]
 [ 7. 17. 37.]
 [ 8. 18. 38.]
 [ 9. 19. 39.]]
[[100.]
 [101.]
 [102.]
 [103.]
 [104.]
 [105.]
 [106.]
 [107.]
 [108.]
 [109.]]
In [322]:
print(X.shape)
print(X.shape[1])
 
(10, 3)
3
In [323]:
#W, b 설정해주기
W = tf.Variable(tf.random.normal((X.shape[1],1)))
b = tf.Variable(tf.random.normal((1,)))
In [324]:
# 예측 모델 및 경사하강법 적용
def predict(X):
    return tf.matmul(X,W) + b

learning_rate = 0.00001


for i in range(1001):
    with tf.GradientTape() as tape:
        cost =tf.reduce_mean((tf.square(predict(X) - y)))
        
    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 % 500 ==0:
        print("{:5} | {:10.6f} | {:10.4f} | {:10.4f} | {:10.6f}".format(
            i, cost.numpy(), W.numpy()[0][0], W.numpy()[1][0], b.numpy()[0]))
 
    0 | 3581.468018 |     1.3541 |     0.4929 |  -2.126617
  500 | 186.300980 |     1.2123 |     0.8905 |  -2.072671
 1000 | 159.831528 |     0.9086 |     0.7253 |  -2.058817
In [325]:
#W값 확인
print(W)
 
<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[0.9085694 ],
       [0.72533375],
       [2.6267443 ]], dtype=float32)>
In [307]:
#X값으로 해 도출
predict(X)
Out[307]:
<tf.Tensor: shape=(10, 1), dtype=float32, numpy=
array([[ 89.7837  ],
       [ 92.84181 ],
       [ 95.899925],
       [ 98.958046],
       [102.01615 ],
       [105.07428 ],
       [108.13239 ],
       [111.190506],
       [114.24863 ],
       [117.30674 ]], dtype=float32)>
In [308]:
#임의의 값으로 해 도출
predict([[ 1.,  1.,  4.],[ 145.,  50.,  50.]]).numpy()
Out[308]:
array([[11.6773615],
       [87.66279  ]], dtype=float32)

'Tensorflow > ML' 카테고리의 다른 글

Python Logistic Regression  (0) 2020.07.28
Python Tensorflow 다중선형회귀  (0) 2020.07.25
Python Tensorflow 단순선형회귀  (0) 2020.07.20

Python Logistic Regression

Tensorflow/ML

 

 

 

Logistic_Regression(Classification)

로지스틱 회귀(분류)

안녕하세요. 이번 포스팅은 로지스틱 회귀에대해 포스팅을 진행하겠습니다.
로지스틱 회귀란 = 독립 변수의 선형 결합을 이용하여 사건의 발생 가능성을 예측하는 통계기법(출처 나무위키)

흔히 로지스틱 회귀는 종속변수가 2개(이항, boolean, True or False)인경우를 말하며, 이를 Classification 분류 기법이라고 한다.

종속변수가 2개이상일 경우 다항로지스틱 회귀라고 한다.(Multinormial logisitic regression).

이번 포스팅은 Classification에 관한 포스팅입니다.

필요한 모듈 세팅 및 tensorflow버전 확인

In [1]:
import numpy as pn
import matplotlib.pyplot as plt
import tensorflow as tf

tf.random.set_seed(0)
print(tf.__version__)
 
2.1.0
 

데이터 세팅

In [2]:
#x1, x2를 각각 x_train의 2차원배열로 정의해줍니다.
x_train = [[1., 6.],
          [2., 5.],
          [3., 4.],
          [4., 3.],
          [5., 2.],
          [6., 1.]]

#각 배열의 도출 값을 선언합니다.
#1,6 -> 0
#6,1 -> 1

y_train = [[0.],
          [0.],
          [0.],
          [1.],
          [1.],
          [1.]]
In [5]:
#데이터 확인
print(x_train, y_train)
 
[[1.0, 6.0], [2.0, 5.0], [3.0, 4.0], [4.0, 3.0], [5.0, 2.0], [6.0, 1.0]] [[0.0], [0.0], [0.0], [1.0], [1.0], [1.0]]
 

테스트 할 데이터 세팅

In [36]:
#test할 데이터를 세팅해 줍니다.
#2,6이 1인지 확인하기 위합니다.
x_test = [[2.,6.]]
y_test = [[0.]]
In [37]:
x_test,y_test
Out[37]:
([[2.0, 6.0]], [[0.0]])
 

x값 할당해 주기

x_train에 있던 값들을 각각 x1, x2로 할당해 주겠습니다. 이때, 리스트 형식으로 할당해 주는데요,
복습차원에서 리스트 컴프리헨션과, append방법 두가지를 활용해 보겠습니다.

In [38]:
x1 = [x[0] for x in x_train]
x1
Out[38]:
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
In [39]:
x1=[]
for x in range(len(x_train)):
    x1.append(x_train[x][0])
x1
Out[39]:
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
In [40]:
x2 = [x[1] for x in x_train]
x2
Out[40]:
[6.0, 5.0, 4.0, 3.0, 2.0, 1.0]
In [41]:
x2=[]
for x in range(len(x_train)):
    x2.append(x_train[x][1])
x2
Out[41]:
[6.0, 5.0, 4.0, 3.0, 2.0, 1.0]
 

데이터 그래프로 확인하기

현재까지 할당된, 데이터를 그래프에서 확인해 보겠습니다.
데이터각각에 색을 입혀줄껀데요, 이것도 역시 리스트컴프리헨션을 복습하겠습니다.

In [42]:
colors = []
for y in range(len(y_train)):
    colors.append(int(y_train[y][0]))
colors
Out[42]:
[0, 0, 0, 1, 1, 1]
In [43]:
colors = [int(y[0]) for y in y_train]
colors
Out[43]:
[0, 0, 0, 1, 1, 1]
In [44]:
#0은 보라색, 1은 노란색으로 표시가 됩니다.
colors = [int(y[0]) for y in y_train]

#x1, x2에 해당되는 값들은 삼각형으로 표시
plt.scatter(x1,x2, c= colors, marker='^')

#제가 찾고자 했던 x_test값 (2,6)은 빨간색으로 표시했습니다.
plt.scatter(x_test[0][0], x_test[0][1], c='red')

plt.xlabel("x1")
plt.ylabel("x2")
plt.show()
 
 

Logistic Classification모델 만들기

In [93]:
#dataset 만들기
#학습시킬 값을 dataset에 담아준다.
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
dataset
Out[93]:
<TensorSliceDataset shapes: ((2,), (1,)), types: (tf.float32, tf.float32)>
 

dataset 살펴보기

현재 dataset은 6슬라이스로 이루어져 있다.
1슬라이스 => [1,6],[0]
2슬라이스 => [2,5],[0] ....

In [95]:
#리스트 컴프리헨션
elem = [i for i in dataset]
print(elem)
print(len(elem))
 
[(<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 6.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([2., 5.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([3., 4.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([4., 3.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([5., 2.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([6., 1.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>)]
6
In [96]:
#append로 확인하기
elem2= []
for i in dataset:
    elem2.append(i)
print(elem2)
len(elem2)
 
[(<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 6.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([2., 5.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([3., 4.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([4., 3.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([5., 2.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>), (<tf.Tensor: shape=(2,), dtype=float32, numpy=array([6., 1.], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>)]
Out[96]:
6
 

W, b 할당해 주기

W,b초기값을 할당해 줍니다. x가 x1,x2 2개의 변수였기 때문에 W는 2행1열의 배열을 선언해준다.
b는 1행 1열로 선언해 준다.

In [105]:
#초기값을 tf.random.normal로 설정해주기
W = tf.Variable(tf.random.normal((2, 1)))
b = tf.Variable(tf.random.normal((1,)))
print(W.numpy(),b.numpy())
 
[[-2.1278012 ]
 [ 0.42648628]] [-1.4933363]
In [111]:
#초기값을 tf.zeros로 설정해 주기
W = tf.Variable(tf.zeros([2,1]), name= 'weight')
b = tf.Variable(tf.zeros([1]), name='bias')
print(W.numpy(),b.numpy())
 
[[0.]
 [0.]] [0.]
 

시그모이드 함수 구현

In [106]:
def logistic_regression(features):
    hypothesis = tf.divide(1., 1. + tf.exp(tf.matmul(features, W) + b))
    return hypothesis
    
 

cost 함수 구현, 러닝레이트 선언

In [107]:
def loss_fn(hypothesis, features, labels):
    cost = -tf.reduce_mean(labels * tf.math.log(logistic_regression(features)) + (1-labels) * tf.math.log(1-hypothesis))
    return cost
optimizer = tf.keras.optimizers.SGD(learning_rate =0.01)
 

결과값 도출 함수 구현

시그모이드 함수로 도출된 hypothesis를 0 or 1로 cast해준다.

tf.cast => 조건이 참일경우 1, 거짓일 경우 0출력
tf.equal => 주어인 값이 같은경우 True, 다를경우 False
아래는 cast와 equal를 이해하기 쉽도록 예시를 작성 하였습니다.

In [119]:
test1 = 0.3
test2 = tf.cast(test1 > 0.5,dtype = tf.float32)
test2.numpy()
Out[119]:
0.0
In [129]:
test1 = 0.6
test2 = tf.cast(test1 > 0.5,dtype = tf.float32)
test2.numpy()
Out[129]:
1.0
In [130]:
test1 = 0.6
test2 = 0.6
test3 = tf.equal(test1,test2)
test3.numpy()
Out[130]:
True
In [131]:
test4 = 0.5
test5 = 0.6
test6 = tf.equal(test4,test5)
test6.numpy()
Out[131]:
False
In [136]:
test7 = tf.cast(tf.equal(test1,test2),dtype = tf.float32)
test7.numpy()
Out[136]:
1.0
In [137]:
test8 = tf.cast(tf.equal(test4,test5),dtype = tf.float32)
test8.numpy()
Out[137]:
0.0
In [141]:
def accuracy_fn(hypothesis, labels):
    predicted = tf.cast(hypothesis > 0.5, dtype =tf.float32)
    accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, labels),dtype =tf.int32))
    return accuracy
 

경사하강법(미분)

In [142]:
def grad(features, labels):
    with tf.GradientTape() as tape:
        loss_value = loss_fn(logistic_regression(features),features,labels)
        return tape.gradient(loss_value, [W,b])
    
 

반복 및 결과 값 도출

어큐러시가 1이 나왔음으로,
위에서 제시했던 test값은 참임

In [144]:
#반복 횟수 선언
EPOCHS = 1001

for step in range(EPOCHS):
    #dataset을 몇 묶음씩 학습 시킬 것인지 정해준다
    #batch size를 선언해줄 수 있다.
    for features, labels in iter(dataset.batch(len(x_train))):
        #print(features)
        #print(labels)
        hypothesis = logistic_regression(features)
        grads = grad(features, labels)
        optimizer.apply_gradients(grads_and_vars =zip(grads,[W,b]))
        if step % 100 ==0:
            print("Iter : {}, Loss: {:.4f}".format(step, loss_fn(logistic_regression(features),features,labels)))
test_acc = accuracy_fn(logistic_regression(x_test),y_test)
print("Testset Accuracy: {:4f}".format(test_acc))
 
Iter : 0, Loss: 0.0908
Iter : 100, Loss: 0.0863
Iter : 200, Loss: 0.0823
Iter : 300, Loss: 0.0787
Iter : 400, Loss: 0.0755
Iter : 500, Loss: 0.0726
Iter : 600, Loss: 0.0699
Iter : 700, Loss: 0.0675
Iter : 800, Loss: 0.0652
Iter : 900, Loss: 0.0631
Iter : 1000, Loss: 0.0612
Testset Accuracy: 1.000000
 

test값 변환 후 결과 값 도출

어큐러시가 0이 나왔음으로 새롭게 제시한 test값은 거짓임

In [147]:
x_test2 = [[2.,6.]]
y_test2 = [[1.]]
In [148]:
#반복 횟수 선언
EPOCHS = 1001

for step in range(EPOCHS):
    #dataset을 몇 묶음씩 학습 시킬 것인지 정해준다
    #batch size를 선언해줄 수 있다.
    for features, labels in iter(dataset.batch(len(x_train))):
        #print(features)
        #print(labels)
        hypothesis = logistic_regression(features)
        grads = grad(features, labels)
        optimizer.apply_gradients(grads_and_vars =zip(grads,[W,b]))
        if step % 100 ==0:
            print("Iter : {}, Loss: {:.4f}".format(step, loss_fn(logistic_regression(features),features,labels)))
test_acc = accuracy_fn(logistic_regression(x_test2),y_test2)
print("Testset Accuracy: {:4f}".format(test_acc))
 
Iter : 0, Loss: 0.0470
Iter : 100, Loss: 0.0460
Iter : 200, Loss: 0.0450
Iter : 300, Loss: 0.0440
Iter : 400, Loss: 0.0431
Iter : 500, Loss: 0.0422
Iter : 600, Loss: 0.0414
Iter : 700, Loss: 0.0406
Iter : 800, Loss: 0.0398
Iter : 900, Loss: 0.0391
Iter : 1000, Loss: 0.0384
Testset Accuracy: 0.000000
 

batch값 설정

batch값을 2로 설정 하였는데,
아래 예 처럼 6개의 슬라이스를 3번에 나눠 각각 학습이 된다.

In [151]:
#반복 횟수 선언
EPOCHS = 1001

for step in range(EPOCHS):
    #dataset을 몇 묶음씩 학습 시킬 것인지 정해준다
    #batch size를 선언해줄 수 있다.
    for features, labels in iter(dataset.batch(2)):
        #print(features)
        #print(labels)
        hypothesis = logistic_regression(features)
        grads = grad(features, labels)
        optimizer.apply_gradients(grads_and_vars =zip(grads,[W,b]))
        if step % 100 ==0:
            print("Iter : {}, Loss: {:.4f}".format(step, loss_fn(logistic_regression(features),features,labels)))
test_acc = accuracy_fn(logistic_regression(x_test2),y_test2)
print("Testset Accuracy: {:4f}".format(test_acc))
 
Iter : 0, Loss: 0.0009
Iter : 0, Loss: 0.1133
Iter : 0, Loss: 0.0009
Iter : 100, Loss: 0.0007
Iter : 100, Loss: 0.1076
Iter : 100, Loss: 0.0007
Iter : 200, Loss: 0.0006
Iter : 200, Loss: 0.1024
Iter : 200, Loss: 0.0006
Iter : 300, Loss: 0.0005
Iter : 300, Loss: 0.0977
Iter : 300, Loss: 0.0005
Iter : 400, Loss: 0.0005
Iter : 400, Loss: 0.0934
Iter : 400, Loss: 0.0005
Iter : 500, Loss: 0.0004
Iter : 500, Loss: 0.0895
Iter : 500, Loss: 0.0004
Iter : 600, Loss: 0.0004
Iter : 600, Loss: 0.0858
Iter : 600, Loss: 0.0004
Iter : 700, Loss: 0.0003
Iter : 700, Loss: 0.0825
Iter : 700, Loss: 0.0003
Iter : 800, Loss: 0.0003
Iter : 800, Loss: 0.0794
Iter : 800, Loss: 0.0003
Iter : 900, Loss: 0.0003
Iter : 900, Loss: 0.0765
Iter : 900, Loss: 0.0003
Iter : 1000, Loss: 0.0002
Iter : 1000, Loss: 0.0739
Iter : 1000, Loss: 0.0002
Testset Accuracy: 0.000000
 

해당 포스팅은 부스트코스 강의와, 텐서플로우공식 홈페이지를 참고하여 작성하였습니다.

'Tensorflow > ML' 카테고리의 다른 글

Tensorflow 다중선형회귀 공부  (0) 2020.08.07
Python Tensorflow 다중선형회귀  (0) 2020.07.25
Python Tensorflow 단순선형회귀  (0) 2020.07.20

Python Tensorflow 단순선형회귀

Tensorflow/ML

 

 

 

 

Tensorflow

Simple_Liner_Regression_study

안녕하세요. 이번 포스팅은 텐서플로우 단순선형회귀에 대한 포스팅입니다.

단순 선형회귀란?
y = ax + b 라는 학창 시절 배운 방정식이라고 생각해도 되는데요,

회귀란 ?
어떤 표본(샘플)의 특징은 모수(전체)의 특징으을 따라간다(회귀)라고 이해 할 수 있습니다.

어디에 쓰는가?
바로 '예측'을 할때 사용 할 수 있습니다.

어떻게?
DB를 바탕으로 최적의 선형 방정식(기울기와 절편)을
솔루션을 가지고 구한 후 찾고자 하는 데이터의 값을 예측 할 수 있다.

Hypothesis(하이포시스, 예측, 가설) = H(x) = Wx + b
cost = 오차 = 에러 = 잔차 제곱의 합의 평균

W = 기울기
b = 절편

 

필요한 모듈 세팅

텐서플로우와, 넘피를 임포트 해준다.

In [145]:
import tensorflow as tf
import numpy as np
 

데이터 세팅

In [146]:
#x는 1,2,3,4,5 로 1씩 증가 되는 값을 세팅
x_data = [1,2,3,4,5]
#y는 2,4,6,8,10 으로 2씩 증가되는, 즉 x에 2를 곱한 값들로 세팅
y_data = [2,4,6,8,10]
 

데이터 확인

In [147]:
import matplotlib.pyplot as plt

plt.plot(x_data, y_data, 'o')
plt.ylim(0,13)
plt.show()
 
 

앞서 단순선형회귀 방정식을.
y = Wx + b라고 했다.

그렇다면 위 데이터로 위방정식을 구한다면,
W = 2
b = 0
라는 해답을 구할수 있는데,
이 값들을 텐서플로우로 찾아야한다.

 

초기값 설정

In [148]:
#W,b는 랜덤값으로로 설정이 가능함
W = tf.Variable(5.0)
b = tf.Variable(0.5)

#y=Wx + b
hypothesis = W * x_data+b
 

초기 값에 따른 가설값 확인

In [149]:
#초기 값에 따른 가설값은 5.5, 10.5, 15.5, 20.5, 25.5 로 확인된다.
# 5.5 = 5.0 * 1 + 0.5 등등
hypothesis = W * x_data+b
hypothesis
Out[149]:
<tf.Tensor: shape=(5,), dtype=float32, numpy=array([ 5.5, 10.5, 15.5, 20.5, 25.5], dtype=float32)>
In [150]:
#numpy를 활용해 확인가능
hypothesis.numpy()
Out[150]:
array([ 5.5, 10.5, 15.5, 20.5, 25.5], dtype=float32)
In [151]:
#초기값으로 주어진 W, b값도 다시한번 확인
W , b
Out[151]:
(<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>,
 <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.5>)
In [152]:
#마찬가지로 numpy로 확인가능
W.numpy(), b.numpy()
Out[152]:
(5.0, 0.5)
In [153]:
#그래프로 확인하기
#빨간선(선형)에 표시된 값은 이번에 구한 가설(y = hypothesis)이다.
#저 선형그래프를 초기 초기 데이터에 가장 근사하게 그려질 수있도록 만들어 줄 것이다.
plt.plot(x_data, hypothesis.numpy(), 'r-+')
plt.plot(x_data, y_data, 'go')
plt.ylim(0, 30)
plt.show()
 
 

cost

cost란 앞서, 잔차 제곱의 합의 평균이라고 했다.
이는 tensorflow에 직접 구현되어있는 함수가 없다. 두가지 함수를 섞어서 사용해야한다. 바로 tf.reduce_mean(평균)과 tf.square(제곱)이다.

In [154]:
#reduce_mean예시
v = [1.,2.,3.,4.]
tf.reduce_mean(v).numpy()
Out[154]:
2.5
In [155]:
#square예시
tf.square(5).numpy()
Out[155]:
25
In [156]:
#초기 cost도출
#cost는 에러, 오차, 이기 때문에 최대한 0에 수렴한 값이 되는것을 목표로 해야한다.
cost = tf.reduce_mean(tf.square(hypothesis - y_data))
cost.numpy()
Out[156]:
108.25
 

Gradient Descent 경사하강법

minimize cost(W,b)

경사하강법 : cost의 최소값을 찾는 알고리즘

In [157]:
#텐서플로우에서 경사하강법은 
#tf.GradientTape()을 with 와 함께사용한다.


#참고 : https://www.tensorflow.org/tutorials/customization/autodiff?hl=ko
#with구문안에 있는 모든 연산을 tape에 저장함
with tf.GradientTape() as tape:
    hypothesis = W * x_data + b
    cost = tf.reduce_mean(tf.square(hypothesis - y_data))
    
#gradient cost를 W,b로 각각 미분한 값을 W_grad와 b_grade에 입력해준다.
W_grad, b_grade = tape.gradient(cost, [W,b])
W_grad.numpy(), b_grade.numpy()
Out[157]:
(69.0, 19.0)
In [158]:
#learning_rate란 미분한 값을 얼마만큼의 비중을두고 반영할 것인가 정하는 것이다
#0.01, 0.001, 0.0001로 흔히 정한다고함.
#작으면 작을수록 정확한 값을 찾는데 유리함, 그만큼 많은 수를 반복 해야하긴함
learning_rate = 0.01
#assign_sub란 -= 와 같은 기능이다.
W.assign_sub(learning_rate * W_grad)#5(W초기값) - 0.69 = 4.31
b.assign_sub(learning_rate * b_grad)#0.5(b초기값) - 0.19 = 0.49
W.numpy(), b.numpy()
Out[158]:
(4.31, 0.50074315)
 

새로운 W,b가 반영된 hypothesis 확인

In [159]:
#확인하기 위하여 한번더 선언해줌
hypothesis = W * x_data + b
plt.plot(x_data, hypothesis.numpy(), 'r-+')
plt.plot(x_data, y_data, 'go')
plt.ylim(0, 30)
plt.show()
print(hypothesis)

#점선은 기본 데이터,
#빨간 선형그래프는 반영된 W,b와 데이터의 계산으로 표시된 것이다.
#즉 
#초기값설정에서 5.5 = 5 x 1 + 0.1
#경사하강법1회 4.8 = 4.31 x 1 + 0.49
#로 변화 되었다. 이것을 반복을 통하여 최적의 값을 찾아야한다.
 
 
tf.Tensor([ 4.8107433  9.120743  13.430743  17.740744  22.050743 ], shape=(5,), dtype=float32)
 

코드 합본

경사하강법 반복을 통한 Simple liner Regression

간단한 방정식이이였기 때문에 내가 생각한 기대값은.
W =2 , b=0 이였다.
하지만 텐서플로우로 찾은값은
W = 2.06, b=-0.22 로 비교적 값에 차이가 있었다.

그래서,

초기값을 4, 0.5로 조작, learning_rate를 조작, 반복수 조작을 해보았다, 위 경우 모두 값을 찾는데 영향을 주었다.

반복을 너무 많이하면 계산시간이 어마어마하게 걸린다.

 

따라서 아래 설정 값들로만 남기고 마무리 하였다.

In [176]:
import tensorflow as tf
import numpy as np

x_data = [1., 2., 3., 4., 5.]
y_data = [2., 4., 6., 8., 10.]

W = tf.Variable(4.0)
b = tf.Variable(0.5)
learning_rate = 0.0001


for i in range(10000):
    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 % 1000 == 0:
      print("{:5}|{:10.4f}|{:10.4f}|{:10.6f}".format(i, W.numpy(), b.numpy(), cost))
    
plt.plot(x_data, y_data, 'o')
plt.plot(x_data, hypothesis.numpy(), 'r-')
plt.ylim(0, 30)
 
    0|    3.9953|    0.4987| 50.250000
 1000|    2.1988|    0.0029|  0.440425
 2000|    2.0303|   -0.0420|  0.004252
 3000|    2.0142|   -0.0448|  0.000407
 4000|    2.0123|   -0.0437|  0.000349
 5000|    2.0117|   -0.0423|  0.000326
 6000|    2.0113|   -0.0409|  0.000305
 7000|    2.0109|   -0.0396|  0.000285
 8000|    2.0106|   -0.0382|  0.000266
 9000|    2.0102|   -0.0370|  0.000249
Out[176]:
(0.0, 30.0)
 
 

해당 포스팅은 부스트코스 강의와, 텐서플로우공식 홈페이지를 참고하여 작성하였습니다.

'Tensorflow > ML' 카테고리의 다른 글

Tensorflow 다중선형회귀 공부  (0) 2020.08.07
Python Logistic Regression  (0) 2020.07.28
Python Tensorflow 다중선형회귀  (0) 2020.07.25