Julia 是一门高度抽象的动态编程语言。虽然它是一门能够开发所有程序的通用语言,但它有几个特点,非常适用于科学计算和数值计算。Python 在 1990 年初作为一种简单的面向对象的程序语言出现,如今已经有了显著的发展。本文将从它们在神经网络和机器学习的性能表现上进行讨论。
Julia 的架构以动态语言中的参数多态性parametric polymorphism和多重派发multiple dispatch的编程范式为主要特色。它允许使用或不使用消息传递接口message passing interface(MPI)或内置的 “OpenMP 式” 线程进行并发、并行和分布式计算,以及直接调用 C 和 FORTRAN 库而无需额外的代码。Julia 使用 即时just-in-time(JIT)编译器,Julia 社区将其称为 “即时预编译just-ahead-of-time(JAOT)”,因为它在运行之前默认将所有代码编译为机器码。
与 Python 不同,Julia 是专为统计学和机器学习而设计的。Julia 可以快速的完成线性代数的运算,但 Python 很慢。这是因为 Python 从来都不是为了适应机器学习用到的矩阵和方程而设计的。Python 本身并不差,特别是 Numpy,但在没有使用包的情况下,Julia 更像是为数学量身定制的。相比 Python,Julia 的运算符更像 R,这是一个显著的优势。大部分的线性代数运算可以用更少的时间和精力去完成。
众所周知,近年来 Python 在机器学习和数据科学领域占据主导地位。因为在 Python 中我们可以使用各种各样的第三方库来帮助我们编写机器学习的代码。虽然 Python 有这么多优势,但仍有一个主要的缺点——它是一门解释性语言,速度非常慢。现在是数据时代,数据越多我们处理它的时间就越长,这也是 Julia 出现的理由。
到目前为止,有关 Julia 的研究工作都集中在高性能或者 Julia 的科学计算能力等主题上。但在这里,我们将讨论 Julia 不仅能够有效地处理复杂的科学计算,还能够处理基于商业的问题,以及像 Python 一样处理机器学习和神经网络。
Julia 像 Python 一样简洁,但却像 C 一样是一门编译语言。首先我们来测试 Julia 要比 Python 快多少。为此,我们先在一些简单的程序上测试它们,然后来到我们实验的重点,测试它们的机器学习和深度学习能力。
Julia 和 Python 都提供了许多库和开源的基准测试工具。为了在 Julia 中进行基准测试和计算时间,我们使用了 CPUTime
和 time
库;对于 Python,我们同样使用了 time
模块。
一開始我們嘗試了簡單的算術運算,但由於這些運算不會產生太大的時間差異,我們決定比較矩陣乘法的時間差異。我們創建了兩個 #(10 * 10)
的隨機浮點數矩陣,並對它們施加點積。眾所周知,Python 有一個 Numpy
庫,常被用來計算矩陣和向量。而 Julia 也有一個 LinearAlgebra
庫,常用於計算矩陣和向量。因此我們分別比較了各自使用和不使用函式庫的矩陣乘法的耗時。本文用到的所有原始碼已經放在了 GitHub 儲存庫。下面給出了用 Julia 編寫的 10×10 矩陣乘法程式:
@time LinearAlgebra.mul!(c,x,y) function MM() x = rand(Float64,(10,10)) y = rand(Float64,(10,10)) c = zeros(10,10) for i in range(1,10) for j in range(1,10) for k in range(1,10) c[i,j] += x[i,k]*y[k,j] end end end end @time MM 0.000001 seconds MM (generic function with 1 method)
Julia 使用函式庫耗時 0.000017 秒,使用循環耗時 0.000001 秒。
使用 Python 寫相同的矩陣乘法程式如下。從結果可以發現,與不使用庫相比,使用庫的程式花費的時間更少:
import numpy as np import time as t x = np.random.rand(10,10) y = np.random.rand(10,10) start = t.time() z = np.dot(x, y) print(“Time = “,t.time()-start) Time = 0.001316070556640625 import random import time as t l = 0 h= 10 cols = 10 rows= 10 choices = list (map(float, range(l,h))) x = [random.choices (choices , k=cols) for _ in range(rows)] y = [random.choices (choices , k=cols) for _ in range(rows)] result = [([0]*cols) for i in range (rows)] start = t.time() for i in range(len(x)): for j in range(len(y[0])): for k in range(len(result)): result[i][j] += x[i][k] * y[k][j] print(result) print(“Time = “, t.time()-start) Time = 0.0015912055969238281
Python 使用庫耗時 0.0013 秒,使用循環耗時 0.0015 秒。
我們進行的下一個實驗是對十萬個隨機產生的數字進行線性搜尋。這裡使用了兩種方法,一種是使用 forfor
循環,另一種是使用運算子。我們使用 1 到 1000 的整數執行了 1000 次搜索,正如你在下面的輸出中看到的那樣,我們還列印了我們在資料集中找到了多少個整數。下面給出了使用循環和使用 IN
運算子的時間。這裡我們使用了 CPU 3 次運行時間的中位數。
使用Julia 編寫的程式和運行結果如下:
(LCTT 翻譯:此處原文缺少Julia 程式碼)
使用Python 編寫的程式和運行結果如下:
import numpy as np import time as t x = np.random.rand(10,10) y = np.random.rand(10,10) start = t.time() z = np.dot(x, y) print(“Time = “,t.time()-start) Time = 0.001316070556640625 import random import time as t l = 0 h= 10 cols = 10 rows= 10 choices = list (map(float, range(l,h))) x = [random.choices (choices , k=cols) for _ in range(rows)] y = [random.choices (choices , k=cols) for _ in range(rows)] result = [([0]*cols) for i in range (rows)] start = t.time() for i in range(len(x)): for j in range(len(y[0])): for k in range(len(result)): result[i][j] += x[i][k] * y[k][j] print(result) print(“Time = “, t.time()-start) Time = 0.0015912055969238281
FOR_SEARCH: Elapsed CPU time: 16.420260511 seconds matches: 550 Elapsed CPU time: 16.140975079 seconds matches: 550 Elapsed CPU time: 16.49639576 seconds matches: 550 IN: Elapsed CPU time: 6.446583343 seconds matches: 550 Elapsed CPU time: 6.216615487 seconds matches: 550 Elapsed CPU time: 6.296716556 seconds matches: 550
從上述結果來看,在Julia 中使用迴圈和運算子並不會產生顯著的時間差異。但是在 Python 中循環幾乎比運算子 IN 多花了三倍的時間。有趣的是,在這兩種情況下,Julia 都比 Python 快得多。
下一個實驗是測試機器學習演算法。我們選擇了以一種最常見和最簡單的機器學習演算法,使用簡單資料集的線性迴歸。我們使用了一個包含 237 個資料的資料集 “Head Brain”,資料集的兩列分別為 “HeadSize” 和 “BrainWeight”。接下來,我們使用 “head size” 資料去計算 “brain weight”。在 Python 和 Julia 中我們都沒有使用第三方函式庫,而是從零實作了線性迴歸演算法。
Julia:
GC.gc() @CPUtime begin linear_reg() end elapsed CPU time: 0.000718 seconds
Python:
gc.collect() start = process_time() linear_reg() end = process_time() print(end-start) elapsed time: 0.007180344000000005
上面給了 Julia 和 Python 所花費的時間。
接下來,我們使用兩種語言的函式庫對最常見的機器學習演算法(即邏輯迴歸)進行了實驗。對於 Python 我們使用最常見的函式庫 sklearn
;對於 Julia,我們使用 GLM
函式庫。我們在這裡使用的資料集是有關銀行客戶的信息,其中包含 10,000 個資料條目。目標變數是一個二元變量,區分消費者是否繼續使用銀行帳戶。
下面給出了 Julia 進行邏輯回歸所花費的時間:
@time log_rec() 0.027746 seconds (3.32 k allocations: 10.947 MiB)
下面給出了 Python 進行邏輯回歸所花費的時間:
gc.collect() start = process_time() LogReg() end = process_time() print(end-start) Accuracy : 0.8068 0.34901400000000005
在各种程序和数据集上测试这两种语言后,我们在神经网络上使用 MNIST 数据集继续测试它们。该数据集包含从零到九的手绘数字的灰度图像。每张图像为 28×28 像素。每个像素值表示该像素的亮度或暗度,该值是包含 0 到 255 之间的整数。该数据还包含一个标签列,该列表示在相关图像中绘制的数字。
Figure 1: Example of MNIST data set
图 1 是 MNIST 数据集的示例。
对两种语言我们都建立了一个简单的神经网络来测试它们耗费的时间。神经网络的结构如下:
Input ---> Hidden layer ---> Output
该神经网络包含了一个输入层、隐层还有输出层。为了避免神经网络的复杂度过高,我们对数据集没有进行任何的预处理工作。在 Julia 和 Python 中我们都进行了40次训练并比较它们的时间差异。
Figure 2: Julia takes 5.76 seconds in a neural network
在 Julia 中,Flux
库通常被用于建立神经网络;在 Python 中我们常使用 Keras
库。图 2 展示了 Julia 在神经网络上的耗时。图 3 展示了 Python 的神经网络经过了若干次训练的耗时。
Figure 3: Python takes 110.3 seconds in a neural network
这个结果展示了 Julia 和 Python 在处理神经网络时存在巨大的时间差异。
表 1 总结了此次实验的测试结果并计算了 Julia 和 Python 时间差异的百分比。
实验 |
Julia(秒) |
Python(秒) |
时间差(%) |
矩阵乘法(不使用库) |
0.000001 |
0.0015 |
99.9 |
矩陣乘法(使用函式庫) |
0.000017 |
#0.0013 |
|
|
|||
|
|
|
|
|
|
|
|
|
0.025 |
0.34901 |
92.83 |
神經網路 |
5.76 |
#110.3 |
#94.77 |
#我們進行的所有實驗都表明,隨著程式複雜性以及資料集大小的增加,Julia 和Python 之間的執行時間差異也會增加。由這個結果我們可以推斷,Julia 是一門更適合機器學習和神經網路的程式語言。
以上是Julia 和 Python,哪一個比較快?的詳細內容。更多資訊請關注PHP中文網其他相關文章!