【问题标题】:Why should we normalize data for deep learning in Keras?为什么我们应该对 Keras 中的深度学习数据进行规范化?
【发布时间】:2018-06-25 08:23:06
【问题描述】:

我在 Keras 中测试了一些用于对 MNIST 数据集进行分类的网络架构。我已经实现了一个类似于 LeNet 的。

我已经看到,在我在互联网上找到的示例中,有一个数据规范化的步骤。例如:

X_train /= 255

我在没有这种标准化的情况下进行了测试,我发现网络的性能(准确度)有所下降(保持相同的 epoch 数)。为什么会这样?

如果我增加 epoch 的数量,准确率可以达到与归一化训练的模型相同的水平吗?

那么,归一化影响准确率,还是只影响训练速度?

我的训练脚本的完整源代码如下:

from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dense
from keras.datasets import mnist
from keras.utils import np_utils
from keras.optimizers import SGD, RMSprop, Adam
import numpy as np
import matplotlib.pyplot as plt
from keras import backend as k


def build(input_shape, classes):
    model = Sequential()

    model.add(Conv2D(20, kernel_size=5, padding="same",activation='relu',input_shape=input_shape))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    model.add(Conv2D(50, kernel_size=5, padding="same", activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    model.add(Flatten())
    model.add(Dense(500))
    model.add(Activation("relu"))

    model.add(Dense(classes))
    model.add(Activation("softmax"))

    return model


NB_EPOCH = 4 # number of epochs
BATCH_SIZE = 128 # size of the batch
VERBOSE = 1 # set the training phase as verbose
OPTIMIZER = Adam() # optimizer
VALIDATION_SPLIT=0.2 # percentage of the training data used for 
evaluating the loss function
IMG_ROWS, IMG_COLS = 28, 28 # input image dimensions
NB_CLASSES = 10 # number of outputs = number of digits
INPUT_SHAPE = (1, IMG_ROWS, IMG_COLS) # shape of the input

(X_train, y_train), (X_test, y_test) = mnist.load_data()

k.set_image_dim_ordering("th")

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

X_train = X_train[:, np.newaxis, :, :]
X_test = X_test[:, np.newaxis, :, :]
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

y_train = np_utils.to_categorical(y_train, NB_CLASSES)
y_test = np_utils.to_categorical(y_test, NB_CLASSES)

model = build(input_shape=INPUT_SHAPE, classes=NB_CLASSES)
model.compile(loss="categorical_crossentropy", 
optimizer=OPTIMIZER,metrics=["accuracy"])

history = model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=NB_EPOCH, verbose=VERBOSE, validation_split=VALIDATION_SPLIT)

model.save("model2")

score = model.evaluate(X_test, y_test, verbose=VERBOSE)
print('Test accuracy:', score[1])

【问题讨论】:

  • 归一化加速你的训练速度
  • 这里的performance 是什么意思?是训练速度还是准确性?
  • 我的意思是准确性。

标签: machine-learning neural-network deep-learning keras conv-neural-network


【解决方案1】:

正如@Shridhar R Kulkarni 所说,规范化是一个通用概念,不仅适用于 keras。

它通常用作 ML 学习模型的数据准备的一部分,以更改数据集中的数值以适应标准规模,而不会扭曲其范围内的差异。因此,规范化通过降低数据不一致的概率来增强模型内实体类型的凝聚力。

但是,并非所有其他数据集和用例都需要归一化,当特征具有不同范围时,这主要是必要的。你可以使用when;

  • 您想提高模型的收敛效率并让
    优化可行
  • 当您想让训练对尺度特征不那么敏感时,您可以更好地 求解系数。
  • 想要改进对多个模型的分析。

不建议在以下情况下进行归一化;

-使用决策树模型或基于它们的集成
-您的数据不是正态分布的-您可能必须预先使用其他数据- 加工技术
- 如果您的数据集包含已缩放的变量

在某些情况下,标准化可以提高性能。但是,这并不总是必要的。

关键是先了解你的数据集和场景,然后你就会知道你是否需要它。有时,您可以进行试验,看看它是否能给您带来良好的性能。

查看deepchecks,了解如何处理您在 ML 中遇到的与数据相关的重要检查。

例如,要检查集合中的重复数据,可以使用以下代码detailed code

from deepchecks.checks.integrity.data_duplicates import DataDuplicates
from deepchecks.base import Dataset, Suite
from datetime import datetime
import pandas as pd

【讨论】:

    【解决方案2】:

    我认为优化器功能的收敛也存在一些问题。在这里,我展示了一个简单的线性回归。三个例子: 首先是一个具有小值的数组,它按预期工作。 其次,具有较大值的数组和损失函数会向无穷大爆炸,这表明需要进行归一化。最后在模型 3 中,数组与案例 2 相同,但它已被归一化并且我们得到收敛。

    github colab enabled ipython notebook

    我使用了 MSE 优化器功能,我不知道其他优化器是否遇到同样的问题。

    【讨论】:

    • 这感觉就像一个仅链接的答案。如果没有实际点击链接,我无法从您的帖子中得到任何信息。你能解释一下笔记本中发生了什么吗?
    【解决方案3】:

    简而言之,规范化降低了您的网络试图解决的问题的复杂性。这可能会提高模型的准确性并加快训练速度。您将数据放在相同的规模上并减少差异。网络中的权重都不会浪费在为您进行归一化上,这意味着可以更有效地使用它们来解决手头的实际任务。

    【讨论】:

      【解决方案4】:

      规范化是一个通用概念,不仅限于深度学习或 Keras。

      为什么要标准化?

      让我举一个简单的逻辑回归示例,该示例将易于理解和解释归一化。 假设我们正在尝试预测是否应该向客户提供贷款。在许多可用的自变量中,我们只考虑AgeIncome。 设方程为:

      Y = weight_1 * (Age) + weight_2 * (Income) + some_constant
      

      为了解释起见,让Age 通常在 [0,120] 范围内,让我们假设 Income 在 [10000, 100000] 范围内。 AgeIncome 的规模有很大不同。如果您按原样考虑它们,那么权重 weight_1weight_2 可能会被分配有偏差的权重。 weight_2Income 的重要性可能比 weight_1Age 的重要性更重要。为了将它们缩放到一个共同的水平,我们可以将它们标准化。例如,我们可以将所有年龄带入 [0,1] 范围内,将所有收入带入 [0,1] 范围内。现在我们可以说AgeIncome 作为一个特征被赋予了同等的重要性。

      规范化是否总能提高准确性?

      显然,不。标准化不一定总是会提高准确性。它可能会也可能不会,在您实施之前您永远不会真正知道。同样,这取决于您在训练的哪个阶段应用归一化,取决于您是否在每次激活后应用归一化等。

      由于归一化,特征值的范围缩小到特定范围,因此很容易在较小的值范围内执行计算。因此,通常模型的训练速度会更快。

      关于 epoch 的数量,只要您的模型没有开始过度拟合,准确度通常会随着 epoch 的数量而增加。


      关于规范化/标准化和相关术语的一个很好的解释是here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-05
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 2016-11-12
        • 2019-03-25
        • 2018-10-19
        • 2017-09-17
        相关资源
        最近更新 更多