알 수 없는 n차 다항 함수에 근사하는 샘플데이터를 학습시켜보자.
단순한 linear regression으로는 다차항 함수의 학습이 되지 않는다.
feature 값을 x^2, x^3, .. 이런식으로 변환하여 feture들을 늘려서 학습시킨다면 가능할수도 있지만, 몇 차로 해야될지도 알 수 없고 전처리를 해야되서 예측이 어렵다.
이것을 해결하기 위해서는 deep and wide한 네트웍을 구성하여 학습을 시킨다.
단, 주의해야될 점은 바로 activation function이다. 항등함수로만 하면 아무리 네트웍을 구성해도 학습이 되지 않는다.
네트웍을 affine 계층으로만 하게되면 weighted sum을 다시 weighted sum을 하게 되므로 다중 레이어를 둔 의미가 상실되게 된다. 즉, xw+b를 다시 (xw+b)w+b가 되서 아무리 반복해도 x*w+b꼴로 표현이 가능하다. 즉, 단층레이어와 동일할 뿐이다.
activation function은 다양한 정보 표현이 가능하도록 비선형 함수들을 사용해야 한다. sigmoid, tanh, relu 등.
그리고 마지막 계층 또한 중요하다. 1/0을 판단하는 binary classification이라면 sigmoid로 하고, multinomial classfication이라면 softmax를 사용하며, 실수범위의 예측이라면??? 출력값의 범위가 표현될 수 있는 function을 만든다. 학습이 잘 되냐 실패하냐거 거의 여기에 달린 것 같다.
ex) sigmoid or tanh or identity 의 값에 * 도메인크기 + bias ,
(identity는 항등함수를 말함. 즉, weighted sum 인풋이 그대로 출력되는 함수)
몇 번 테스트해보니 sigmoid나 tanh가 적당하다.
단, 이렇게 학습하여 예측하는 것에는 한계가 있다.
학습한 데이터의 도메인에 해당되는 범위내에서는 예측가능하나, 학습되지 않은 구간에서는 맞지 않게 된다.
# -*- coding: utf-8 -*-
'''
Created on Sat May 13 10:54:59 2017
@author: Junhee
'''
#
# complex algbra predict learning? is it possible???
# continous valued target bounded range (-1000,1000)
# not using polynomial modified input!. because I don't know
# what polynomial degree is correct.
#
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import time
bDrawFigure = True
# train yes or no
bTrain = 1
#learning_rate = 0.1
#learning_rate = 0.0001
learning_rate = 0.00001
#learning_rate = 0.1
trainset_cnt = 200
epoch_cnt = 4000
#epoch_cnt = 40000
# unknown algbra function
def problem(x):
# y = x**2
y = x**2-30*x
return y
# can u imagine? i dont know.
xrange = np.linspace(0, 100, 200)
y_correct = problem(xrange)
# draw graph?
if bDrawFigure:
plt.figure()
plt.plot(xrange, y_correct)
output_space = 40000 # tanh ; -1~1 X output_space ; output range! ; -2000~2000
# x domain ; -1000~1000
trainx = np.random.rand(trainset_cnt)*100-0 # training set must be shuffle!!!
trainx = trainx.reshape([-1,1])
trainy_cor = problem(trainx)
trainy_cor = trainy_cor.reshape([-1,1])
X = tf.placeholder(tf.float32, shape=[None,1])
Y = tf.placeholder(tf.float32, shape=[None,1])
# make network NN
W1 = tf.Variable(tf.random_normal([1,512]))
b1 = tf.Variable(tf.zeros([512]))
L1 = tf.nn.sigmoid(tf.matmul(X, W1)+b1)
#L1 = tf.nn.tanh(tf.matmul(X, W1)+b1)
W2 = tf.Variable(tf.random_normal([512,1024]))
b2 = tf.Variable(tf.zeros([1024]))
L2 = tf.nn.sigmoid( tf.matmul(L1, W2)+b2)
W3 = tf.Variable(tf.random_normal([1024,1024]))
b3 = tf.Variable(tf.zeros([1024]))
L3 = tf.nn.sigmoid( tf.matmul(L2, W3)+b3)
W4 = tf.Variable(tf.random_normal([1024,1024]))
b4 = tf.Variable(tf.zeros([1024]))
L4 = tf.nn.sigmoid( tf.matmul(L3, W4)+b4)
W5 = tf.Variable(tf.random_normal([1024,1]))
b5 = tf.Variable(tf.zeros([1]))
#Llast = tf.nn.tanh( tf.matmul(L4, W5)+b5) *output_space
#good
Llast = (tf.nn.sigmoid( tf.matmul(L4, W5)+b5)) *output_space - 500
#Llast = (tf.matmul(L4, W5)+b5) *output_space
# bad...
#Llast = (tf.matmul(L4, W5)+b5)
cost = tf.reduce_mean( tf.square(Llast-Y) )
train = tf.train.AdamOptimizer(learning_rate).minimize(cost)
sess = tf.Session()
sess.run( tf.global_variables_initializer())
param_list = {'W1':W1,'b1':b1,
'W2':W2,'b2':b2,
'W3':W3,'b3':b3,
'W4':W4,'b4':b4,
'W5':W5,'b5':b5,
}
saver = tf.train.Saver(param_list)
#saver.restore(sess, './unknown_predict_poly.ptl') # continue train
print( "bTrain=", bTrain, " trainset_cnt=", trainset_cnt, " epoch=cnt", epoch_cnt)
# train
oldtime = time.time()
if bTrain:
for i in range(epoch_cnt) :
_, _cost = sess.run( [train, cost], feed_dict={X:trainx, Y:trainy_cor})
if i%100==(100-1):
newtime = time.time()
term = newtime-oldtime
print( "train=",i," cost=",_cost, " remaintime=", ((epoch_cnt-i)/100+1)*term)
oldtime=newtime
saver.save(sess, './unknown_predict_poly.ptl')
##########################################################
# test
saver.restore(sess, './unknown_predict_poly.ptl')
#draw compare
if bDrawFigure:
# xrange = np.linspace(-1000, 1000, 2000)
xrange = np.linspace(1, 200, 200)
xrange = xrange.reshape(-1, 1)
_llast2 = sess.run( Llast, feed_dict = { X:xrange } )
xrange = xrange.reshape(-1)
testyrange = _llast2.reshape(-1)
plt.plot(xrange, testyrange, c='r')
plt.show()
출력결과
bTrain= 1 trainset_cnt= 200 epoch=cnt 4000
train= 99 cost= 4.10605e+07 remaintime= 408.33133206844326
train= 199 cost= 6.47534e+06 remaintime= 374.9750850892067
train= 299 cost= 3.22122e+06 remaintime= 390.8726796555519
...
train= 3399 cost= 12447.5 remaintime= 73.77905233621597
train= 3499 cost= 12130.0 remaintime= 62.91447646141052
train= 3599 cost= 11828.8 remaintime= 51.30402812004089
train= 3699 cost= 11539.5 remaintime= 43.085111978054044
train= 3799 cost= 11257.4 remaintime= 33.96168860197067
train= 3899 cost= 10978.7 remaintime= 21.201974751949308
train= 3999 cost= 10699.7 remaintime= 11.279016330242158
INFO:tensorflow:Restoring parameters from ./unknown_predict_poly.ptl
초반에 cost가 어마어마하다. 학습이 잘 된다면 위와 같이 점점 줄어들 것이다.
임의의 다차항 함수의 샘플을 생성하여 학습한다.
y=x^2-30x 라는 함수를 배워본다. 단, 전체 실수범위에 대해서 학습은 불가능하다.
샘플의 범위는 유한하기 때문. x의 범위를 0~100까지를 학습해 본다.
학습데이터의 모습은 아래와 같다.
이를 학습하여 200까지 예측해 보면, 100~200 범위는 배우지 않았기 때문에 오차가 커진다.
그러나 학습한 범위인 0~100까지는 거의 정확하다!
최종 학습 결과.
위 그림에서 0~100 구간은 파란선과 빨간선의 거의 일치한다.
추신)
샘플에 noise를 가해주고 학습하는게 좋을 것 같다.
학습시에는 batch로 샘플데이터를 random select하게 해야 학습이 더 잘 될 것 같다.
다른 복잡한 곡선도 테스트해 보자.
'AI(DeepLearning)' 카테고리의 다른 글
[tf] tensorflow 강좌1 로딩테스트 (0) | 2018.07.16 |
---|---|
[tf] 더 복잡한 함수를 학습해보자 (0) | 2017.06.01 |
[tf] XOR tensorflow로 학습구현 (0) | 2017.05.23 |
[tf] XOR manual solve (0) | 2017.05.23 |
[R] multinomial classification. 다중분류 (0) | 2017.05.19 |