繁体   English   中英

关于 DNN model 中 Dropout 层和 Batch Normalization 层的问题

[英]Question About Dropout Layer and Batch Normalization Layer in DNN model

我对 Dropout 层和 Batch 标准化层有一些疑问。 基本上,我制作了一个带有 Dropout 层和 Batch 归一化层的简单 DNN 结构,并对其进行训练就可以了。

以 DNN model 的简单结构为例:

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(10, activation='relu', input_shape=[11]),
    layers.Dropout(0.3),
    layers.BatchNormalization(),
    layers.Dense(8, activation='relu'),
    layers.Dropout(0.3),
    layers.BatchNormalization(),
    layers.Dense(6, activation='relu'),
    layers.Dropout(0.3),
    layers.BatchNormalization(),
    layers.Dense(1,activation='softmax'),
])

model.compile(
    optimizer='adam',
    loss='mae',
)

history = model.fit(
    X_train, y_train,
    validation_data=(X_valid, y_valid),
    batch_size=256,
    epochs=100,
    verbose=0,
)

但是现在我想在我的自定义预测模型中使用所有层的训练模型的权重和偏差(忘记另一种方式)。

# Predictions for test
test_logits_1 = tf.matmul(tf_test_dataset, weights_1) + biases_1
test_relu_1 = tf.nn.relu(test_logits_1)

test_logits_2 = tf.matmul(test_relu_1, weights_2) + biases_2
test_relu_2 = tf.nn.relu(test_logits_2)

test_logits_3 = tf.matmul(test_relu_2, weights_3) + biases_3
test_relu_3 = tf.nn.relu(test_logits_3)

test_logits_4 = tf.matmul(test_logits_3 , weights_4) + biases_4
test_prediction = tf.nn.softmax(test_relu_4)

现在问题来了:必须在预测model中添加dropout层和batch normalized层,batch size? 如果是,那么为什么要这样做以及如何提取图层的所有细节并将它们用于我的自定义预测 model?

@博士。 史努比感谢您指出 BatchNormalization 具有参数,但据我所知,它们不是基于我从文档和少量研究中得出的归一化权重(归一化的权重)。

文档说明了以下内容(下面引用了文本),并且根据描述,很明显betagamma值是可训练的变量,与 tensorflow 的 output 相符。

在训练期间(即使用 fit() 或使用参数 training=True 调用层/模型时),层使用当前批次输入的均值和标准差对其 output 进行归一化。 也就是说,对于每个被归一化的通道,该层返回 (batch - mean(batch)) / (var(batch) + epsilon) * gamma + beta,其中:

  • epsilon 是一个小常数(可配置为构造函数参数的一部分)
  • gamma 是一个学习的缩放因子(初始化为 1),可以通过将 scale=False 传递给构造函数来禁用它。
  • beta 是一个学习的偏移因子(初始化为 0),可以通过将 center=False 传递给构造函数来禁用它。

在此处输入图像描述

但这并不是故事的结局,因为 model 总结表明参数数量超过了betagamma所包含的参数数量。

在此处输入图像描述

这里可以观察到因子4 ,即 BatchNormalization 层中的参数数量是该层操作的输入形状的 4 倍。

这些附加参数是moving_meanmoving_variance值,可以在下面的output中看到

在此处输入图像描述

回到 OP 最初的问题和关注点,“我应该担心哪些参数?”,推理所需的参数是Moving_meanMoving_variancebetagamma值。

使用这些值/参数的方式很容易从我在这里再次引用的文档中推断出来-

在推理过程中(即使用 evaluate() 或 predict() 或使用参数 training=False(这是默认值)调用层/模型时,层使用均值和标准差的移动平均值对其 output 进行归一化。它在训练期间看到的批次。也就是说,它返回 (batch - self.moving_mean) / (self.moving_var + epsilon) * gamma + beta。

self.moving_mean 和 self.moving_var 是不可训练的变量,每次在训练模式下调用层时都会更新,如下所示:

  • 移动均值 = 移动均值 * 动量 + 均值(批次)*(1 - 动量)
  • 移动变量 = 移动变量 * 动量 + var(batch) * (1 - 动量)

因此,该层仅在对具有与推理数据相似统计数据的数据进行训练后,才会在推理期间对其输入进行归一化。

因此,假设每个 BatchNormalization 层都可以使用moving_meanmoving_variancebetagamma值,我认为在第一次激活后需要添加以下代码 -

# epsilon is just to avoid ZeroDivisionError, so the default value should be okay
test_BN_1 = (test_relu_1 - moving_mean_1) / (moving_var_1 + epsilon_1) * gamma_1 + beta_1

编辑:

结果证明文档似乎是错误的,但根据我可以从 github 上的源代码中推断出的内容,实施似乎是正确的。

如果您按照以下链接,您将看到BatchNormalization class 这里https://github.com/keras-team/keras/blob/master/keras/layers/normalization.py#L1227call方法实际上是done by keras backend normalization function batch_normalization here https://github.com/keras-team/keras/blob/35146d00b44ca645fbf4ad0b007faa07632c6f9e/keras/backend.py#L2963 . 后端 function 文档字符串似乎与参考文件中提到的内容和您发布的图片一致。

这意味着,您应该只使用方差的平方根。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM