【问题标题】:Normalization of input data in KerasKeras 中输入数据的规范化
【发布时间】:2019-09-19 08:13:52
【问题描述】:

DL 中的一项常见任务是将输入样本标准化为零均值和单位方差。可以使用如下代码“手动”执行规范化:

mean = np.mean(X, axis = 0)
std = np.std(X, axis = 0)
X = [(x - mean)/std for x in X]

但是,除了正在训练的 Keras 模型之外,还必须保持均值和标准值左右,以标准化测试数据。既然 mean 和 std 是可学习的参数,也许 Keras 可以学习它们?像这样的:

m = Sequential()
m.add(SomeKerasLayzerForNormalizing(...))
m.add(Conv2D(20, (5, 5), input_shape = (21, 100, 3), padding = 'valid'))
... rest of network
m.add(Dense(1, activation = 'sigmoid'))

我希望你明白我的意思。

【问题讨论】:

    标签: keras deep-learning normalization


    【解决方案1】:

    也许您可以使用sklearn.preprocessing.StandardScaler 来扩展您的数据, 此对象允许您将缩放参数保存在对象中, 然后你可以在你的模型中使用 Mixin 类型输入,比如说:

    1. 你的模型
    2. [param1_scaler, param2_scaler]

    这是一个链接https://www.pyimagesearch.com/2019/02/04/keras-multiple-inputs-and-mixed-data/

    https://keras.io/getting-started/functional-api-guide/

    【讨论】:

      【解决方案2】:

      BatchNormalization,它学习输入的均值和标准差。我没有尝试将它用作网络的第一层,但据我了解,它应该做的事情与您正在寻找的非常相似。

      【讨论】:

      • 批范数层不标准化(即均值 = 0,标准差 = 1)特征,它们将特征线性转换为任意尺度,这是学习的。这使得它与问题所问的内容大不相同。
      • 来自文档:“批量归一化应用了一种转换,使平均输出接近 0,输出标准偏差接近 1。”它不会对每个样本进行标准化,但据我了解,这不是所要求的。
      • 继续阅读该文档页面。你引用了第一步。随后的步骤涉及比例因子 gamma 和偏移量 beta。这需要使用scale=False, center=False 明确停用。
      • Denziloe 的评论可能更友善,但他对如何改进您的回答有很好的建议。
      • 在这一点上,我建议删除这个答案,因为Wenuka's answer 说出了这个人所说的一切等等。
      【解决方案3】:

      BatchNormalization 添加为第一层,它按预期工作,但与 OP 的示例不完全相同。可以看详细解释here

      OP 的示例和批量标准化都在推理过程中使用输入数据的学习均值和标准差。但是 OP 的示例使用了一个简单的平均值,为每个训练样本赋予相同的权重,而 BatchNormalization 层使用移动平均值,赋予最近看到的样本比旧样本更大的权重。

      重要的是,批量标准化在训练期间的工作方式与 OP 的示例不同。在训练期间,该层使用当前批次输入的均值和标准差对其输出进行归一化。

      第二个区别是 OP 的代码产生的输出均值为 0,标准差为 1。 Batch Normalization 会学习输出的均值和标准差,从而改善整个网络的损失。要获得 OP 示例的行为,应使用参数 scale=Falsecenter=False 初始化 Batch Normalization。

      【讨论】:

      • BatchNormalization 确实 not 行为与 OP 的示例完全相同。 OP 的代码学习平均值和标准偏差,批量归一化层没有学习参数。相反,他们计算每个 mini-batch 的平均值和标准差,或者计算通过网络的最近样本的运行平均值。这种区别很重要——例如,它是StyleGAN2 相对于StyleGAN1 的主要改进之一。
      • 从技术上讲,批量标准化在前馈而不是反馈期间“学习”,并在推理期间继续“学习”。 “权重(移动统计)的更新是基于模型的前向传播,而不是梯度计算的结果。”
      • @JosiahYoder 您是正确的,批次规范与 OP 的问题不同,但是您关于“批次规范层没有学习参数”的说法是错误的;批量规范层学习其输出数据的尺度(平均 beta 和标准差 gamma)。事实上,这是批量规范与 OP 所描述的显着不同的主要原因之一。
      • @Denziloe 我明白你的意思。我一定一直在使用设置scale=Falsecenter=False 的网络。
      • @Wenuka 您能否更新您的答案以反映我们的 cmets?那么请通过@提及我让我知道。
      【解决方案4】:

      现在有一个用于此目的的 Keras 层,Normalization。在撰写本文时,它位于实验模块中,keras.layers.experimental.preprocessing

      https://keras.io/api/layers/preprocessing_layers/core_preprocessing_layers/normalization/

      在您使用它之前,您调用图层的adapt 方法,并使用您想要从中导出比例的数据X(即平均值和标准差)。一旦你这样做了,规模是固定的(它在训练期间不会改变)。然后,无论何时使用模型(在训练和预测期间),都会将比例应用于输入。

      from keras.layers.experimental.preprocessing import Normalization
      
      norm_layer = Normalization()
      norm_layer.adapt(X)
      model = keras.Sequential()
      model.add(norm_layer)
      # ... Continue as usual.
      

      【讨论】:

      • 这一层目前处于非常早期的草稿格式。而且我不确定我是否喜欢在fit 之前添加adapt 方法。但是,它似乎完全符合 OP 的要求。
      猜你喜欢
      • 2012-09-19
      • 2015-06-05
      • 2021-05-13
      • 1970-01-01
      • 2023-01-25
      • 2018-04-23
      • 2013-12-11
      • 2019-01-18
      相关资源
      最近更新 更多