下面列出的是源码部分:
tf.nn.dropout(
x, #一个tensor
keep_prob, #决定每个元素被保留的概率,(0,1]
noise_shape=None, #暂留问题
seed=None,
name=None){
......
noise_shape = _get_noise_shape(x, noise_shape)#若noise_shape保留默认值,则返回x的形状
# uniform [keep_prob, 1.0 + keep_prob)
random_tensor = keep_prob #假设keep_prob为0.5
random_tensor += random_ops.random_uniform ( noise_shape , seed=seed , dtype = x.dtype) #本来默认均匀分布返回值范围为[0,1),加上keep_prob后返回值范围为[0.5,1.5)
# 0. if [keep_prob, 1.0) and 1. if [1.0, 1.0 + keep_prob)
binary_tensor = math_ops.floor(random_tensor) #向下取整
ret = math_ops.div(x, keep_prob) * binary_tensor #对binary_tensor中取值为0的直接丢弃,取值为1的扩大为原来的1/keep_prob倍
return ret
}
总是有刨根问底的习惯,想要知道它到底是怎么实现的,所以去看了源码,并且在上面都做了注释,更好的方便理解。
下面看个简单的代码:
import tensorflow as tf
x=tf.constant([[1.0,2.0,3.0],[1.0,2.0,3.0]])
x_dropout = tf.nn.dropout(
x,
keep_prob=0.5,
)
with tf.Session() as sess:
print(sess.run(x_dropout))
结果如下:[[ 2. 4. 0.]
[ 2. 0. 0.]]
可以看到这里有3个元素成为原来的2倍,有3个元素被丢弃,而对这个起到关键作用的就是源码里的random_uniform()和floor()
总结:
1、在保持noise_shape默认值的条件下,x中的元素独立的安排保留或丢弃,丢弃的直接等于0,保留的则扩大为原来的1/keep_prob倍;
2、Keep_prob=1时,random_tensor的范围为[1,2),通过向下取整后都为1,所以所有元素都被保留;
3、如果keep_prob在(0,1]范围外,则会引起ValueError。
遗留问题:noise_shape这个参数虽然很少使用,但还是想搞明白,等搞清楚了再补充!