Dropout這個(gè)概念已經(jīng)推出4年了紊选,它的詳細(xì)描述見(jiàn)論文〉蓝海可是呢兵罢,它仿佛是個(gè)猶抱琵琶半遮面的美女,難以捉摸W仪稀卖词!許多文獻(xiàn)都對(duì)dropout有過(guò)描述,但解釋的含糊不清吏夯,這里呢此蜈,我也不打算解釋清楚,只是通過(guò)tensorflow來(lái)看一看dropout的運(yùn)行機(jī)理噪生。
文章分兩部分裆赵,第一部分介紹tensorflow中的dropout函數(shù),第二部分是我的思考
一跺嗽、tf.nn.dropout函數(shù)
首先看官方函數(shù)定義:
def dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
輸入是:
- x战授,你自己的訓(xùn)練、測(cè)試數(shù)據(jù)等
- keep_prob桨嫁,dropout概率
- ……植兰,其它參數(shù)不咋用,不介紹了
輸出是:
- A Tensor of the same shape of x
然后我們看看官方API是怎么說(shuō)這個(gè)函數(shù)的:
With probability keep_prob, outputs the input element scaled up by 1 / keep_prob, otherwise outputs 0. The scaling is so that the expected sum is unchanged.
注意璃吧,輸出的非0元素是原來(lái)的 “1/keep_prob” 倍楣导!說(shuō)了這么多,下面給一個(gè)程序例子:
import tensorflow as tf
dropout = tf.placeholder(tf.float32)
x = tf.Variable(tf.ones([10, 10]))
y = tf.nn.dropout(x, dropout)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
print sess.run(y, feed_dict = {dropout: 0.4})
運(yùn)行的結(jié)果如下:
[[ 0. 0. 2.5 2.5 0. 0. 2.5 2.5 2.5 2.5]
[ 0. 2.5 2.5 2.5 2.5 2.5 0. 2.5 0. 2.5]
[ 2.5 0. 0. 2.5 0. 0. 2.5 0. 2.5 0. ]
[ 0. 2.5 2.5 2.5 2.5 0. 0. 2.5 0. 2.5]
[ 0. 0. 0. 0. 0. 0. 0. 0. 2.5 2.5]
[ 2.5 2.5 2.5 0. 2.5 0. 0. 2.5 2.5 2.5]
[ 0. 2.5 2.5 2.5 0. 2.5 2.5 0. 0. 0. ]
[ 0. 2.5 0. 2.5 0. 0. 2.5 2.5 0. 0. ]
[ 2.5 2.5 2.5 2.5 2.5 0. 0. 2.5 0. 0. ]
[ 2.5 0. 0. 0. 0. 0. 2.5 2.5 0. 2.5]]
分析一下運(yùn)行結(jié)果:
- 輸入和輸出的tensor的shape果然是一樣的
- 不是0的元素都變成了原來(lái)的 “1/keep_prob” 倍
特點(diǎn)分析完畢畜挨,小總結(jié)一下筒繁,dropout這個(gè)概念看起來(lái)好高大上,然而在程序中實(shí)現(xiàn)竟然如此簡(jiǎn)單巴元!說(shuō)白了毡咏,tensorflow中的dropout就是:使輸入tensor中某些元素變?yōu)?,其它沒(méi)變0的元素變?yōu)樵瓉?lái)的1/keep_prob大小务冕!
二血当、關(guān)于dropout的吐槽
首先引用此篇博文的話:
個(gè)人總結(jié):個(gè)人感覺(jué)除非是大型網(wǎng)絡(luò)幻赚,才采用dropout禀忆,不然我感覺(jué)自己在一些小型網(wǎng)絡(luò)上臊旭,訓(xùn)練好像很是不爽。之前搞一個(gè)比較小的網(wǎng)絡(luò)箩退,搞人臉特征點(diǎn)定位的時(shí)候离熏,因?yàn)橛?xùn)練數(shù)據(jù)不夠,怕過(guò)擬合戴涝,于是就采用dropout滋戳,最后感覺(jué)好像訓(xùn)練速度好慢,從此就對(duì)dropout有了偏見(jiàn)啥刻,感覺(jué)訓(xùn)練過(guò)程一直在波動(dòng)奸鸯,很是不爽。
然后可帽,我就自己試了試娄涩,看看小型網(wǎng)絡(luò)中dropout效果到底怎么樣,程序片段如下:
def inference(img, dropout=1.0):
fc1 = activation(tf.nn.bias_add(tf.matmul(img, W_fc1), b_fc1))
# dropout
fc1_dropout = tf.nn.dropout(fc1, dropout)
fc2 = tf.nn.bias_add(tf.matmul(fc1_dropout, W_fc2), b_fc2)
return fc2
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(inference(X, dropout), y_)
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
網(wǎng)絡(luò)很簡(jiǎn)單映跟,形如 784-30-10 的一個(gè)網(wǎng)絡(luò)蓄拣,只不過(guò)在輸出層前用dropout處理了一下,訓(xùn)練的數(shù)據(jù)是MNIST的手寫(xiě)數(shù)據(jù)集努隙,然后你猜怎么著球恤?采用dropout以后的訓(xùn)練精度不升反降,后來(lái)我把網(wǎng)絡(luò)隱藏層改成100個(gè)神經(jīng)元荸镊,結(jié)果依舊咽斧,看來(lái),我的網(wǎng)絡(luò)還是太小了贷洲,真的如上面那篇博客所說(shuō)收厨,dropout用不好的話,真是個(gè)累贅优构!