Press "Enter" to skip to content

Java程序员深度学习入门:动手学深度学习(Java版)

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

引言:为何用Java学深度学习

 

相信很多知友最开始都使用Python来入门机器学习。从语言本身的特性看,Python是一门已于入门、对使用者非常友好的语言。Python可以让程序员聚焦于算法逻辑本身的实现而不需要过多关注繁重的语法。下图相当准确地描述了各种语言的特点,其中,Python的学习难度只有一颗星,是所有语言中唯一一个获得最低一颗星的语言。

What Programming Language Should I Learn?(https://codeburst.io/what-programming-language-should-i-learn-f3f164ca376c)

从机器学习角度看,知乎机器学习领域优秀答主@齐鹏 准确地总结了原因:Python好写、支持全面、好调、速度不慢的几个重要特性,使得Python非常适合在机器学习领域得到应用。

 

Python入门简单、在机器学习领域应用广泛,为什幺还有人想用其他语言(如本文提到的Java)来学习、研究、甚至重构机器学习算法库呢?

 

我的工作聚焦在数据安全与隐私保护技术。如果知友们最近关注数据安全与隐私保护技术的发展,那幺一定绕不开如下几个词:安全多方计算(Secure Multi-Party Computation,MPC)、同态加密(Homomorphic Encryption,HE)、差分隐私(Differential Privacy,DP)。MPC、HE、DP都是可证明安全技术,其相应的实现涉及到比较复杂的密码学或隐私保护技术。

MPC和HE:一般使用C/C++实现,因为MPC和HE涉及到较为复杂的密码学运算,需要应用比较底层的语言实现最优的性能,特别是会大范围用到单指令流多数据流(Single instruction, multiple data,SIMD)。对于MPC这类涉及到通信、并发、分布式计算等诸多技术的领域来说,虽然C/C++实现可以带来极致的性能,但如果想真正落地,就可能需要对其实现进行拆分,将复杂密码学运算(如公钥运算、多项式运算等)放置在C/C++层,而用其他语言实现通信、并发、分布式等功能。一提到通信、并发、分布式,相信Java类型的语言便会自然而然地走到知友们的脑海中了。
DP:如果你在2017年左右就开始关注DP,相信你一定阅读了微软的PINQ代码。PINQ使用C#语言结合微软特有的LINQ查询语言实现的差分隐私数据查询库。如果在那个时候就想参考PINQ实现DP模块,可能就已经使用了与C#很类似的Java进行了改造。如果你在2020年后开始关注DP,那幺你很可能已经开始研究 谷歌的差分隐私库 了。谷歌提供了C++、Go、Java的实现。

如果想将数据安全和隐私保护技术引入机器学习领域,实现隐私保护机器学习(Privacy-Preserving Machine Learing,PPML),一般都会从已有的MPC、HE、DP库出发,重新构建机器学习算法。这是因为PPML一般都涉及算法的较大改造,很难直接调用已有的机器学习算法库完成实现。这种实现方法对于学术研究来说已经足够。然而,如果想真正在实际中使用,有必要深入研究已有的机器学习库。原因如下:

 

 

    1. 实现PPML后,可以对外暴露和已有机器学习库类似的API,使得算法研发团队可以较为平滑级地完成切换。这也促使PPML研发团队可以更多地站在算法工程师角度,而非仅站在安全角度思考问题。

 

    1. 充分研究已有实现可以更全面地考虑哪些功能是PPML下可以支持的,哪些是无法支持的,可以对无法支持的功能进行屏蔽或说明。

 

    1. 从代码层面深入研究已有的机器学习库,可以更准确地发现学术研究中可能没有考虑的细节问题并提前解决。

 

 

虽然我可以阅读C/C++和Python,但目前我已经完成的功能函数都是用Java实现的,特别是MPC和HE已经完成了较多的工作。如果可以用相同的语言进一步切入到机器学习领域,就可以更快、更方便地完善PPML的研发了。特别要再次强调, 由于实现PPML几乎都要对机器学习算法实现进行较大程度的修改甚至重构,通过相同的语言实现可以帮助我更好地了解细节,从而更快地进行实现修改 。如果研究发现可以通过黑盒调用已有算法库的形式实现PPML,那就没必要统一语言了。

 

对于传统机器学习算法库,我找到了一个非常好的框架:SMILE。

 

SMILE的全称是Statistical Machine Intelligence and Learning Engine,是用Java和Scala实现的高性能机器学习库,目前GitHub上拥有5000多的Star。通过深入研究SMILE对各个算法的实现,我才深刻理解了很多只阅读论文和开源实现所没有描述或注意到的问题,并学习到了很多实现和优化技巧。

 

对于深度学习这个领域,有什幺好的Java实现供学习呢?

 

探索:搜集的资料和阅读反馈

 

提到Java的深度学习库,很多知友一定会想到Deeplearning4j(DL4j)。

Deeplearning4j

DL4j是Eclipse基金会的项目,是第一个用Java和Scala实现的商业可用、开源、支持分布式和GPU的深度学习算法库。DL4j也与Hadoop和Apache Spark兼容。我也查找了DL4j的一些学习材料,特别是以DL4j为基础讲解深度学习的资料。其中,B站Up主寒沧上传的一系列DL4j视频是一个不错的资料。

 

DL4j的作者Josh Patterson、Adam Gibson专门出版过一本书《Deep Learning: A Practitioner’s Approach》,就是以DL4j为基础介绍深度学习的。这本书的中文翻译版本名为《深度学习基础与实践》,郑明智翻译,由中国工信出版集团和人民邮电出版社出版。DL4j的作者Josh Patterson、Adam Gibson专门出版过一本书《Deep Learning: A Practitioner’s Approach》,就是以DL4j为基础介绍深度学习的。这本书的中文翻译版本名为《深度学习基础与实践》,郑明智翻译,由中国工信出版集团和人民邮电出版社出版。这本书唯一一个评论特别能体现出用Java入门深度学习的感受:

 

在图书馆偶然看到就翻了翻,感觉没什幺用,,,不过孤陋寡闻的俺发现居然可以用java搭dl,觉得非常有趣。

 

我也购买了《深度学习基础与实践》这本书,但阅读起来感觉难度还是比较大的。看着其他人愉快地使用Python做深度学习,我便查了查Python深度学习的方法。这就找到了豆瓣评分高达9.4分的《动手学深度学习》。

 

趁着双十一,我赶快入手了这本书,并打开了本书的官方网站。我看到了这本书完整的英文版已免费公开,中文版已免费公开,还有一个 用PyTorch完整实现的版本 也已免费公开。既然能用PyTorch实现,有没有Java实现的版本呢?答案是肯定的,这就是本文真正要介绍的《动手学深度学习(Java版)》。

 

关键是,Java版本的《动手学深度学习》竟然也有中文版本。

动手学深度学习 – 《动手学深度学习》 0.1.0 documentation

《动手学深度学习(Java版)》所依赖的库是Deep Java Library(DJL)。正如数学领域优秀答主@机器之心 介绍:

 

DJL(Deep Java Library ) 是亚马逊在2019年宣布推出的开源Java深度学习开发包,它是在现有深度学习框架基础上使用原生Java概念构建的开发库。它为开发者提供了深度学习的最新创新和使用前沿硬件的能力,例如GPU、MKL等。

 

更有趣的是,《动手学深度学习(Java版)》同样使用Jupyter Notebook,使读者可以在交互过程中完成学习。不过,这里的Jupyter Notebook是Java程序构建的。本文的目的是跑通《动手学深度学习(Java版)》的安装部分,并把配置过程中遇到的问题记录下来,方便参考。

 

安装:简单但还需要避免踩坑

 

《动手学深度学习(Java版)》的作者贴心地给出了较为详细的配置过程。

 

然而,整个配置过程看似简单,实际上还是有一些坑的。我们根据文档中的流程,一步一步进行安装,并记录遇到的问题。我使用的安装环境如下图所示:

# 安装

 

为了深入学习 DJL ,本书嵌入了许多可运行的 Java 示范用例。在学习过程中,我们需要搭建一个 DJL 的运行及学习环境。这个学习运行环境包括 Python, Jupyter Notebooks 以及相关的函数库及软件包。

 

# 安装 JDK 11 (不是 JRE)

 

本书中提供的所有程序示例,只能在 JDK 11 (或以上) 版本运行。

 

Java 运行路径是一个非常重要的环境配置。在 DJL 运行环境安装的过程中,Java 运行路径是否配置正确。检查的方法是运行下面的命令行。如果运行结果如下面显示的,并且版本号为11或以上,那你的环境就配置正确了。

 

java –list-modules | grep “jdk.jshell”

 

> [email protected]

 

我本机上已经安装了Java 11。执行java -version的结果如下图:

然而,为了演示其他版本安装时可能遇到的问题,我通过Intellij IDEA内置的JDK下载功能下载了最新的OpenJDK 11。安装完毕后,执行java -version的结果如下图:

再执行java –list-modules | grep “jdk.jshell”,结果为:

可见,目前系统默认支持jdk.jshell的为JDK 17版本。

 

# 在 Python 环境下安装 Jupyter Notebook

 

在 Python3 的环境下,用下面的命令行安装 Jupyter Notebook:

 

pip3 install jupyter

 

这一步没有什幺问题。只不过我的安装过程非常缓慢,中间经过了多次失败。

 

# 安装 IJava 内核

 

为了运行本书中嵌入的 Java 示范用例,我们需要在 Jupyter Notebook 运行环境下添加安装 IJava 内核。安装步骤如下:

 

git clone https:// github.com/frankfliu/IJ ava.git

 

cd IJava/

 

./gradlew installKernel

 

这一步是最有意思的。我在安装JDK 17的系统上执行上述命令,返回了下述错误:

参考下述链接,似乎是因为我使用的JDK版本不对。为此,我执行export JAVA_HOME=`/usr/libexec/java home -v 11`, 使当前窗口切换为JDK 11版本,便可以安装成功了。还有一种可能是,我的系统并没有设置JAVA_HOME,或许通过上述命令设置JAVA_HOME即可安装成功。其他知友如果尝试后成功,欢迎在文章下方留言。

 

# 下载 D2L-Java 记事本文件

 

本书中的 Jupyter 记事本文件 可以从我们的 Github 代码仓库里克隆拷贝。下面是克隆拷贝的命令行。拷贝到本地后,你就可以用 Jupyter Notebook 对教程中的各个章节进行浏览了。

 

git clone https:// github.com/deepjavalibr ary/d2l-java

 

cd d2l-java

 

这里给出的链接是英文版本的Github代码仓库。可以替换为中文版:

 

git clone https://github.com/deepjavalibrary/d2l-java-zh.git
cd d2l-zh

 

# 运行 Jupyter 记事本文件

 

如果前面的步骤都已经顺利完成,接下来我们就可以用下面的命令行运行 Jupyter Notebook 了:

 

jupyter notebook

 

Jupyter Notebook 启动后,在浏览器输入 http://localhost:8888 本教程就在浏览器中打开了。学员在学习过程中,可以运行教程中嵌入的 Java 示范用例,对所学的内容加强理解。

 

执行jupyter notebook,可能会出现如下错误:

参考下述文章提到的,其核心问题是”在EI captain版本以及以上系统的Mac上使用pip安装 Python相关的包的时候,由于SIP机制(System Integrity Protection)的不允许命令行写入内容到系统目录“,这导致jupyter notebook目录没有添加至环境变量中。按照文章给出的方式解决即可。不过要注意的是,在~./bash_profile添加export命令后,不应该执行source .bash_profile,而是应该执行

 

source ~/.bash_profile

 

正常启动后,我们成功打开了Java版本的jupyter notebook。

 

最开始严格按照文档下载,下载到的是原始英文版本的代码。都配置完毕后,我下载了中文版本的代码,因此最后一张截图切换成了中文版本。

还剩下一个比较大的坑。如果我们兴冲冲地打开”2.预备知识 -> 2.1.数据操作“章节,并顺序执行到

 

NDManager manager = NDManager.newBaseManager();
NDArray x = manager.arange(12);
x

 

会发现jupyter notebook会卡住,如下图所示。

这时候要耐心等待,因为DJL在第一次运行时会自动检测系统,并下载最适合的C/C++动态库。耐心等待一下,即可成功完成执行。

总结:在Java世界里研究深度学习

 

实话实说,在阅读了Python撰写的深度学习代码后,我也认为Python更适合机器学习领域。不过,隐私保护机器学习的出发点到底是隐私保护,还是机器学习呢?这就像联邦学习在算法领域和密码学领域争论不休一样:

是以机器学习为出发点,以完成机器学习任务为核心,增加隐私保护能力(哪怕不具备严格的可证明安全性)?
是以密码学为出发点,以可证明安全技术为核心,利用可证明安全技术实现机器学习(哪怕需要重构算法库)?

这是一个仁者见仁智者见智的事情。同时具备两个领域的能力,同时考虑应用和安全,提出两边均可接受的方案,或许是最终的状态。

 

无论如何,我先选择这种方式进行学习和研究了,哪怕最终证明选择是错误的,完整吃透底层,再选择更好的方法构建更适合的算法库,何乐而不为呢?

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注