pytorch命令式和符号式混合编程
命令式和符號(hào)式編程
命令式編程
命令式編程使用編程語句改變程序狀態(tài),如下:
def add(a, b):return a + bdef fancy_func(a, b, c, d):e = add(a, b)f = add(c, d)g = add(e, f)return gfancy_func(1, 2, 3, 4) # 10在運(yùn)行語句e = add(a, b)時(shí),Python會(huì)做加法運(yùn)算并將結(jié)果存儲(chǔ)在變量e中,從而令程序的狀態(tài)發(fā)生改變。類似地,后面的兩條語句f = add(c, d)和g = add(e, f)會(huì)依次做加法運(yùn)算并存儲(chǔ)變量。
雖然使用命令式編程很方便,但
- 它的運(yùn)行可能很慢
- 即使fancy_func函數(shù)中的add是被重復(fù)調(diào)用的函數(shù),Python也會(huì)逐一執(zhí)行這3條函數(shù)調(diào)用語句。
- 需要保存變量e和f的值直到fancy_func中所有語句執(zhí)行結(jié)束。這是因?yàn)樵趫?zhí)行e = add(a, b)和f = add(c, d)這2條語句之后我們并不知道變量e和f是否會(huì)被程序的其他部分使用。
符號(hào)式編程
與命令式編程不同,符號(hào)式編程通常在計(jì)算流程完全定義好后才被執(zhí)行。多個(gè)深度學(xué)習(xí)框架,如Theano和TensorFlow,都使用了符號(hào)式編程。通常,符號(hào)式編程的程序需要下面3個(gè)步驟:
- 定義計(jì)算流程;
- 把計(jì)算流程編譯成可執(zhí)行的程序;
- 給定輸入,調(diào)用編譯好的程序執(zhí)行。
下面我們用符號(hào)式編程重新實(shí)現(xiàn)之前的命令式編程代碼。
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) y = compile(prog, '', 'exec') exec(y)以上定義的3個(gè)函數(shù)都僅以字符串的形式返回計(jì)算流程。最后,我們通過compile函數(shù)編譯完整的計(jì)算流程并運(yùn)行。
由于在編譯時(shí)系統(tǒng)能夠完整地獲取整個(gè)程序,因此有更多空間優(yōu)化計(jì)算。例如,編譯的時(shí)候可以將程序改寫成print((1 + 2) + (3 + 4)),甚至直接改寫成print(10)。這樣不僅減少了函數(shù)調(diào)用,還節(jié)省了內(nèi)存。
對(duì)比
對(duì)比這兩種編程方式,我們可以看到以下兩點(diǎn)。
- 命令式編程更方便。當(dāng)我們?cè)赑ython里使用命令式編程時(shí),大部分代碼編寫起來都很直觀。同時(shí),命令式編程更容易調(diào)試。這是因?yàn)槲覀兛梢院芊奖愕孬@取并打印所有的中間變量值,或者使用Python的調(diào)試工具。
- 符號(hào)式編程更高效并更容易移植。一方面,在編譯的時(shí)候系統(tǒng)容易做更多優(yōu)化;另一方面,符號(hào)式編程可以將程序變成一個(gè)與Python無關(guān)的格式,從而可以使程序在非Python環(huán)境下運(yùn)行,以避開Python解釋器的性能問題。
大部分深度學(xué)習(xí)框架在命令式編程和符號(hào)式編程之間二選一。例如,Theano和受其啟發(fā)的后來者TensorFlow使用了符號(hào)式編程,Chainer和它的追隨者PyTorch使用了命令式編程,而Gluon則采用了混合式編程的方式。
PyTorch僅僅采用了命令式編程
總結(jié)
以上是生活随笔為你收集整理的pytorch命令式和符号式混合编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汉诺塔java程序_Java编写一个汉诺
- 下一篇: (pytorch-深度学习)包含并行连结