首页 > 技术文章 > 使用Java语言开发机器学习框架和参数服务器

23lalala 2018-06-26 16:58 原文

https://github.com/wudikua/ps

本项目是我自己动手实现的机器学习训练框架,代码简单,有很多不完善,但是也保留了最小可用功能

通过自己编写这个项目,可以帮助自己入门机器学习

准备

1. 学习梯度下降法训练LR模型原理,了解机器学习一般的套路

2. 学习神经网络的模型结构,正向传导和反向传导

3. 学习一些python写的神经网络,训练代码

4. 参考tiny dnn这种小型机器学习训练框架,学习如何封装组件

5. 学习computional graph,自动求导

6. 学习除了fully connected layer以外的其他一些layer算法

7. 学习一些更新算法,激活算法,Loss计算方法等

8. 学习机器学习的分布式训练,主要是参数服务器,设计网络通信,分布式存储等

以上部分的学习过程是比较曲折的,主要参考一些博客,文章,视频,论文等

 

代码实现

具体的代码可以参考git项目

机器学习训练框架需要考虑很多东西,除了最核心的算法外,还需要考虑扩展性,内存,网络,CPU,GPU等计算资源,以及分布式存储的相关知识

我认为分布式机器学习框架需要解决好如下几个大问题

 

1. 算法实现

各种算法的实现,这部分需要一些纯粹的机器学习知识,通过参考别人代码和一些资料可以实现

2. 矩阵库

因为机器学习的算法最后都会转为对矩阵操作,所以这一层最好是使用别人写好的一些库

这种数学运算,又涉及到CPU和GPU作为最后的计算设备,GPU计算的并行度远高于CPU,但是GPU显存有限,对GPU做调用也有一定开销

3. 参数服务器分布式

参数服务器这块属于工程方面,涉及到网络通信,序列化反序列化,传输中的压缩,以及合理利用网络带宽都是需要考虑的

还有一些优化是结合算法,在分布式环境下做出让步,取舍。比如一些异步更新机制。

4. 充分利用机器资源

机器学习是CPU密集型也是IO密集型,又非常吃内存,好的机器学习框架应该最大限度利用机器的计算资源和IO资源

 

还有一些其他能力比如说是否有一些可视化的图表帮助调试,是否有一些集群容灾功能,不过这些我觉得都是锦上添花

最重要的问题还是收敛速度

 

Java与机器学习

Java中有腾讯的angel和dl4j这两个项目,不过目前来看机器学习的训练框架主要还是c++,api是python

Java性能不如c++?

  Java因为有JIT技术,所以跑一些基准测试并不比c++逊色,反而因为JIT的优化,可能还会比c++要好

Java写机器学习训练库有两个重要短板:

  a. 对于底层设备的支持不行

  但是目前加速机器学习训练速度的什么cuda,nccl,blas相关各种库都是c++接口,java想用的话只能jni或javacpp跨平台调用

  再比如说CPU的SSE4指令集可以对浮点数乘法有优化,而Java只能在限制条件靠JIT自动做这种优化

  

  b. 还有一个问题就是GC会影响机器学习的吞吐量

 

是不是有短板就不行?

  跨平台调用虽然慢,但是如果一次训练很多数据,只做很少的跨平台调用,这样训练时间远大于调用的损失就无所谓

  而且机器学习是个系统工程,更重要的是各子模块的配合,网络,内存,线程同步等等问题都会影响性能

 

机器学习框架展望

如何描述模型

第一代 sequence of layer

第二代 op graph,以tensorflow为代表

第三代 机器学习编译器,paddlepaddle中提出

paddlepaddle应该是最先进的,tensorflow还需要python调用c++,paddlepaddle相当于发明了一种机器学习语言,由编译器自动优化,让他跑在不同的设备上

 

可视化,可调式,易用性

调试和可视化这两点个人认为非常有意义的,类似tensorboard这种东西

 

推荐阅读