[ Python ] TensorFlow 1.x save & load model & predict

2019. 8. 17. 21:16분석 Python/Tensorflow

728x90

최근에 Flask를 이용해서 모델을 load 하고 예측을 하려고 한다.

예측을 빠르게 하기 위해선 모델을 불러오고 모델의 결괏값만 불러오게 해야 하는데

여기선 모델의 아키텍처와 가중치를 저장을 해서 인풋만 넣어도 예측하게 하는 과정을 해보려고 한다.

일단 모델을 하나 만든다. 여기선 간단하게 binary class를 해본다.

여기서 만들 때 가중 중요하게 생각한 것은 name을 지정해야 합니다!

그래야 나중에 모델만 불러와서 사용할 수 있는 것 같습니다.

만든 후에 각 지정한 이름을 확인하고 싶은 경우

save_file = "./savemodel/.meta"
saver = tf.train.import_meta_graph(save_file)
saver.restore(sess, tf.train.latest_checkpoint('./savemodel/'))
graph = tf.get_default_graph()
[tensor.name for tensor in graph.as_graph_def().node ]

모델 학습 및 저장

import tensorflow as tf
from sklearn import datasets
import numpy as np
breast = datasets.load_breast_cancer()

x = breast["data"]
y = breast["target"].reshape(-1,1).astype(float)

tf.reset_default_graph()
X = tf.placeholder(tf.float32 , shape = [None , x.shape[1]], name = "input")
Y = tf.placeholder(tf.float32 , shape = [None , 1] ,name = "output")

X1 = tf.layers.dense(X , 40)
X1 = tf.layers.dense(X1 , 20)
logit = tf.layers.dense(X1 , 1 , name = "logit")
prob = tf.nn.sigmoid(logit , name = "prob")

loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=Y, logits=logit)
cost = tf.reduce_mean(loss)
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(cost)
saver = tf.train.Saver()
import os
os.environ["CUDA_VISIBLE_DEVICES"]="-1"
config=tf.ConfigProto(log_device_placement=True)
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
    sess.run(tf.global_variables_initializer())

    # 최적화를 100번 수행합니다.
    for step in range(100):
        # sess.run 을 통해 train_op 와 cost 그래프를 계산합니다.
        # 이 때, 가설 수식에 넣어야 할 실제값을 feed_dict 을 통해 전달합니다.
        _, cost_val  = sess.run([train_op, cost ] , feed_dict={X: x, Y: y })
        saver.save(sess, "./basic_model" )
        print(step, cost_val)

    print(sess.run([prob ] , feed_dict={X: x}))

모델 불러오고 인풋 넣어서 예측하기

graph에서 해당하는 이름의 tensor를 가져오고 결과를 내려면 인풋을 알아야 하나 x 도 가져와야 한다.

암튼 요렇게 하면 된다!

import tensorflow as tf
from sklearn import datasets
import numpy as np

breast = datasets.load_breast_cancer()
x = breast["data"]
import os
path = './save_tf/basic_model.meta'
def load_model(file_path) :
    saver = tf.train.import_meta_graph(file_path)
    os.environ["CUDA_VISIBLE_DEVICES"]="-1"
    config=tf.ConfigProto(log_device_placement=True)
    config.gpu_options.allow_growth = True
    sess = tf.Session(config= config)
    saver.restore(sess, tf.train.latest_checkpoint('./save_tf/'))
    graph = tf.get_default_graph()
    ## INPUT 지정
    X = graph.get_tensor_by_name("input:0")
    ## OUTPUT 지정
    prob = graph.get_tensor_by_name("prob:0")
    return sess , X , prob
    
sess , X , prob = load_model( path)
probability = sess.run(prob , feed_dict={X : x[1:10,:]})

 

tf.Dataset을 사용하는 경우

각 필요한 부분에 대해서 iteratorGetNext를 가져옵니다.

정답은 아니겠지만, 특히 원하는 만큼 사용하기 위해서는 batch_size도 모델을 만들 때 placeholder로 만들어서 해주면 나중에 원하는 만큼만 할 수 있습니다.

config=tf.ConfigProto(log_device_placement=True)
config.gpu_options.allow_growth = True
z_batch = sample_Z(data_len , latet_dim )
tf.reset_default_graph()
with tf.Session(config= config) as sess:
    save_file = "./savemodel/model_v0.meta"
    saver = tf.train.import_meta_graph(save_file)
    saver.restore(sess, tf.train.latest_checkpoint('./savemodel/'))
    graph = tf.get_default_graph()
    G = graph.get_tensor_by_name('GAN/Generator/total:0')
    z = graph.get_tensor_by_name('IteratorGetNext:2')
    y = graph.get_tensor_by_name('IteratorGetNext:1')
    batch_size = graph.get_tensor_by_name('Batchsize:0')
    generate_n = 5000
    y_batch = np.concatenate((np.tile( np.array([1,0]) ,(int(generate_n/2),1) ) ,
                    np.tile( np.array([0,1]) ,(int(generate_n/2),1) )),axis = 0)
    z_batch = sample_Z(generate_n  , latet_dim )
    arg_g = sess.run(G , 
                 feed_dict = {z : z_batch , y : y_batch , batch_size : generate_n})
    print("end!")

 

728x90