8

我对带有noise_shape 参数的Keras 函数Dropout 有疑问。

问题一:

如果您的输入具有形状 (batch_size, timesteps, features) 并且您希望所有时间步长的 dropout 掩码都相同,您可以使用 noise_shape=(batch_size, 1, features) 是什么意思?添加的好处是什么这个论点?

这是否意味着将被丢弃的神经元数量在时间步长上是相同的?这意味着在每个时间步 t,会有 n 个神经元被丢弃?

问题 2: 创建模型时是否必须在 noise_shape 中包含“batch_size”?--> 看下面的例子。

假设我有一个形状为 (10000, 1, 100, 2) --> (数据数、通道、时间步长、特征数)的多元时间序列数据。

然后我创建批次大小为 64 --> (64, 1, 100, 2)

如果我想创建一个带有 dropout 的 CNN 模型,我使用 Keras 函数式 API:

inp = Input([1, 100, 2])
conv1 = Conv2D(64, kernel_size=(11,2), strides(1,1),data_format='channels_first')(inp)
max1 = MaxPooling2D((2,1))(conv1)
max1_shape = max1._keras_shape
drop1 = Dropout((0.1, noise_shape=[**?**, max1._keras_shape[1], 1, 1]))

因为 max1 层的输出形状应该是 (None, 64, 50, 1),而我不能将 None 分配给问号(对应于 batch_size)

我想知道我应该如何应对这种情况?我应该只使用 (64, 1, 1) 作为噪声形状吗?或者我应该定义一个名为“batch_size”的变量,然后将它传递给这个参数,比如 (batch_size, 64, 1, 1)?

4

2 回答 2

6

问题一:

我认为这有点像一个 numpy 广播。

想象一下,你有 2 个批次,有 3 个时间步长和 4 个特征(这是一个小例子,便于展示):(2, 3, 4)

如果您使用 (2, 1, 4) 的噪声形状,每个批次将有自己的 dropout 掩码,将应用于所有时间步长。

假设这些是形状 (2, 3, 4) 的权重:

array([[[  1,   2,   3,   4],
        [  5,   6,   7,   8],
        [ 10,  11,  12,  13]],

       [[ 14,  15,  16,  17],
        [ 18,  19,  20,  21],
        [ 22,  23,  24,  25]]])

这将是随机的 noise_shape (2, 1, 4) (1 就像保持,0 就像关闭它):

array([[[ 1,  1,  1,  0]],

       [[ 1,  0,  0,  1]]])

所以你有这两种噪声形状(对于每一批)。然后它将沿时间步长轴进行广播。

array([[[ 1,  1,  1,  0],
        [ 1,  1,  1,  0],
        [ 1,  1,  1,  0]],

       [[ 1,  0,  0,  1],
        [ 1,  0,  0,  1],
        [ 1,  0,  0,  1]]])

并应用于权重:

array([[[  1,   2,   3,   0],
        [  5,   6,   7,   0],
        [ 10,  11,  12,   0]],

       [[ 14,   0,   0,  17],
        [ 18,   0,   0,  21],
        [ 22,   0,   0,  25]]])

问题2:

老实说,我不确定你的第二个问题。

编辑: 您可以做的是采用输入形状的第一个维度,应该是 batch_size,正如在这个github 问题中提出的那样:

import tensorflow as tf

...

batch_size = tf.shape(inp)[0]
drop1 = Dropout((0.1, noise_shape=[batch_size, max1._keras_shape[1], 1, 1]))

如您所见,我在 tensorflow 后端。不知道 theano 是否也有这些问题,如果有的话,您也许可以使用等效的 theano 形状来解决它。

于 2018-01-11T14:39:38.987 回答
1

下面是示例代码,看看到底发生了什么。输出日志是不言自明的。

如果您对动态感到困扰,只需按以下方式制作to的batch_size第一个元素,即noise_shapeNone

dl1 = tk.layers.Dropout(0.2, noise_shape=[_batch_size, 1, _num_features])

dl1 = tk.layers.Dropout(0.2, noise_shape=[None, 1, _num_features])

import tensorflow as tf
import tensorflow.keras as tk
import numpy as np

_batch_size = 5
_time_steps = 2
_num_features = 3
input = np.random.random((_batch_size, _time_steps, _num_features))
dl = tk.layers.Dropout(0.2)
dl1 = tk.layers.Dropout(0.2, noise_shape=[_batch_size, 1, _num_features])

out = dl(input, training=True).numpy()
out1 = dl1(input, training=True).numpy()


for i in range(_batch_size):
    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>", i)
    print("input")
    print(input[i])
    print("out")
    print(out[i])
    print("out1")
    print(out1[i])

输出是:

>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0
input
[[0.53853024 0.80089701 0.64374258]
 [0.06481775 0.31187039 0.5029061 ]]
out
[[0.6731628  1.0011213  0.        ]
 [0.08102219 0.38983798 0.6286326 ]]
out1
[[0.6731628  0.         0.8046782 ]
 [0.08102219 0.         0.6286326 ]]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1
input
[[0.70746014 0.08990712 0.58195288]
 [0.75798534 0.50140453 0.04914242]]
out
[[0.8843252  0.11238389 0.        ]
 [0.9474817  0.62675565 0.        ]]
out1
[[0.         0.11238389 0.        ]
 [0.         0.62675565 0.        ]]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2
input
[[0.85253707 0.55813084 0.70741476]
 [0.98812977 0.21565134 0.67909392]]
out
[[1.0656713  0.69766355 0.8842684 ]
 [0.         0.26956415 0.        ]]
out1
[[1.0656713  0.69766355 0.8842684 ]
 [1.2351623  0.26956415 0.84886736]]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3
input
[[0.9837272  0.3504008  0.37425778]
 [0.67648931 0.74456052 0.6229444 ]]
out
[[1.2296591  0.438001   0.        ]
 [0.84561163 0.93070066 0.7786805 ]]
out1
[[0.         0.438001   0.46782222]
 [0.         0.93070066 0.7786805 ]]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4
input
[[0.45599217 0.80992091 0.04458478]
 [0.12214568 0.09821599 0.51525869]]
out
[[0.5699902  1.0124011  0.        ]
 [0.1526821  0.         0.64407337]]
out1
[[0.5699902  1.0124011  0.05573097]
 [0.1526821  0.12276999 0.64407337]]
于 2022-01-04T19:13:22.860 回答