tf.py_func 사용해보기

2020. 4. 17. 22:47분석 Python/Tensorflow

728x90

광고 한 번씩 눌러주세요! 블로그 운영에 큰 힘이 됩니다 :)

tensorflow graph 내에 파이썬 연산을 해줄 수 있는 tf.py_func

만약 데이터가 크다면, 전체를 읽지 못하고 배치성으로 데이터를 읽어서 해야하는데, 그럴 때 그래프내에서 할 수 있기 때문에 괜찮다고 생각함. (사실 텐서플로우 그래프 밖에서 해도 될 것 같긴 함.)

Tensorflow에 python_func 사용해보기

import tensorflow as tf
import numpy as np
from sklearn.preprocessing import MinMaxScaler

X = tf.placeholder(tf.float32 , (None , 3), name ="X")

def numpy_use(x) :
    result = x- np.mean(x)
    return result
def sklearn_use(x) :
    result = minmax.transform(x)
    return result
def sklearn_f_use(x, func) :
    result = func.transform(x)
    return result
def sklearn_f_use(func) :
    def some_func(x) :
        result = func.transform(x)
        return result
    return some_func
def slice_f(x) :
    result = x[:,[0,1]]
    return result
x = np.random.normal(size = (10,3))
minmax = MinMaxScaler(feature_range=(-1,1))
minmax.fit(x)

output = tf.py_func(numpy_use , [X], [tf.float32])[0]
sklearn_output = tf.py_func(sklearn_use , [X], [tf.float32])[0]
sklearn_f_output = tf.py_func(sklearn_f_use(minmax) , [X], [tf.float32])[0]
slice_output = tf.py_func(slice_f , [X], [tf.float32])[0]

sess = tf.InteractiveSession()


단순 회귀분석 해보기

tf.data로 모델링 해보기 (map 사용하지 않은 버전) (기존과 동일)

x = np.random.normal(size = (1000,2))
y = 5*x[:,[0]] +0.5*x[:,[1]] + 0.5

minmax = MinMaxScaler(feature_range=(-1,1))
minmax.fit(x)
y_minmax = MinMaxScaler(feature_range=(-1,1))
y_minmax.fit(y)
def sklearn_use(x) :
    result = minmax.transform(x)
    return result
def target_sklearn_use(y) :
    result = y_minmax.transform(y)
    return result
    
tf.reset_default_graph()
X = tf.placeholder(tf.float32 , (None , 2), name ="X")
Y = tf.placeholder(tf.float32 , (None , 1), name ="y")
w = tf.get_variable("w",[2,1])
b = tf.get_variable("b",[1])

data_tuple = (X,Y)
dataset = tf.data.Dataset.from_tensor_slices(data_tuple)
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(batch_size=10, drop_remainder=True)
iter = dataset.make_initializable_iterator()
feature_batch , y_batch = iter.get_next()

transX = tf.py_func(sklearn_use, [feature_batch], [tf.float32])[0]
transY = tf.py_func(target_sklearn_use, [y_batch], [tf.float32])[0]

transX.set_shape([None,int(X.get_shape()[1])])
transX.set_shape([None,int(Y.get_shape()[1])])

logit = tf.nn.bias_add(tf.matmul(transX,w),b)
mse = tf.reduce_mean(tf.square(tf.subtract(transY,logit)))
opt = tf.train.AdamOptimizer(1e-3).minimize(mse)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
epoch_n = 1000
for i in range(epoch_n) :
    sess.run(iter.initializer , feed_dict= {X : x,
                                            Y : y
                                           }) # switch to train dataset
    while True :
        try :
            result = sess.run([opt,mse,w,b])
        except tf.errors.OutOfRangeError :
                break
    print(f"loss : {result[-3]} , w : {result[-2]} , b : {result[-1]}")

 tf.data map을 사용해서 해보기

x = np.random.normal(size = (1000,2),loc = 5)
y = 5*x[:,[0]] +0.5*x[:,[1]] + 0.5

minmax = MinMaxScaler(feature_range=(-1,1))
minmax.fit(x)
y_minmax = MinMaxScaler(feature_range=(-1,1))
y_minmax.fit(y)

def py_func(x, y):
    x_result = minmax.transform(x)
    y_result = y_minmax.transform(y)
    return x_result , y_result

tf.reset_default_graph()
X = tf.placeholder(tf.float32 , (None , 2), name ="X")
Y = tf.placeholder(tf.float32 , (None , 1), name ="y")
w = tf.get_variable("w",[2,1])
b = tf.get_variable("b",[1])

data_tuple = (X,Y)
dataset = tf.data.Dataset.from_tensor_slices(data_tuple)
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(batch_size=10, drop_remainder=True)
## 배치 단위로 적용 py_func 적용
dataset = dataset.map(
    lambda xx, yy: tuple(tf.py_func(py_func, [xx, yy], [tf.float32, tf.float32])))

iter = dataset.make_initializable_iterator()
feature_batch , y_batch = iter.get_next()

feature_batch.set_shape([None,2])
y_batch.set_shape([None,1])

logit = tf.nn.bias_add(tf.matmul(feature_batch,w),b)
mse = tf.reduce_mean(tf.square(tf.subtract(y_batch,logit)))
opt = tf.train.AdamOptimizer(1e-3).minimize(mse)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
epoch_n = 1000
for i in range(epoch_n) :
    sess.run(iter.initializer , feed_dict= {X : x,
                                            Y : y
                                           }) # switch to train dataset
    while True :
        try :
            result = sess.run([opt,mse,w,b, feature_batch])
        except tf.errors.OutOfRangeError :
                break
    print(f"loss : {result[1]} , w : {result[2]} , b : {result[3]}")

 

728x90