使用Java语言开发机器学习框架和参数服务器
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这种东西