tf.nn.dropout

tf.nn.dropout函数

首先看官方函数定义:

def dropout(x, keep_prob, noise_shape=None, seed=None, name=None)

输入是:

  • x,你自己的训练、测试数据等
  • keep_prob,dropout概率
  • ……,其它参数不咋用,不介绍了

输出是:

  • A Tensor of the same shape of x

然后我们看看官方API是怎么说这个函数的:

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元素是原来的 “1/keep_prob” 倍!说了这么多,下面给一个程序例子:

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})

运行的结果如下:

[[ 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]]

分析一下运行结果:

  • 输入和输出的tensor的shape果然是一样的
  • 不是0的元素都变成了原来的 “1/keep_prob” 倍

特点分析完毕,小总结一下,dropout这个概念看起来好高大上,然而在程序中实现竟然如此简单!说白了,tensorflow中的dropout就是:使输入tensor中某些元素变为0,其它没变0的元素变为原来的1/keep_prob大小

dropout 一般是用来消除过拟合的

在机器学习中可能会存在过拟合的问题,表现为在训练集上表现很好,但在测试集中表现不如训练集中的那么好。

tf.nn.dropout_第1张图片

图中黑色曲线是正常模型,绿色曲线就是overfitting模型。尽管绿色曲线很精确的区分了所有的训练数据,但是并没有描述数据的整体特征,对新测试数据的适应性较差。

一般用于解决过拟合的方法有增加权重的惩罚机制,比如L2正规化,但在本处我们使用tensorflow提供的dropout方法,在训练的时候, 我们随机忽略掉一些神经元和神经联结 , 是这个神经网络变得”不完整”. 用一个不完整的神经网络训练一次.
到第二次再随机忽略另一些, 变成另一个不完整的神经网络. 有了这些随机 drop 掉的规则, 我们可以想象其实每次训练的时候, 我们都让每一次预测结果都不会依赖于其中某部分特定的神经元. 像l1, l2正规化一样, 过度依赖的 W , 也就是训练参数的数值会很大, l1, l2会惩罚这些大的 参数. Dropout 的做法是从根本上让神经网络没机会过度依赖.

 

def add_layer(inputs, in_size, out_size, activation_function=None):
    """
    添加层
    :param inputs: 输入数据
    :param in_size: 输入数据的列数
    :param out_size: 输出数据的列数
    :param activation_function: 激励函数
    :return:
    """

    # 定义权重,初始时使用随机变量,可以简单理解为在进行梯度下降时的随机初始点,这个随机初始点要比0值好,因为如果是0值的话,反复计算就一直是固定在0中,导致可能下降不到其它位置去。
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    # 偏置shape为1行out_size列
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    # 建立神经网络线性公式:inputs * Weights + biases,我们大脑中的神经元的传递基本上也是类似这样的线性公式,这里的权重就是每个神经元传递某信号的强弱系数,偏置值是指这个神经元的原先所拥有的电位高低值
    Wx_plus_b = tf.matmul(inputs, Weights) + biases
    # 调用dropout功能
    Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob)

    if activation_function is None:
        # 如果没有设置激活函数,则直接就把当前信号原封不动地传递出去
        outputs = Wx_plus_b
    else:
        # 如果设置了激活函数,则会由此激活函数来对信号进行传递或抑制
        outputs = activation_function(Wx_plus_b)
    return outputs

 

你可能感兴趣的:(机器学习)