Получение различной точности данных испытаний при распознавании цифр MNIST в Керасе - PullRequest
0 голосов
/ 08 ноября 2018

Я делаю распознавание рукописных цифр с использованием Keras, и у меня есть два файла: Foregnet.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])

Вот вывод (при условии, что модель была обучена ранее, и на этот раз модель будет просто загружена):

(«Испытательная потеря», 1,741784990310669)

(«Точность теста», 0,414)

realt.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
_________________________________________________________________

Я не могу понять причину этого поведения. Это нормально? Или я что-то упустил?

1 Ответ

0 голосов
/ 08 ноября 2018

Расхождение возникает из-за того, что один раз вы вызываете метод evaluate() с нормализованными данными (т. Е. Разделенными на 255), а в другой раз (например, в файле "Foregnet.py") вы вызываете его с ненормализованным данные. Во время вывода (т. Е. Времени тестирования) вы всегда должны использовать один и тот же этап предварительной обработки, который вы использовали для обучающих данных.

Далее, сначала преобразуйте данные в число с плавающей запятой, а затем разделите их на 255 (в противном случае при / в Python 2.x выполняется истинное деление, а в Python 3.x вы получите ошибки при запуске * 1005). * и X_test /= 255):

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

X_train /= 255.
X_test /= 255.
...