[tf] 더 복잡한 함수를 학습해보자
아래와 같은 함수를 x가 -500~500 까지인 샘플을 가지고, 학습하여 -1000에서 1000까지의 출력결과를 보자.
학습은 기존의 샘플에 맞는 최적화된 모델을 찾을 뿐 그것으로 미래를 예측하는 것은 이 방식으로는 한계가 있다. 주어진 범위 내에서만 가능하다. 학습된 범위 밖의 영역에서는 정확하지 않다. 물론 가까운 정도는 어느정도 맞지 않을까.
학습할 그래프.
위 그래프의 수식은 아무렇게나 만들어본
y=sin(x/100)*500+ cos(x/27)*300 + x
# -*- 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.00001
learning_rate = 0.001
train_cnt = 4000
# unknown algbra function
def problem(x):
y = np.sin(x/100)*500 + np.cos(x/27)*300 +x
return y
# can u imagine? i dont know.
xrange = np.linspace(-500, 500, 1000)
y_correct = problem(xrange)
# draw graph?
if bDrawFigure:
plt.figure()
plt.plot(xrange, y_correct)
output_space = 2000 # tanh ; -1~1 X output_space ; output range! ; -2000~2000
# x domain ; -1000~1000
trainx = np.random.rand(train_cnt)*2000-1000 # 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
#Llast = (tf.matmul(L4, W5)+b5) *output_space
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.ptl') # continue train
print( "bTrain=", bTrain, " train_cnt=", train_cnt)
# train
oldtime = time.time()
if bTrain:
for i in range(train_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=", ((train_cnt-i)/100+1)*term)
oldtime=newtime
saver.save(sess, './unknown_predict.ptl')
##########################################################
# test
saver.restore(sess, './unknown_predict.ptl')
test_cnt = 500
testx = np.random.rand(test_cnt)*1000-500 # training set must be shuffle!!!
testx = testx.reshape([-1,1])
testy_cor = problem(testx)
testy_cor = testy_cor.reshape([-1,1])
_llast = sess.run( Llast, feed_dict = { X:testx } )
testcost = np.mean( np.square(_llast-testy_cor))
print ( "cost=", testcost )
#for i in range(test_cnt):
# print("input=", testx[i], " predict=", _llast[i], " correct=", testy_cor[i])
#draw compare
if bDrawFigure:
# xrange = np.linspace(-1000, 1000, 2000)
xrange = np.linspace(-500, 500, 1000)
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()
GPU로 돌려야지 안 그럼 오래걸린다.
어쨋거나 결과는 아래와 같다.
0부근에서 오차가 심하다.
학습을 오래 할수록 좋아지기는 한다.