Во время обучения нейронной сети, использующей обучение мини-пакета, следует ли создавать новую маску отсева для каждого образца в мини-пакете или эту же маску следует применять ко всем образцам в мини-пакете?Изменится ли что-нибудь, если в рекуррентных нейронных сетях используется вариационный выпад, что, на мой взгляд, означает использование одних и тех же масок (вход, выход, состояние) для всех временных шагов?
Я спрашиваю из-за DropoutWrapper
в Tensorflow.Использование variational_recurrent=False
, кажется, применяет маску для образца, в то время как variational_recurrent=True
, кажется, применяет ее для мини-пакета?Как я могу получить одну логику для обоих вариантов?
Вот некоторый код для воспроизведения вышеприведенного утверждения:
import tensorflow as tf
import numpy as np
tf.reset_default_graph()
tf.set_random_seed(0)
np.random.seed(0)
print("Tensorflow:", tf.__version__)
print("NumPy:", np.__version__)
variational_recurrent = False #True
n_input = 2
n_neurons = 1
output_keep_prob = 0.5
X0 = tf.placeholder(tf.float32, shape=(None, n_input))
X1 = tf.placeholder(tf.float32, shape=(None, n_input))
basic_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons,
activation=tf.nn.tanh)
drop_cell = tf.nn.rnn_cell.DropoutWrapper(basic_cell,
output_keep_prob=output_keep_prob,
variational_recurrent=variational_recurrent,
dtype=tf.float32)
output_seqs, states = tf.nn.static_rnn(drop_cell,
[X0, X1],
dtype=tf.float32)
# get respective mask tensors
g = tf.get_default_graph()
if variational_recurrent:
mask_0 = g.get_tensor_by_name("rnn/Floor:0")
mask_1 = g.get_tensor_by_name("rnn/Floor_1:0")
else:
mask_0 = g.get_tensor_by_name("rnn/dropout/Floor:0")
mask_1 = g.get_tensor_by_name("rnn/dropout_1/Floor:0")
init = tf.global_variables_initializer()
n_batch = 10
v_X0 = np.random.randn(n_batch, n_input)
v_X1 = np.random.randn(n_batch, n_input)
with tf.Session() as sess:
sess.run(init)
v_mask_0, v_mask_1, v_output_seqs = \
sess.run([mask_0, mask_1, output_seqs], feed_dict={X0: v_X0, X1: v_X1})
print("use_new_dropout:", use_new_dropout)
print("mask_0:", v_mask_0.flatten())
print("mask_1:", v_mask_1.flatten())
print("output_seq_0:", v_output_seqs[0].flatten())
print("output_seq_1:", v_output_seqs[1].flatten())
Использование variational_recurrent = False
дает, например,
Tensorflow: 1.11.0
NumPy: 1.15.2
use_new_dropout: True
mask_0: [1. 0. 0. 1. 0. 0. 1. 0. 0. 0.]
mask_1: [1. 1. 1. 1. 1. 1. 1. 0. 0. 0.]
output_seq_0: [ 1.4711434 0. -0. 0.42718613 0. 0.
0.7002963 0. 0. -0. ]
output_seq_1: [-0.1192586 0.30452126 -0.7493641 -0.07260141 1.8993055 1.2405635
-1.8763325 0. 0. -0. ]
в то время как variational_recurrent = True
производит:
use_new_dropout: True
mask_0: [0.]
mask_1: [0.]
output_seq_0: [ 0. -0. 0. 0. -0. -0. 0. -0. 0. 0.]
output_seq_1: [-0. 0. 0. 0. -0. -0. 0. -0. -0. -0.]