Python - 【轉】命令式編程與符號編程


原文鏈接:https://zh.d2l.ai/chapter_computational-performance/hybridize.html
本文是對原文內容的摘取和擴展。

命令式編程(imperative style programs)

使用編程語句改變程序狀態,明確輸入變量,並根據程序邏輯逐步運算。

  • 易於理解:在Python里使用命令式編程時,大部分代碼編寫起來都很直觀。
  • 容易調試:可以很方便地進行單步跟蹤,獲取並分析所有中間變量,或者使用Python的調試工具。

雖然使用命令式編程很方便,但它的運行可能很慢,會存在重復調用函數和長時間保存變量值等問題,耗費內存。

示例:

def sample_add(a, b):
    return a + b


def sample_fancy_func(a, b, c, d):
    e = sample_add(a, b)
    f = sample_add(c, d)
    g = sample_add(e, f)
    return g


print(sample_fancy_func(1, 2, 3, 4))

運行結果:10

符號式編程(symbolic style programs)

通常在計算流程完全定義好后才被執行。

  • 更高效:在編譯的時候系統容易做更多優化。
  • 更容易移植:符號式編程可以將程序變成一個與Python無關的格式,從而可以使程序在非Python環境下運行,以避開Python解釋器的性能問題。

一般來說,符號式編程的程序需要下面3個步驟:

  1. 定義計算流程;
  2. 把計算流程編譯成可執行的程序;
  3. 給定輸入,調用編譯好的程序執行。

由於在編譯時系統能夠完整地獲取整個程序,因此有更多空間優化計算,不僅減少了函數調用,還節省了內存。
深度學習框架TensorFlow和Theano采用了符號式編程的方法。

示例:

def add_str():
    """僅以字符串形式返回計算流程"""
    return '''
def add(a, b):
    return a + b
'''


def fancy_func_str():
    """僅以字符串形式返回計算流程"""
    return '''
def fancy_func(a, b, c, d):
    e = add(a, b)
    f = add(c, d)
    g = add(e, f)
    return g
'''


def evoke_str():
    """僅以字符串形式返回計算流程"""
    return add_str() + fancy_func_str() + '''
print(fancy_func(1, 2, 3, 4))
'''


prog = evoke_str()
print(prog)
x = compile(prog, '', 'exec')  # 通過compile函數編譯完整的計算流程並運行
exec(x)

運行結果:

def add(a, b):
    return a + b

def fancy_func(a, b, c, d):
    e = add(a, b)
    f = add(c, d)
    g = add(e, f)
    return g

print(fancy_func(1, 2, 3, 4))

10

計算圖/符號圖(computation graph/symbolic graph)

符號式編程將計算過程抽象為一張計算圖(符號圖)來描述整個計算過程。

  • 易於描述計算過程,所有輸入節點、運算節點、輸出節點均符號化處理。
  • 通過建立輸入節點到輸出節點的傳遞閉包,從輸入節點出發,沿着傳遞閉包完成數值計算和數據流動,直到達到輸出節點。
  • 經過計算圖優化,以數據(計算)流方式完成,節省內存空間使用,計算速度快,但不適合程序調試,通常不用於編程語言中。

大多數符號式程序都會顯式地或是隱式地包含編譯步驟,將計算圖轉換為能被調用的函數,在代碼的最后一行才真正地進行運算。
也就是說,符號式程序清晰地將定義運算圖的步驟與編譯運算的步驟分割開來。

混合式編程

簡而言之,命令式編程容易理解和調試,命令語句基本沒有優化,按原有邏輯執行。
符號式編程涉及較多的嵌入和優化,不容易理解和調試,但運行速度有同比提升。

有沒有可能既得到命令式編程的好處,又享受符號式編程的優勢?
開發者們認為,用戶應該用純命令式編程進行開發和調試;
當需要產品級別的計算性能和部署時,用戶可以將大部分命令式程序轉換成符號式程序來運行。
深度學習框架caffe和mxnet采用了兩種編程模式混合的方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM