成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python對陣Julia:機器學習實例

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

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

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

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

線性PAVA

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

Julia代碼采用的是最為簡單的PAVA表達,不摻雜任何花哨的內容與修飾;@inbounds宏的作用是客觀比較Cython的執行效果并關閉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的行數與Cython代碼基本相當,而且在結構上可能更為簡潔(通過顯式復合type ActiveState實現)、旨在維持給定主動雙重變量中的參數。Active Set會將重復代碼拆分為獨立函數,從而由LLVM對其實現內聯——這一點很難借由Cython中的任何參數實現。

Julia中的檢索機制也會對算法作出一定程度的精簡。

  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 

性能表現

可以看到,在與Cython實例進行比對時,我們發現即使是同樣的算法在Julia中的平均執行速度也會更快。


[點擊擴大]

對于上述Active Set實例,Julia在處理回歸計算時的表現都能實現5倍到300倍的速度提升。

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

這樣的結果證明,Julia在性能敏感型機器學習應用領域具有顯著吸引力。

大家可以點擊此處了解更多關于上述性能測試結果的獲取方法。

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

責任編輯:林師授 來源: 51CTO
相關推薦

2019-12-16 14:53:44

機器學習人工智能計算機

2018-12-12 09:33:58

編程語言機器學習代碼

2022-01-13 15:55:20

開發技能代碼

2020-04-17 14:35:28

JuliaPython編程

2016-08-31 06:55:45

機器學習標題誘餌

2020-05-06 09:15:40

Python Julia編程語言

2020-09-10 11:20:37

Python機器學習人工智能

2020-12-16 15:56:26

機器學習人工智能Python

2020-05-17 14:37:37

機器學習技術架構

2018-09-13 08:19:50

Python Java 編程語言

2020-09-22 15:16:49

Python編程語言Julia

2024-02-05 09:30:10

推薦算法深度學習內容過濾

2020-10-18 21:33:35

PythonJuliaSwift

2019-08-13 10:53:04

2020-05-25 09:06:58

Julia語言Python

2024-11-29 12:00:00

Python機器學習

2022-03-11 08:00:00

編程語言JuliaPython

2020-11-06 17:34:30

Python開發工具

2022-06-05 21:16:08

機器學習Python

2021-07-29 13:06:29

Python機器學習編程語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美高清 | 欧美激情久久久 | 久久免费大片 | 国产黄色在线观看 | 中文字幕中文字幕 | 国产一区在线免费观看视频 | www.干| 亚洲成人三级 | www.成人在线视频 | av在线免费观看网站 | 在线欧美亚洲 | 成人免费视频一区二区 | 偷拍自拍第一页 | 欧美一区免费 | 久久免费视频1 | 国产精品一区二区免费看 | 国产精品毛片一区二区在线看 | 91啪亚洲精品 | 久日精品 | 男女爱爱网站 | 亚洲欧美日韩精品久久亚洲区 | 亚洲欧美日韩电影 | 亚洲精品视频在线观看免费 | 国产精品一区二区视频 | 麻豆91精品91久久久 | 亚州精品天堂中文字幕 | 亚洲3级 | 91在线资源 | 国产资源网 | 成人高潮片免费视频欧美 | 国产精品一区久久久 | 国产精品视频一二三区 | 久久高清精品 | 青草久久免费视频 | 欧美1区 | 日韩三级免费网站 | 久久久久久久久99 | 日本精品在线观看 | 色精品| 国产精品99久久久久久宅男 | 国产精品一区二区免费看 |