在 CNN 中实现 dropout 层的正确方法是什么?

What is the proper way to implement a dropout layer in a CNN?

这个过程是否正确?

我的意图是在连接后添加一个丢失层,但为此我需要将连接层的输出调整为适当的 shape (样本、时间步长、通道),因此从(None, 4096) to (None, 1, 4096)扩展维度,从而在输出后撤消操作。

如果您打算使用 SpatialDropout1D 层,它必须接收 3D 张量 (batch_size, time_steps, features),因此在将张量馈送到 dropout 层之前向其添加额外维度是一种选择是完全合法的。 不过请注意,在您的情况下,您可以同时使用 SpatialDropout1DDropout:

import tensorflow as tf

samples = 2
timesteps = 1
features = 5
x = tf.random.normal((samples, timesteps, features))
s = tf.keras.layers.SpatialDropout1D(0.5)
d = tf.keras.layers.Dropout(0.5)

print(s(x, training=True))
print(d(x, training=True))
tf.Tensor(
[[[-0.5976591  1.481788   0.         0.         0.       ]]

 [[ 0.        -4.6607018 -0.         0.7036132  0.       ]]], shape=(2, 1, 5), dtype=float32)
tf.Tensor(
[[[-0.5976591  1.481788   0.5662646  2.8400114  0.9111476]]

 [[ 0.        -0.        -0.         0.7036132  0.       ]]], shape=(2, 1, 5), dtype=float32)

我觉得SpatialDropout1D层在CNN层之后最合适

在 tensorflow 2.7.0 中,您可以只使用 keepdims=True 作为 GlobalAveragePooling2D 层的参数,而不是显式添加新维度。

示例:

def TestModel():
  # specify the input shape
  in_1 = tf.keras.layers.Input(shape = (256,256,3))
  in_2 = tf.keras.layers.Input(shape = (256,256,3))

  x1 = tf.keras.layers.Conv2D(64, (3,3))(in_1)
  x1 = tf.keras.layers.LeakyReLU()(x1)
  x1 = tf.keras.layers.GlobalAveragePooling2D(keepdims = True)(x1)

  x2 = tf.keras.layers.Conv2D(64, (3,3))(in_2)
  x2 = tf.keras.layers.LeakyReLU()(x2)
  x2 = tf.keras.layers.GlobalAveragePooling2D(keepdims = True)(x2)
 
  x = tf.keras.layers.concatenate([x1,x2])
  x = tf.keras.layers.SpatialDropout2D(0.2)(x)
  x = tf.keras.layers.Dense(1000)(x)

  # create the model
  model = tf.keras.Model(inputs=(in_1,in_2), outputs=x)

  return model

#Testcode
model = TestModel()
model.summary()
tf.keras.utils.plot_model(model, show_shapes=True, expand_nested=False, show_dtype=True, to_file="model.png")

如果最后要挤的话,还是可以的