我正在测试Keras中的一些网络架构,用于对MNIST数据集进行分类。我已经实现了一个类似于LeNet的。
我似乎在我在互联网上找到的示例中,有一个数据规范化步骤。例如:
X_train /= 255
我在没有这种规范化的情况下进行了测试,似乎网络的性能(准确性)已经降低(保持相同的时期数)。为什么会这样?
如果我增加了纪元的数量,精度可以达到通过标准化训练的模型所达到的水平?
那么,归一化会影响准确性,还是仅影响训练速度?
我的培训脚本的完整源代码如下:
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])
答案 0 :(得分:9)
归一化是一个通用概念,不仅限于深度学习或Keras。
为什么要规范化?
让我举一个简单的逻辑回归实例,这个实例很容易理解并解释规范化。
假设我们正在尝试预测客户是否应该获得贷款。在许多可用的自变量中,我们只考虑Age
和Income
。
让方程式为:
Y = weight_1 * (Age) + weight_2 * (Income) + some_constant
为了便于解释,让Age
通常在[0,120]的范围内,让我们假设Income
在[10000,100000]的范围内。 Age
和Income
的比例非常不同。如果您按原样考虑它们,则可以为权重weight_1
和weight_2
分配偏差权重。 weight_2
可能会使Income
作为一项功能更加重要,而weight_1
会使Age
更重要。为了将它们扩展到一个共同的水平,我们可以将它们标准化。例如,我们可以将[0,1]范围内的所有年龄和[0,1]范围内的所有收入都纳入。现在我们可以说Age
和Income
作为一个特征同等重要。
规范化是否始终提高准确度?
显然,不是。标准化不一定总能提高准确性。它可能会也可能不会,在您实施之前,您永远不会知道。同样,这取决于您在训练的哪个阶段应用标准化,是否在每次激活后应用标准化等等。
由于标准化,特征值的范围变窄到特定范围,因此很容易在较小范围的值上执行计算。所以,通常模型训练得更快一些。
关于时期的数量,如果您的模型没有开始过度拟合,精度通常会随着时期的数量而增加。
标准化/标准化及相关术语的一个非常好的解释是here。
答案 1 :(得分:4)
简而言之,规范化降低了网络试图解决的问题的复杂性。这可以提高模型的准确性并加快培训速度。您以相同的比例提供数据并减少差异。在为您进行规范化时,网络中的权重都没有被浪费,这意味着可以更有效地使用它们来解决手头的实际任务。
答案 2 :(得分:0)
我认为优化器函数的收敛也存在一些问题。这里我展示了一个简单的线性回归。三个例子: 首先是一个具有小值的数组,它按预期工作。 其次,具有更大值的数组和损失函数向无穷大爆炸,表明需要归一化。最后在模型 3 中使用与案例 2 相同的数组,但它已被归一化,我们得到了收敛。
github colab enabled ipython notebook
我使用过 MSE 优化器功能,不知道其他优化器是否遇到同样的问题。