在 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 层之前向其添加额外维度是一种选择是完全合法的。
不过请注意,在您的情况下,您可以同时使用 SpatialDropout1D
或 Dropout
:
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")
如果最后要挤的话,还是可以的
这个过程是否正确?
我的意图是在连接后添加一个丢失层,但为此我需要将连接层的输出调整为适当的 shape (样本、时间步长、通道),因此从(None, 4096) to (None, 1, 4096)
扩展维度,从而在输出后撤消操作。
如果您打算使用 SpatialDropout1D
层,它必须接收 3D 张量 (batch_size, time_steps, features)
,因此在将张量馈送到 dropout 层之前向其添加额外维度是一种选择是完全合法的。
不过请注意,在您的情况下,您可以同时使用 SpatialDropout1D
或 Dropout
:
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")
如果最后要挤的话,还是可以的