在 Keras 的 MNIST 数字识别中获得不同的测试数据精度

Posted

技术标签:

【中文标题】在 Keras 的 MNIST 数字识别中获得不同的测试数据精度【英文标题】:Getting different accuracy on test data in MNIST digit recognition in Keras 【发布时间】:2019-04-11 23:51:42 【问题描述】:

我正在使用 Keras 进行 手写数字识别,我有两个文件:predict.pytrain.py

train.py 训练模型(如果尚未训练)并将其保存到一个目录中,否则它只会从保存到的目录中加载经过训练的模型并打印 @ 987654321@和Test Accuracy

def getData():
    (X_train, y_train), (X_test, y_test) = mnist.load_data()
    y_train = to_categorical(y_train, num_classes=10)
    y_test = to_categorical(y_test, num_classes=10)
    X_train = X_train.reshape(X_train.shape[0], 784)
    X_test = X_test.reshape(X_test.shape[0], 784)
    
    # normalizing the data to help with the training
    X_train /= 255
    X_test /= 255
    
 
    return X_train, y_train, X_test, y_test

def trainModel(X_train, y_train, X_test, y_test):
    # training parameters
    batch_size = 1
    epochs = 10
    # create model and add layers
    model = Sequential()    
    model.add(Dense(64, activation='relu', input_shape=(784,)))
    model.add(Dense(10, activation = 'softmax'))

  
    # compiling the sequential model
    model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
    # training the model and saving metrics in history
    history = model.fit(X_train, y_train,
          batch_size=batch_size, epochs=epochs,
          verbose=2,
          validation_data=(X_test, y_test))

    loss_and_metrics = model.evaluate(X_test, y_test, verbose=2)
    print("Test Loss", loss_and_metrics[0])
    print("Test Accuracy", loss_and_metrics[1])
    
    # Save model structure and weights
    model_json = model.to_json()
    with open('model.json', 'w') as json_file:
        json_file.write(model_json)
    model.save_weights('mnist_model.h5')
    return model

def loadModel():
    json_file = open('model.json', 'r')
    model_json = json_file.read()
    json_file.close()
    model = model_from_json(model_json)
    model.load_weights("mnist_model.h5")
    return model

X_train, y_train, X_test, y_test = getData()

if(not os.path.exists('mnist_model.h5')):
    model = trainModel(X_train, y_train, X_test, y_test)
    print('trained model')
    print(model.summary())
else:
    model = loadModel()
    print('loaded model')
    print(model.summary())
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    loss_and_metrics = model.evaluate(X_test, y_test, verbose=2)
    print("Test Loss", loss_and_metrics[0])
    print("Test Accuracy", loss_and_metrics[1])
   

这是输出(假设模型之前训练过,这次模型将被加载):

('测试损失', 1.741784990310669)

('测试精度', 0.414)

predict.py,另一方面,预测一个手写数字:

def loadModel():
    json_file = open('model.json', 'r')
    model_json = json_file.read()
    json_file.close()
    model = model_from_json(model_json)
    model.load_weights("mnist_model.h5")
    return model

model = loadModel()

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

(X_train, y_train), (X_test, y_test) = mnist.load_data()
y_test = to_categorical(y_test, num_classes=10)
X_test = X_test.reshape(X_test.shape[0], 28*28)


loss_and_metrics = model.evaluate(X_test, y_test, verbose=2)

print("Test Loss", loss_and_metrics[0])
print("Test Accuracy", loss_and_metrics[1])

在这种情况下,令我惊讶的是,得到以下结果:

('测试损失', 1.8380377866744995)

('测试精度', 0.8856)

在第二个文件中,我得到的 Test Accuracy 为 0.88(是我之前得到的两倍多)。

另外,model.summery() 在两个文件中是相同的:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 64)                50240     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                650       
=================================================================
Total params: 50,890
Trainable params: 50,890
Non-trainable params: 0
_________________________________________________________________

我无法弄清楚这种行为背后的原因。正常吗?还是我错过了什么?

【问题讨论】:

在训练模型之前没有进行任何预处理吗? 我做到了。编辑了我的问题(我现在已经包含了完整的文件) 我猜你使用的是 Python 2.x? 是的,Python 2.7.15rc1 【参考方案1】:

这种差异是由于一次您使用标准化数据(即除以 255)调用evaluate() 方法而另一次(即在“predict.py”文件中)您使用非标准化数据调用它数据。在推理时间(即测试时间),您应该始终使用与训练数据相同的预处理步骤。

此外,首先将数据转换为浮点数,然后将其除以 255(否则,使用/,在 Python 2.x 中会进行真正的除法,而在 Python 3.x 中运行@987654323 时会出错@和X_test /= 255):

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

X_train /= 255.
X_test /= 255.

【讨论】:

以上是关于在 Keras 的 MNIST 数字识别中获得不同的测试数据精度的主要内容,如果未能解决你的问题,请参考以下文章

深度学习笔记:基于Keras库的MNIST手写数字识别

keras实现mnist数据集手写数字识别

keras实现mnist数据集手写数字识别

keras库的安装及使用,以全连接层和手写数字识别MNIST为例

AI常用框架和工具丨11. 基于TensorFlow(Keras)+Flask部署MNIST手写数字识别至本地web

AI常用框架和工具丨11. 基于TensorFlow(Keras)+Flask部署MNIST手写数字识别至本地web