当前位置:   article > 正文

java web应用调用python机器学习训练的模型_python训练的机器模型可以用到java中吗

python训练的机器模型可以用到java中吗

              java web应用调用python机器学习训练的模型

项目线上平台是用java编写的web应用程序,而深度学习使用的是python语言,这就涉及到了在java代码中调用python语言的方法。为了能在java应用中使用python语言训练的算法模型,我在网上找了很久。我大概找到了三种方法:

       1. java代码可以直接调用python代码,只需要下载相应的jar包就行。这种方式我没有尝试,只是觉得这样做使得java应用太过于依赖python的环境了。还有网上也有将python代码打包成jar的方法,然后可以让java代码调用,但是很多第三方库不能打包成jar包。

  2. 将python训练的模型参数保存到文本中,用java代码重现模型的预测算法。我之前就这样做过。这么做显然工作量太大,而且出现的bug几率大大增加。最重要的是很多深度学习的框架就没办法用了。

  3. 使用python进程运行深度学习中训练的模型,在java应用程序中调用python进程提供的服务。这种方法我认为是最好的。python语言写得程序毕竟还是在python环境中执行最有效率。而且python应用和java应用可以运行在不同的服务器上,通过进程的远程访问调用。

以下是我实现java应用程序访问python进程的python代码部分。进程之间只能是通过socket进行通信。我本来想过用python编写一个web应用,对java提供HTTP服务,后来觉得这样还需要web服务器,对环境依赖太大,而且两个进程间的通信也很简单,所以干脆直接用socket进行调用得了

  1. import socket
  2. import sys
  3. import threading
  4. import json
  5. import numpy as np
  6. from tag import train2
  7. # nn=network.getNetWork()
  8. # cnn = conv.main(False)
  9. # 深度学习训练的神经网络,使用TensorFlow训练的神经网络模型,保存在文件中
  10. nnservice = train2.NNService(model='model/20180731.ckpt-1000')
  11. def main():
  12. # 创建服务器套接字
  13. serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  14. # 获取本地主机名称
  15. host = socket.gethostname()
  16. # 设置一个端口
  17. port = 12345
  18. # 将套接字与本地主机和端口绑定
  19. serversocket.bind((host,port))
  20. # 设置监听最大连接数
  21. serversocket.listen(5)
  22. # 获取本地服务器的连接信息
  23. myaddr = serversocket.getsockname()
  24. print("服务器地址:%s"%str(myaddr))
  25. # 循环等待接受客户端信息
  26. while True:
  27. # 获取一个客户端连接
  28. clientsocket,addr = serversocket.accept()
  29. print("连接地址:%s" % str(addr))
  30. try:
  31. t = ServerThreading(clientsocket)#为每一个请求开启一个处理线程
  32. t.start()
  33. pass
  34. except Exception as identifier:
  35. print(identifier)
  36. pass
  37. pass
  38. serversocket.close()
  39. pass
  40. class ServerThreading(threading.Thread):
  41. # words = text2vec.load_lexicon()
  42. def __init__(self,clientsocket,recvsize=1024*1024,encoding="utf-8"):
  43. threading.Thread.__init__(self)
  44. self._socket = clientsocket
  45. self._recvsize = recvsize
  46. self._encoding = encoding
  47. pass
  48. def run(self):
  49. print("开启线程.....")
  50. try:
  51. #接受数据
  52. msg = ''
  53. while True:
  54. # 读取recvsize个字节
  55. rec = self._socket.recv(self._recvsize)
  56. # 解码
  57. msg += rec.decode(self._encoding)
  58. # 文本接受是否完毕,因为python socket不能自己判断接收数据是否完毕,
  59. # 所以需要自定义协议标志数据接受完毕
  60. if msg.strip().endswith('over'):
  61. msg=msg[:-4]
  62. break
  63. # 解析json格式的数据
  64. re = json.loads(msg)
  65. # 调用神经网络模型处理请求
  66. res = nnservice.hand(re['content'])
  67. sendmsg = json.dumps(res)
  68. # 发送数据
  69. self._socket.send(("%s"%sendmsg).encode(self._encoding))
  70. pass
  71. except Exception as identifier:
  72. self._socket.send("500".encode(self._encoding))
  73. print(identifier)
  74. pass
  75. finally:
  76. self._socket.close()
  77. print("任务结束.....")
  78. pass
  79. def __del__(self):
  80. pass
  81. if __name__ == "__main__":
  82. main()

在java代码中访问python进程的代码:

  1. private Object remoteCall(String content){
  2. JSONObject jsonObject = new JSONObject();
  3. jsonObject.put("content", content);
  4. String str = jsonObject.toJSONString();
  5. // 访问服务进程的套接字
  6. Socket socket = null;
  7. List<Question> questions = new ArrayList<>();
  8. log.info("调用远程接口:host=>"+HOST+",port=>"+PORT);
  9. try {
  10. // 初始化套接字,设置访问服务的主机和进程端口号,HOST是访问python进程的主机名称,可以是IP地址或者域名,PORT是python进程绑定的端口号
  11. socket = new Socket(HOST,PORT);
  12. // 获取输出流对象
  13. OutputStream os = socket.getOutputStream();
  14. PrintStream out = new PrintStream(os);
  15. // 发送内容
  16. out.print(str);
  17. // 告诉服务进程,内容发送完毕,可以开始处理
  18. out.print("over");
  19. // 获取服务进程的输入流
  20. InputStream is = socket.getInputStream();
  21. BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf-8"));
  22. String tmp = null;
  23. StringBuilder sb = new StringBuilder();
  24. // 读取内容
  25. while((tmp=br.readLine())!=null)
  26. sb.append(tmp).append('\n');
  27. // 解析结果
  28. JSONArray res = JSON.parseArray(sb.toString());
  29. return res;
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. } finally {
  33. try {if(socket!=null) socket.close();} catch (IOException e) {}
  34. log.info("远程接口调用结束.");
  35. }
  36. return null;
  37. }

【参考】:https://www.cnblogs.com/maosonglin/p/9397257.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/201042
推荐阅读
相关标签
  

闽ICP备14008679号