在嵌入层的输出上使用 Dropout 会更改数组值,为什么?
Using Dropout on output of embedding layer changes array values, Why?
观察嵌入层有和没有丢弃的输出表明数组中的值被替换为 0。但是为什么数组的其他值随之改变?
以下是我的模型:-
input = Input(shape=(23,))
model = Embedding(input_dim=n_words, output_dim=23, input_length=23)(input)
model = Dropout(0.2)(model)
model = Bidirectional(LSTM(units=LSTM_N, return_sequences=True, recurrent_dropout=0.1))(model)
out = TimeDistributed(Dense(n_tags, activation="softmax"))(model) # softmax output layer
model = Model(input, out)
从经过训练的模型构建模型 2,输入作为输入层,输出作为 Dropout(0.2) 的输出。 -
from keras import backend as K
model2 = K.function([model.layers[0].input , K.learning_phase()],
[model.layers[2].output] )
dropout = model2([X_train[0:1] , 1])[0]
nodrop = model2([X_train[0:1] , 0])[0]
打印第一个包含 dropout 和 no dropout 的数组:
dropout[0][0]
输出-
array([ 0. , -0. , -0. , -0.04656423, -0. ,
0.28391626, 0.12213208, -0.01187495, -0.02078421, -0. ,
0.10585815, -0. , 0.27178472, -0.21080771, 0. ,
-0.09336889, 0.07441022, 0.02960865, -0.2755439 , -0.11252255,
-0.04330419, -0. , 0.04974075], dtype=float32)
-
nodrop[0][0]
输出-
array([ 0.09657606, -0.06267098, -0.00049554, -0.03725138, -0.11286845,
0.22713302, 0.09770566, -0.00949996, -0.01662737, -0.05788678,
0.08468652, -0.22405024, 0.21742778, -0.16864617, 0.08558936,
-0.07469511, 0.05952817, 0.02368692, -0.22043513, -0.09001804,
-0.03464335, -0.05152775, 0.0397926 ], dtype=float32)
一些值被替换为 0 ,同意,但为什么其他值被更改了?
由于嵌入输出具有意义并且对于每个单词都是唯一的,如果通过应用 dropout 更改这些输出,那么 在嵌入层之后应用 dropout 是否正确?
Note- I have used "learning_phase" as 0 and 1 for testing(nodropout)
and training(droput) respectively.
这就是 dropout 正则化的工作原理。应用 dropout 后,值除以保持概率(在本例中为 0.8)。
当您使用 dropout 时,该函数接收将神经元变为零的概率作为输入,例如 0.2,这意味着它有 0.8 的机会保留任何给定的神经元。因此,剩余的值将乘以 1/(1-0.2)。
这称为"inverted dropout technique",这样做是为了确保激活的预期值保持不变。否则,在不使用 dropout 的情况下,推理时预测会出错。
你会注意到你的 dropout 是 0.2,并且在你应用 dropout 之后你所有的值都乘以了 0.8。
看看如果我将你的第二个输出除以第一个会发生什么:
import numpy as np
a = np.array([ 0. , -0. , -0. , -0.04656423, -0. ,
0.28391626, 0.12213208, -0.01187495, -0.02078421, -0. ,
0.10585815, -0. , 0.27178472, -0.21080771, 0. ,
-0.09336889, 0.07441022, 0.02960865, -0.2755439 , -0.11252255,
-0.04330419, -0. , 0.04974075])
b = np.array([ 0.09657606, -0.06267098, -0.00049554, -0.03725138, -0.11286845,
0.22713302, 0.09770566, -0.00949996, -0.01662737, -0.05788678,
0.08468652, -0.22405024, 0.21742778, -0.16864617, 0.08558936,
-0.07469511, 0.05952817, 0.02368692, -0.22043513, -0.09001804,
-0.03464335, -0.05152775, 0.0397926 ])
print(b/a)
[ inf inf inf 0.79999991 inf 0.80000004
0.79999997 0.8 0.8000001 inf 0.8 inf
0.80000001 0.80000001 inf 0.79999998 0.79999992 0.8
0.80000004 0.8 0.79999995 inf 0.8 ]
观察嵌入层有和没有丢弃的输出表明数组中的值被替换为 0。但是为什么数组的其他值随之改变?
以下是我的模型:-
input = Input(shape=(23,))
model = Embedding(input_dim=n_words, output_dim=23, input_length=23)(input)
model = Dropout(0.2)(model)
model = Bidirectional(LSTM(units=LSTM_N, return_sequences=True, recurrent_dropout=0.1))(model)
out = TimeDistributed(Dense(n_tags, activation="softmax"))(model) # softmax output layer
model = Model(input, out)
从经过训练的模型构建模型 2,输入作为输入层,输出作为 Dropout(0.2) 的输出。 -
from keras import backend as K
model2 = K.function([model.layers[0].input , K.learning_phase()],
[model.layers[2].output] )
dropout = model2([X_train[0:1] , 1])[0]
nodrop = model2([X_train[0:1] , 0])[0]
打印第一个包含 dropout 和 no dropout 的数组:
dropout[0][0]
输出-
array([ 0. , -0. , -0. , -0.04656423, -0. ,
0.28391626, 0.12213208, -0.01187495, -0.02078421, -0. ,
0.10585815, -0. , 0.27178472, -0.21080771, 0. ,
-0.09336889, 0.07441022, 0.02960865, -0.2755439 , -0.11252255,
-0.04330419, -0. , 0.04974075], dtype=float32)
-
nodrop[0][0]
输出-
array([ 0.09657606, -0.06267098, -0.00049554, -0.03725138, -0.11286845,
0.22713302, 0.09770566, -0.00949996, -0.01662737, -0.05788678,
0.08468652, -0.22405024, 0.21742778, -0.16864617, 0.08558936,
-0.07469511, 0.05952817, 0.02368692, -0.22043513, -0.09001804,
-0.03464335, -0.05152775, 0.0397926 ], dtype=float32)
一些值被替换为 0 ,同意,但为什么其他值被更改了? 由于嵌入输出具有意义并且对于每个单词都是唯一的,如果通过应用 dropout 更改这些输出,那么 在嵌入层之后应用 dropout 是否正确?
Note- I have used "learning_phase" as 0 and 1 for testing(nodropout) and training(droput) respectively.
这就是 dropout 正则化的工作原理。应用 dropout 后,值除以保持概率(在本例中为 0.8)。
当您使用 dropout 时,该函数接收将神经元变为零的概率作为输入,例如 0.2,这意味着它有 0.8 的机会保留任何给定的神经元。因此,剩余的值将乘以 1/(1-0.2)。
这称为"inverted dropout technique",这样做是为了确保激活的预期值保持不变。否则,在不使用 dropout 的情况下,推理时预测会出错。
你会注意到你的 dropout 是 0.2,并且在你应用 dropout 之后你所有的值都乘以了 0.8。
看看如果我将你的第二个输出除以第一个会发生什么:
import numpy as np
a = np.array([ 0. , -0. , -0. , -0.04656423, -0. ,
0.28391626, 0.12213208, -0.01187495, -0.02078421, -0. ,
0.10585815, -0. , 0.27178472, -0.21080771, 0. ,
-0.09336889, 0.07441022, 0.02960865, -0.2755439 , -0.11252255,
-0.04330419, -0. , 0.04974075])
b = np.array([ 0.09657606, -0.06267098, -0.00049554, -0.03725138, -0.11286845,
0.22713302, 0.09770566, -0.00949996, -0.01662737, -0.05788678,
0.08468652, -0.22405024, 0.21742778, -0.16864617, 0.08558936,
-0.07469511, 0.05952817, 0.02368692, -0.22043513, -0.09001804,
-0.03464335, -0.05152775, 0.0397926 ])
print(b/a)
[ inf inf inf 0.79999991 inf 0.80000004
0.79999997 0.8 0.8000001 inf 0.8 inf
0.80000001 0.80000001 inf 0.79999998 0.79999992 0.8
0.80000004 0.8 0.79999995 inf 0.8 ]