以下代码有何不同?
使用tf.contrib.rnn.DropoutWrapper
enc_cell = tf.contrib.rnn.MultiRNNCell([tf.contrib.rnn.DropoutWrapper(tf.contrib.rnn.BasicLSTMCell(rnn_sizes, output_keep_prob=1-keep_prob) for _ in range(num_layers)])
_, encoding_state = tf.nn.dynamic_rnn(enc_cell, rnn_inputs, dtype=tf.float32)
使用tf.nn.droupout
enc_cell = tf.contrib.rnn.MultiRNNCell([tf.contrib.rnn.BasicLSTMCell(rnn_size) for _ in range(num_layers)])
_, encoding_state = tf.nn.dynamic_rnn(enc_cell, tf.nn.dropout(rnn_inputs, 1 - keep_prob), dtype=tf.float32)
我们从tf.nn.dynamic_rnn获得的状态数似乎有所不同。 len(编码状态)在tf.nn.dropout中更大。
将非常感谢您的解释。
谢谢。
答案 0 :(得分:1)
我认为辍学只能掩盖一端,就像您对rnn_inputs所做的那样。 DropoutWrapper可以屏蔽多端,就像lstm单元一样。
答案 1 :(得分:0)
两者背后的想法是相同的,它是辍学:网络"下降" (即不使用)预测中的一些节点。这意味着在训练期间减少模型的能力以防止过度拟合。由于辍学,网络学会了不要完全依赖特定节点进行预测。
两种方法的区别在于:
tf.nn.droput
是执行droput到给定输入张量的通用函数。查看文档:
计算辍学率。
概率为
keep_prob
,输出元素按比例放大1 /keep_prob
,否则输出0.缩放是预期的 总和不变。
tf.contrib.rnn.DropoutWrapper
或tf.nn.rnn_cell.DropoutWrapper
是一个特定类,用于定义在单元格的输入和输出处应用了压降的递归神经网络单元格。查看文档:
运算符将dropout添加到给定单元格的输入和输出。
特别是,它uses tf.nn.droput
来屏蔽单元格,状态和输出的输入。
两段代码之间的区别在于,当您使用tf.nn.dropout
时,您只屏蔽第一层的输入。在包装器案例中,每层图层,您正在屏蔽单元格的输出(因为您只提供输出概率)