在 Keras 的 MNIST 数字识别中获得测试数据的不同准确度
Getting different accuracy on test data in MNIST digit recognition in Keras
我正在使用 Keras 进行手写数字识别,我有两个文件:predict.py 和 train.py.
train.py 训练模型(如果尚未训练)并将其保存到一个目录,否则它只会从它所在的目录加载训练好的模型被保存到并打印 Test Loss
和 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])
这是输出(假设模型之前训练过并且这次模型将被加载):
('Test Loss', 1.741784990310669)
('Test Accuracy', 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])
在这种情况下,令我惊讶的是,得到以下结果:
('Test Loss', 1.8380377866744995)
('Test Accuracy', 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
_________________________________________________________________
我无法弄清楚此行为背后的原因。正常吗?还是我遗漏了什么?
差异是由于您一次使用标准化数据调用 evaluate()
方法(即除以 255)而另一次(即在 "predict.py" 文件中)调用它使用非标准化数据。在推理时间(即测试时间),您应该始终使用与训练数据相同的预处理步骤。
进一步,首先将数据转换为浮点数,然后除以255(否则,使用/
,真正的除法是在Python 2.x和Python 3.x 当 运行 X_train /= 255
和 X_test /= 255
时你会得到错误:
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255.
X_test /= 255.
我正在使用 Keras 进行手写数字识别,我有两个文件:predict.py 和 train.py.
train.py 训练模型(如果尚未训练)并将其保存到一个目录,否则它只会从它所在的目录加载训练好的模型被保存到并打印 Test Loss
和 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])
这是输出(假设模型之前训练过并且这次模型将被加载):
('Test Loss', 1.741784990310669)
('Test Accuracy', 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])
在这种情况下,令我惊讶的是,得到以下结果:
('Test Loss', 1.8380377866744995)
('Test Accuracy', 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
_________________________________________________________________
我无法弄清楚此行为背后的原因。正常吗?还是我遗漏了什么?
差异是由于您一次使用标准化数据调用 evaluate()
方法(即除以 255)而另一次(即在 "predict.py" 文件中)调用它使用非标准化数据。在推理时间(即测试时间),您应该始终使用与训练数据相同的预处理步骤。
进一步,首先将数据转换为浮点数,然后除以255(否则,使用/
,真正的除法是在Python 2.x和Python 3.x 当 运行 X_train /= 255
和 X_test /= 255
时你会得到错误:
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255.
X_test /= 255.