Keras 3 API 文档 / KerasCV / / 正则化层 / DropBlock2D 层

DropBlock2D 层

[源代码]

DropBlock2D

keras_cv.layers.DropBlock2D(rate, block_size, seed=None, **kwargs)

对输入特征应用 DropBlock 正则化。

DropBlock 是一种结构化 dropout,其中特征图中相邻区域的单元被一起丢弃。DropBlock 比 dropout 在卷积层上的效果更好,因为卷积层的激活单元在空间上是相关的。

建议在网络的后续层中,在 Conv -> BatchNorm -> Activation 块之后使用 DropBlock。例如,论文中提到在 ResNet 块的第三和第四组中使用 DropBlock。

参考

参数

  • rate: 浮点数。丢弃单元的概率。必须介于 0 和 1 之间。为了获得最佳结果,值应介于 0.05-0.25 之间。
  • block_size: 整数,或整数元组。要丢弃的块的大小。如果是整数,则将丢弃一个正方形块。如果是元组,则数字表示块的(高度,宽度)。必须大于 0,并且不应该大于输入特征图大小。论文作者对大小为 14x14xchannels 的输入特征使用 block_size=7。如果此值大于或等于输入特征图大小,您将遇到 nan 值。
  • seed: 整数。用作随机种子。
  • name: 字符串。层的名称。

示例

DropBlock2D 可以用在 keras.Model

# (...)
x = Conv2D(32, (1, 1))(x)
x = BatchNormalization()(x)
x = ReLU()(x)
x = DropBlock2D(0.1, block_size=7)(x)
# (...)

直接使用时,该层将在相邻区域中将一些输入归零,并对剩余的值进行归一化。

# Small feature map shape for demonstration purposes:
features = tf.random.stateless_uniform((1, 4, 4, 1), seed=[0, 1])

# Preview the feature map
print(features[..., 0])
# tf.Tensor(
# [[[0.08216608 0.40928006 0.39318466 0.3162533 ]
#   [0.34717774 0.73199546 0.56369007 0.9769211 ]
#   [0.55243933 0.13101244 0.2941643  0.5130266 ]
#   [0.38977218 0.80855536 0.6040567  0.10502195]]], shape=(1, 4, 4),
# dtype=float32)

layer = DropBlock2D(0.1, block_size=2, seed=1234) # Small size for
    demonstration
output = layer(features, training=True)

# Preview the feature map after dropblock:
print(output[..., 0])
# tf.Tensor(
#     [[[0.10955477 0.54570675 0.5242462  0.42167106]
#       [0.46290365 0.97599393 0.         0.        ]
#       [0.7365858  0.17468326 0.         0.        ]
#       [0.51969624 1.0780739  0.80540895 0.14002927]]],
#     shape=(1, 4, 4),
#     dtype=float32)

# We can observe two things:
# 1. A 2x2 block has been dropped
# 2. The inputs have been slightly scaled to account for missing values.

# The number of blocks dropped can vary, between the channels - sometimes no
# blocks will be dropped, and sometimes there will be multiple overlapping
# blocks. Let's present on a larger feature map:

features = tf.random.stateless_uniform((1, 4, 4, 36), seed=[0, 1])
layer = DropBlock2D(0.1, (2, 2), seed=123)
output = layer(features, training=True)

print(output[..., 0])  # no drop
# tf.Tensor(
#     [[[0.09136613 0.98085546 0.15265216 0.19690938]
#       [0.48835075 0.52433217 0.1661478  0.7067729 ]
#       [0.07383626 0.9938906  0.14309917 0.06882786]
#       [0.43242374 0.04158871 0.24213943 0.1903095 ]]],
#     shape=(1, 4, 4),
#     dtype=float32)

print(output[..., 9])  # drop single block
# tf.Tensor(
#     [[[0.14568178 0.01571623 0.9082305  1.0545396 ]
#       [0.24126057 0.86874676 0.         0.        ]
#       [0.44101703 0.29805306 0.         0.        ]
#       [0.56835717 0.04925899 0.6745584  0.20550345]]],
#     shape=(1, 4, 4),
#     dtype=float32)

print(output[..., 22])  # drop two blocks
# tf.Tensor(
#     [[[0.69479376 0.49463132 1.0627024  0.58349967]
#       [0.         0.         0.36143216 0.58699244]
#       [0.         0.         0.         0.        ]
#       [0.0315055  1.0117861  0.         0.        ]]],
#     shape=(1, 4, 4),
#     dtype=float32)

print(output[..., 29])  # drop two blocks with overlap
# tf.Tensor(
#     [[[0.2137237  0.9120104  0.9963533  0.33937347]
#       [0.21868704 0.44030213 0.5068906  0.20034194]
#       [0.         0.         0.         0.5915383 ]
#       [0.         0.         0.         0.9526224 ]]],
#     shape=(1, 4, 4),
#     dtype=float32)