machine-learning - 在经过训练的 CNN 模型中使用自己的类似 MNIST 的图像数据进行错误的预测

标签 machine-learning neural-network keras conv-neural-network mnist

我制作了一个 CNN 模型来预测数字,并通过 MNIST 数据进行训练。使用 keras 包装器进行 tensorflow 。我在预测自己的输入数据时遇到困难。我已经使用 epochs = 100 训练了模型,并使用 MNIST 测试集测试了模型,该模型运行良好,准确率约为 97%。我已将此模型保存为“my_model_conv2d.h5”。

第一个代码:

# importing modules
import numpy as np
import keras
import matplotlib.pyplot as plt 
from keras.optimizers import SGD
from keras.models import Sequential
from keras.layers import Dense,Activation,  Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.datasets import mnist
from keras.utils import np_utils 


plt.rcParams['figure.figsize'] = (7,7)

#reading MNIST data
(X_train,y_train),(X_test,y_test)=mnist.load_data('mnist.npz')
print X_train.shape, " train datad shape"
print y_train.shape, " labels shape"

#copying data for plotting 
test=X_test.copy()

#reshaping data type according to the tensorflow param.
X_train=X_train.reshape(X_train.shape[0],X_train.shape[1],X_train.shape[2],1)
X_test=X_test.reshape(X_test.shape[0],X_test.shape[1],X_test.shape[2],1)
input_shape=(X_train.shape[1],X_train.shape[2],1)


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

X_train/=255
X_test/=255

# one_hot vector 
Y_train=np_utils.to_categorical(y_train,10)
Y_test=np_utils.to_categorical(y_test,10)



print X_train.shape, " train datad shape"
print y_train.shape, " labels shape"

#building CNN model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))

#optimizer type initialization
sgd=SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

#compiling model
model.compile(loss='categorical_crossentropy', optimizer='sgd')

#training model 
model.fit(X_train,Y_train, batch_size=128,epochs=100, verbose=1,validation_data=(X_test,Y_test))

#evaluating
score=model.evaluate(X_test,Y_test,verbose=1)
print score,  "score"

#predicting classes using MNIST test data
predicted_classes=model.predict_classes(X_test)
print predicted_classes.shape, "predicted_classes.shape"
correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]

#saving model for future use
model.save('my_model_conv2d.h5')


print len(correct_indices), "no . of correct samples"
print len(incorrect_indices), "no . of incorrect samples"
print str((len(incorrect_indices)/float(len(y_test)))*100)+'%', "error percentage"

#plotting graph of predicted test data
plt.figure()
for i, correct in enumerate(correct_indices[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(test[correct], cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], y_test[correct]))
plt.show()

plt.figure()
for i, incorrect in enumerate(incorrect_indices[:9]):

    plt.subplot(3,3,i+1)
    plt.imshow(test[incorrect], cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], y_test[incorrect]))
plt.show()

我制作了第二个Python代码,用于打开模型“my_model_conv2d.h5”。在这段代码中,我还制作了一个交互式窗口来绘制一个数字,该数字用作预测的输入图像。我已经处理了图像的背景和字体颜色以及大小 (28,28),大约与 MNIST 数据类似。

第二个代码:

import cv2
import numpy as np 

from keras.models import Sequential,load_model



drawing=False 
mode=True 

#function for mouse events
def interactive_drawing(event,x,y,flags,param):
    global ix,iy,drawing, mode

    if event==cv2.EVENT_LBUTTONDOWN:
        drawing=True
        ix,iy=x,y
        print "EVENT_LBUTTONDOWN"

    elif event==cv2.EVENT_MOUSEMOVE:
        if drawing==True:
            print "EVENT_MOUSEMOVE"

            if mode==True:
                print "EVENT_MOUSEMOVE"
                cv2.line(img,(ix,iy),(x,y),1,1)
                ix=x
                iy=y 
    elif event==cv2.EVENT_LBUTTONUP:
        drawing=False
        print "EVENT_LBUTTONUP"
        if mode==True:
            print "EVENT_LBUTTONUP"
            cv2.line(img,(ix,iy),(x,y),1,1)
            ix=x
            iy=y
    return x,y
#function for predicting number
def cnn(img):
    im=img.copy() 

    #loading cnn model 
    model = load_model('my_model_conv2d.h5')
    img=img.reshape(1,28,28,1).astype('float32')

    #prediction of class using drawn image as an input
    predicted_class=model.predict_classes(img)
    print predicted_class, "class"

    cv2.imwrite('actual=9:predicted='+str(predicted_class)+'.jpg',im*255)



#image same as mnist image     
img = np.zeros((28,28), 'float32')
cv2.namedWindow('Drawing_window')
cv2.setMouseCallback('Drawing_window',interactive_drawing)
while(1):
    cv2.imshow('Drawing_window',img*255)
    k=cv2.waitKey(1)&0xFF
    if k==27:
        break
cv2.destroyAllWindows() 
#calling cnn function for prediction
cnn(img)

我的输入数据的大多数预测都是错误的。另外,我在实现CNN之前已经做了全连接层,但结果是一样的。所以,我尝试了 CNN,但问题是一样的。我在第二个代码中检查了 MNIST 的测试数据,运行良好。您可以在这里查看结果 https://drive.google.com/open?id=1E26zinOLrMw7XKhsHd9vnSYoHXzadiJ3 。请检查图像名称,图像名称将显示实际值和预测值。 我哪里做错了请提出建议。

最佳答案

您需要对训练期间的图像使用与推理期间的图像完全相同的预处理。

这就是为什么您的程序以相同的方式标准化训练和测试数据。

X_train/=255
X_test/=255

这也适用于您可能想要执行的任何其他预处理,例如 PCA 或通过 z 分数标准化。

因此,在您的情况下,请确保您的输入图像在除以 255 的范围内 (0,1)(如果 opencv 调用的预期范围为 0 到 255)

编辑:

我只是继续训练模型并尝试了你的程序。事实上,它似乎犯了很多错误(比预期的错误多得多,因为它有 1% 的验证错误)。

enter image description here

我的猜测是,因为 mnist 已经有点 preprocessed ,

The digits have been size-normalized and centered in a fixed-size image.

您的模型可能希望您的测试图像也得到预处理。

我建议使用一些具有更多噪音/旋转的 mnist 变体,这可能会缓解问题。例如:mnist-rot、mnist-back-rand。

关于machine-learning - 在经过训练的 CNN 模型中使用自己的类似 MNIST 的图像数据进行错误的预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47815401/

相关文章:

eclipse - UIMA 中的名称实体关系

python - "ValueError: Expected 2D array, got 1D array instead"将数据拟合到模型中时

python-3.x - 使用分类数据集 : how to deal with different values (less number) in categorical data 进行 One-hot 编码

python - 如何在keras中连接两层?

python - Keras 预测准确度与拟合结果不匹配

python-3.x - Keras 模型 - Unet 图像分割

python - 如何从 BernoulliRBM 获得分数

user-interface - 是否为机器人的神经网络大脑找到合适的编程语言?

python - 我应该如何解释 sparse_categorical_crossentropy 函数的输出?

TensorFlow & Keras 预测阈值