最近在做一個(gè)文本檢測(cè)的項(xiàng)目,在訓(xùn)練的過(guò)程中遇到了很?chē)?yán)重的梯度爆炸情況,今天就來(lái)談?wù)勌荻缺ㄔ趺唇鉀Q。
首先我們要清楚,為什么會(huì)產(chǎn)生梯度爆炸。要知道就目前來(lái)說(shuō),我們一般都認(rèn)為深層的神經(jīng)網(wǎng)絡(luò)會(huì)比淺層的神經(jīng)網(wǎng)絡(luò)的表現(xiàn)要好,所以在處理一些較為復(fù)雜的任務(wù)的時(shí)候,人們往往會(huì)使用更深層次的神經(jīng)網(wǎng)絡(luò),而現(xiàn)在的大部分神經(jīng)網(wǎng)絡(luò)的權(quán)重更新都要依靠反向傳播。
那么,問(wèn)題來(lái)了。要知道權(quán)重的更新的公式是這樣的:
對(duì)于每個(gè)變量的更新,都要求梯度,也就是求鏈?zhǔn)狡珜?dǎo)。假如,我們想象一下,我們的模型處在一個(gè)很陡的陡坡上,那么在求梯度的時(shí)候,在網(wǎng)絡(luò)層上出現(xiàn)了指數(shù)型的遞增,也就是說(shuō),梯度爆炸了。
那么具體上是怎么樣的呢?我們來(lái)看下面這張圖:
可以看到,上面是我輸出的每一步的損失函數(shù)的值,損失值在指數(shù)型地增加。nan是not a number的意思,它表示無(wú)窮大的數(shù)或者無(wú)意義的數(shù)。遇到這個(gè)問(wèn)題的時(shí)候,我第一反應(yīng)是:是不是我學(xué)習(xí)率太大了。然后我調(diào)小了學(xué)習(xí)率,發(fā)現(xiàn)情況有所改善,但是到最后還是出現(xiàn)的梯度爆炸。然后我又思考,會(huì)不會(huì)是我網(wǎng)絡(luò)結(jié)構(gòu)有問(wèn)題啊,為了驗(yàn)證這問(wèn)題,我把batch size調(diào)為了1,固定輸入一張圖片,發(fā)現(xiàn)也是收斂到一定程度也出現(xiàn)了梯度爆炸的情況。那么我可以斷定了,是由于網(wǎng)絡(luò)層數(shù)過(guò)多導(dǎo)致的梯度爆炸的問(wèn)題。
問(wèn)題找到了,那我面臨了兩個(gè)選擇:一是降低網(wǎng)絡(luò)層數(shù),二是做梯度裁剪??紤]到了數(shù)據(jù)的復(fù)雜性,我選擇了后者。好,那就來(lái)說(shuō)說(shuō)梯度裁剪是什么?如何做梯度裁剪。
梯度裁剪
梯度裁剪是指在一個(gè)變量計(jì)算的梯度過(guò)大的情況下,人為地將梯度控制在一定的范圍以內(nèi)。
那直接來(lái)看一下代碼實(shí)現(xiàn)。
optimizer = tf.train.GradientDescentOptimizer(learning_rate)params = tf.trainable_variables()gradients = tf.gradients(loss, params)clipped_gradients, norm = tf.clip_by_global_norm(gradients, clip_norm)optimizer_op = optimizer.apply_gradients(zip(clipped_gradients, params), global_step)
你只要設(shè)置里面的clip_norm就可以了,那么設(shè)置多少合適呢?
t_list在這里是所有梯度的張量,然后可以看下它是怎么算的。如果global_norm
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4733瀏覽量
100417 -
梯度
+關(guān)注
關(guān)注
0文章
30瀏覽量
10300
原文標(biāo)題:項(xiàng)目實(shí)戰(zhàn) | 實(shí)戰(zhàn)中如何解決梯度爆炸的問(wèn)題
文章出處:【微信號(hào):gh_a204797f977b,微信公眾號(hào):深度學(xué)習(xí)實(shí)戰(zhàn)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論