1
本文作者: 楊曉凡 | 2017-09-30 17:13 |
雷鋒網(wǎng) AI 科技評論按:不管是一般的編程還是機器學(xué)習(xí),凡是計算機中的數(shù)據(jù)都是以一定的數(shù)據(jù)格式表示的。但有些情況下數(shù)據(jù)格式會帶來明顯的限制,造成計算結(jié)果的異常。
不過在 OpenAI 的研究人員們看來,這種“計算結(jié)果的異?!笨梢猿蔀榻o神經(jīng)網(wǎng)絡(luò)帶來新的可能性的落腳點。在這篇博文中,他們就介紹了一種異常的來源以及如何運用,還取得了不錯的效果。雷鋒網(wǎng) AI 科技評論把文章編譯如下。
之前已經(jīng)有證據(jù)表明,深度線性網(wǎng)絡(luò)如果用浮點數(shù)值運算實現(xiàn)的話,結(jié)果是不完全線性的,會展現(xiàn)出一些非線性的計算特點。在這項研究中,OpenAI的研究人員們使用了進化計算的策略,在線性網(wǎng)絡(luò)中找到帶來非線性特點的參數(shù),希望能夠幫助一些疑難問題。
神經(jīng)網(wǎng)絡(luò)是由許多線性層和其后的非線性層堆疊起來形成的,常見的非線性函數(shù)有 tanh 或者 ReLU。如果沒有這些非線性的部分,連續(xù)的幾個線性層在數(shù)學(xué)理論上應(yīng)當(dāng)?shù)刃в趩为氁粋€線性層。所以浮點數(shù)的計算具有足夠的非線性程度,以至于這樣也能形成一個可訓(xùn)練的深度神經(jīng)網(wǎng)絡(luò),這就有點出乎意料。
計算機中使用的數(shù)字并不是理想的數(shù)學(xué)化的對象,而是用有限位的0和1近似地表示的。計算機中常用的一類數(shù)學(xué)對象表示方法就是浮點數(shù)。每個浮點格式的數(shù)據(jù)都可以分為小數(shù)和指數(shù)兩個部分。在 IEEE 的32位浮點數(shù)標(biāo)準(zhǔn)中,其中的23位用來表示小數(shù)部分,8位用來表示指數(shù)部分,還有一位用來表示符號。
根據(jù)浮點數(shù)的定義和其中使用的2進制位的表示范圍限制,它所能表示的最小非零數(shù)字就是(二進制)1.000...0 x 2^-126,這里把這個值稱為 min。然而,可表示的數(shù)字里面第二小的是 1.000...01 x 2^-126,這個數(shù)字可以用 min + 0.000...01 x 2^-126 表示??梢悦黠@看到, min 和第二小的數(shù)之間的差距,只有 min 和0之間差距的 2^-20 那么大,還不到一百萬分之一倍。在32位浮點數(shù)中,如果要需要表示的數(shù)字比 min 還要接近0,那么這個數(shù)就會直接被表示為0。由于這種“下溢”(underflow)的影響,所有在0附近進行的浮點數(shù)運算都會變成非線性的。
“非規(guī)格化數(shù)”(denormal numbers)就不受這些限制的影響,不過某些計算硬件上是不支持這種數(shù)據(jù)格式的。雖然 GPU 和 cuBLAS 默認(rèn)都是可以使用非規(guī)格化數(shù)的,TensorFlow 在構(gòu)建模型的時候卻是默認(rèn)把非規(guī)格化數(shù)選項關(guān)閉的(對于 ftz=true 標(biāo)志集)。這就意味著,在TensorFlow中編寫的所有非矩陣乘法操作都帶有隱含的非線性(假設(shè)參與計算的數(shù)量級在 e^-38 附近)。
所以,雖然總體來說任何一個數(shù)字的真實值和用浮點格式表示以后的值之間的區(qū)別都很小,但是當(dāng)這個數(shù)字非常接近0的時候,這一部分近似誤差就會變得非常顯著。
這件事的后果就是我們熟悉的數(shù)學(xué)規(guī)律不再適用,接下來就會有很多奇怪的事情發(fā)生。比如 (a + b) x c 就不再和 a x c + b x c 相等。
舉例說明,令 a = 0.4 x min ,b = 0.5 x min ,c = 1/ min
那么, (a+b) x c = (0.4 x min + 0.5 x min ) x 1 / min = (0 + 0) x 1 / min = 0
然而 (a x c) + (b x c) = 0.4 x min / min + 0.5 x min x 1 / min = 0.9
再舉一個例子,這次令 a = 2.5 x min, b = -1.6 x min , c = 1 x min
那么 (a+b) + c = (0) + 1 x min = min
然而 (b+c) + a = (0 x min) + 2.5 x min = 2.5 x min
在這樣的數(shù)量級上,連最基本的結(jié)合律都變得非線性了!
OpenAI 的研究人員們很想知道這種固有的非線性可否作為計算中的非線性得到利用,如果可行的話就可以讓深度線性網(wǎng)絡(luò)實現(xiàn)非線性的計算操作。其中的挑戰(zhàn)是,用到的現(xiàn)代微分庫通常都對如此小尺度下的非線性視而不見。這樣以來,就非常困難、甚至沒有可能通過反向傳播的方法訓(xùn)練一個神經(jīng)網(wǎng)絡(luò)來利用這些非線性。
OpenAI 的研究人員們決定使用進化策略(evolution strategies)來估計梯度,不再依靠微分一類的方法。通過進化策略,他們確實能夠把32位浮點數(shù)在零值附近的非線性行為加以利用,發(fā)展為計算性的非線性。以 MNIST 數(shù)據(jù)集的訓(xùn)練為例,用反向傳播算法訓(xùn)練的深度線性網(wǎng)絡(luò)可以達到94%的訓(xùn)練準(zhǔn)確率和92%的測試準(zhǔn)確率;相比之下,同一個線性神經(jīng)網(wǎng)絡(luò)可以達到超過99%的訓(xùn)練準(zhǔn)確率和96.7%的測試準(zhǔn)確只,就是用進化策略訓(xùn)練得到的,同時保證激活權(quán)重都足夠小,在32位浮點數(shù)的非線性行為能夠產(chǎn)生影響的范圍內(nèi)即可。這種訓(xùn)練表現(xiàn)的提升就是因為進化策略發(fā)現(xiàn)并充分利用了32位浮點數(shù)表示中的非線性。這些強有力的非線性行為可以讓任意一個層根據(jù)低層特征的非線性組合產(chǎn)生全新的特征。這個網(wǎng)絡(luò)的結(jié)構(gòu)如下:
x = tf.placeholder(dtype=tf.float32, shape=[batch_size,784])
y = tf.placeholder(dtype=tf.float32, shape=[batch_size,10])
w1 = tf.Variable(np.random.normal(scale=np.sqrt(2./784),size=[784,512]).astype(np.float32))
b1 = tf.Variable(np.zeros(512,dtype=np.float32))
w2 = tf.Variable(np.random.normal(scale=np.sqrt(2./512),size=[512,512]).astype(np.float32))
b2 = tf.Variable(np.zeros(512,dtype=np.float32))
w3 = tf.Variable(np.random.normal(scale=np.sqrt(2./512),size=[512,10]).astype(np.float32))
b3 = tf.Variable(np.zeros(10,dtype=np.float32))
params = [w1,b1,w2,b2,w3,b3]
nr_params = sum([np.prod(p.get_shape().as_list()) for p in params])
scaling = 2**125
def get_logits(par):
h1 = tf.nn.bias_add(tf.matmul(x , par[0]), par[1]) / scaling
h2 = tf.nn.bias_add(tf.matmul(h1, par[2]) , par[3] / scaling)
o = tf.nn.bias_add(tf.matmul(h2, par[4]), par[5]/ scaling)*scaling
return o
除了 MNIST 之外,OpenAI 的研究人員們相信未來還會有更多有意思的實驗把這種思想拓展到循環(huán)神經(jīng)網(wǎng)絡(luò),或者把非線性計算運用在提升復(fù)雜語言建模和翻譯之類的機器學(xué)習(xí)任務(wù)表現(xiàn)中。他們非常期待可以和廣大研究人員們一起探索其中的可能性。
via OpenAI Blog,雷鋒網(wǎng) AI 科技評論編譯
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。