机器学习与深度学习的应用已广泛渗透到各个行业和领域中,但随之而来的计算复杂性和时间耗费也日益增加。如何有效地优化和加速这些计算过程成为了研究者和开发者的关键问题。而这正是Intel®oneAPI发挥作用的地方。oneAPI为数据科学和机器学习领域带来了巨大的进步。通过其强大的加速能力,不仅可以大幅提高算法的执行速度,还能有效地降低资源消耗。
近日,复旦大学的赵卫东教授以《oneAPI驱动机器学习加速》为题,分享了oneAPI应用于机器学习的案例和他的学生参加黑客松比赛的一些经验和体会。
以下内容根据赵卫东演讲整理:
传统的机器学习里,利用oneAPI的加速技术来实现机器学习的训练和推理的过程,常用的Numpy、Pandas、Scikit等机器学习库。
如何利用oneAPI的一些加速的算法能提升效率?通过具体的例子来阐述。
Numpy的加速技术
如何在Numpy上面做模型运算的加速?
Numpy有很多的矩阵和循环的一些计算。Numpy在很多的场合都需要做循环的操作,循环是非常耗费时间和算力的。Numpy如何来减少循环的时间。可以看一些例子:例如一个常用的for循环,甚至说for循环的嵌套,需要大量的运算,如何来提升for循环执行的效率,可以比较一下map函数、list推导以及Numpy操作。
有一个包含100万个随机浮点数的列表,通过for循环来遍历其元素。
用原生的for循环的方法,耗时是13秒89。改用map函数,执行的时间有了一些变化。
可以采用list推导的方法或者说Numpy向量化的方法,会发现执行的速度有了一定的改善。右边的这几种方法,比如list方法,还有Numpy里面向量化的方法,会发现同样的遍历操作,执行的时间明显有变化。
平移的例子,有一个非常大的数要做一个平移。如果用for循环的方法,再调一下list的推导方法,以及Numpy里面的ufunc通用函数的方法。很容易通过简单的实验发现,几种方法有明显的不同。从时间上看,Numpy里面的ufunc函数的时间可以大大压缩。
Numpy里面有多个通用的函数。这些函数都可以起到加速的作用。无论是求变量的最大值最小值,还是进行其他统计操作,发现用ufunc里的通用函数比原生的操作要快得多。
在NumPy上如何实现矩阵和向量之间的计算?
在Numpy的广播操作里,大家可以看到例如矩阵之间的加法和乘法。通过“广播”操作,能提高这些矩阵运算的速度。
有两个数组,一个是x,一个是y。这两个数组的维度必须一样才能相加。通过广播操作,可以使两者满足相加的条件,并且加速过程。
在加州住房数据集的例子里,可以看到,采用Numpy的向量化操作,可以大大减少计算耗时。结合了Numpy里的聚合和广播操作。在常见的矩阵计算中,比如在机器学习和深度学习算法里,如果用常规的矩阵计算方法,会非常耗时。但改用Numpy里的dot或者matmul方法,用于二维数组即矩阵之间的计算,速度会有较大提升。
Pandas的加速技术
在Pandas里也可以采用加速的方法。在Numpy的基础上,如何来提升判断式里面的,以及一些其他操作的速度。例如,有循环操作。在循环里,比如说要做某一种操作。这里面是一个非常简单的例子:有一个100000×5的DataFrame。
可以遍历所有的行,然后把某一行的值取一个对数。还可以用iloc方法。当然也可以使用iterrow方法进行加速。大家可以比较一下时间,总的时间从25.1秒减少到5.25秒。
还可以使用Pandas的at和apply的方法。执行相同的操作时,这几种方法有明显的加速效果。对于一个包含10个5次方行数的记录,记录里有a、b、c、d、e这五个字段,对其中的某一个字段,比如c字段,进行对数操作。通过比较这几种方法,明显看到运算时间有差别。
如果数据量增加的更大一些,效果可能更明显。把刚才循环里的函数操作换成了DataFrame的语句。用刚才的几种方法,也能发现时间有差别。可以看到图中纵坐标的时间耗时,用Pandas的不同方法都做了一些优化。
无论是在Numpy还是Pandas,如果做了一些优化操作,对于大数据量的处理,时间会有多倍的增长。如何进一步实现数据分析的加速增长呢?比如机器学习库Scikit-learn,英特尔在加速方面实际上做了很多工作。
Scikit-learn的加速技术
对于TensorFlow或者PyTorch等开源的框架,框架里面可以实现机器学习的常用一些算法,比如说分类、聚类、回归等等。
如何来提升这些数据分析算法的训练和推理速度呢?
Intel®oneAPI实际上做了一些底层的优化。这种优化可以在Numpy或者Pandas里面看到,就是其中的一些方法融合在底层。底层对于用户来说是不透明的,不需要关注在底层是如何优化的。但只要安装了oneAPI的加速库,就可以实现数据分析,尤其是机器学习算法的加速。
机器学习算法加速的一些方法。在Scikit机器学习库里面,有大量的分类、聚类、回归等等这样的方法。使用的时候,要装一个加速库。在CMD交互界面上,可以用pip命令,比如说pip install scikit-learn-intelex,来安装一个加速的插件和库。装好以后,就可以从底层做一个加速。
底层的加速,比如在Numpy和Pandas里,如何采用一些新方法来减少运算的时间。对用户来说是屏蔽的,不需要了解细节。在底层加速的时候,对代码几乎不需要修改。只要安装了英特尔的加速包scikit-learn-intelex,就可以实现加速。
安装方法是几个简单的命令。首先要建立一个Python运行环境,Python的版本一般选的是3.9。然后主要装的一个加速库就是scikit-learn-intelex。装好以后,就可以把常用的算法做一个加速。
可以看到执行刚才的命令以后,在加速环境里,已经有被优化的算法库。这些算法有分类、聚类和回归等。在这一列表里,是常见的机器学习算法,比如ElasticNet回归,K-Means聚类,最近邻分类等等,都是在传统机器学习里经常用的算法。
英特尔在底层都做了一些优化,只要会用就可以了。这张表格,是罗列了一些 scikit-learn 在 oneAPI 已经加速的这些算法的列表。可以参考一下。
右上角命令,就可以看到安装了加速包以后,哪些算法可以加速。绝大部分,常见的算法都是可以加速的。可以在使用的时候可以查表格,看看能不能加速。
在 Jupyter Notebook 上也是可以实现加速的。不仅在命令行上。如何在 Notebook 的战法里面做加速呢?只要添上这句话 import the sklearnex library,然后加速的时候再加上这句话 patch_sklearn()。有了这两行代码,刚才表格里面能够加速的算法就能够自动加速。
做一个实验,安装了加速包以后,可以对一些常用的算法,比如说最近邻、PCA、就主分量分析还有 Kmeans,可以做些加速。如果不想加速,只要把patch_sklearn() 在后面再加上一个 unpatch_sklearn(),就相当于不需要加速的功能。如果需要使用,加上去以后,可以看一下效果。使用加速器和不使用加速器,实际上可以看到,速度会得到一个非常大的提升。
有一个加速的测试。对一定的相应的数据集做分类回归的分析。举个例子,可以看到有 8 种的分类和回归的方法。可以看到加速还有不加速的差别。这里面有一个 unpatch_sklearn(),不加速可以看看,比如说每一种算法的耗时这里面有一个输出。然后再用加速的还是这 8 种算法,大家会发现耗时明显的降低了。
为了进一步的验证加速的效果,实际地抽取了一个项目,可以再抽取一个项目,然后去进一步的比较。这是刚才的 8 种算法的比较的情况。
实际应用举例
蓝颜色的加速,黄颜色的度量图的表示时间。就这是同样的数据集,加速不加速,看蓝色和黄色的高度,时间明显的有差别。做一个集装箱危险品瞒报预测的真实项目。用了神经网络、逻辑回归、贝叶斯还有随机森林等等算法。算法需要大量的计算,算力非常耗时。也就是说,越复杂的项目,数据量越大,加速的效果越明显。
获取和使用oneAPI
想使用Intel®oneAPI,可以到 GitHub 的地址上去安装。上面有很多非常详细的文档,用来说明一些加速的方法以及一些案例。可以进一步的学习。
想在英特尔的 Devcloud 上面做实操,可以注册一个账号。注册一个账号以后,就可以在上面来做一些练习。也就是说,在英特尔的云服务器上面,可以采用云资源来验证一下机器学习转法加速的效果。
总结
oneAPI为数据科学和机器学习领域带来了巨大的进步。通过其强大的加速能力,不仅可以大幅提高算法的执行速度,还能有效地降低资源消耗。对于任何希望优化和提高其机器学习或深度学习项目效率的研究者和开发者来说,探索和利用oneAPI都是非常有价值的尝试。