2012年,在通過防止特征探測器的共適應來改進神經網絡論文中引入了dropout,它是一種流行的正則化技術,工作非常好。我不會深入了解它為什么這么好的細節(jié),你可以在別的地方讀到。
像任何其他正則化技術一樣,如果我們有一個過度擬合的網絡,dropout才有意義,這在上一節(jié)中我們訓練的net5網絡顯然是這樣。 重要的是要記住,讓你的網絡訓練得很好,首先過擬合,然后正則化。
要在Lasagne中使用dropout,我們將在現(xiàn)有圖層之間添加DropoutLayer圖層,并為每個圖層指定退出概率。 這里是我們新網的完整定義。我在這些行的末尾添加了一個#!,用于區(qū)分和net5的不同。
net6 = NeuralNet(
layers=[
('input', layers.InputLayer),
('conv1', layers.Conv2DLayer),
('pool1', layers.MaxPool2DLayer),
('dropout1', layers.DropoutLayer), # !
('conv2', layers.Conv2DLayer),
('pool2', layers.MaxPool2DLayer),
('dropout2', layers.DropoutLayer), # !
('conv3', layers.Conv2DLayer),
('pool3', layers.MaxPool2DLayer),
('dropout3', layers.DropoutLayer), # !
('hidden4', layers.DenseLayer),
('dropout4', layers.DropoutLayer), # !
('hidden5', layers.DenseLayer),
('output', layers.DenseLayer),
],
input_shape=(None, 1, 96, 96),
conv1_num_filters=32, conv1_filter_size=(3, 3), pool1_pool_size=(2, 2),
dropout1_p=0.1, # !
conv2_num_filters=64, conv2_filter_size=(2, 2), pool2_pool_size=(2, 2),
dropout2_p=0.2, # !
conv3_num_filters=128, conv3_filter_size=(2, 2), pool3_pool_size=(2, 2),
dropout3_p=0.3, # !
hidden4_num_units=500,
dropout4_p=0.5, # !
hidden5_num_units=500,
output_num_units=30, output_nonlinearity=None,
update_learning_rate=theano.shared(float32(0.03)),
update_momentum=theano.shared(float32(0.9)),
regression=True,
batch_iterator_train=FlipBatchIterator(batch_size=128),
on_epoch_finished=[
AdjustVariable('update_learning_rate', start=0.03, stop=0.0001),
AdjustVariable('update_momentum', start=0.9, stop=0.999),
],
max_epochs=3000,
verbose=1,
)
我們的網路現(xiàn)在已經大到可以讓Python報一個“超過最大遞歸限制”錯誤了,所以為了避免這一點,我們最好增加python的遞歸限制。
import sys
sys.setrecursionlimit(10000)
X, y = load2d()
net6.fit(X, y)
import cPickle as pickle
with open('net6.pickle', 'wb') as f:
pickle.dump(net6, f, -1)
看一下我們現(xiàn)在的訓練,我們注意到訓練速度又變慢了,以為添加了dropout,這是不出意料的效果。然而,整個網絡的表現(xiàn)事實上超過了net5:
Epoch | Train loss | Valid loss | Train / Val
--------|--------------|--------------|---------------
50 | 0.004619 | 0.005198 | 0.888566
100 | 0.004369 | 0.004182 | 1.044874
250 | 0.003821 | 0.003577 | 1.068229
500 | 0.002598 | 0.002236 | 1.161854
1000 | 0.001902 | 0.001607 | 1.183391
1500 | 0.001660 | 0.001383 | 1.200238
2000 | 0.001496 | 0.001262 | 1.185684
2500 | 0.001383 | 0.001181 | 1.171006
3000 | 0.001306 | 0.001121 | 1.164100
過擬合也似乎沒有那么糟糕。雖然我們必須小心這些數(shù)字:訓練錯誤和驗證錯誤之間的比率現(xiàn)在有一個稍微不同的意義,因為訓練錯誤評估與遺漏,而驗證錯誤評估沒有遺漏。訓練錯誤的更有價值的值是
from sklearn.metrics import mean_squared_error
print mean_squared_error(net6.predict(X), y)
# prints something like 0.0010073791
在我們以前的沒有dropout的模型中,訓練上的誤差為0.000373。 所以不僅我們的dropout網表現(xiàn)略微好一點,它的過擬合也比我們以前的模型少得多。 這是個好消息,因為這意味著當我們使網絡更大(更具表現(xiàn)力)時,我們可以期望更好的性能。 這就是我們將嘗試下一步:我們將最后兩個隱藏層中的單位數(shù)從500增加到1000。我們需要修改這些行:
net7 = NeuralNet(
# ...
hidden4_num_units=1000, # !
dropout4_p=0.5,
hidden5_num_units=1000, # !
# ...
)
相比于沒有dropout的網絡,改進效果更加明顯:
Epoch | Train loss | Valid loss | Train / Val
--------|--------------|--------------|---------------
50 | 0.004756 | 0.007043 | 0.675330
100 | 0.004440 | 0.005321 | 0.834432
250 | 0.003974 | 0.003928 | 1.011598
500 | 0.002574 | 0.002347 | 1.096366
1000 | 0.001861 | 0.001613 | 1.153796
1500 | 0.001558 | 0.001372 | 1.135849
2000 | 0.001409 | 0.001230 | 1.144821
2500 | 0.001295 | 0.001146 | 1.130188
3000 | 0.001195 | 0.001087 | 1.099271
有一點過擬合,但效果著實不錯。我的感覺是,如果繼續(xù)增加訓練次數(shù),模型效果會變得更棒。試一下:
net12 = NeuralNet(
# ...
max_epochs=10000,
# ...
)
Epoch | Train loss | Valid loss | Train / Val
--------|--------------|--------------|---------------
50 | 0.004756 | 0.007027 | 0.676810
100 | 0.004439 | 0.005321 | 0.834323
500 | 0.002576 | 0.002346 | 1.097795
1000 | 0.001863 | 0.001614 | 1.154038
2000 | 0.001406 | 0.001233 | 1.140188
3000 | 0.001184 | 0.001074 | 1.102168
4000 | 0.001068 | 0.000983 | 1.086193
5000 | 0.000981 | 0.000920 | 1.066288
6000 | 0.000904 | 0.000884 | 1.021837
7000 | 0.000851 | 0.000849 | 1.002314
8000 | 0.000810 | 0.000821 | 0.985769
9000 | 0.000769 | 0.000803 | 0.957842
10000 | 0.000760 | 0.000787 | 0.966583
現(xiàn)在你是dropout魔力的見證者了。:-)
讓我們比較一下到目前為止我們訓練過的網絡:
Name Description Epochs Train loss Valid loss
net1?single hidden?400?0.002244?0.003255?
net2?convolutions?1000?0.001079?0.001566?
net3?augmentation?3000?0.000678?0.001288?
net4?mom + lr adj?1000?0.000496?0.001387?
net5?net4 + augment?2000?0.000373?0.001184?
net6?net5 + dropout?3000?0.001306?0.001121?
net7?net6 + epochs?10000?0.000760?0.000787
評論
查看更多