如何将TensorFlow模型封装成服务(网页服务)

版本: 

tensorflow == 1.14.0

python == 3.7

Flask == 1.1.1

对于下面程序,x为传入参数,封装成网页

import tensorflow as tf

def main():

    x = tf.placeholder("float")
    y = x * 2
    with tf.Session() as sess:
        print(sess.run(y, feed_dict={x:2}))

if __name__ == '__main__':
    main()

方法一:(函数传参)

main.py

import tensorflow as tf

def main(m):

    x = tf.placeholder("float")
    y = x * 2
    with tf.Session() as sess:
        res = sess.run(y, feed_dict={x:m})
        return str(res)

run.py

from flask import Flask, request
from main import main

app = Flask(__name__)

@app.route('/')
def index():
    x = int(request.args.get('x', 0))
    return main(x)

if __name__ == '__main__':
    app.run()

运行结果: 

 

该方法比较简单,多线程运行互不干扰,但每次调用需要重现构建张量图,模型复杂时开销较大

方法二: (管道多进程)

main.py

import tensorflow as tf

def main(_):

    def get_pipe():
        from multiprocessing.managers import BaseManager
        BaseManager.register('get_pipe')
        m = BaseManager(address=('localhost', 30030), authkey=b'awadffwea')
        m.connect()
        return m.get_pipe()

    x = tf.placeholder("float")
    y = x * 2
    with tf.Session() as sess:
        while True:
            try:
                pipe = get_pipe()
                m = pipe.recv()
                res = sess.run(y, feed_dict={x:m})
                pipe.send(str(res))
            except:
                pipe.send('error')

run.py

from flask import Flask, request
import tensorflow as tf
from main import main
from multiprocessing.managers import BaseManager
import multiprocessing
parent_conn, child_conn = multiprocessing.Pipe()

app = Flask(__name__)

def get_parent_pipe():
    from multiprocessing.managers import BaseManager
    BaseManager.register('get_parent_pipe')
    m = BaseManager(address=('localhost', 30030), authkey=b'awadffwea')
    m.connect()
    return m.get_parent_pipe()

def register():
    BaseManager.register('get_pipe', callable=lambda: child_conn)
    BaseManager.register('get_parent_pipe', callable=lambda: parent_conn)
    m = BaseManager(address=('localhost', 30030), authkey=b'awadffwea')
    s = m.get_server()
    s.serve_forever()

@app.route('/')
def index():
    x = int(request.args.get('x', 0))
    parent_conn = get_parent_pipe()
    parent_conn.send(x)
    return parent_conn.recv()

if __name__ == '__main__':
    multiprocessing.Process(target=register, args=()).start()
    multiprocessing.Process(target=tf.app.run, args=(main,)).start()
    app.run(threaded=False)

运行结果:

该方法不需要每次调用构建张量图,但是程序比较复杂,需要预防死锁,只能串行调用

方法三:(协程)

main.py

#tensorflow == 1.14.0 python == 3.7 Flask == 1.1.1
import tensorflow as tf

def main():

    x = tf.placeholder("float")
    y = x * 2
    with tf.Session() as sess:
        while True:
            try:
                m = yield
                res = sess.run(y, feed_dict={x:m})
                yield str(res)
            except:
                yield 'error'

if __name__ == '__main__':
    main()

run.py

from flask import Flask, request
import tensorflow as tf
from main import main

app = Flask(__name__)
m = main()
next(m)

@app.route('/')
def index():
    x = int(request.args.get('x', 0))
    res = m.send(x)
    next(m)
    return res

if __name__ == '__main__':
    app.run(threaded=False)

运行结果:

注:

1、yield在接收参数的同时将当前运行结果返回出去,所以第一次必须调用next(m)开启迭代器,同时将第一个yield的结果返回

2、run.py中的程序运行,将参数传入第一个yield中,在main.py执行程序,将结果返回到第二个yield中,如图所示:

3、多线程调用需要加锁,否则出现ValueError: generator already executing

参考资料:

https://blog.csdn.net/buptgshengod/article/details/106861118

https://blog.csdn.net/stu_py/article/details/115067192

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值