地震去噪新探索(二)——無監督卷積神經網絡調優實戰

“心中有歌,到處都是舞臺”。


地震去噪新探索(二)——無監督卷積神經網絡調優實戰


自從投入了自編碼的深度學習研究後,一路走來就是磕磕碰碰。

上一篇將地震信號用在了自編碼卷積神經網絡降噪(見《地震去噪新探索——無監督卷積神經網絡實戰》),結果那叫一個慘。如下面的圖示,上邊是噪聲圖,下邊是去噪圖:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


地震去噪新探索(二)——無監督卷積神經網絡調優實戰

從去噪效果來看,僅能獲取到一些支離破碎的有效信號,這是一張完全拿不出手的效果圖。

01屢敗屢戰的調優之旅

卷積神經網絡不是更能學習到特徵細節,性能更好嗎?為啥我做出來的效果如此之慘?

前期的參數設置包括:使用10000個28*28的訓練小塊,訓練epoch:5,學習率:0.001,優化器:tf.train.AdamOptimizer(learn).minimize(cost),LOSS函數:tf.nn.sigmoid_cross_entropy_with_logits(labels=targets_, logits=logits_),cost = tf.reduce_mean(loss)

網絡結構圖為:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


訓練損失曲線:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


1.歸一化的優化

慘不忍睹的LOSS訓練結果引起了我的注意。將收斂失敗這個問題拿到網上去尋找答案,有大神說這是歸一化沒做好。

那就先進行2項優化:


一是控制訓練樣本的取值範圍到(-1,1),使用方法是原值除以最大值的方法,就像這樣:

noisy_imgs=noisy_imgs/abs(noisy_imgs).max()

二是在訓練網絡的每個卷積後增加BN,就像這樣:

conv1 = tf.layers.conv2d(inputs_, 64, (3,3), padding='same', activation=tf.nn.relu)

conv1 = tf.layers.batch_normalization(conv1, training=True)

再進行訓練,效果不明顯,還是沒有收斂。

另外,很多歸一化的方法是將取值範圍集中在(0,1),使用這樣的算法:

imgs= (imgs-imgs.min())/(imgs.max()-imgs.min())#歸一化到[0,1]

結果證明對於地震數據完全沒法訓練,曲線是這樣的:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


2.學習函數的調整

“一計不成,再生一計”。

我想到了對優化器和LOSS函數進行改動。

在神經網絡學習中,損失函數的作用是度量神經網絡的輸出的預測值,計算與實際值之間的差距,可以說是實現學習的關鍵函數。常見的損失函數包括:最小二乘損失函數、交叉熵損失函數、迴歸中使用的smooth L1損失函數等。

而優化函數的原理是:把損失值從神經網絡的最外層傳遞到最前面,實現反向傳播學習,這是神經網絡實現持續學習達到收斂的關鍵。如最基礎的梯度下降算法包括:隨機梯度下降算法,批量梯度下降算法,帶動量的梯度下降算法,Adagrad,Adadelta,Adam等。

那我就先從優化器函數入手吧。

既然學習率為0.001無法收斂,那試試0.0001呢。結果還真收斂了,如下圖:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


那預測效果如何呢?結果是一塌糊塗,連基本特徵都學習不到,如下圖:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


這是怎麼回事呢?我的理解是學習率太高,就會讓神經網絡學習到更細粒度的特徵,而失去了我們想要的特徵。就相當於研究一個人的特徵,我們通常是從五官、體型等方面來看,但如果從細胞的角度的去學習,那就無法還原人的外貌特徵了。

另外,設置為0.0005也好不了多少。

那改動LOSS函數能不能起作用呢?

比如改為softmax_cross_entropy_with_logits,像這樣:

loss = tf.nn.softmax_cross_entropy_with_logits(labels=targets_, logits=logits_)

結果是無法學習,如下圖:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


3.其它的嘗試

兩板斧過去,還沒有看到變好的跡象。我沒有放棄,我開始思考為啥原程序訓練Mnist效果都如此好,換到地震數據訓練就不行了呢?

我想到了訓練樣本數據是不是有問題。我又進行了以下嘗試:

一是調整訓練樣本數據的尺寸:有128*128,40*40,32*32,28*28等。

二是對樣本數據進行截斷:地震數據不是異常值多,偏離度大嗎。我就篩選數據集中的90%區間,區間外面的進行截斷,再進行歸一化。這樣數據分佈就均勻多了。

三是擴充採樣數據來源,從不同的數據源採樣。是不是數據更豐富,訓練效果就會改觀呢?

……

你可以想象做這些實驗有多麼瑣碎和繁雜,然而現實卻是如此的無情。最後結局都是一個——失敗,根本拿不出一個像樣的效果,連一個較為清晰的結果都沒有。

02 柳暗花明,找到了一個方法

“山窮水復疑無路,柳暗花明又一村”。

在持續N天被現實按在地上摩擦後,我痛定思痛:到底解決的方向在哪裡?

在現有這個無可救藥的神經網絡中,提高學習率可以收斂,但是無法學習到有效特徵。降低學習率可以學習到有效特徵但是無法收斂,也就是說無法持續優化的學習。整個成了一個悖論。

面對這張醜陋的預測結果圖,我意識到可能是網絡結構本身出了問題。很有可能是網絡對圖片數據學習有效,對地震數據學習就是不行。

在翻閱了其它研究者的論文後,我逐步聚焦到了一個結構——解碼。我的程序在這部分是使用卷積核上採樣的結構。像這樣:

conv4 = tf.image.resize_nearest_neighbor(conv3, (8,8))

conv4 = tf.layers.conv2d(conv4, 32, (3,3), padding='same', activation=tf.nn.relu)

而其它地震論文結構卻包含了一個我沒有的結構——反捲積。

如果我也使用反捲積,甚至就只有卷積和反捲積這種最簡單的自編碼結構,效果如何呢?像這樣的結構:

x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)

x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)

x = Conv2DTranspose(32, (3,3), padding='same', activation='relu', kernel_initializer='glorot_normal')(x)#反捲積

x = Conv2DTranspose(32, (3,3), padding='same', activation='relu', kernel_initializer='glorot_normal')(x)

decoded = Conv2DTranspose(1, (1,1), padding='same', activation='tanh', kernel_initializer='glorot_normal')(x)

結果是令人驚豔的。下圖是收斂的效果,很快就能夠收斂:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


訓練的效果更好。以下分別是原圖,噪聲圖和去噪效果圖:

地震去噪新探索(二)——無監督卷積神經網絡調優實戰


地震去噪新探索(二)——無監督卷積神經網絡調優實戰


地震去噪新探索(二)——無監督卷積神經網絡調優實戰


可以看到,上面噪聲幾乎淹沒了有效信號。然後通過訓練,僅僅5個迭代,就較好的分離出了有效信號。

03 下一步計劃

“既然選擇了遠方 便只顧風雨兼程”。

看來反捲積是是解決地震學習的一把鑰匙。下一步我將研究反捲積能適應地震處理的原因,然後繼續進行優化和創新,並使用其它算法做對比實驗,爭取做出更好的效果。

如果喜歡請點“贊”,如果小夥伴對程序感興趣,可以聯繫我獲取。


分享到:


相關文章: