在Java中调用Python函数:基于socket的方法

最近想写一个算法,考虑到执行效率和开发效率,准备使用Java来实现,不过在算法执行过程中我打算使用基于pytorch的神经网络,此时就涉及如何在Java语言中执行Python程序。

最简单的想法当然就是直接使用命令行调用:Runtime.getRuntime().exec("python xxx.py --yyy zzz"),但是这种方式每次调用python脚本都需要重启python解释器以及重新将pytorch神经网络加载进内存,如果调用频繁的话就会非常耗时,因此并不合适。

更好的方式是让两个程序通过网络来通信,python可以启动时加载好神经网络,之后就开一个socket服务等待请求,让java程序把参数通过socket发给python程序,然后python拿到参数后执行函数,再把返回值发送回java即可。python程序并不退出,因此就不需要重复神经网络的加载过程了。而且基于socket可以让java和python跑在不同的机器上。

Read More »

我该装什么CUDA版本的pytorch-gpu

也许你疑惑过对于自己电脑中的NVIDIA显卡型号,应该装什么CUDA版本的pytroch-gpu。结论是太老或者太新的CUDA版本都不行,一个显卡型号能支持的CUDA版本是一个有限的范围。

首先打开NVIDIA控制面板,点击“帮助->系统信息->组件”,能够看到NVCUDA.dll后面的一个CUDA版本,这个就是当前驱动程序支持的最大CUDA版本,如果你升级了驱动,可能会支持更高的CUDA版本,也可能不会提升。

而当你想跑别人的一份远古pytorch版本的代码时,也许你会发现对于新型号显卡如果安装太老CUDA版本的pytorch-gpu也会无法调用GPU(调用GPU会报错),实际上一个显卡型号支持的CUDA版本也有下限。

Read More »

Pytorch debug经验之RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation

有一次,我在自己写的关于“神经组合优化”的项目中遭遇报错:

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [CUDABoolType [1024, 21]] is at version 139; expected version 138 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

此报错令人一头雾水,因为抛出异常的位置位于loss.backward(),显然跟真正出问题的地方相去甚远,而其他有价值的信息就只有关于问题张量的数据类型与形状,所以想要进行问题定位还是比较困难的。

Read More »

使用torchvision.datasets下载数据集时如何借助代理

比如使用pytorch下载数据集时:

trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)

如果直连网络状况不好,则下载会很慢,此时我们可以通过urllib模块配置代理:

Read More »

浅析函数装饰器与functools.wraps

只要把握住一个概念,使用函数装饰器时就不会被绕晕:函数装饰器就是一个可调用对象,它接受一个参数(一般是函数对象),返回一个可调用对象。

所谓的“带参数的函数装饰器”,其实并不是函数装饰器了,“带参数的函数装饰器”的主要目的是使用参数来制作一个更好的函数装饰器,所以它返回一个函数装饰器。

我们知道functools.wraps可以让被装饰的函数具有原本的元信息(即__name__、__doc__等),它是怎么做到的呢?我们可以实现一个自己版本的简易wraps:

Read More »

Python标准库的“三六九等”

我们知道python标准库中有os,sys,string等模块,此时当前路径下有a.py,os.py,sys.py,string.py四个文件,其中除了a.py其余文件都为空,a.py内容如下:

#a.py
import sys
print(sys)
import os
print(os)
import string
print(string)

请问在当前路径运行a.py后,三个print出来的模块路径分别是什么,三个选项:A,当前路径;B,标准库路径;C,都不是。

Read More »

Python3模块包导入内部模块时为何应该使用“包相对导入”

目录
一、使用“绝对导入”代表你想使用外部模块
二、导入内部模块时也不应该使用自己包的名字
三、即使使用了“包相对导入”,也可以直接进行主模块测试

一、使用“绝对导入”代表你想使用外部模块

假设我们是模块包mod的编写者,现在用户的主目录中有a.py,b.py和我们的模块包mod,mod内含有b.py和c.py,目录结构如下:

Read More »

Python虚拟环境(venv)失效后的修复方式

以下示例环境是Windows下的Python内置模块venv。其他平台以及其他相似功能模块(如virtualenv)其实都是类似的。

首先第一个常见的导致虚拟环境失效的原因是虚拟环境文件夹路径变化,包括对虚拟环境重命名,复制移动等等,之所以虚拟环境路径变化会导致其失效是因为在虚拟环境的scripts文件夹下的一堆activate启动脚本中记录着原本虚拟环境的绝对路径,所以路径变更后这些绝对路径也应当更新。

还有就是scripts中除了python.exe和pythonw.exe外的所有模块exe文件都硬编码了虚拟环境中的python解释器的绝对路径。如图:(我的虚拟环境位置就是D:\workspace\virtualenvs\test)

Read More »