自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python對陣Julia:機(jī)器學(xué)習(xí)實(shí)例

譯文
開發(fā) 后端 前端
在之前談到的保序回歸加速話題中,我們聊起如何利用Cython改進(jìn)回歸算法的性能表現(xiàn)。我覺得將Python優(yōu)化代碼的性能表現(xiàn)與原生Julia方案加以比對能夠進(jìn)一步明確大家對于速度提升的直觀感受。

在之前談到的保序回歸加速話題中,我們聊起如何利用Cython改進(jìn)回歸算法的性能表現(xiàn)。我覺得將Python優(yōu)化代碼的性能表現(xiàn)與原生Julia方案加以比對能夠進(jìn)一步明確大家對于速度提升的直觀感受。

今天的文章將承接上一篇,因此大家在進(jìn)行閱讀前,不妨先對前文進(jìn)行一番回顧、旨在掌握相關(guān)背景信息。

我們將借用前文中提到的兩種算法,并在這里就性能表現(xiàn)在Julia與Python之間展開一番比拼。

線性PAVA

相關(guān)Cython代碼可以通過Github上的scikit-learn進(jìn)行下載,而Julia代碼則來自GitHub上的Isotonic.jl。

Julia代碼采用的是最為簡單的PAVA表達(dá),不摻雜任何花哨的內(nèi)容與修飾;@inbounds宏的作用是客觀比較Cython的執(zhí)行效果并關(guān)閉bound check。

  1. function isotonic_regression(y::Vector{Float64}, weights::Vector{Float64})  
  2.     @inbounds begin  
  3.         n = size(y, 1)  
  4.         if n <= 1 
  5.             return y  
  6.         end  
  7.         n -= 1 
  8.         while true  
  9.             i = 1 
  10.             pooled = 0 
  11.             while i <= n  
  12.                 k = i  
  13.                 while k <= n && y[k] >= y[k+1]  
  14.                     k += 1 
  15.                 end  
  16.    
  17.                 # Find a decreasing subsequence, and update  
  18.                 # all points in the sequence to the weighted average.  
  19.                 if y[i] != y[k]  
  20.                     numerator = 0.0 
  21.                     denominator = 0.0 
  22.                     for j in i : k  
  23.                         numerator += y[j] * weights[j]  
  24.                         denominator += weights[j]  
  25.                     end  
  26.    
  27.                     for j in i : k  
  28.                         y[j] = numerator / denominator  
  29.                     end  
  30.                     pooled = 1 
  31.                 end  
  32.                 i = k + 1 
  33.             end  
  34.             if pooled == 0 
  35.                 break 
  36.             end  
  37.         end  
  38.     end  
  39.     return y  
  40. end  
  41.    
  42. isotonic_regression(y::Vector{Float64}) = isotonic_regression(y, ones(size(y, 1)))  

linear_pava.jl hosted with ❤ by GitHub

  1. @cython.boundscheck(False)  
  2. @cython.wraparound(False)  
  3. @cython.cdivision(True)  
  4. def _isotonic_regression(np.ndarray[DOUBLE, ndim=1] y,  
  5.                          np.ndarray[DOUBLE, ndim=1] weight,  
  6.                          np.ndarray[DOUBLE, ndim=1] solution):  
  7.     cdef:  
  8.         DOUBLE numerator, denominator  
  9.         Py_ssize_t i, pooled, n, k  
  10.    
  11.     n = y.shape[0]  
  12.     # The algorithm proceeds by iteratively updating the solution  
  13.     # array.  
  14.    
  15.     # TODO - should we just pass in a pre-copied solution  
  16.     # array and mutate that?  
  17.     for i in range(n):  
  18.         solution[i] = y[i]  
  19.    
  20.     if n <= 1:  
  21.         return solution  
  22.    
  23.     n -1 
  24.     while 1:  
  25.         # repeat until there are no more adjacent violators.  
  26.         i = 0 
  27.         pooled = 0 
  28.         while i < n: 
  29.             k = i 
  30.             while k < n and solution[k] >= solution[k + 1]:  
  31.                 k += 1  
  32.             if solution[i] != solution[k]:  
  33.                 # solution[i:k + 1] is a decreasing subsequence, so  
  34.                 # replace each point in the subsequence with the  
  35.                 # weighted average of the subsequence.  
  36.    
  37.                 # TODO: explore replacing each subsequence with a  
  38.                 # _single_ weighted point, and reconstruct the whole  
  39.                 # sequence from the sequence of collapsed points.  
  40.                 # Theoretically should reduce running time, though  
  41.                 # initial experiments weren't promising.  
  42.                 numerator = 0.0  
  43.                 denominator = 0.0  
  44.                 for j in range(i, k + 1):  
  45.                     numerator += solution[j] * weight[j]  
  46.                     denominator += weight[j]  
  47.                 for j in range(i, k + 1):  
  48.                     solution[j] = numerator / denominator  
  49.                 pooled = 1 
  50.             i = k + 1  
  51.         # Check for convergence  
  52.         if pooled == 0:  
  53.             break  
  54.    
  55.     return solution  

_isotonic.pyx hosted with ❤ by GitHub

Active Set

Active Set的行數(shù)與Cython代碼基本相當(dāng),而且在結(jié)構(gòu)上可能更為簡潔(通過顯式復(fù)合type ActiveState實(shí)現(xiàn))、旨在維持給定主動(dòng)雙重變量中的參數(shù)。Active Set會(huì)將重復(fù)代碼拆分為獨(dú)立函數(shù),從而由LLVM對其實(shí)現(xiàn)內(nèi)聯(lián)——這一點(diǎn)很難借由Cython中的任何參數(shù)實(shí)現(xiàn)。

Julia中的檢索機(jī)制也會(huì)對算法作出一定程度的精簡。

  1. immutable ActiveState  
  2.     weighted_label::Float64  
  3.     weight::Float64  
  4.     lower::Int64  
  5.     upper::Int64  
  6.    
  7. end  
  8.    
  9. function merge_state(l::ActiveState, r::ActiveState)  
  10.     return ActiveState(l.weighted_label + r.weighted_label,  
  11.                        l.weight + r.weight,  
  12.                        l.lower,  
  13.                        r.upper)  
  14. end  
  15.    
  16. function below(l::ActiveState, r::ActiveState)  
  17.     return l.weighted_label * r.weight <= l.weight * r.weighted_label  
  18. end  
  19.    
  20. function active_set_isotonic_regression(y::Vector{Float64}, weights::Vector{Float64})  
  21.     @inbounds begin  
  22.         active_set = [ActiveState(weights[i] * y[i], weights[i], i, i) for i in 1 : size(y, 1)]  
  23.         current = 1 
  24.         while current < size(active_set, 1)  
  25.             while current < size(active_set, 1) && below(active_set[current], active_set[current+1])  
  26.                 current += 1 
  27.             end  
  28.             if current == size(active_set, 1)  
  29.                 break 
  30.             end  
  31.    
  32.             merged = merge_state(active_set[current], active_set[current+1])  
  33.             splice!(active_set, current:current+1, [merged])  
  34.             while current > 1 && !below(active_set[current-1], active_set[current])  
  35.                 current -= 1 
  36.                 merged = merge_state(active_set[current], active_set[current+1])  
  37.                 splice!(active_set, current:current+1, [merged])  
  38.             end  
  39.         end  
  40.    
  41.         for as in active_set  
  42.             y[as.lower:as.upper] = as.weighted_label / as.weight  
  43.         end  
  44.     end  
  45.     return y  
  46. end  
  47.    
  48. active_set_isotonic_regression(y::Vector{Float64}) = active_set_isotonic_regression(y, ones(size(y, 1)))  

active_set.jl hosted with ❤ by GitHub

  1. @cython.boundscheck(False)  
  2. @cython.wraparound(False)  
  3. @cython.cdivision(True)  
  4. def _isotonic_regression(np.ndarray[DOUBLE, ndim=1] y,  
  5.                          np.ndarray[DOUBLE, ndim=1] weight,  
  6.                          np.ndarray[DOUBLE, ndim=1] solution):  
  7.    
  8.     cdef:  
  9.         Py_ssize_t current, i  
  10.         unsigned int len_active_set  
  11.         DOUBLE v, w  
  12.    
  13.     len_active_set = y.shape[0]  
  14.     active_set = [[weight[i] * y[i], weight[i], [i, ]]  
  15.                   for i in range(len_active_set)]  
  16.     current = 0 
  17.    
  18.     while current < len_active_set - 1:  
  19.         while current < len_active_set -1 and \  
  20.               (active_set[current][0] * active_set[current + 1][1] <=   
  21.                active_set[current][1] * active_set[current + 1][0]):  
  22.             current += 1 
  23.    
  24.         if current == len_active_set - 1:  
  25.             break 
  26.    
  27.         # merge two groups  
  28.         active_set[current][0] += active_set[current + 1][0]  
  29.         active_set[current][1] += active_set[current + 1][1]  
  30.         active_set[current][2] += active_set[current + 1][2]  
  31.    
  32.         active_set.pop(current + 1)  
  33.         len_active_set -= 1 
  34.         while current > 0 and \  
  35.               (active_set[current - 1][0] * active_set[current][1] >   
  36.                active_set[current - 1][1] * active_set[current][0]):  
  37.             current -= 1 
  38.             active_set[current][0] += active_set[current + 1][0]  
  39.             active_set[current][1] += active_set[current + 1][1]  
  40.             active_set[current][2] += active_set[current + 1][2]  
  41.    
  42.             active_set.pop(current + 1)  
  43.             len_active_set -= 1 
  44.    
  45.     for v, w, idx in active_set:  
  46.         solution[idx] = v / w  
  47.     return solution  

_isotonic.pyx hosted with ❤ by GitHub 

性能表現(xiàn)

可以看到,在與Cython實(shí)例進(jìn)行比對時(shí),我們發(fā)現(xiàn)即使是同樣的算法在Julia中的平均執(zhí)行速度也會(huì)更快。


[點(diǎn)擊擴(kuò)大]

對于上述Active Set實(shí)例,Julia在處理回歸計(jì)算時(shí)的表現(xiàn)都能實(shí)現(xiàn)5倍到300倍的速度提升。

對于線性PAVA實(shí)例,Julia的速度提升效果則為1.1倍到4倍之間。

這樣的結(jié)果證明,Julia在性能敏感型機(jī)器學(xué)習(xí)應(yīng)用領(lǐng)域具有顯著吸引力。

大家可以點(diǎn)擊此處了解更多關(guān)于上述性能測試結(jié)果的獲取方法。

英文原文:http://tullo.ch/articles/python-vs-julia/

責(zé)任編輯:林師授 來源: 51CTO
相關(guān)推薦

2019-12-16 14:53:44

機(jī)器學(xué)習(xí)人工智能計(jì)算機(jī)

2018-12-12 09:33:58

編程語言機(jī)器學(xué)習(xí)代碼

2022-01-13 15:55:20

開發(fā)技能代碼

2016-08-31 06:55:45

機(jī)器學(xué)習(xí)標(biāo)題誘餌

2020-05-06 09:15:40

Python Julia編程語言

2020-04-17 14:35:28

JuliaPython編程

2020-09-10 11:20:37

Python機(jī)器學(xué)習(xí)人工智能

2020-12-16 15:56:26

機(jī)器學(xué)習(xí)人工智能Python

2020-05-17 14:37:37

機(jī)器學(xué)習(xí)技術(shù)架構(gòu)

2018-09-13 08:19:50

Python Java 編程語言

2020-09-22 15:16:49

Python編程語言Julia

2024-02-05 09:30:10

推薦算法深度學(xué)習(xí)內(nèi)容過濾

2020-10-18 21:33:35

PythonJuliaSwift

2024-11-29 12:00:00

Python機(jī)器學(xué)習(xí)

2020-05-25 09:06:58

Julia語言Python

2019-08-13 10:53:04

2022-06-05 21:16:08

機(jī)器學(xué)習(xí)Python

2021-07-29 13:06:29

Python機(jī)器學(xué)習(xí)編程語言

2016-11-03 09:19:04

Python機(jī)器學(xué)習(xí)庫

2022-06-09 09:14:31

機(jī)器學(xué)習(xí)PythonJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號